"Who gets fish at a chicken place? That's like getting chicken at a fish place!"
- some guy in front of me in line at Harold's Chicken Shack
Schlox (pronounced like schlock) is an implementation of the Lox programming language from Bob Nystrom's book Crafting Interpreters, written in Chicken Scheme. It's based on jlox, the tree-walk interpreter written in Java which he describes in part II of the book. There are a few differences in behavior and implementation, though:
-
Running the interpreter with the flag
--pretty-printwill pretty-print the AST instead of evaluating it. -
Schlox supports C-style block comments, as described in challenge #4 of chapter 4 ("Scanning").
-
Schlox supports Scheme's full numeric tower. The syntax for number literals is
\d+(\.\d+)?i?, where the trailingiindicates an imaginary number. There's no literal syntax for the real part of a complex number or for ratios, but if you write them the normal way, the syntax for addition and division will evaluate correctly. -
Everywhere that jlox uses exceptions for control flow, schlox uses continuations.
-
The jlox parser has a
try/catchblock at the top of the grammar and throws aParseErrorwhen it encounters invalid syntax. Schlox saves the current continuation at the top of the grammar and calls it when it encounters invalid syntax. -
While jlox throws an exception when it reaches a return statement to unwind the call stack, schlox saves the continuation of the function when it's called and calls that continuation with the return value when it evaluates a return statement in that function.
-
-
Instead of using the visitor pattern to mimic a functional style, schlox walks the tree using multimethods. The book hints at this in an aside in chapter 5, section 3.1 ("The Expression Problem").
-
Schlox handles
NaNas specified by IEEE 754, so all comparisons toNaNare false. I chose not to follow the semantics from the book because jlox and clox are actually inconsistent with each other here. -
Proper tail-call elimination!
- Chicken Scheme version 5 or greater
- The COOPS egg. This is necessary for multimethods. It's also the biggest barrier to making schlox portable, since multimethods aren't in the R7RS standard.
- The SRFI-69 egg. This provides hash tables, which I use for environments.
-
Install Chicken Scheme. If you're on Ubuntu,
apt-get install chicken-binwill work fine, but it doesn't include Feathers, the graphical debugger for Chicken. -
Install the COOPS and SRFI-69 eggs with
chicken-install coops srfi-69. You may need to run that as the superuser depending on where you or your package manager installedlib/chicken. -
Navigate to the top directory of this repository (i.e. where this README is located) and run
make. The executable for the interpreter will bebuild/schlox. To make a debug build that you can use with Feathers, runmake debug, and the interpreter will bedebug/schlox.
Writing schlox was a whole lot of fun, but as far as I can tell, it's done. It passes almost all of the jlox test suite---the only exceptions are those that arise from Schlox having a proper numeric tower instead of using floats for all its numbers. The only remaining task I see is getting LoxLox to run.