StaPLe
StaPLe (Stack Processing Language) is a stack-based programming language created by User:BCompton in 2014 influenced by Lisp and Joy, among others.
Stacks
Almost everything in the language is stored on a pair of stacks. Stack one starts as the code stack, and stack two starts as the data (current) stack. There is also a register that can be used for storing a single token.
You can push and pop to either stack, depending on what stack is currently selected. The flip command changes the current stack. The warp command changes the code stack.
It's possible to have the data stack and the code stack pointing to the same stack. This can lead to infinite loops in many cases.
New stacks can be created with square brackets []. They can include commands inside them. You can push to and pop from created stacks using <- and ->. Subroutines can be executed by constructing a stack and then calling eval, which unwraps the new stack and pushes it onto the code stack.
Code
The code stack is initially populated by the source code, with the last commands in the code being the first to be executed.
Code execution begins by popping the code stack, then executing the command that was popped. If the item popped is not a command, it will be pushed on to the current stack.
Execution continues until there are no items left on the code stack.
Code tokens are terminated with a ;
. Comments start with a #
and go to the next ;
. Strings start with a "
and continue to the ;
. There is no escape character.
Register
You can prepend a command with R to access the register instead of the current stack.In the case of multi - parameter commands, the FIRST value popped will be from the register. Items popped from any stack will be stored in the register - the current value in the register will be clobbered. You can store a code defined stack in the register.
Types
The supported types in StaPLe are integers, strings, booleans, commands, and stacks. Stacks can be nested. All types have truthey and falsey values.
Instructions
StaPLe has the following commands:
Mathematical Operations
Cmd | Description | Allow R tag |
---|---|---|
+
|
Addition: Pop a and b, then push a+b | Yes |
-
|
Subtraction: Pop a and b, then push b-a | Yes |
*
|
Multiplication: Pop a and b, then push a*b | Yes |
/
|
Division: Pop a and b, then push b/a, rounded down. | Yes |
%
|
Modulo: Pop a and b, then push b%a. | Yes |
^
|
Exponentiation: Pop a and b, then push b^a. | Yes |
Stack Operations
Cmd | Description | Allow R tag |
---|---|---|
push
|
Push from register to current stack. | No |
pop
|
Pop from current stack to register. | No |
swap
|
Swap the top two values of the current stack. | Yes |
dup
|
Duplicate the top value of the current stack. | No |
drop
|
Discard the top token of the current stack. | Yes |
rot
|
Rotate the top values of the two stacks. | Yes |
flip
|
Change the current stack. | No |
warp
|
Change the code stack. | No |
drain
|
Drains the current stack. | Yes |
<-
|
Push to stack on top of current stack. | Yes |
->
|
Pop from stack on top of current stack. | Yes |
Boolean Operations
If a boolean operation pops a stack as a parameter, the stack will be evaluated before the condition is resolved. Be aware, this happens on the same stacks as the rest of the program, so side effects are always possible.
Cmd | Description | Allow R tag |
---|---|---|
>
|
Pop a and b, then push b > a. | Yes |
<
|
Pop a and b, then push b < a. | Yes |
>=
|
Pop a and b, then push b >= a. | Yes |
<=
|
Pop a and b, then push b <= a. | Yes |
!
|
Pop the top of the current stack, push True if 0, False otherwise. | Yes |
==
|
Pop a and b, then push a == b. | Yes |
&&
|
Pop and b, then push a && b. | Yes |
||
|
Pop a and b, then push a || b. | Yes |
Flow Control
Cmd | Description | Allow R tag |
---|---|---|
eval
|
Pops the current stack, unwraps if necessary, then appends to the code stack. | Yes |
unwrap
|
Takes a stack, and appends the contents of the stack to the current stack. | Yes |
if
|
Pops a, b. If a is true, eval b.
|
Yes |
ife
|
Pops a, b, c. If a is true, eval b, else eval c.
|
Yes |
I/O
Cmd | Description | Allow R tag |
---|---|---|
get
|
Get input, interpreted as code tokens, and push to current stack. | No |
getc
|
Get input, interpreted as a string, and push to current stack. | Yes |
put
|
Pop current stack, output based on token type. | Yes |
putc
|
Same as put, but it will convert a number to its ascii value. | Yes |
Example Programs
Hello World
drain; flip; warp; unwrap; [eval;]; [putc;]; "Hello world!; unwrap; [warp;];
This will also work, but isn't near as fun:
put;"Hello world!;
Factorial
eval;dup;[eval;dup;swap;ife;swap;[pop;*;push;dup;];swap;[drain;flip;Rput;];dup;-;1;swap;];pop;dup;get;
Truth-machine
eval;pop;dup;[if;put;dup;swap;[eval;pop;dup;push;dup;];];dup;get;
Deadfish interpreter
eval;dup; [eval;dup;if;swap;[R0;];||;!;+;1;swap;!;-;256;dup;pop;dup;push;ife;swap; [drop;pop;+;1;push;];swap;[ife;swap;[drop;pop;-;1;push;];swap;[ife;swap; [drop;pop;*;dup;push;];swap;[ife;swap;[putc;10;put;pop;dup;push;]; swap;[putc;10;];==;"o;];==;"s;dup;];==;"d;dup;];==;"i;dup;getc;];R0;