Rox is a strongly-typed, tree-walk interpreter, implemented in Rust.
Based on the excellent book Crafting Interpreters by Bob Nystrom, this implementation diverges to Rust patterns, focusing on memory safety, strict type checking, and a robust error handling architecture.
- Tree-Walk Architecture: Implements a complete recursive descent parser and a direct AST evaluator.
- Object-Oriented: Full support for Classes, Inheritance, Methods, Initializers, and super calls.
- Lexical Scoping & Closures: Robust environment management allowing for first-class functions and closures.
- Strict Type System: Rox adopts a Rust-like philosophy, rejecting implicit type coercions (e.g., "1" + 1 raises a runtime error).
- Control Flow: Supports if-else, while, and for loops, along with semantic checks for break, continue, and return.
- Extended Operations: support for bitwise arithmetic and compound assignment operators.
Rox implements a standard compiler pipeline with a focus on separation of concerns:
- Tokenizer (Lexer): Converts raw source code into a stream of tokens. Handles comments and line tracking.
- Parser: A recursive descent parser that produces an Abstract Syntax Tree (AST).
- Design Choice: Separation of
Expr(Expressions producing values) andStmt(Statements performing actions) for type safety. - Fail-Fast: Static checks for loop boundaries (preventing
breakoutside loops) are handled here.
- Design Choice: Separation of
- Resolver (Semantic Analysis): A static analysis pass that resolves variable scope distances.
- Solves the "funarg problem" for closures.
- Performs static checks for
returnlocations,thisusage, and variable shadowing rules.
- Interpreter: The runtime engine.
- Environment: Uses
Rc<RefCell<Environment>>to manage the scope chain, allowing efficient memory sharing for closures without a garbage collector. - Side Tables: Utilizes resolution data to perform direct variable lookups (hopping scopes) rather than dynamic searches.
- Environment: Uses
Rox extends the Lox language with modern features, making it a capable scripting language.
Supports Lists, Dicts, and Tuples with native method chaining. Rox is strongly typed (no implicit type coercion failures).
var data = [1, 2, 3];
var map = {"a": 10, "b": 20};
// Native methods with Lambdas
var squared = data.map(fun(x) { return x * x; });
print "Result: " + squared; // [1, 4, 9]Complete support for Classes, Inheritance, Mixins (via closures), and Static Analysis for this/super.
class Shape {
init(name) { this.name = name; }
area() { return 0; }
}
class Circle < Shape {
init(r) {
super.init("Circle");
this.r = r;
}
area() { return math.PI * this.r * this.r; }
}
print Circle(5).area();Build complex applications with File-based Modules. Features isolated environments, caching, and cycle detection.
// math_lib.rox
export var PI = 3.14159;
export fun add(a, b) { return a + b; }
// main.rox
var m = import("./math_lib.rox");
print m.add(10, 5);Includes Try-Catch for error handling and standard loop controls (break/continue).
try {
var file = fs.readFile("missing.txt");
} catch (e) {
print "Error handled: " + e;
}
for (var i = 0; i < 10; i += 1) {
if (i % 2 == 0) continue;
print i;
}Everything you need to get started.
- Math:
sin,cos,sqrt,pow,abs, etc. - IO/FS:
input(),clock(),fs.readFile,fs.writeFile. - Core: String manipulation (
len,upper), List operations (push,pop,join), Dict access.
- Rust Toolchain (cargo 1.x+)
Clone the repository and build the project:
git clone https://github.com/inblossoms/rox.git
cd rox
cargo build --release1. REPL Mode (Interactive) Run without arguments to start the interactive shell:
cargo run> var a = "Hello";
> print a + " World";
Hello World2. Script Mode
Run a .rox file:
cargo run -- scripts/fibonacci.roxRox supports anonymous functions (lambdas) and native list operations.
var numbers = [1, 2, 3, 4, 5];
// Use map with a lambda function
var squared = numbers.map(fun(n) {
return n * n;
});
// Use filter
var evens = squared.filter(fun(n) {
return n % 2 == 0;
});
print evens; // Output: [4, 16]Support for classes, inheritance, this, and super.
class Shape {
init(name) {
this.name = name;
}
area() {
return 0;
}
describe() {
print "I am a " + this.name + " with area " + this.area();
}
}
class Circle < Shape {
init(radius) {
super.init("Circle");
this.radius = radius;
}
area() {
return math.PI * this.radius * this.radius;
}
}
var c = Circle(4);
c.describe();
// Output: I am a Circle with area 50.265482...Robust control flow with try-catch and loop controls.
fun riskyOperation(x) {
if (x < 0) {
throw "Negative number error!";
}
return 100 / x;
}
var inputs = [10, 0, -5, 20];
for (var i = 0; i < inputs.len(); i += 1) {
var n = inputs[i];
if (n == 0) {
print "Skipping zero to avoid division error...";
continue;
}
try {
var result = riskyOperation(n);
print "Result: " + result;
} catch (err) {
print "Caught exception: " + err;
}
}Rox features a module system with explicit exports and path resolution.
math_utils.rox:
var internal_rate = 1.5; // Private variable
export fun scale(n) {
return n * internal_rate;
}
export var version = "1.0.0";main.rox:
var utils = import("./math_utils.rox");
print "Using utils version: " + utils.version;
print utils.scale(10); // Output: 15
// print utils.internal_rate; // Error: Module has no export 'internal_rate'Interaction with the OS using the built-in fs module.
var path = "log.txt";
if (fs.exists(path)) {
var content = fs.readFile(path);
print "Current log: " + content;
} else {
fs.writeFile(path, "Initialization log...");
print "Log file created.";
}The project includes a comprehensive test suite covering AST structure, parser logic, and runtime evaluation (including scope resolution).
# Run all tests
cargo test
# Run specific test modules
cargo test parser
cargo test evaluatesrc/
โโโ std_lib/ // Native modules
โโโ reader/ // Source file reading
โโโ ast/ // AST definitions (Expr/Stmt)
โโโ tokenizer/ // Lexical analysis
โโโ parser/ // Parsing logic & ParseHelper
โโโ resolver/ // Semantic analysis & Variable resolution
โโโ evaluate/ // Runtime execution
โโโ diagnostic.rs // Diagnostic messages
โโโ error.rs // Unified error handling
โโโ main.rs // Entry point (CLI)
Contributions are welcome! If you are interested in fixing a bug or adding a new feature, please read our CONTRIBUTING | ่ดก็ฎ guide first to set up your development environment.
This project is licensed under the MIT License - see the LICENSE file for details.
Built with โค๏ธ in Rust.