Evaluating Expressions
Representing Values
We need to represent primitives. This can be done using Java objects, or c# records. They can inherit from the same parent, and then use instanceOf style to determine what it is.
| Lox type | Java representation |
| Any Lox value | Object |
nil | null |
| Boolean | Boolean |
| number | Double |
| string | String |
Evaluating Expressions
Here the best approach is to follow a visitor style pattern.
Alternatively you can follow a pattern matching approach, where you switch based on the tree you see.
The following denotes what each pattern matched should do.
Visiting a literal
This should be simple all we need to do is return the literal value from the node.
Evaluating Grouping
Recursively call the evaluate expression method, to enter into the grouping.
Evaluating Unary
We first call the evaluate expression method for the right node.
We then switch based on the operators type.
Finally we cast the right expression into a double if the operator is a - or a boolean if the operator is a !
In the lox language truthiness and falseness are a thing; we can determine it as follows false and nil are falsey, and everything else is truthy.
Evaluating Binary
First we call the evaluate expression method for the left and right nodes.
We then switch based on the operator type again.
For -, /, * we convert to double and perform the operation on the left and right nodes.
For + we determine if the type of left and right nodes is number or string, and then add or concatenate respectively.
For <, <=, >, >= we cast into doubles and perform the operation.
For == and != we do a simple isEqual check where if left and right is null we return true, if just a is null or b is null return false, otherwise we just compare their values and return the result.
Runtime Errors
We must not kill the interpreter on an error, since we may want to continue executing such as for a REPL.
We must detect the following errors:
- Type conversion
- Type mixing