Torth
Jump to navigation
Jump to search
| Paradigm(s) | Concatenative |
|---|---|
| Designed by | User:DolphyWind |
| Appeared in | 2024 |
| Memory system | Stack-based |
| Computational class | Turing complete |
| Major implementations | Torth |
| Influenced by | Forth |
| File extension(s) | .tth |
Torth is a Forth-like esoteric programming language created to write Olus2000 programs with ease. Torth uses a single stack memory system that operates with ternary integers. All binary operations, including addition, multiplication, and comparison, follow the Forth-style approach.
Grammar
<Program> ::= <Block>
<Block> ::= <Stmt> <WS> <Block> | ε
<Stmt> ::= <Word> | <SpecialWord> | <Number> | <String> | <IfStmt> | <WhileStmt> | <Colon> | <Comment>
<Word> ::= <Letter> { <Letter> | <Base10Digit> | "-" }
<Number> ::= [ "+" | "-" ] <TernaryDigit> { <TernaryDigit> }
<String> ::= "\"" { <CHARACTER> } "\""
<IfStmt> ::= "IF" <WS> <Block> [ "ELSE" <WS> <Block> ] "THEN"
<WhileStmt> ::= "WHILE" <Block> "THEN"
<Colon> ::= ":" <WS> ( <Word> | <SpecialWord> ) <WS> <Block> ";"
<Comment> ::= "(" <WS> { <CHARACTER> } <WS> ")"
<Letter> ::= "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N"
| "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "a" | "b"
| "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p"
| "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "_" ;
<Base10Digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<TernaryDigit> ::= "0" | "1" | "2"
<SpecialCharacter> ::= "!" | "@" | "#" | "$" | "%" | "^" | "&" | "*" | "(" | ")" | "-"
| "=" | "+" | "[" | "]" | "{" | "}" | ";" | ":" | "'" | "," | "."
| "/" | "?" | "<" | ">" | "|" | "\\" | "~" | "`" | " "
<SpecialWord> ::= "." | "," | "+" | "-" | "*" | "/" | "%" | "<" | "<=" | "==" | "!=" | ">=" | ">"
<EscapeSequence> ::= "\\" ( "\"" | "\\" | "n" | "t" | "r" | "\'" )
<WhiteSpace> ::= " " | "\t" | "\n"
<WS> ::= <WhiteSpace> { <WhiteSpace> }
<CHARACTER> ::= <Letter> | <Base10Digit> | <SpecialCharacter> | <EscapeSequence>
Numbers
When encountered, numbers of Torth are directly pushed onto the stack, just like how it is done in Forth.
Strings
When a string statement is executed, the content of the string is immediately printed to the console. The program below prints "Hello World!" and inserts a new line
"Hello World!\n"
Words
By following Forth, Torth allows creation of custom words. Below, you can find a list of built-in words.
| Word | Action |
|---|---|
| . | Pops the top value and prints it to stdout as a ternary integer
|
| , | Reads a ternary integer from the stdin and pushes it onto the stack
|
| + | Pops two ternary integers and pushes their sum |
| - | Pops two ternary integers and pushes their difference |
| * | Pops two ternary integers and pushes their product |
| / | Pops two ternary integers, applies integer division and pushes the result |
| % | Pops two ternary integers, applies modulo operation and pushes the result |
| < | Pops two ternary integers and pushes 1 if the second one is less than the first one. Otherwise pushes zero |
| <= | Pops two ternary integers and pushes 1 if the second one is less than or equal to the first one. Otherwise pushes zero |
| == | Pops two ternary integers and pushes 1 if the second one is equal to the first one. Otherwise pushes zero |
| != | Pops two ternary integers and pushes 1 if the second one is not equal to the first one. Otherwise pushes zero |
| >= | Pops two ternary integers and pushes 1 if the second one is greater than or equal to the first one. Otherwise pushes zero |
| > | Pops two ternary integers and pushes 1 if the second one is greater than the first one. Otherwise pushes zero |
| REVERSE | Reverses the entire stack |
| DUP | Pops the top value and pushes it back twice |
| SWAP | Reverses the order of the top two elements on the stack |
| DROP | Pops the top value |
| ROT | Rotates the top three values |
| DEPTH | Pushes the current length of the stack to the stack itself |
| IF | If statement, must be terminated with THEN. Checks, without popping, the top value of the stack. If it is a nonzero executes its body
|
| ELSE | Else keyword, must be used between IF and THEN. Executes its body if the previous if block didn't execute
|
| THEN | Marks the end of IF or WHILE words
|
| WHILE | While loop, must be terminated with THEN. Executes its body as long as the top value of the stack is non-zero without removing the value it checks
|
| : | Used to create new words, must be terminated with ;
|
| ; | Marks the end of :
|
| GET | Pops an index and moves the item at the given index to the top of the stack |
| SET | Pops a ternary integer and a stack index. Moves the integer to the specified index |
Examples
Some example programs written in Torth
Truth-Machine
, DUP . WHILE DUP . THEN
99 Bottles of Beer on The Wall
: WRITE_9 IF DROP "ERROR" ELSE DROP "9" THEN ; : WRITE_8 IF 1 - WRITE_9 ELSE DROP "8" THEN ; : WRITE_7 IF 1 - WRITE_8 ELSE DROP "7" THEN ; : WRITE_6 IF 1 - WRITE_7 ELSE DROP "6" THEN ; : WRITE_5 IF 1 - WRITE_6 ELSE DROP "5" THEN ; : WRITE_4 IF 1 - WRITE_5 ELSE DROP "4" THEN ; : WRITE_3 IF 1 - WRITE_4 ELSE DROP "3" THEN ; : WRITE_2 IF 1 - WRITE_3 ELSE DROP "2" THEN ; : WRITE_1 IF 1 - WRITE_2 ELSE DROP "1" THEN ; : WRITE_0 IF 1 - WRITE_1 ELSE DROP "0" THEN ; : WRITE_HELPER DEPTH IF DROP 1 + IF 1 - ELSE DROP WRITE_0 WRITE_HELPER THEN ELSE DROP THEN ; : WRITE_NUM IF DUP 101 % SWAP -1 SWAP 101 / WRITE_NUM ELSE DROP WRITE_HELPER THEN ; : BOTTLES DUP 1 - IF DROP "bottles" ELSE DROP "bottle" THEN ; : LAST_LINE DUP IF WRITE_NUM ELSE DROP "No more" THEN " " BOTTLES " of beer on the wall.\n\n" ; : BEER_REGULAR DUP WRITE_NUM " " BOTTLES " of beer on the wall,\n" DUP WRITE_NUM " " BOTTLES " of beer.\nTake one down, pass it around\n" 1 - LAST_LINE ; : BEER DUP IF BEER_REGULAR BEER THEN ; 10200 BEER
Look And Say Sequence
: PRINT_3 IF DROP "ERROR" ELSE DROP "3" THEN ;
: PRINT_2 IF 1 - PRINT_3 ELSE DROP "2" THEN ;
: PRINT_1 IF 1 - PRINT_2 ELSE DROP "1" THEN ;
: PRINT_NUM 1 - PRINT_1 ;
: PRINT_STACK (For debug purposes) DEPTH IF DROP "[ " . " ]\n" PRINT_STACK THEN ;
: OPERATE_BODY
DUP ROT SWAP DUP ROT ==
IF
DROP 0 GET 1 + 0 SWAP SET DROP
ELSE
DROP DUP 0 SWAP SET 0 1 SET SWAP DROP
THEN
;
: OPERATE
SWAP DUP -1 !=
WHILE
DROP SWAP OPERATE_BODY SWAP DUP -1 !=
THEN
DROP SWAP DROP DROP
;
: STEP
OPERATE REVERSE DEPTH
WHILE
SWAP DUP PRINT_NUM 0 SWAP SET 1 -
THEN "\n" DROP -1 REVERSE 0
;
(Initial state of the stack) -1 1 0
(Print 1) 1 PRINT_NUM "\n"
(Print the look and say sequence indefinitely) 1 WHILE DROP STEP 1 THEN