I built this to understand how compilers actually work (at least in theory). Not just reading about it, but trying to implement each phase myself.
I'm learning Rust, and it's memory-safe without garbage collection. Building this project seemed like a good way to practice Rust concepts.
Takes simple math expressions and variables, compiles them to bytecode, then runs them.
let x = 10
let y = 20
print x + y
That's it.
Lexer -> Breaks text into tokens (numbers, operators, keywords)
Parser -> Builds a tree structure (AST) from tokens using recursive descent
Compiler -> Converts the tree into bytecode instructions
VM -> Executes the bytecode on a stack
cargo run examples/tests.txt
cargo run examples/variables.txt
cargo run examples/errors.txt- How operator precedence works (multiplication before addition)
- Why recursive descent parsing is intuitive
- Stack-based VM Implementations are simpler than I thought
- Error handling with line/column numbers
lexer.rs- Character by character scanningparser.rs- Recursive descent, one function per precedence levelcompiler.rs- Walks the AST and emits bytecodevm.rs- Stack machine that executes instructionsbytecode.rs- Instruction definitions (Add, Multiply, LoadVar, etc.)ast.rs- Tree node typestoken.rs- Token typeserror.rs- Error handling with locations
Variables, arithmetic (+, -, *, /), parentheses, negative numbers, print statements, comments. That's all.
If-Else statementsLoopsFunctionsStrings