/// <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); }
/// <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); }
/// <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); }
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); }