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