Stacks of Queues
A language based on using stacks and queues to manipulate values, created by User:Jemhunter.
Concept
Everything is performed on a stack or a queue, represented by a pair of brackets and depending on the type of brackets used determines the exact behaviour of the structure.
It is intended that this language be a relatively simple way to work with pure stacks and queues, hence the range of manipulation methods. As well as being created to be usable for at least basic programming so that the usage and comparison of stacks and queues can be explored by the programmer.
For example:
(53(T4*G))
Would first create the stack 5, 3.
Then the sub stack begins with no values
The the popped value 3 is pushed to the new stack via the take (T) command, leaving only 5 in the original stack.
Then 4 would be pushed, and then the product calculated which would be 12. So the sub stack would contain only 12.
The sub stack gives (G) the top value from its stack and so pushes value 12 back to the parent stack so the original stack would be 5, 12.
The program would end so the values would be output: 12 then 5.
This language is heavily inspired by similar stack based languages such as ><> (which also was very informative in using argparse in python) and befunge but without being 2d and thus needing another way to create conditions and loops.
Program Structure
The program should entirely be contained within stack and queue braces, any invalid character is considered a no-op and any characters outside the braces is considered a comment. If there are no braces in a program nothing happens but the failure to close a brace will result in an error.
Creating sub stacks and queues and combining with the conditional operator allows for both conditional code and for sub sections of programs which do not interfere with the current working stack or queue.
A program may contain multiple top level stacks or queues which will be fully evaluated before moving on to the next.
If when the current structure ends there is no parent structure the interpreter will automatically display each of the values in the structure. This respects the current output mode and places spaces between numeric values.
The only other error occurs when attempting to divide by 0. All attempts to pop or dequeue from an empty structure give -1.
Files should be utf-8 encoded and saved with a .sq extension.
Command Characters
A comprehensive list of reserved characters and what they do. Any value not in this list, including newlines and spaces, are considered no-op as well as any commands that appear outside of a working stack or queue.
Literals
0-9 a-z |
Pushes or enqueues the numerical value from 0 to 35, with a representing 10 and z 35. |
' |
Switch to character mode where all characters will be read and their ordinal value pushed or enqueued instead of their usual meaning until another single quote is reached (it is impossible to add the ' character using this method but its ordinal value is 39). |
Operators
All of these operators pop or dequeue two items (depending on the current structure) and push or enqueue the result
Arithmetic
+ |
Add, returns the sum of the two values. |
- |
Subtract, returns the result of the first subtracted from the second. |
* |
Multiply, returns the product of the two values. |
/ |
Divide, returns the result of the second divided by the first. |
\ |
Integer Division - returns the quotient (whole number part) of the second divided by the first. |
% |
Modulo - returns the remainder of the second divided by the first. |
Logical
= |
Equal, returns 1 if the two values are the same 0 otherwise. |
M |
Greater than, returns 1 if the second item is greater than the first, 0 otherwise. |
W |
Less than, returns 1 if the second item is smaller than the first, 0 otherwise. |
Stacks and Queues
() |
Stack, a new working stack is created, when the end is reached the stack is removed and control returns to the original parent structure. |
{} |
Queue, a new working queue is created, when the end is reached the queue is removed and control returns to the original parent structure. |
<> |
Repeating Stack, same as () except when > is reached execution jumps back to the paired <, meaning that the old sub-stack will be removed and replaced with a new empty one is created, the content of the <> stack is performed again. |
[] |
Repeating Queue, same as {} except when ] is reached execution jumps back to the paired [, meaning that the old sub-queue will be removed and replaced with a new empty one is created, the content of the [] queue is performed again. |
Conditional
? |
A conditional jump, pops or dequeues a value and if it is less than or equal to 0 the next instruction is skipped. If this skips a stack or queue start it skips the entire stack or queue execution. If this skips the end of a stack or queue it terminates the stack or queue even if it would repeat. |
Stack / Queue Manipulation
R |
Reverse the current stack or queue. |
S |
Swap the top two items of the current stack or queue. |
D |
Duplicate the top item of the current stack or queue. |
P orQ |
Removes the top item of the current stack or queue (while they are named for Pop and deQueue both do the same for stacks and queues, it is just for logical convenience). |
L |
Pushes or enqueues the length of the current structure. |
F |
Forward rotation, top item becomes bottom and all others shifted up. |
B |
Backward rotation, bottom item becomes top and all others shifted down. |
T |
Take, one item is popped or dequeued from the parent structure (if there is one) and added to the current working stack or queue. If there is no parent structure -1 will be retrieved. |
G |
Give, one item is popped or dequeued from the current working stack or queue and is pushed or enqueued onto the parent structure. If there is no parent structure this is the same as P or Q .
|
Input
X |
Single character mode, change input mode to take only a single character from the user, if the interpreter receives more than one character only the first character's ordinal value is pushed or enqueued. |
Y |
Line mode, change input mode to take a full line of characters from the user up to a new line, each ordinal value is pushed or enqueued in turn. |
Z |
Number mode, change input mode to take a single numerical value from the user, a number may be negative and contain a fractional part, if an invalid value is entered the value should be interpreted as -1. |
I |
Request input from the user, respecting the current input mode. |
Output
When the end of the program is reached without an error occurring the contents of the final stack or queue are automatically output, respecting the current output mode
C |
Character mode, change output mode to display character associated with ordinal value, negative values display nothing. |
N |
Number mode, change output mode to display numerical values. |
O |
Pop or dequeue once and output the value, respecting the current output mode. |
Example Programs
Hello World
('Hello World!'RC)
A simple hello world using a stack and reversing the values so it can be written forwards.
('!dlroW olleH'C)
Slightly shorter as stack does not need to be reversed.
{'Hello World!'C}
Using a queue instead makes the above example more readable but the same length.
('!dlroW olleH'C<TDO?>)
And a version that will do the same thing but does not make use of the automatic printing, useful within other code.
Cat
[DCYIFDDB?<TDO?>aBO?]
A cat program that will repeatedly copy input to output until an empty line is given.
{CYI}
A very simplified version that repeats one line.
{CYI01BBS-<TDDGO?><TDO?>}
A double cat that outputs the input twice.
Infinite Loop
<>
and []
Both are infinte loops.
Fibonacci Sequence
(10<TTSDOaCONSDF+GG>)
Infinite fibonacci sequence, recommended to use -t with the original interpreter to add a delay so you can read the values.
({'How many? >'C<TDO?>}NI01<TTTDG0M?(TTSDOaCONSDF+GG)T1-DGFGG?><T?>)
Or a more usable version which asks for a number of items and prints that many fibonacci numbers, number given should be greater than 0 (and floats will be rounded up).
Truth Machine
(ID0=?(0O)1=?<1O>)
Basic truth machine, outputs 0 and terminates if 0 is entered, repeatedly outputs 1 if 1 is entered and just terminates otherwise.
Zeller's Congruence
(C{'Enter the year >'<TDO?>}I
{'Enter the month number >'<TDO?>}ID3W?(Tc+T1-GG)
{'Enter the day number >'<TDO?>}I
(TT1+d*5\TDaa*%D4\+Saa*\D4\S02-*++++7%G)
D0=?{'Saturday'<TDO?>}
D1=?{'Sunday'<TDO?>}
D2=?{'Monday'<TDO?>}
D3=?{'Tuesday'<TDO?>}
D4=?{'Wednesday'<TDO?>}
D5=?{'Thursday'<TDO?>}
6=?{'Friday'<TDO?>})
An implementation of Zeller's Congruence for the Gregorian calendar, with input, printed output and using newlines to improve readability.
Computational Class
Currently unknown. But should be at least be equivalent to a push-down automaton. Some form of storage (probably a stack and a queue) that is globally accessible could be added if it would be needed to be turing complete.