private Expr Addition() { Expr expr = Multiplication(); while (Match(MINUS, PLUS)) { Token op = Previous(); Expr right = Multiplication(); expr = new Expr.Binary(expr, op, right); } return(expr); }
private Expr LeftBinary(Func <Expr> leftP, TokenType[] tokens, Func <Expr> rightP) { Expr expr = leftP(); while (MatchAny(tokens)) { var op = Previous(); var right = rightP(); expr = new Expr.Binary(expr, op, right); } return(expr); }
private Expr Multiplication() { Expr expr = Unary(); while (Match(SLASH, STAR)) { Token op = Previous(); Expr right = Unary(); expr = new Expr.Binary(expr, op, right); } return(expr); }
private Expr Comparison() { Expr expr = Addition(); while (Match(GREATER, GREATER_EQUAL, LESS, LESS_EQUAL)) { Token op = Previous(); Expr right = Addition(); expr = new Expr.Binary(expr, op, right); } return(expr); }
private Expr Equality() { var expr = Comparison(); while (Match(BANG_EQUAL, EQUAL_EQUAL)) { Token op = Previous(); Expr right = Comparison(); expr = new Expr.Binary(expr, op, right); } return(expr); }
public string VisitBinary(Expr.Binary expr) { return(Parenthesize(expr.Op.Lexeme, expr.Left, expr.Right)); }
public Unit VisitBinary(Expr.Binary expr) { Resolve(expr.Left); Resolve(expr.Right); return(Unit.Default); }
public object VisitBinary(Expr.Binary expr) { // We evaluate the operands left-to-right, and we're eager. object left = Evaluate(expr.Left); object right = Evaluate(expr.Right); switch (expr.Op.Type) { case TokenType.Greater: AssertNumberOperands(expr.Op, left, right); return((double)left > (double)right); case TokenType.GreaterEqual: AssertNumberOperands(expr.Op, left, right); return((double)left >= (double)right); case TokenType.Less: AssertNumberOperands(expr.Op, left, right); return((double)left < (double)right); case TokenType.LessEqual: AssertNumberOperands(expr.Op, left, right); return((double)left <= (double)right); case TokenType.Minus: AssertNumberOperands(expr.Op, left, right); return((double)left - (double)right); case TokenType.Plus: if (left is double && right is double) { return((double)left + (double)right); } else if (left is string && right is string) { return((string)left + (string)right); } else { throw new RuntimeError(expr.Op, "Operands must be two numbers or two strings"); } case TokenType.Slash: AssertNumberOperands(expr.Op, left, right); return((double)left / (double)right); case TokenType.Star: AssertNumberOperands(expr.Op, left, right); return((double)left * (double)right); case TokenType.Percent: AssertNumberOperands(expr.Op, left, right); return((double)left % (double)right); case TokenType.BangEqual: return(!IsEqual(left, right)); case TokenType.EqualEqual: return(IsEqual(left, right)); } throw new NotSupportedException(); }
object Expr.IVisitor <object> .VisitBinaryExpr(Expr.Binary expr) { Resolve(expr.left); Resolve(expr.right); return(null); }