Tree-walk interpreter (Rust) and bytecode VM (Zig) implementations for Lox
  • Zig 49.8%
  • Rust 35.7%
  • Dart 11.4%
  • Nix 2.7%
  • C 0.1%
Find a file
2026-09-15 12:51:12 +09:00
bench 30. Optimization: Benchmark 2026-09-15 12:51:12 +09:00
rlox 13. Inheritance 2026-09-15 12:51:12 +09:00
tool Initialize zlox project 2026-09-15 12:51:12 +09:00
zlox Add readme 2026-09-15 12:51:12 +09:00
.banger.toml Initialize rlox project 2026-09-15 12:51:12 +09:00
.gitignore Add testing infrastructure 2026-09-15 12:51:12 +09:00
flake.lock Initialize zlox project 2026-09-15 12:51:12 +09:00
flake.nix 30. Optimization: Benchmark 2026-09-15 12:51:12 +09:00
LICENSE Add license 2026-09-15 12:50:46 +09:00
README.md Add readme 2026-09-15 12:51:12 +09:00

Tree-walk interpreter (Rust) and bytecode VM (Zig) implementations for Lox

This is my implementations for Lox programming language in Crafting Interpreters by Bob Nystrom. There are two variants in the book: tree-walk interpreter in Java and bytecode VM in C. I chose Rust for the former and Zig for the latter instead. I did not add any new features, so my implementations should work almost exactly like the original implementations. Also, they pass the test suite in the official repository. The test suite is migrated to tool directory in this repository.

The commit messages follow each chapter in the book. I reduced redundant change sets by editing the commit history after the fact, so it should be relatively easy to follow changes in chronological order.

Tree-Walk Interpreter: rlox

Rust version: 1.97.0

There are some major changes from jlox. Those stem from Java features not in Rust or Rust features that reduces the tedious manual work in Java. I compiled these into brief descriptions at rlox/notes.md.

Bytecode VM: zlox

Zig version: 0.16.0.

Unlike clox, I did not use global variables to manage compiler and interpreter states. I would say comptime meta-programming, single/many item pointers, allocator APIs, and error union are certainly unique to Zig. I had to write a bespoke code for printing floats, but that is because Zig's standard library doesn't have an API for %g format specifier like used in printf. Other than these, there are no major changes and both codebases look quite similar to be honest.