예제 #1
0
        public object visitBinaryExpr(Expr.Binary expr)
        {
            object left  = Evaluate(expr.left);
            object right = Evaluate(expr.right);

            if (expr.op.type == TokenType.AND)
            {
                return(GetTruthValue(left) && GetTruthValue(right));
            }
            if (expr.op.type == TokenType.OR)
            {
                return(GetTruthValue(left) || GetTruthValue(right));
            }

            // same for strings, numbers and bools
            switch (expr.op.type)
            {
            case TokenType.EQUAL_EQUAL:
                return(IsEqual(left, right));

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

            // string specific
            if (left is string || right is string)
            {
                if (expr.op.type != TokenType.PLUS)
                {
                    throw new RuntimeError(expr.op, expr.op.type.ToString() + " not a valid operator on strings.");
                }
                return(Stringify(left) + Stringify(right));
            }

            // number specific
            CheckNumberOperands(expr.op, left, right);

            switch (expr.op.type)
            {
            case TokenType.PLUS:
                return((double)left + (double)right);

            case TokenType.MINUS:
                return((double)left - (double)right);

            case TokenType.STAR:
                return((double)left * (double)right);

            case TokenType.SLASH:
                double r = (double)right;
                if (r == 0)
                {
                    throw new RuntimeError(expr.op, "Divide by zero error.");
                }
                return((double)left / r);

            case TokenType.GREATER:
                return((double)left > (double)right);

            case TokenType.GREATER_EQUAL:
                return((double)left >= (double)right);

            case TokenType.LESS:
                return((double)left < (double)right);

            case TokenType.LESS_EQUAL:
                return((double)left <= (double)right);

            default:
                Lox.ReportError(expr.op, expr.op.type.ToString() + " not a valid operator on doubles.");
                return(right);
            }
        }