Skip to content

aurelilia/cloxrs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

56 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cloxrs

An interpreter for Lox. Written in Rust. It follows the 3rd part of the book, and is similar in structure to clox. It also replaces some parts of clox by leveraging Rust's features.

It is a fully-featured Lox VM, and all features are implemented, however it's about 4-7x slower (depending on the benchmark) than clox due to different design decisions as well as a few limitations of Rust's memory model.

Notable user-facing differences to clox

  • Stack can be bigger than 256
  • Strings can be concatenated with anything
  • Missing class fields produce nil instead of a runtime error
  • Multiplying something other than a number with a number will repeat its string representation (("a" * 3) == "aaa")

Additional native functions

  • readfile: Takes 1 path parameter, returns file content as string or nil if file could not be read
  • writefile: Takes 1 path parameter and one file content parameter, returns success (bool)
  • input: Waits for user to input one line, returns input. Newline at the end is stripped.
  • printf: Takes 1 argument, prints it without a newline.

Implementation differences

  • Opcodes are simply an enum, which contains the opcode arguments.
  • Instead of a per-chunk constant table, constant strings are inside a global interner, with all other constants embedded into the instruction.
  • The table/map implementation uses the interner key for faster hashing instead of storing the hash of every string.
  • Frames are stored implicitly in the VM callstack, with run recursing with every call. This is faster, but also means that the VM does not display stack traces.
  • Due to not wanting to use unsafe Rust, upvalues are implemented entirely different and use Rc<Cell<...>>. This mostly removes the need for GC, which is why cloxrs GC only has to infreqently collect upvalues. This does make them slower though.
  • Methods are implemented by adding an EndClass opcode instead of Method, and pushing each method onto the stack above the class. EndClass then pops methods off the stack until it reaches the class, where it then inserts them.

Build/Run

As of 2021-03-11, cloxrs requires a nightly version of Rust due to use of const_mut_refs and const_fn_fn_ptr_basics features (they might be stablized by the time you read this). If you use rustup, rustup default nightly will automatically install the newest nightly version.

# Build release, output in ./target/release/cloxrs
cargo build --release

# Run as REPL
./target/release/cloxrs 

# Execute $file
./target/release/cloxrs $file

Code style

Follow the style used by rustfmt.

Releases

No releases published

Packages

No packages published

Languages