public object Visit(Expr.Super expr) { if (currentClass == ClassType.None) { Lox.Error(expr.keyword, "Cannot use 'super' outside of a class."); } else if (currentClass != ClassType.Subclass) { Lox.Error(expr.keyword, "Cannot use 'super' in a class with no superclass."); } ResolveLocal(expr, expr.keyword); return(null); }
private Expr Primary() { Expr expr = null; if (Match(TokenType.False)) { expr = new Expr.Literal(false); } else if (Match(TokenType.True)) { expr = new Expr.Literal(true); } else if (Match(TokenType.Nil)) { expr = new Expr.Literal(null); } else if (Match(TokenType.Number, TokenType.String)) { expr = new Expr.Literal(Previous().literal); } else if (Match(TokenType.Super)) { Token keyword = Previous(); Consume(TokenType.Dot, "Expect '.' after 'super'."); Token method = Consume(TokenType.Identifier, "Expect superclass method name."); expr = new Expr.Super(keyword, method); } else if (Match(TokenType.This)) { expr = new Expr.This(Previous()); } else if (Match(TokenType.Identifier)) { expr = new Expr.Variable(Previous()); } else if (Match(TokenType.LeftParen)) { expr = Expression(); Consume(TokenType.RightParen, "Expect ')' after expression."); expr = new Expr.Grouping(expr); } else { throw Error(Peek(), "Expect expression."); } return(expr); }
public object Visit(Expr.Super expr) { int distance = locals[expr]; LoxClass superclass = (LoxClass)environment.GetAt(distance, "super"); // "this" is always one level nearer than "super"'s environment; LoxInstance obj = (LoxInstance)environment.GetAt(distance - 1, "this"); LoxFunction method = superclass.FindMethod(obj, expr.method.lexeme); if (method == null) { throw new RuntimeError(expr.method, "Undefined property '" + expr.method.lexeme + "."); } return(method); }