This is Chapter 9: Control Flow. The following additional statements and expressions have been implemented: Stmt::If, Expr::Logical, and Stmt::While. Lox now supports if, else, and, or, while, and for. Despite this long list of new features, the implementation remains fairly straightforward.

🦀 Index of the Complete Series.

145-feature-image.png
rlox: A Rust Implementation of “Crafting Interpreters” – Control Flow

🚀 Note: You can download the code for this post from GitHub using:

git clone -b v0.4.0 https://github.com/behai-nguyen/rlox.git

Running the CLI Application

💥 The interactive mode is still available. However, valid expressions—such as ((4.5 / 2) * 2) == 4.50;—currently produce no output. I’m unsure when interactive mode will be fully restored, and it’s not a current priority.

For now, Lox scripts can be executed via the CLI application. For example:

cargo run --release ./tests/data/for/book_end_section.lox
Content of book_end_section.lox:
var a = 0;
var temp;

for (var b = 1; a < 10000; b = temp + b) {
  print a;
  temp = a;
  a = b;
}

This Lox script is at the end of the For Loops section: it prints the first 21 Fibonacci numbers.

For more details, refer to this section of the README.md.

Updated Repository Layout

Legend: = updated, = new.

💥 Files not modified are omitted for brevity.

.
├── docs
│   └── RLoxGuide.md ★
├── README.md ★
├── src
│   ├── ast_printer.rs ★
│   ├── interpreter.rs ★
│   ├── parser.rs ★
│   └── stmt.rs ★
├── tests
│   ├── data/ ☆ ➜ added more
│   ├── test_control_flow.rs ☆
│   └── test_parser.rs ★
└── tool
    └── generate_ast
        └── src
            └── main.rs ★

Bug Fix: Stmt::If Struct

In stmt.rs, the struct If field then_branch was updated to Box<Stmt>: this branch is always present in an if statement. Consequently, the new() constructor was refactored. This is the updated stmt.rs module. Fixing the earlier bug also led to minor refactoring in the CLI generation tool. See tool/generate_ast/src/main.rs.

Parser and Interpreter Updates

The new code is relatively straightforward. The Rust version closely mirrors the Java version.

  1. In the src/parser.rs module, the following methods were added: The following methods were updated:
  2. In the src/interpreter.rs module, the following methods were added:

    Note: for loops are desugared into while loops, so no separate code for for loops was added to the Interpreter.

New and Updated Tests

Additional tests based on the author’s test scripts were incorporated:

  1. A new tests/test_control_flow.rs module was added.
  2. The existing tests/test_parser.rs module was updated with three new test methods.

What’s Next

That wraps up this post. There are still some warnings about dead code—which I’m okay with for now.

Thanks for reading! I hope this post supports others on the same journey. As always—stay curious, stay safe 🦊

✿✿✿

Feature image sources:

🦀 Index of the Complete Series.