|
| 1 | +# Lox Interpreter |
| 2 | + |
| 3 | +A Go implementation of the Lox programming language interpreter |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Lox is a dynamically-typed, interpreted programming language with a clean and simple syntax. This implementation provides a complete interpreter with lexical analysis, parsing, and execution capabilities. |
| 8 | + |
| 9 | +## Language Syntax |
| 10 | + |
| 11 | +### Basic Syntax Rules |
| 12 | + |
| 13 | +1. **Statements** must end with a semicolon (`;`) |
| 14 | +2. **Identifiers** can contain letters, digits, and underscores, but cannot start with a digit |
| 15 | +3. **Keywords** are reserved and cannot be used as identifiers |
| 16 | +4. **Case sensitivity**: Lox is case-sensitive |
| 17 | +5. **Whitespace** is generally ignored except for separating tokens |
| 18 | + |
| 19 | +### Reserved Keywords |
| 20 | + |
| 21 | +``` |
| 22 | +and, class, else, false, for, fun, if, nil, or, print, return, super, this, true, var, while |
| 23 | +``` |
| 24 | + |
| 25 | +### Operators |
| 26 | + |
| 27 | +| Operator | Description | Example | |
| 28 | +|----------|-------------|---------| |
| 29 | +| `+` | Addition / String concatenation | `1 + 2` or `"hello" + "world"` | |
| 30 | +| `-` | Subtraction / Negation | `5 - 3` or `-x` | |
| 31 | +| `*` | Multiplication | `3 * 4` | |
| 32 | +| `/` | Division | `10 / 2` | |
| 33 | +| `!` | Logical NOT | `!true` | |
| 34 | +| `==` | Equality | `x == y` | |
| 35 | +| `!=` | Inequality | `x != y` | |
| 36 | +| `>` | Greater than | `5 > 3` | |
| 37 | +| `>=` | Greater than or equal | `5 >= 5` | |
| 38 | +| `<` | Less than | `3 < 5` | |
| 39 | +| `<=` | Less than or equal | `3 <= 5` | |
| 40 | +| `and` | Logical AND | `true and false` | (yet to be implemented) |
| 41 | +| `or` | Logical OR | `true or false` | (yet to be implemented) |
| 42 | + |
| 43 | +## Usage |
| 44 | + |
| 45 | +### Building the Interpreter |
| 46 | + |
| 47 | +```bash |
| 48 | +go build |
| 49 | +``` |
| 50 | + |
| 51 | +### Running Programs |
| 52 | + |
| 53 | +#### From a File |
| 54 | +```bash |
| 55 | +./Lox script.lox |
| 56 | +``` |
| 57 | + |
| 58 | +#### Interactive Mode |
| 59 | +```bash |
| 60 | +./Lox |
| 61 | +``` |
| 62 | + |
| 63 | +In interactive mode, you can: |
| 64 | +- Enter expressions and statements |
| 65 | +- Type `clear` to clear the screen |
| 66 | +- Type `exit` to quit |
| 67 | + |
| 68 | +### Example Programs |
| 69 | + |
| 70 | +#### Basic Arithmetic |
| 71 | +```lox |
| 72 | +var a = 10; |
| 73 | +var b = 20; |
| 74 | +print a + b; // Output: 30 |
| 75 | +print a * b; // Output: 200 |
| 76 | +``` |
| 77 | + |
| 78 | +#### String Operations |
| 79 | +```lox |
| 80 | +var greeting = "Hello"; |
| 81 | +var name = "World"; |
| 82 | +print greeting + " " + name; // Output: Hello World |
| 83 | +``` |
| 84 | + |
| 85 | +#### Boolean Logic |
| 86 | +```lox |
| 87 | +var x = true; |
| 88 | +var y = false; |
| 89 | +print y == x; |
| 90 | +print !x; // Output: false |
| 91 | +``` |
| 92 | + |
| 93 | +#### Variable Assignment |
| 94 | +```lox |
| 95 | +var count = 0; |
| 96 | +print count; // Output: 0 |
| 97 | +count = count + 1; |
| 98 | +print count; // Output: 1 |
| 99 | +``` |
| 100 | + |
| 101 | +## Project Structure |
| 102 | + |
| 103 | +``` |
| 104 | +Lox/ |
| 105 | +├── Token/ # Token definitions and types |
| 106 | +├── Scanner/ # Lexical analysis (tokenization) |
| 107 | +├── parser/ # Syntax analysis (parsing) |
| 108 | +├── ast/ # Abstract Syntax Tree nodes |
| 109 | +├── Interpreter/ # Expression and statement evaluation |
| 110 | +├── environment/ # Variable environment management |
| 111 | +├── LoxErrors/ # Error handling and reporting |
| 112 | +├── state/ # Global interpreter state |
| 113 | +├── printer/ # AST pretty printing utilities |
| 114 | +└── main.lox # Example Lox program |
| 115 | +``` |
| 116 | + |
| 117 | +## Architecture |
| 118 | + |
| 119 | +The interpreter follows a traditional pipeline architecture: |
| 120 | + |
| 121 | +1. **Scanner**: Converts source code into tokens |
| 122 | +2. **Parser**: Builds an Abstract Syntax Tree (AST) from tokens |
| 123 | +3. **Interpreter**: Evaluates the AST and produces results |
| 124 | + |
| 125 | +### Key Components |
| 126 | + |
| 127 | +- **Token**: Represents lexical units (keywords, operators, literals) |
| 128 | +- **Scanner**: Implements lexical analysis with support for comments, strings, numbers, and identifiers |
| 129 | +- **Parser**: Recursive descent parser with error recovery |
| 130 | +- **AST**: Tree representation of program structure |
| 131 | +- **Interpreter**: Visitor pattern implementation for expression and statement evaluation |
| 132 | +- **Environment**: Manages variable storage and lookup |
| 133 | + |
| 134 | +## Error Handling |
| 135 | + |
| 136 | +The interpreter provides comprehensive error reporting: |
| 137 | + |
| 138 | +- **Lexical Errors**: Invalid characters, unterminated strings |
| 139 | +- **Parse Errors**: Syntax errors with line numbers and helpful messages |
| 140 | +- **Runtime Errors**: Type mismatches, undefined variables |
| 141 | + |
| 142 | +Error messages include: |
| 143 | +- Line number where the error occurred |
| 144 | +- Description of the error |
| 145 | +- Context around the error location |
| 146 | + |
| 147 | +## Development Status |
| 148 | + |
| 149 | +This implementation represents the early stages of a complete Lox interpreter. The core expression evaluation and basic statements are functional, providing a solid foundation for adding more advanced language features. |
| 150 | + |
| 151 | +### Next Steps |
| 152 | + |
| 153 | +1. Implement control flow statements (`if`, `while`, `for`) |
| 154 | +2. Add function support |
| 155 | +3. Implement classes and objects |
| 156 | +4. Add local scoping |
| 157 | +5. Enhance error handling and debugging features |
| 158 | + |
| 159 | + |
| 160 | +## Features |
| 161 | + |
| 162 | +#### **Data Types** |
| 163 | +- **Numbers**: Floating-point numbers, all numbers are double, with 2 place float precision (e.g., `42`, `3.14`) |
| 164 | +- **Strings**: Text literals enclosed in double quotes (e.g., `"hello world"`) |
| 165 | +- **Booleans**: `true` and `false` |
| 166 | +- **Nil**: Represents the absence of a value |
| 167 | + |
| 168 | +#### **Expressions** |
| 169 | +- **Arithmetic Operations**: |
| 170 | + - Addition: `+` (supports numbers and string concatenation) |
| 171 | + - Subtraction: `-` |
| 172 | + - Multiplication: `*` |
| 173 | + - Division: `/` |
| 174 | +- **Comparison Operations**: |
| 175 | + - Equality: `==`, `!=` |
| 176 | + - Relational: `>`, `>=`, `<`, `<=` |
| 177 | +- **Logical Operations**: |
| 178 | + - Logical AND: `and` |
| 179 | + - Logical OR: `or` |
| 180 | + - Logical NOT: `!` |
| 181 | +- **Unary Operations**: |
| 182 | + - Negation: `-` (for numbers) |
| 183 | + - Logical NOT: `!` |
| 184 | +- **Grouping**: Parentheses `()` for expression precedence |
| 185 | +- **Variable Access**: Direct variable name references |
| 186 | + |
| 187 | +#### **Statements** |
| 188 | +- **Variable Declaration**: `var name = value;` |
| 189 | +- **Print Statement**: `print expression;` |
| 190 | +- **Expression Statement**: Any expression followed by `;` |
| 191 | + |
| 192 | +#### **Variables** |
| 193 | +- **Declaration**: `var variableName;` or `var variableName = initialValue;` |
| 194 | +- **Assignment**: `variableName = newValue;` |
| 195 | +- **Scope**: Global scope (variables are accessible throughout the program) |
| 196 | + |
| 197 | +#### **Comments** |
| 198 | +- **Single-line comments**: `// This is a comment` |
| 199 | + |
| 200 | +#### **Error Handling** |
| 201 | +- **Lexical Errors**: Invalid characters, unterminated strings |
| 202 | +- **Parse Errors**: Syntax errors with helpful error messages |
| 203 | +- **Runtime Errors**: Type errors, undefined variables |
0 commit comments