A simple stack-based programming language interpreter written in Rust.
This is a minimalist stack-based language similar to Forth or PostScript. Programs manipulate a stack of 32-bit integers and can store values in named variables.
cargo build --releasecargo run <program_file>Example:
cargo run examples/countdown.emu- PUSH <value|variable> - Push a number or variable value onto the stack
PUSH 42 # Push literal 42
PUSH x # Push value of variable x
- POP - Pop and print the top value from the stack
PUSH 5
POP
- ADD - Pop two values, push their sum
PUSH 3
PUSH 4
ADD # Stack: [7]
- SUB - Pop two values, push their difference (second - first)
PUSH 10
PUSH 3
SUB # Stack: [7]
- ASSIGN - Pop top value and store it in a variable
PUSH 42
ASSIGN x # x = 42
- VAR - Print the value of a variable
VAR x # Prints: 42
- LABEL - Mark a position in the program for jumping
LABEL loop_start
- JNZ - Pop a value; if non-zero, jump to the label
PUSH 1
JNZ loop_start # Jumps if top of stack != 0
- GZ - Pop a value; push 1 if > 0, otherwise push 0
PUSH 5
GZ # Stack: [1]
- PRINT - Print literal text
PRINT Hello # Prints: "Hello"
PUSH 5
LABEL loop
ASSIGN counter
VAR counter # Prints: counter
PUSH counter
PUSH 1
SUB
JNZ loop
PUSH 10
PUSH 5
ADD
POP # Prints: 15
PUSH 20
PUSH 7
SUB
POP # Prints: 13
PUSH 42
ASSIGN x
PUSH 8
ASSIGN y
PUSH x
PUSH y
ADD
POP # Prints: 50
PUSH 1
PUSH 2
ASSIGN x
ASSIGN y
PUSH 10
LABEL fib
ASSIGN counter
PUSH y
PUSH x
ADD
PUSH x
ASSIGN y
ASSIGN x
PUSH counter
PUSH 1
SUB
JNZ fib
PRINT RESULT
VAR x
The interpreter provides detailed error messages with line numbers:
ERROR: Invalid PUSH operation at LINE: 5: Variable does not exist
ERROR: Invalid POP operation at LINE: 3: Empty stack
- Only supports 32-bit signed integers
- No floating-point arithmetic
- No string manipulation
- No file I/O operations
- No functions/subroutines