This is the raw hand rolled implementation for Lox language as described in the book "Crafting Interpreters" by Robert Nystrom.
This repository represents my personal journey towards working through the books and all the code inside.
To organize the work and separate implementations of the language, this repository is split into several branches:
-
mainbranch is where I keep this README file and other shared resources.Eventually, once I have a good enough grasp on the Lox language, this is also where I intend to host Lox Tree-Sitter grammar and various code editorplugins. Hopefully.
-
jloxbranch is where my first implementation based on the Part II (A Tree-Walk Interpreter) of the book goes to live and grow. -
cloxbranch is where I intend to build the second interpreter (Part III: A Bytecode Virtual Machine).
To work on the source code, I am using jujutsu version control (jj for short) with Git backend.
This means I can craft my git history chapter by chapter and keep it tidy as I go on. Each git commit published to
If you want to know more about jj, please go and read an excellent tutorial by Steve Klabnik
Branch: jlox
Java implementation of jlox based on and only very slightly modified compared to the source code
--- title: Git history --- gitGraph BT: commit id:"Initial commit" branch jlox commit id:"Chapter 4: Scanner" branch jlox-scanner-block-comment commit id:"C style block comments" commit id:"Nested C style block comments"
Mostly verbatim code from the book, copied and cleaned up a little.
Added a test suite for testing token scanning. This reads test cases from src/test/resources/scanner/*.lox.txt files.
The file has basic structure like this:
=== Optional Test case display name // (1) === var language = "lox"; // (2) --- // (3) --- VAR var IDENTIFIER language EQUAL STRING '"lox"' lox SEMICOLON --- EOF
-
- Optional header block containing the human-readable display name for the test case.
The header block is surrounded on both sides with a block markers starting with at least three or more equals signs
-
- Source of the input to be scanned
-
- List of parsed tokens.
List of tokens is separated into lines by a line of three dashes. Each token MUST be listed on a separate line in a following general format:
<tokenType> [lexeme]? [value]?
See lox/src/test/resources/scanner/ for actual test cases.
For this chapter, I bit the bullet and deviated from the code style in the book to take advantage of more modern Java code patterns: records and sealed interfaces, where it made sense.
Modern Java now also has pattern matching and destructuring for records to replace many uses of Visitor pattern. I kept the visitor pattern from the book for now as I have a feeling, that much of the book will have to be dealing with it. At least in the short term, this is going to be easier to follow the patterns outlined in the book as closely as possible.
As an additional simplification, moving over to using sealed interface instead of abstract base class simplified both AstGenerator and the resulting Ast implementation.
All that at the very small price of adding () at the end of each field accessed.
Also, as we now have several distinct concerns in out Lox implementation, this implementation adds two new modules (in addition to original lox) to the build:
-
tool— for hosting the AstGenerator and any other development time tools we encounter. -
clifor hosting the lox cli entrypoint (separately from the rest of the language implementation.)