Пример #1
0
        /// <summary>
        /// Gets the type of the binary implicit scalar conversion.
        /// </summary>
        /// <param name="span">The span.</param>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <returns>
        /// The implicit conversion between the two scalar types
        /// </returns>
        protected ScalarType GetBinaryImplicitScalarConversionType(SourceSpan span, TypeBase left, TypeBase right)
        {
            var result = CastHelper.GetBinaryImplicitScalarConversionType(left, right);

            if (result == null)
            {
                Error(MessageCode.ErrorScalarTypeConversion, span, left, right);
            }
            return(result);
        }
Пример #2
0
        /// <summary>
        /// Gets the type of the binary implicit conversion.
        /// </summary>
        /// <param name="span">The span.</param>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <param name="isBinaryOperator">if set to <c>true</c> [is binary operator].</param>
        /// <returns>
        /// The implicit conversion between between to two types
        /// </returns>
        protected virtual TypeBase GetBinaryImplicitConversionType(SourceSpan span, TypeBase left, TypeBase right, bool isBinaryOperator)
        {
            var result = CastHelper.GetBinaryImplicitConversionType(left, right, isBinaryOperator);

            if (result == null)
            {
                Error(MessageCode.ErrorBinaryTypeDeduction, span, left, right);
            }

            return(result);
        }
Пример #3
0
        /// <summary>
        /// Gets the type of the binary implicit conversion.
        /// </summary>
        /// <param name="span">The span.</param>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <returns>The implicit conversion between between to two types</returns>
        protected virtual TypeBase GetDivideImplicitConversionType(SourceSpan span, TypeBase left, TypeBase right)
        {
            var result = CastHelper.GetDivideImplicitConversionType(left.ResolveType(), right.ResolveType());

            if (result == null)
            {
                Error(MessageCode.ErrorBinaryTypeDeduction, span, left, right);
            }

            return(result);
        }
Пример #4
0
        public override Node Visit(BinaryExpression expression)
        {
            // First, dispatch to resolve type of node at deeper level
            base.Visit(expression);

            var leftType   = expression.Left.TypeInference.TargetType;
            var rightType  = expression.Right.TypeInference.TargetType;
            var returnType = expression.TypeInference.ExpectedType ?? expression.TypeInference.TargetType;

            bool isNumericOperator = true;

            switch (expression.Operator)
            {
            case BinaryOperator.LogicalAnd:
            case BinaryOperator.LogicalOr:
                isNumericOperator = false;
                returnType        = GetBinaryImplicitConversionType(expression.Span, leftType, rightType, true);
                expression.TypeInference.TargetType = returnType;
                break;

            case BinaryOperator.Less:
            case BinaryOperator.LessEqual:
            case BinaryOperator.Greater:
            case BinaryOperator.GreaterEqual:
            case BinaryOperator.Equality:
            case BinaryOperator.Inequality:
                isNumericOperator = false;
                returnType        = GetBinaryImplicitConversionType(expression.Span, leftType, rightType, false);

                TypeBase resultType = ScalarType.Bool;
                if (returnType is VectorType)
                {
                    resultType = new VectorType(ScalarType.Bool, ((VectorType)returnType).Dimension);
                }
                else if (returnType is MatrixType)
                {
                    var matrixType = (MatrixType)returnType;
                    resultType = new MatrixType(ScalarType.Bool, matrixType.RowCount, matrixType.ColumnCount);
                }
                expression.TypeInference.TargetType = resultType;
                break;
            }

            if (returnType != null)
            {
                if (returnType == ScalarType.Bool && isNumericOperator)
                {
                    var typeToCheck = leftType ?? rightType;
                    if (typeToCheck != null)
                    {
                        return(ConvertExpressionToBool(expression, typeToCheck));
                    }
                }
            }

            if (!isNumericOperator || CastHelper.NeedConvertForBinary(leftType, returnType))
            {
                expression.Left = Cast(leftType, returnType, expression.Left);
            }
            if (!isNumericOperator || CastHelper.NeedConvertForBinary(rightType, returnType))
            {
                expression.Right = Cast(rightType, returnType, expression.Right);
            }

            return(expression);
        }