Example #1
0
        private BoundExpression BindBinaryExpression(BinaryExpressionSyntax syntax)
        {
            var boundLeft  = BindExpression(syntax.Left);
            var boundRight = BindExpression(syntax.Right);

            if (boundLeft.Type == TypeSymbol.Error || boundRight.Type == TypeSymbol.Error)
            {
                return(new BoundErrorExpression());
            }

            var boundOperator = BoundBinaryOperator.Bind(syntax.OperatorToken.Kind, boundLeft.Type, boundRight.Type);

            if (boundOperator == null)
            {
                _diagnostics.ReportUndefinedBinaryOperator(syntax.OperatorToken.Span, syntax.OperatorToken.Text, boundLeft.Type, boundRight.Type);
                return(new BoundErrorExpression());
            }

            return(new BoundBinaryExpression(boundLeft, boundOperator, boundRight));
        }
 public BoundCompoundAssignmentExpression(SyntaxNode syntax, VariableSymbol variable, BoundBinaryOperator op, BoundExpression expression)
     : base(syntax)
 {
     Variable   = variable;
     Op         = op;
     Expression = expression;
 }
 public BoundBinaryExpression(BoundExpression left, BoundBinaryOperator @operator, BoundExpression right)
 {
     Left     = left;
     Operator = @operator;
     Right    = right;
 }
Example #4
0
 public BoundBinaryExpression(BoundExpression left, BoundBinaryOperator op, BoundExpression right)
 {
     Left  = left;
     Op    = op;
     Right = right;
 }
Example #5
0
 public static BoundBinaryExpression Binary(SyntaxNode syntax, BoundExpression left, BoundBinaryOperator op, BoundExpression right)
 {
     return(new BoundBinaryExpression(syntax, left, op, right));
 }
Example #6
0
        public static BoundBinaryExpression Binary(SyntaxNode syntax, BoundExpression left, SyntaxKind kind, BoundExpression right)
        {
            var op = BoundBinaryOperator.Bind(kind, left.Type, right.Type) !;

            return(Binary(syntax, left, op, right));
        }
Example #7
0
 public BoundCompoundAssignmentExpression(VariableSymbol variable, BoundBinaryOperator op, BoundExpression expression)
 {
     Variable   = variable;
     Op         = op;
     Expression = expression;
 }
Example #8
0
        public static BoundConstant?Fold(BoundExpression left, BoundBinaryOperator op, BoundExpression right)
        {
            var leftConstant  = left.ConstantValue;
            var rightConstant = right.ConstantValue;

            // Special case && and || because there are cases where only one
            // side needs to be known.

            if (op.Kind == BoundBinaryOperatorKind.LogicalAnd)
            {
                if (leftConstant != null && !(bool)leftConstant.Value ||
                    rightConstant != null && !(bool)rightConstant.Value)
                {
                    return(new BoundConstant(false));
                }
            }

            if (op.Kind == BoundBinaryOperatorKind.LogicalOr)
            {
                if (leftConstant != null && (bool)leftConstant.Value ||
                    rightConstant != null && (bool)rightConstant.Value)
                {
                    return(new BoundConstant(true));
                }
            }

            if (leftConstant == null || rightConstant == null)
            {
                return(null);
            }

            var l = leftConstant.Value;
            var r = rightConstant.Value;

            switch (op.Kind)
            {
            case BoundBinaryOperatorKind.Addition:
                if (left.Type == TypeSymbol.Int)
                {
                    return(new BoundConstant((int)l + (int)r));
                }
                else
                {
                    return(new BoundConstant((string)l + (string)r));
                }

            case BoundBinaryOperatorKind.Subtraction:
                return(new BoundConstant((int)l - (int)r));

            case BoundBinaryOperatorKind.Multiplication:
                return(new BoundConstant((int)l * (int)r));

            case BoundBinaryOperatorKind.Division:
                return(new BoundConstant((int)l / (int)r));

            case BoundBinaryOperatorKind.BitwiseAnd:
                if (left.Type == TypeSymbol.Int)
                {
                    return(new BoundConstant((int)l & (int)r));
                }
                else
                {
                    return(new BoundConstant((bool)l & (bool)r));
                }

            case BoundBinaryOperatorKind.BitwiseOr:
                if (left.Type == TypeSymbol.Int)
                {
                    return(new BoundConstant((int)l | (int)r));
                }
                else
                {
                    return(new BoundConstant((bool)l | (bool)r));
                }

            case BoundBinaryOperatorKind.BitwiseXor:
                if (left.Type == TypeSymbol.Int)
                {
                    return(new BoundConstant((int)l ^ (int)r));
                }
                else
                {
                    return(new BoundConstant((bool)l ^ (bool)r));
                }

            case BoundBinaryOperatorKind.LogicalAnd:
                return(new BoundConstant((bool)l && (bool)r));

            case BoundBinaryOperatorKind.LogicalOr:
                return(new BoundConstant((bool)l || (bool)r));

            case BoundBinaryOperatorKind.Equals:
                return(new BoundConstant(Equals(l, r)));

            case BoundBinaryOperatorKind.NotEquals:
                return(new BoundConstant(!Equals(l, r)));

            case BoundBinaryOperatorKind.Less:
                return(new BoundConstant((int)l < (int)r));

            case BoundBinaryOperatorKind.LessOrEquals:
                return(new BoundConstant((int)l <= (int)r));

            case BoundBinaryOperatorKind.Greater:
                return(new BoundConstant((int)l > (int)r));

            case BoundBinaryOperatorKind.GreaterOrEquals:
                return(new BoundConstant((int)l >= (int)r));

            default:
                throw new Exception($"Unexpected binary operator {op.Kind}");
            }
        }