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.java28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/com/craftinginterpreters/lox/Interpreter.java b/src/com/craftinginterpreters/lox/Interpreter.java
index 101c33c..3f4d385 100644
--- a/src/com/craftinginterpreters/lox/Interpreter.java
+++ b/src/com/craftinginterpreters/lox/Interpreter.java
@@ -63,6 +63,22 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
}
@Override
+ public Object visitSuperExpr(Expr.Super expr) {
+ int distance = locals.get(expr);
+ LoxClass superclass = (LoxClass) environment.getAt(distance, "super");
+
+ LoxInstance object = (LoxInstance) environment.getAt(distance - 1, "this");
+
+ LoxFunction method = superclass.findMethod(expr.method.lexeme);
+
+ if (method == null) {
+ throw new RuntimeError(expr.method, "Undefined property '" + expr.method.lexeme + "'.");
+ }
+
+ return method.bind(object);
+ }
+
+ @Override
public Object visitThisExpr(Expr.This expr) {
return lookUpVariable(expr.keyword, expr);
}
@@ -190,13 +206,23 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
}
environment.define(stmt.name.lexeme, null);
+ if (stmt.superclass != null) {
+ environment = new Environment(environment);
+ environment.define("super", superclass);
+ }
+
Map<String, LoxFunction> methods = new HashMap<>();
for (Stmt.Function method : stmt.methods) {
LoxFunction function = new LoxFunction(method, environment, method.name.lexeme.equals("init"));
methods.put(method.name.lexeme, function);
}
- LoxClass klass = new LoxClass(stmt.name.lexeme, (LoxClass)superclass, methods);
+ LoxClass klass = new LoxClass(stmt.name.lexeme, (LoxClass) superclass, methods);
+
+ if (superclass != null) {
+ environment = environment.enclosing;
+ }
+
environment.assign(stmt.name, klass);
return null;
}