This is it... the guts of the interpreter are essentially done. The rest of the Lox language features will be adding to, refining and improving the existing code. Or so I believe. I can't imaging there is any other large piece of code to be added still though.
The current code can be seen here.
It is satisfying to finally see some computation being done by the interpreter, even though it is essentially a calculator. It doesn't handle statements yet, so you can't declare a variable. Even if you could there is no environment to store the variable and its value.
There isn't much to say about the implementation. I stuck pretty close to the code in the tutorial.
I did add code to handle the comma and ternary operators that I added in the last sections challenge. The comma re-used the
Ringo::Binary AST node class, so processing that amounted to adding another case statement to the
visit_binary(binary) left = evaluate(binary.left) right = evaluate(binary.right) case binary.operator.type when :plus ... when :minus ... when :comma return right end end
The comma operator evaluates each expression, one at a time, and throws away the results until it reaches the last expression on the right. That expression result is returned. Since the left and right expressions are evaluated at the top of the method all I had to do is return the right result.
The ternary operator was also easy enough to implement.
def visit_conditional(conditional) expr = evaluate(conditional.expression) return evaluate(conditional.then_branch) if is_truthy?(expr) return evaluate(conditional.else_branch) end
First evaluate the first expression, that part before the
?. Then check if the result of that evaluation is true. If so evaluate the
then_branch, otherwise evaluate the
The next section is about adding statements. That should add some keyword processing and the ability to create and reference variables. That also means maintaining an environment for the running code.