Whitespace is a command-oriented stack-based programming language that provides programmers with a stack and heap.
All operations operate internally on integers of arbitrary bit length. However, there is an option to output a character identified by its ASCII code value.
The commands and control statements consist of defined sequences of spaces (s), tab characters (t), and linefeed (l).
There is no syntax element to identify comments. Instead, comments, which themselves must not contain whitespaces, can be entered anywhere in the source code. The interpreter ignores all characters that have no meaning for it.
Commands
Commands are composed of sequences of spaces, tab stops and linefeeds. For example, t-s-s-s performs arithmetic addition of the top two elements on the stack. Data is represented in binary using spaces (0) and tabs (1), followed by a linefeed; thus, s-s-s-t-s-t-t-l is the binary number 0001011, which is 11 in decimal. All other characters are ignored and thus can be used for comments.
Code is written as an Instruction Modification Parameter (IMP) followed by the operation and a parameter if needed.
IMP | Meaning |
s | Stack Manipulation |
t s | Arithmetic |
t t | Heap Access |
l | Flow Control |
t l | Input/Output |
Stack manipulation
IMP | Command | Parameter | Meaning |
---|---|---|---|
s | s | Number | Push the number onto the stack |
s | l s | – | Duplicate the top item on the stack |
s | l t | – | Swap the top two items on the stack |
s | l l | – | Discard the top item on the stack |
Arithmetic
IMP | Command | Parameter | Meaning |
---|---|---|---|
t s | s s | – | Addition |
t s | s t | – | Subtraction |
t s | s l | – | Multiplication |
t s | t s | – | Integer Division |
t s | t t | – | Modulo |
Heap Access
IMP | Command | Parameter | Meaning |
---|---|---|---|
t t | s | – | Store in heap |
t t | s | – | Retrieve from heap |
Flow Control
IMP | Command | Parameter | Meaning |
---|---|---|---|
l | s s | Label | Mark a location in the program |
l | s t | Label | Call a subroutine |
l | s l | Label | Jump to a label |
l | t s | Label | Jump to a label if the top of the stack is zero |
l | t t | Label | Jump to a label if the top of the stack is negative |
l | t t | – | End a subroutine and transfer control back to the caller |
l | l l | – | End the program |
Input/Output
IMP | Command | Parameter | Meaning |
---|---|---|---|
t l | s s | – | Output the character at the top of the stack |
t l | s t | – | Output the number at the top of the stack |
t l | t s | – | Read a character and place it in the location given by the top of the stack |
t l | t t | – | Read a number and place it in the location given by the top of the stack |
Data
While the commands use a three-valued place system, the data is mapped in the dual system: In the first place from the left, a “t” represents a negative number; a “l” represents a positive number. Further on, “t” stands for 1 and “l” for 0. The specification states that numbers can have any bit length, but compilers and interpreters can set a reasonable upper limit here. A datum is terminated by a line break.