private GExpr.Expr assignment() { GExpr.Expr expr = or(); if (Match(tt.EQUAL)) { Token equals = previous(); GExpr.Expr value = assignment(); if (expr is GExpr.Variable) { Token name = ((GExpr.Variable)expr).name; return(new GExpr.Assign(name, value)); } else if (expr is GExpr.Get) { GExpr.Get get = (GExpr.Get)expr; return(new GExpr.Set(get.Object, get.name, value)); } error(equals, "Invalid assignment target."); } return(expr); }
private GStmt.Stmt whileStatement() { consume(tt.LEFT_PAREN, "Expect '(' after 'while'"); GExpr.Expr condition = expression(); consume(tt.RIGHT_PAREN, "Expect ')' after condition"); GStmt.Stmt body = statement(); return(new GStmt.While(condition, body)); }
private GStmt.Stmt forStatement() { consume(tt.LEFT_PAREN, "Expect '(' after 'for'."); GStmt.Stmt initializer; if (Match(tt.SEMICOLON)) { initializer = null; } else if (Match(tt.VAR)) { initializer = varDeclaration(); } else { initializer = expressionStatement(); } GExpr.Expr condition = null; if (!check(tt.SEMICOLON)) { condition = expression(); } consume(tt.SEMICOLON, "Expect ';' after loop condition."); GExpr.Expr increment = null; if (!check(tt.RIGHT_PAREN)) { increment = expression(); } consume(tt.RIGHT_PAREN, "Expect ')' after for clauses"); GStmt.Stmt body = statement(); if (increment != null) { body = new GStmt.Block(new List <GStmt.Stmt>() { body, new GStmt.Expression(increment) }); } if (condition == null) { condition = new GExpr.Literal(true); } body = new GStmt.While(condition, body); if (initializer != null) { body = new GStmt.Block(new List <GStmt.Stmt>() { initializer, body }); } return(body); }
private GStmt.Stmt expressionStatement() { GExpr.Expr expr = expression(); consume(tt.SEMICOLON, "Expect ';' after value."); if (isRepl) { return(new GStmt.Print(expr)); } return(new GStmt.Expression(expr)); }
private void resolveLocal(GExpr.Expr expr, Token name) { for (int i = scopes.Count - 1; i >= 0; i--) { if (scopes.ElementAt(i).ContainsKey(name.lexeme)) { interpreter.resolve(expr, i); return; } } }
private GExpr.Expr unary() { if (Match(tt.BANG, tt.MINUS)) { Token Operator = previous(); GExpr.Expr right = unary(); return(new GExpr.Unary(Operator, right)); } return(call()); }
private GExpr.Expr equality() { GExpr.Expr expr = comparison(); while (Match(tt.BANG_EQUAL, tt.EQUAL_EQUAL)) { Token Operator = previous(); GExpr.Expr right = comparison(); expr = new GExpr.Binary(expr, Operator, right); } return(expr); }
private GExpr.Expr and() { GExpr.Expr expr = equality(); while (Match(tt.AND)) { Token op = previous(); GExpr.Expr right = equality(); expr = new GExpr.Logical(expr, op, right); } return(expr); }
private GExpr.Expr or() { GExpr.Expr expr = and(); while (Match(tt.OR)) { Token op = previous(); GExpr.Expr right = and(); expr = new GExpr.Logical(expr, op, right); } return(expr); }
private Object lookUpVariable(Token name, GExpr.Expr expression) { int distance = locals.ContainsKey(expression) ? locals[expression] : -1; if (distance >= 0) { return(environment.getAt(distance, name.lexeme)); } else { return(globals.get(name)); } }
private GExpr.Expr addition() { GExpr.Expr expr = multiplication(); while (Match(tt.MINUS, tt.PLUS)) { Token Operator = previous(); GExpr.Expr right = multiplication(); expr = new GExpr.Binary(expr, Operator, right); } return(expr); }
private GStmt.Stmt varDeclaration() { Token name = consume(tt.IDENTIFIER, "Expect variable name"); GExpr.Expr initializer = null; if (Match(tt.EQUAL)) { initializer = expression(); } consume(tt.SEMICOLON, "Expect ';' after variable declaration"); return(new GStmt.Var(name, initializer)); }
private GExpr.Expr multiplication() { GExpr.Expr expr = unary(); while (Match(tt.SLASH, tt.STAR)) { Token Operator = previous(); GExpr.Expr right = unary(); expr = new GExpr.Binary(expr, Operator, right); } return(expr); }
private GExpr.Expr comparison() { GExpr.Expr expr = addition(); while (Match(tt.GREATER, tt.GREATER_EQUAL, tt.LESS, tt.LESS_EQUAL)) { Token Operator = previous(); GExpr.Expr right = addition(); expr = new GExpr.Binary(expr, Operator, right); } return(expr); }
private GStmt.Stmt returnStatement() { Token keyword = previous(); GExpr.Expr value = null; if (!check(tt.SEMICOLON)) { value = expression(); } consume(tt.SEMICOLON, "Expect ';' after return value"); return(new GStmt.Return(keyword, value)); }
private GStmt.Stmt ifStatement() { consume(tt.LEFT_PAREN, "Expect ( after 'if'"); GExpr.Expr condition = expression(); consume(tt.RIGHT_PAREN, "Expect ) after if condition."); GStmt.Stmt thenBranch = statement(); GStmt.Stmt elseBranch = null; if (Match(tt.ELSE)) { elseBranch = statement(); } return(new GStmt.If(condition, thenBranch, elseBranch)); }
private GExpr.Expr primary() { if (Match(tt.FALSE)) { return(new GExpr.Literal(false)); } if (Match(tt.TRUE)) { return(new GExpr.Literal(true)); } if (Match(tt.NIL)) { return(new GExpr.Literal(null)); } if (Match(tt.SUPER)) { Token keyword = previous(); consume(tt.DOT, "Expect '.' after 'super'"); Token method = consume(tt.IDENTIFIER, "Expect superclass method name"); return(new GExpr.Super(keyword, method)); } if (Match(tt.NUMBER, tt.STRING)) { return(new GExpr.Literal(previous().literal)); } if (Match(tt.LEFT_PAREN)) { GExpr.Expr expr = expression(); consume(tt.RIGHT_PAREN, "Expect ')' after expression."); return(new GExpr.Grouping(expr)); } if (Match(tt.THIS)) { return(new GExpr.This(previous())); } if (Match(tt.IDENTIFIER)) { return(new GExpr.Variable(previous())); } throw error(peek(), "unexpected token"); }
private GExpr.Expr finishCall(GExpr.Expr callee) { List <GExpr.Expr> arguments = new List <GExpr.Expr>(); if (!check(tt.RIGHT_PAREN)) { do { if (arguments.Count >= 8) { error(peek(), "Cannot have more than 8 arguments"); } arguments.Add(expression()); } while (Match(tt.COMMA)); } Token paren = consume(tt.RIGHT_PAREN, "Expect ')' after arguments"); return(new GExpr.Call(callee, paren, arguments)); }
private GExpr.Expr call() { GExpr.Expr expr = primary(); while (true) { if (Match(tt.LEFT_PAREN)) { expr = finishCall(expr); } else if (Match(tt.DOT)) { Token name = consume(tt.IDENTIFIER, "Expect property name after '.'."); expr = new GExpr.Get(expr, name); } else { break; } } return(expr); }
private Object evaluate(GExpr.Expr Expression) { return(Expression.Accept(this)); }
public void resolve(GExpr.Expr expr, int depth) { locals.Add(expr, depth); }
private void resolve(GExpr.Expr expr) { expr.Accept(this); }
private GStmt.Stmt printStatement() { GExpr.Expr value = expression(); consume(tt.SEMICOLON, "Expect ';' after value."); return(new GStmt.Print(value)); }