Statements and State 8
This commit is contained in:
parent
f4338ba51f
commit
e749367886
7 changed files with 250 additions and 69 deletions
|
|
@ -8,10 +8,12 @@ import std.functional : ctEval;
|
|||
import taggedalgebraic;
|
||||
|
||||
import jlox.expr;
|
||||
import jlox.stmt;
|
||||
import jlox.token;
|
||||
import jlox.tokentype;
|
||||
import jlox.token : TValue;
|
||||
import jlox.main;
|
||||
import jlox.environment;
|
||||
|
||||
class RuntimeError : Exception{
|
||||
const Token token;
|
||||
|
|
@ -21,15 +23,29 @@ class RuntimeError : Exception{
|
|||
}
|
||||
}
|
||||
|
||||
class Interpreter : Expr.Visitor!TValue{
|
||||
void interpret(Expr expression) {
|
||||
class Interpreter : Stmt.Visitor!void, Expr.Visitor!TValue {
|
||||
private Environment environment = new Environment();
|
||||
void interpret(Stmt[] statements){
|
||||
try {
|
||||
TValue value = evaluate(expression);
|
||||
writeln(value);
|
||||
foreach(statement; statements)
|
||||
execute(statement);
|
||||
} catch(RuntimeError error){
|
||||
Lox.runtimeError(error);
|
||||
}
|
||||
}
|
||||
private void execute(Stmt stmt){
|
||||
stmt.accept(this);
|
||||
}
|
||||
private void executeBlock(Stmt[] statements, Environment environment){
|
||||
Environment previous = this.environment;
|
||||
try {
|
||||
this.environment = environment;
|
||||
foreach(Stmt statement; statements)
|
||||
execute(statement);
|
||||
} finally {
|
||||
this.environment = previous;
|
||||
}
|
||||
}
|
||||
private TValue evaluate(Expr expr){
|
||||
return expr.accept(this);
|
||||
}
|
||||
|
|
@ -51,13 +67,29 @@ class Interpreter : Expr.Visitor!TValue{
|
|||
return;
|
||||
throw new RuntimeError(operator, "Operand must be a number.");
|
||||
}
|
||||
|
||||
|
||||
void visit(Stmt.Block stmt){
|
||||
executeBlock(stmt.statements, new Environment(environment));
|
||||
}
|
||||
void visit(Stmt.Expression stmt){
|
||||
evaluate(stmt.expression);
|
||||
}
|
||||
void visit(Stmt.Print stmt){
|
||||
TValue value = evaluate(stmt.expression);
|
||||
writeln(tvalueToString(value));
|
||||
}
|
||||
void visit(Stmt.Var stmt){
|
||||
environment.define(stmt.name.lexeme, stmt.initialiser is null ? TValue.nil(0) : evaluate(stmt.initialiser));
|
||||
}
|
||||
|
||||
TValue visit(Expr.Literal expr){
|
||||
return expr.value;
|
||||
}
|
||||
TValue visit(Expr.Grouping expr) {
|
||||
TValue visit(Expr.Grouping expr){
|
||||
return evaluate(expr.expression);
|
||||
}
|
||||
TValue visit(Expr.Unary expr) {
|
||||
TValue visit(Expr.Unary expr){
|
||||
TValue right = evaluate(expr.right);
|
||||
switch(expr.operator.type){
|
||||
case TokenType.MINUS:
|
||||
|
|
@ -104,5 +136,13 @@ class Interpreter : Expr.Visitor!TValue{
|
|||
assert(0);
|
||||
}
|
||||
}
|
||||
TValue visit(Expr.Variable expr){
|
||||
return environment.get(expr.name);
|
||||
}
|
||||
TValue visit(Expr.Assign expr){
|
||||
TValue value = evaluate(expr.value);
|
||||
environment.assign(expr.name, value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue