aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/craftinginterpreters/lox/Resolver.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/craftinginterpreters/lox/Resolver.java')
-rw-r--r--src/com/craftinginterpreters/lox/Resolver.java25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/com/craftinginterpreters/lox/Resolver.java b/src/com/craftinginterpreters/lox/Resolver.java
index dc7332b..fe3a641 100644
--- a/src/com/craftinginterpreters/lox/Resolver.java
+++ b/src/com/craftinginterpreters/lox/Resolver.java
@@ -19,7 +19,7 @@ class Resolver implements Expr.Visitor<Void>, Stmt.Visitor<Void> {
}
private enum ClassType {
- NONE, CLASS
+ NONE, CLASS, SUBCLASS
}
private ClassType currentClass = ClassType.NONE;
@@ -51,9 +51,16 @@ class Resolver implements Expr.Visitor<Void>, Stmt.Visitor<Void> {
}
if (stmt.superclass != null) {
+ currentClass = ClassType.SUBCLASS;
+
resolve(stmt.superclass);
}
+ if (stmt.superclass != null) {
+ beginScope();
+ scopes.peek().put("super", true);
+ }
+
beginScope();
scopes.peek().put("this", true);
@@ -67,6 +74,10 @@ class Resolver implements Expr.Visitor<Void>, Stmt.Visitor<Void> {
endScope();
+ if (stmt.superclass != null) {
+ endScope();
+ }
+
currentClass = enclosingClass;
return null;
}
@@ -184,6 +195,18 @@ class Resolver implements Expr.Visitor<Void>, Stmt.Visitor<Void> {
}
@Override
+ public Void visitSuperExpr(Expr.Super expr) {
+ if (currentClass == ClassType.NONE) {
+ Lox.error(expr.keyword, "Can't use 'super' outside of a class.");
+ } else if (currentClass != ClassType.SUBCLASS) {
+ Lox.error(expr.keyword, "Can't use 'super' in a class with no superclass.");
+ }
+
+ resolveLocal(expr, expr.keyword);
+ return null;
+ }
+
+ @Override
public Void visitThisExpr(Expr.This expr) {
if (currentClass == ClassType.NONE) {
Lox.error(expr.keyword, "Can't use 'this' outside of a class.");