Statements and State 8

This commit is contained in:
nazrin 2025-06-01 19:53:00 +00:00
parent f4338ba51f
commit e749367886
7 changed files with 250 additions and 69 deletions

View file

@ -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;
}
}