aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/craftinginterpreters/lox/Interpreter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/craftinginterpreters/lox/Interpreter.java')
-rw-r--r--src/com/craftinginterpreters/lox/Interpreter.java27
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;
}