diff options
Diffstat (limited to 'src/com/craftinginterpreters/lox/Interpreter.java')
-rw-r--r-- | src/com/craftinginterpreters/lox/Interpreter.java | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/src/com/craftinginterpreters/lox/Interpreter.java b/src/com/craftinginterpreters/lox/Interpreter.java index 3e3be86..4092191 100644 --- a/src/com/craftinginterpreters/lox/Interpreter.java +++ b/src/com/craftinginterpreters/lox/Interpreter.java @@ -1,11 +1,14 @@ package com.craftinginterpreters.lox; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> { final Environment globals = new Environment(); private Environment environment = globals; + private final Map<Expr, Integer> locals = new HashMap<>(); Interpreter() { globals.define("clock", new LoxCallable() { @@ -64,7 +67,16 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> { @Override public Object visitVariableExpr(Expr.Variable expr) { - return environment.get(expr.name); + return lookUpVariable(expr.name, expr); + } + + private Object lookUpVariable(Token name, Expr expr) { + Integer distance = locals.get(expr); + if (distance != null) { + return environment.getAt(distance, name.lexeme); + } else { + return globals.get(name); + } } private void checkNumberOperand(Token operator, Object operand) { @@ -125,6 +137,10 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> { stmt.accept(this); } + public void resolve(Expr expr, int depth) { + locals.put(expr, depth); + } + public void executeBlock(List<Stmt> statements, Environment environment) { Environment previous = this.environment; @@ -208,7 +224,14 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> { @Override public Object visitAssignExpr(Expr.Assign expr) { Object value = evaluate(expr.value); - environment.assign(expr.name, value); + + Integer distance = locals.get(expr); + if (distance != null) { + environment.assignAt(distance, expr.name, value); + } else { + globals.assign(expr.name, value); + } + return value; } |