# Soallang

Paradigm(s) | stack-driven |
---|---|

Designed by | HungKhanh0106 |

Appeared in | 2022 |

Memory system | Stack-based |

Dimensions | one-dimensional |

Computational class | Turing complete |

Reference implementation | Scratch |

Influenced by | Piet Scratch Volatile |

File extension(s) | `.sl` |

**Soallang** is a stack-based esoteric programming language designed by HungKhanh0106 (talk).

## Data structure

Soallang's only data structure is a dynamic block containing either a string, an integer or a floating-point number. It is required to be enclosed using quotation marks for convenience since interpreters will be determined to bundle a whole script into single-line (see § Commands). It can be simply referred to as a "memory block".

### 64-bit numerals

There is an optional criterion for memory blocks that can be implemented, which is 64-bit numerals. In case of that, numbers can only range from -9223372036854775807 to 9223372036854775807, in which an undefined behaviour will occur at overflow.

## Error detection

For Soallang, errors that are syntactically- and statement disclosure-related are required to be announced at runtime (excluding compilers). Meanwhile, segmentation faults relating to stack access (TL;DR stack out-of-bounds) are required to be omitted. Any other errors are considered of undefined behaviour.

## Commands

Soallang commands are executed from left to right, character by character. It is noted that multi-lined scripts may be stacked upon a line while retaining its full context (for interpreters). Currently, there are 19 commands and 1 initialiser.

Instruction | Pseudo-code |
---|---|

`[" or ']` (to be written)`[" or ']` |
Push |

`~` |
Pop |

`+` /`a/code>` |
Add |

`-` /`s` |
Subtract |

`*` /`m` |
Multiply |

`/` /`d` |
Subtract |

`%` /`r` |
Modulo |

`&` |
And |

`|` |
Or |

`\` |
Xor |

`!` |
Not |

`>` |
Greater |

`<` |
Lower |

`=` |
Equal |

`$` |
Swap |

`]` |
Jump past if |

`[` |
Jump back if |

`^` |
Fore |

`:` |
Duplicate |

`,` |
Roll |

`i` |
Input |

`o` |
Output |

### Usage

**Push:**Pushes a block of memory onto the stack.**Pop:**Pops the top value off the stack.**Add:**Pops the top two blocks off the stack, sums them up, then pushes the result back onto the stack.**Subtract:**Pops the top two blocks off the stack, subtracts the top value from the second-top value, and pushes the difference back onto the stack. Note that if the top block contains*x*and the next block is*y*, this means that*y ÷ x*will be pushed, not*x ÷ y*.**Multiply:**Pops the top two values off the stack, multiplies them together, and pushes the product back onto the stack.**Divide:**Pops the top two values off the stack, performs division on the second-to-top value divided by the top value, and pushes the quotient back onto the stack. This has the same stack evaluation order as Subtraction.**Modulo:**Pops the top two blocks off the stack, divides the second-top value by the top value, and pushes the remainder back onto the stack. This has got the same stack evaluation order as Subtraction.**Not:**Pops the top value off the stack. If the value is 0, it pushes 1 onto the stack. Otherwise, it pushes 0.**Lower:**Pops the top two blocks off the stack. If the second-top value is lower than the top value, it pushes 1 onto the stack. Otherwise, it pushes 0. This has the same stack evaluation order as Subtraction.**Greater:**Pops the top two blocks off the stack. If the second-top value is greater than the top value, it pushes 1 onto the stack. Otherwise, it pushes 0. This has the same stack evaluation order as Subtraction.**Equal**: Pops the top two blocks off the stack. If the second-top value is equal to the top value, it pushes 1 onto the stack. Otherwise, it pushes 0. This has the same stack evaluation order as Subtraction.**Swap**: Pops the top two blocks off the stack, orders back the top value to before the second-top value.**Jump past if**: Jumps past the next ']' if the top value is non-zero.**Jump back if**: Jump back to the previous '[' if the top value is non-zero.**Fore**: Directs the interpreter back to the previous command if the top value is non-zero.**Duplicate:**Pushes a copy of the top value onto the stack.**Roll:**Pops the top two values off the stack, and then rotates the top Y values on the stack up by X, wrapping values that pass the top around to the bottom of the rolled portion, where X is the first value popped (top of the stack), and Y is the second value popped (second on the stack). (Example: If the stack is currently {1, 2, 3}, with 3 at the top, and then you push 3 and then 1, and then roll, its result will be {3, 2, 1}.)**Input:**Takes a user input, then pushes it onto the stack.**Output:**Pops the top value off the stack then prints it.

## Examples

### Hello, world!

"Hello, world!"o

### Cat program

io

### Truth-machine

''i!]![~'1':o[]

### 99 bottles of beer

'100'['1's:::' bottles of beer.'+,' bottles of beer on the wall,'+,$ 'Take one down, pass it around,'$'1's:'0'=]~' bottles of beer on the wall.' +'',o$o$o$o$o:'1'-~[]~~~,$~,'No bottles of beer on the wall.',oooo$~