A complete tree-walking interpreter implementation for the Lox programming language, built from scratch in C++ following the principles from "Crafting Interpreters" by Robert Nystrom.
- About the Project
- Language Features
- Quick Start
- Installation
- Usage
- Language Syntax
- Examples
- Architecture
- Testing
- Contributing
- License
- Acknowledgments
LOX is a dynamically-typed, interpreted programming language designed for simplicity, clarity, and educational purposes. This interpreter implements the complete Lox language specification using a tree-walking interpreter approach, making it an excellent resource for understanding interpreter design and implementation.
- Educational: Perfect for learning interpreter construction concepts
- Simple Syntax: C-like syntax that's easy to read and write
- Dynamic Typing: Flexible type system for rapid prototyping
- Functional Features: First-class functions, closures, and higher-order programming
- Modern Features: Supports contemporary programming paradigms
- π’ Arithmetic Operations: Standard operators (
+,-,*,/) plus exponentiation (**) - π¦ Variables: Dynamic variable declaration and assignment
- π§ Functions: First-class functions with support for recursion and higher-order functions
- π Control Flow: Conditional statements (
if/else if/else) and loops (while/for) - π Closures: Functions that capture their lexical environment
- π€ I/O Operations: Built-in
printstatement for output - ποΈ Scoping: Lexical scoping with proper variable resolution
- Numbers: Double-precision floating-point
- Strings: Unicode string support
- Booleans: True/false values
- Nil: Null/void value
- Functions: First-class function objects
# Clone the repository
git clone https://github.com/Islam-Imad/LOX-Interpreter.git
cd LOX-Interpreter
# Build the project
mkdir build && cd build
cmake .. && make
# Run a simple example
./lox ../Grammer/hello_world.lox- C++17 compatible compiler (GCC, Clang, or MSVC)
- CMake 3.10 or higher
- Git for cloning the repository
-
Clone the repository:
git clone https://github.com/Islam-Imad/LOX-Interpreter.git cd LOX-Interpreter -
Install CMake (if not already installed):
-
Linux (Ubuntu/Debian):
sudo apt-get install cmake
-
macOS:
brew install cmake
-
Windows: Download the installer from the official CMake website
-
-
Build the project:
mkdir build cd build cmake .. make -
Verify installation:
./lox ../Grammer/hello_world.lox
The interpreter accepts a single Lox source file as an argument:
./lox <source_file.lox># Run a simple hello world program
./lox ../Grammer/hello_world.lox
# Execute a Fibonacci sequence program
./lox ../Grammer/fibonaci.lox
# Test closure functionality
./lox ../Grammer/closure.loxvar name = "Lox";
var age = 25;
var isActive = true;
fun greet(name) {
print "Hello, " + name + "!";
}
fun fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
// Conditionals
if (age >= 18) {
print "Adult";
} else {
print "Minor";
}
// Loops
for (var i = 0; i < 10; i = i + 1) {
print i;
}
while (condition) {
// loop body
}
fun makeCounter() {
var count = 0;
fun increment() {
count = count + 1;
return count;
}
return increment;
}
var counter = makeCounter();
print counter(); // 1
print counter(); // 2
The Grammer/ directory contains various example programs demonstrating different language features:
| Example | Description |
|---|---|
hello_world.lox |
Basic print statement |
fibonaci.lox |
Recursive Fibonacci sequence |
closure.lox |
Closure and lexical scoping demonstration |
function.lox |
Function definition and calls |
for.lox |
For loop examples |
while.lox |
While loop examples |
if_else_if_else.lox |
Conditional statement examples |
var.lox |
Variable declaration and assignment |
// Comprehensive example showcasing multiple features
var message = "Welcome to Lox!";
print message;
fun factorial(n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}
fun makeMultiplier(factor) {
fun multiply(x) {
return x * factor;
}
return multiply;
}
var result = factorial(5);
print "5! = " + result;
var doubler = makeMultiplier(2);
var tripler = makeMultiplier(3);
for (var i = 1; i <= 5; i = i + 1) {
print "Double " + i + " = " + doubler(i);
print "Triple " + i + " = " + tripler(i);
}
The interpreter follows a classic tree-walking design with the following components:
- Scanner (
scanner.h/cc): Tokenizes source code into tokens - Parser (
parser.h/cc): Builds an Abstract Syntax Tree (AST) from tokens - Interpreter (
interpreter.h/cc): Evaluates the AST using the visitor pattern - Environment (
object.h/cc): Manages variable scoping and storage
- Visitor Pattern: Used for AST traversal and evaluation
- Strategy Pattern: Implemented for operator handling
- Factory Pattern: Token and object creation
src/
βββ include/ # Header files
β βββ scanner.h # Lexical analysis
β βββ parser.h # Syntax analysis
β βββ interpreter.h # Execution engine
β βββ expression.h # Expression AST nodes
β βββ statement.h # Statement AST nodes
β βββ ...
βββ scanner.cc # Scanner implementation
βββ parser.cc # Parser implementation
βββ interpreter.cc # Interpreter implementation
βββ ...
The project includes comprehensive unit tests using Google Test framework.
# Build and run all tests
cd build
ctest
# Run specific test suites
./test/test_scanner
./test/test_parser
./test/test_interpreter- Scanner Tests: Token recognition and lexical analysis
- Parser Tests: AST construction and syntax validation
- Interpreter Tests: Expression evaluation and statement execution
- Environment Tests: Variable scoping and closure behavior
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for new functionality
- Ensure all tests pass (
ctest) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Language Extensions: Add new operators, control structures, or built-in functions
- Error Handling: Improve error messages and recovery
- Performance: Optimize interpreter performance
- Documentation: Improve code documentation and examples
- Testing: Add more comprehensive test cases
- Follow C++17 best practices
- Use consistent naming conventions
- Add appropriate comments and documentation
- Ensure code is properly formatted
This project is licensed under the MIT License - see the LICENSE file for details.
- Robert Nystrom for the exceptional book "Crafting Interpreters" that inspired this implementation
- Google Test for providing the testing framework
- The open-source community for continuous inspiration and support
Made with β€οΈ by Islam-Imad
Happy interpreting! π