Evaluating Expressions

https://craftinginterpreters.com/evaluating-expressions.html

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 typeJava representation
Any Lox valueObject
nilnull
BooleanBoolean
numberDouble
stringString

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: