private Expr Multiplication() { Expr expr = Unary(); while (Match(TokenType.SLASH, TokenType.STAR)) { Token oper = Previous(); Expr right = Unary(); expr = new Expr.Binary(expr, oper, right); } return(expr); }
private Expr Addition() { Expr expr = Multiplication(); while (Match(TokenType.MINUS, TokenType.PLUS)) { Token oper = Previous(); Expr right = Multiplication(); expr = new Expr.Binary(expr, oper, right); } return(expr); }
private Expr Comparison() { Expr expr = Addition(); while (Match(TokenType.GREATER, TokenType.GREATER_EQUAL, TokenType.LESS, TokenType.LESS_EQUAL)) { Token oper = Previous(); Expr right = Addition(); expr = new Expr.Binary(expr, oper, right); } return(expr); }
private Expr Equality() { Expr expr = Comparison(); while (Match(TokenType.BANG_EQUAL, TokenType.EQUAL_EQUAL)) { Token oper = Previous(); Expr right = Comparison(); expr = new Expr.Binary(expr, oper, right); } return(expr); }
public Void VisitBinaryExpr(Expr.Binary expr) { Resolve(expr.left); Resolve(expr.right); return(null); }
public object VisitBinaryExpr(Expr.Binary expr) { object left = Evaluate(expr.left); object right = Evaluate(expr.right); switch (expr.oper.Type) { case TokenType.PLUS: if (left is int && right is int) { return((int)left + (int)right); } if (left is float && right is float) { return((float)left + (float)right); } if (left is string && right is string) { return((string)left + (string)right); } throw new RuntimeError(expr.oper, "Operands must be two numbers or two strings."); case TokenType.GREATER: CheckNumberOperands(expr.oper, left, right); return((float)left > (float)right); case TokenType.GREATER_EQUAL: CheckNumberOperands(expr.oper, left, right); return((float)left >= (float)right); case TokenType.LESS: CheckNumberOperands(expr.oper, left, right); return((float)left < (float)right); case TokenType.LESS_EQUAL: CheckNumberOperands(expr.oper, left, right); return((float)left <= (float)right); case TokenType.BANG_EQUAL: return(!IsEqual(left, right)); case TokenType.EQUAL_EQUAL: return(IsEqual(left, right)); case TokenType.MINUS: CheckNumberOperands(expr.oper, left, right); return((float)left - (float)right); case TokenType.STAR: CheckNumberOperands(expr.oper, left, right); return((float)left * (float)right); case TokenType.SLASH: CheckNumberOperands(expr.oper, left, right); return((float)left / (float)right); } // Unreachable. return(null); }