diff options
Diffstat (limited to 'src/com/craftinginterpreters/lox/Resolver.java')
-rw-r--r-- | src/com/craftinginterpreters/lox/Resolver.java | 25 |
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."); |