Esempio n. 1
0
        private DataType InferBinaryExpressionType(
            BinaryExpressionSyntax binaryExpression)
        {
            InferExpressionType(binaryExpression.LeftOperand);
            var leftType  = binaryExpression.LeftOperand.Type;
            var @operator = binaryExpression.Operator;

            InferExpressionType(binaryExpression.RightOperand);
            var rightType = binaryExpression.RightOperand.Type;

            // If either is unknown, then we can't know whether there is a a problem.
            // Note that the operator could be overloaded
            if (leftType == DataType.Unknown || rightType == DataType.Unknown)
            {
                return(binaryExpression.Type = DataType.Unknown);
            }

            bool compatible;

            switch (@operator)
            {
            case BinaryOperator.Plus:
            case BinaryOperator.Minus:
            case BinaryOperator.Asterisk:
            case BinaryOperator.Slash:
                compatible            = NumericOperatorTypesAreCompatible(ref binaryExpression.LeftOperand, ref binaryExpression.RightOperand, null);
                binaryExpression.Type = compatible ? leftType : DataType.Unknown;
                break;

            case BinaryOperator.EqualsEquals:
            case BinaryOperator.NotEqual:
            case BinaryOperator.LessThan:
            case BinaryOperator.LessThanOrEqual:
            case BinaryOperator.GreaterThan:
            case BinaryOperator.GreaterThanOrEqual:
                compatible = (leftType == DataType.Bool && rightType == DataType.Bool) ||
                             NumericOperatorTypesAreCompatible(ref binaryExpression.LeftOperand, ref binaryExpression.RightOperand, null);
                binaryExpression.Type = DataType.Bool;
                break;

            case BinaryOperator.And:
            case BinaryOperator.Or:
                compatible            = leftType == DataType.Bool && rightType == DataType.Bool;
                binaryExpression.Type = DataType.Bool;
                break;

            default:
                throw NonExhaustiveMatchException.ForEnum(@operator);
            }
            if (!compatible)
            {
                diagnostics.Add(TypeError.OperatorCannotBeAppliedToOperandsOfType(file,
                                                                                  binaryExpression.Span, @operator,
                                                                                  binaryExpression.LeftOperand.Type,
                                                                                  binaryExpression.RightOperand.Type));
            }

            return(binaryExpression.Type);
        }