https://github.com/jdcodework/rslox
Implementation of the lox language proposed by the book “Crafting Interpreters”.
https://github.com/jdcodework/rslox
crafting-interpreters interpreted-programming-language lox-interpreter rust-lang
Last synced: about 2 months ago
JSON representation
Implementation of the lox language proposed by the book “Crafting Interpreters”.
- Host: GitHub
- URL: https://github.com/jdcodework/rslox
- Owner: JDCodeWork
- Created: 2025-01-06T00:58:37.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-11-19T21:08:09.000Z (3 months ago)
- Last Synced: 2025-11-19T23:10:39.336Z (3 months ago)
- Topics: crafting-interpreters, interpreted-programming-language, lox-interpreter, rust-lang
- Language: Rust
- Homepage:
- Size: 108 KB
- Stars: 0
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# rslox
An implementation of the Lox language in Rust, following the book [Crafting Interpreters](https://craftinginterpreters.com/) by Robert Nystrom.
---
## 🎯 Goals
1. Practice interpreter construction.
2. Apply idiomatic Rust patterns.
3. Incrementally evolve into a full interpreter.
---
## ✨ Features
- **Data Types**: Booleans, Numbers, Strings, Nil.
- **Expressions**: Arithmetic, Logic, Comparison, Grouping.
- **Statements**: Print, Expression, Block, If-Else, While, For.
- **Functions**: Declaration, Calls, Return, Closures, Native Functions.
- **Error Handling**: Syntax and Runtime errors.
---
## ⚙️ Requirements
- Rust 1.70+ (edition 2021) — install via
---
## 🚀 Quick Start
```bash
git clone https://github.com/JDCodeWork/rslox.git
cd rslox
cargo build --release
./target/release/rslox run --help
```
### Optional dev alias
```bash
echo "alias crq='cargo run -q --'" >> ~/.zshrc # or ~/.bashrc
exec $SHELL -l
```
---
## 🖥️ CLI Usage
Help:
```bash
crq --help
```
Start REPL:
```bash
crq run
```
Run a file:
```bash
crq run -p examples/expr.lox
```
If you omit `.lox`, it will be appended automatically.
### Debug mode
```bash
crq run --debug --show-tokens
crq run --debug --show-ast
crq run --debug --show-ast --show-tokens
```
Works inside the REPL as well.
### Tools (subcommand `tool`)
Generate AST boilerplate (requires an output dir):
```bash
crq tool gen-ast ./out
```
---
## 📦 Project Structure
```text
src/
cli.rs # CLI (clap)
errors.rs # Error types
lox/
scanner.rs # Source -> tokens
token.rs # Token & TokenType
parser.rs # Recursive descent expression parser
expr.rs # AST node definitions & pretty printing
tools/
mod.rs # AstPrinter + AST code generator
```
---
## 🔤 Tokens Supported
- Single-char: `(` `)` `{` `}` `,` `.` `-` `+` `;` `/` `*`
- One/two-char: `!` `!=` `=` `==` `>` `>=` `<` `<=`
- Literals: identifiers, numbers (`f64`), strings
- Keywords: `and class else false fun for if nil or print return super this true var while`
- Comments: `//` (line) and `/* ... */` (block)
- EOF sentinel
Literals are stored directly in `TokenType` as `String(String)` and `Number(f64)` (no separate literal field).
---
## 🌳 Interpreter Status
Features:
- Arithmetic expressions: `+ - * /`
- Correct precedence & associativity
- Grouping via `(...)`
- Literals: numbers, strings, `true`, `false`, `nil`
- AST generation (printed in Lisp-like form)
- **Evaluation**: Tree-walk interpreter
- **Control Flow**: `if-else`, `while`, `for`
- **Logical Operators**: `and`, `or`
- **Statements**: `print`, blocks, variable declarations, function declaration
(temporal) Limitations:
- No classes
---
## 🧪 Examples
Input:
```text
1 + 2 * (3 - 4)
```
With `--debug --show-ast --show-tokens`:
```text
INFO Token( type: Number(1.0), literal: (1), lexeme: 1 ) at line 1
INFO Token( type: Plus, literal: (), lexeme: + ) at line 1
INFO Token( type: Number(2.0), literal: (2), lexeme: 2 ) at line 1
INFO Token( type: Star, literal: (), lexeme: * ) at line 1
INFO Token( type: LeftParen, literal: (), lexeme: ( ) at line 1
INFO Token( type: Number(3.0), literal: (3), lexeme: 3 ) at line 1
INFO Token( type: Minus, literal: (), lexeme: - ) at line 1
INFO Token( type: Number(4.0), literal: (4), lexeme: 4 ) at line 1
INFO Token( type: RightParen, literal: (), lexeme: ) ) at line 1
INFO Token( type: EOF, literal: (), lexeme: ) at line 2
INFO AST -> (+ 1 (* 2 (group (- 3 4))))
```
Another:
```text
-("hello" + " world")
```
AST:
```text
INFO Token( type: Minus, literal: (), lexeme: - ) at line 1
INFO Token( type: LeftParen, literal: (), lexeme: ( ) at line 1
INFO Token( type: String("hello"), literal: (hello), lexeme: "hello" ) at line 1
INFO Token( type: Plus, literal: (), lexeme: + ) at line 1
INFO Token( type: String(" world"), literal: ( world), lexeme: " world" ) at line 1
INFO Token( type: RightParen, literal: (), lexeme: ) ) at line 1
INFO Token( type: EOF, literal: (), lexeme: ) at line 2
INFO AST -> (- (group (+ hello world)))
```
---
## 🛠️ AST Generator
Generates enums/structs + `new` constructors from concise type descriptions to reduce boilerplate while iterating on the language.
Conceptual description example:
```text
Expr -> Binary left: Expr, operator: Token, right: Expr
```
---
## 🚨 Error Handling
Reports:
- Unexpected character
- Unterminated string
- Unknown token / type during parse
- Syntax errors (missing `)` etc.)
Colored output via `owo-colors`.
---
## 💡 Technical Notes
- `TokenType` embeds literal values (removed dynamic literal field).
- AST printing uses a parenthesized style: `(+ 1 (* 2 3))`.
- `AstPrinter` centralizes string representation.
## 🧾 Changelog
See `CHANGELOG.md` (e.g. v0.5.1: literals embedded into `TokenType`).
---
## 🛠️ Handy Commands
```bash
cargo run -q -- run --debug --show-tokens --show-ast
cargo test
cargo build --release
```