private Stmt ClassDeclaration() { Token name = Consume(TokenType.Identifier, "Expect class name."); Expr superclass = null; if (Match(TokenType.Less)) { Consume(TokenType.Identifier, "Expect superclass name."); superclass = new Expr.Variable(Previous()); } Consume(TokenType.LeftBrace, "Expect '{' before class body."); List <Stmt.Function> methods = new List <Stmt.Function>(); while (!Check(TokenType.RightBrace) && !IsAtEnd()) { methods.Add(Function("method")); } Consume(TokenType.RightBrace, "Expect '}' after class body."); return(new Stmt.Class(name, superclass, methods)); }
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); }
// Expr Visitors public object Visit(Expr.Variable expr) { if (scopes.Count > 0) { Dictionary <string, Tracker> scope = scopes.Peek(); if (scope.ContainsKey(expr.name.lexeme) && // variable declared scope[expr.name.lexeme].Initialized == false) // variable not initialized { Lox.Error(expr.name, "Cannot read local variable in its own initializer."); } } ResolveLocal(expr, expr.name); return(null); }
public object Visit(Expr.Variable expr) { return(LookUpVariable(expr.name, expr)); }
public string Visit(Expr.Variable variable) { return(variable.name.lexeme); }