|
| 1 | +# Lox Interpreter |
| 2 | + |
| 3 | +A complete implementation of the Lox programming language interpreter in Kotlin, following the principles from "Crafting Interpreters". |
| 4 | + |
| 5 | +## Features |
| 6 | + |
| 7 | +- **Lexical Analysis**: Full tokenization with keyword and identifier distinction |
| 8 | +- **Parsing**: Recursive descent parser building an abstract syntax tree |
| 9 | +- **Variables**: Dynamic typing with `var` declarations and lexical scoping |
| 10 | +- **Functions**: First-class functions with named (`fun`) and anonymous (`fn`) syntax, closures, and proper tail behavior |
| 11 | +- **Classes**: Object-oriented programming with inheritance, instance fields, and methods |
| 12 | +- **Static Methods**: Class-level methods accessible directly on the class |
| 13 | +- **Native Functions**: Built-in functions for I/O and timing (clock, println, scan, input) |
| 14 | +- **Control Flow**: if/else statements and while loops |
| 15 | +- **Operators**: All standard arithmetic, comparison, logical, and assignment operators |
| 16 | +- **Scope Resolution**: Static analysis pass that pre-computes variable binding distances for efficient runtime lookup |
| 17 | +- **Error Handling**: Proper runtime error reporting with token information |
| 18 | + |
| 19 | +## Language Syntax Basics |
| 20 | + |
| 21 | +Variables and assignment: |
| 22 | +``` |
| 23 | +var x = 10; |
| 24 | +x = 20; |
| 25 | +``` |
| 26 | + |
| 27 | +Functions: |
| 28 | +``` |
| 29 | +fun greet(name) { |
| 30 | + println("Hello, " + name); |
| 31 | +} |
| 32 | +
|
| 33 | +greet("Alice"); |
| 34 | +``` |
| 35 | + |
| 36 | +Anonymous functions: |
| 37 | +``` |
| 38 | +var add = fn(a, b) { a + b }; |
| 39 | +println(add(3, 4)); |
| 40 | +``` |
| 41 | + |
| 42 | +Classes and inheritance: |
| 43 | +``` |
| 44 | +class Animal { |
| 45 | + init(name) { |
| 46 | + this.name = name; |
| 47 | + } |
| 48 | + |
| 49 | + speak() { |
| 50 | + println(this.name + " makes a sound"); |
| 51 | + } |
| 52 | +} |
| 53 | +
|
| 54 | +class Dog > Animal { |
| 55 | + speak() { |
| 56 | + println(this.name + " barks"); |
| 57 | + } |
| 58 | +} |
| 59 | +
|
| 60 | +var dog = Dog("Buddy"); |
| 61 | +dog.speak(); |
| 62 | +``` |
| 63 | + |
| 64 | +## Building and Running |
| 65 | + |
| 66 | +Compile the Kotlin code and run the interpreter: |
| 67 | + |
| 68 | +```bash |
| 69 | +kotlinc -include-runtime -d lox.jar src/*.kt |
| 70 | +java -jar lox.jar script.lox |
| 71 | +``` |
| 72 | + |
| 73 | +Or use the REPL for interactive mode. |
| 74 | + |
| 75 | +## Implementation Highlights |
| 76 | + |
| 77 | +- **Visitor Pattern**: AST traversal for both parsing and interpretation |
| 78 | +- **Environment Chains**: Linked scopes for variable storage and lookup |
| 79 | +- **Resolver**: Two-pass compilation approach (resolve then execute) for scope analysis |
| 80 | +- **LoxCallable**: Interface for both user-defined and native functions |
| 81 | +- **Exception-based Control Flow**: RuntimeReturn for return statements, RuntimeError for errors |
| 82 | + |
| 83 | +## Project Structure |
| 84 | + |
| 85 | +- `Interpreter.kt`: Core execution engine with expression and statement visitors |
| 86 | +- `Expr.kt`: AST node definitions for expressions |
| 87 | +- `Stmt.kt`: AST node definitions for statements |
| 88 | +- `Scanner.kt`: Lexical analysis |
| 89 | +- `Parser.kt`: Syntax analysis and AST building |
| 90 | +- `Resolver.kt`: Static scope analysis |
| 91 | +- `Environment.kt`: Scope and variable storage |
| 92 | +- `LoxCallable.kt`: Interface for callable objects |
| 93 | +- `LoxClass.kt`, `LoxInstance.kt`: Object-oriented features |
| 94 | +- `Token.kt`: Token representation |
| 95 | + |
| 96 | +## References |
| 97 | + |
| 98 | +This implementation closely follows the Lox language design and interpreter architecture from "Crafting Interpreters" by Robert Nystrom, adapted to Kotlin's modern language features. |
0 commit comments