Torth

From Esolang
Jump to navigation Jump to search
Torth
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.

Torth 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