public string VisitBinaryExpr(BinaryExpr expr)
 {
     return(Parenthesize(expr.Operator.Lexeme, expr.Left, expr.Right));
 }
 public void VisitBinaryExpr(BinaryExpr expr)
 {
     Resolve(expr.Left);
     Resolve(expr.Right);
 }
        public object VisitBinaryExpr(BinaryExpr expr)
        {
            var left  = Evaluate(expr.Left);
            var right = Evaluate(expr.Right);

            switch (expr.Operator.Type)
            {
            case TokenType.Greater:
                CheckNumberOperands(expr.Operator, left, right);
                return((double)left > (double)right);

            case TokenType.GreaterEqual:
                CheckNumberOperands(expr.Operator, left, right);
                return((double)left >= (double)right);

            case TokenType.Less:
                CheckNumberOperands(expr.Operator, left, right);
                return((double)left < (double)right);

            case TokenType.LessEqual:
                CheckNumberOperands(expr.Operator, left, right);
                return((double)left <= (double)right);

            case TokenType.BangEqual:
                return(!IsEqual(left, right));

            case TokenType.EqualEqual:
                return(IsEqual(left, right));

            case TokenType.Minus:
                CheckNumberOperands(expr.Operator, left, right);
                return((double)left - (double)right);

            case TokenType.Plus:
                if (left is double && right is double)
                {
                    return((double)left + (double)right);
                }
                if (left is string && right is string)
                {
                    return((string)left + (string)right);
                }
                if (left is string)
                {
                    return((string)left + Stringify(right));
                }
                if (right is string)
                {
                    return(Stringify(left) + (string)right);
                }
                throw new RuntimeError(expr.Operator, "Operands must be two numbers or at least one string.");

            case TokenType.Slash:
                CheckNumberOperands(expr.Operator, left, right);
                return((double)left / (double)right);

            case TokenType.Star:
                CheckNumberOperands(expr.Operator, left, right);
                return((double)left * (double)right);
            }

            // unreachable
            return(null);
        }