Statements and State
https://craftinginterpreters.com/statements-and-state.htmlStatements
- Statement - Doesn’t not evaluate to a value, and instead produces side effects (such as var)
- Expression Statement - allows you to put an expression in a statement
program → statement* EOF ;
statement → exprStmt
| printStmt ;
exprStmt → expression ";" ;
printStmt → "print" expression ";" ;
We are going to add print to the actual syntax of the language instead of using a core lib, since it will allow us to implement it sooner
Parsing statement
Parse method should return a list of statements, and repeat adding statements until the end of the file has been reached.
When matching for a statement we first check that the first token is of type print, and then if it is not recognised we assume it must be an expression statement.
private Stmt statement() {
if (match(PRINT)) return printStatement();
return expressionStatement();
}
To handle the print statement, we first consume the expression to the right up to the ;
We shall return a new statement object, called print.
To handle the expression statement, we first consume the expression on the right, and then pass that into the expression statement object.
Executing statement
We add new methods to handle the statements. Like we have already for the Evaluate class. Statements do not return anything hence we return void.
This new class must handle both of the new statement methods, exprStmt & printStmt.
We can now implement an Interpeter class that will loop through all the statements.
void interpret(List<Stmt> statements) {
try {
for (Stmt statement : statements) {
execute(statement);
}
} catch (RuntimeError error) {
Lox.runtimeError(error);
}
}
Testing now should allow the following code
print "one";
print true;
print 2 + 1;Global Variables
Variable Declaration
var beverage = "espresso";
Variable Expression
print beverage;
The following if (monday) var beverage = "espresso"; is not allowed since it is ambiguous, what do we do with beverage on days that are not Monday ect ect.
To handle this senario we add another rule, to determine if its a variable declaration or a statement. Since the alternative would allow for nesting of declarations.
program → declaration* EOF ;
declaration → varDecl
| statement ;
statement → exprStmt
| printStmt ;
We can easily determine this by checking if the first token is var.
varDecl → "var" IDENTIFIER ( "=" expression )? ";" ;Parsing Variables