示例#1
0
        private static bool ValidateTypeForBinaryExpression(TypeSymbol type,
                                                            bool requiresIntegralType, bool requiresNumericType)
        {
            IntrinsicNumericTypeSymbol numericType = null;

            if (requiresIntegralType || requiresNumericType)
            {
                numericType = type as IntrinsicNumericTypeSymbol;
                if (numericType == null)
                {
                    return(false);
                }
            }

            if (requiresIntegralType && !numericType.ScalarType.IsIntegral())
            {
                return(false);
            }

            return(true);
        }
示例#2
0
        private static ConversionTypes ClassifyTypeConversion(IntrinsicNumericTypeSymbol numericSourceType, IntrinsicNumericTypeSymbol numericTargetType)
        {
            var parameterScalarType = numericTargetType.ScalarType;
            var argumentScalarType  = numericSourceType.ScalarType;

            if (argumentScalarType.IsFloat() && !parameterScalarType.IsFloat())
            {
                return(ConversionTypes.FloatToIntConversion);
            }

            if (!argumentScalarType.IsFloat() && parameterScalarType.IsFloat())
            {
                return(ConversionTypes.IntToFloatConversion);
            }

            switch (argumentScalarType)
            {
            case ScalarType.Float:
                switch (parameterScalarType)
                {
                case ScalarType.Half:
                    return(ConversionTypes.FloatTruncation);

                case ScalarType.Double:
                    return(ConversionTypes.FloatPromotion);
                }
                break;

            case ScalarType.Half:
                switch (parameterScalarType)
                {
                case ScalarType.Float:
                case ScalarType.Double:
                    return(ConversionTypes.FloatPromotion);
                }
                break;

            case ScalarType.Double:
                switch (parameterScalarType)
                {
                case ScalarType.Half:
                case ScalarType.Float:
                    return(ConversionTypes.FloatTruncation);
                }
                break;

            case ScalarType.Bool:
                if (parameterScalarType != ScalarType.Bool)
                {
                    return(ConversionTypes.IntToFloatConversion);
                }
                break;

            case ScalarType.Int:
                if (parameterScalarType == ScalarType.Uint)
                {
                    return(ConversionTypes.SignedToUnsigned);
                }
                break;

            case ScalarType.Uint:
                if (parameterScalarType == ScalarType.Int)
                {
                    return(ConversionTypes.UnsignedToSigned);
                }
                break;
            }

            if (argumentScalarType != parameterScalarType)
            {
                return(ConversionTypes.SignedToUnsigned); // TODO: Check this. Int/Uint => Bool?
            }
            return(ConversionTypes.None);
        }
 protected bool Equals(IntrinsicNumericTypeSymbol other)
 {
     return(base.Equals(other) && ScalarType == other.ScalarType);
 }
示例#4
0
        private static ConversionTypes ClassifyDimensionConversion(IntrinsicNumericTypeSymbol sourceType, IntrinsicNumericTypeSymbol targetType)
        {
            var targetDim0 = targetType.GetDimensionSize(0);
            var targetDim1 = targetType.GetDimensionSize(1);
            var sourceDim0 = sourceType.GetDimensionSize(0);
            var sourceDim1 = sourceType.GetDimensionSize(1);

            if ((sourceDim0 == targetDim0 && sourceDim1 == targetDim1) || (sourceDim1 == targetDim0 && sourceDim0 == targetDim1))
            {
                switch (sourceType.Kind)
                {
                case SymbolKind.IntrinsicMatrixType:
                    switch (targetType.Kind)
                    {
                    case SymbolKind.IntrinsicVectorType:         // float1x1 => float1
                    case SymbolKind.IntrinsicScalarType:         // float1x1 => float
                        return(ConversionTypes.SameSizeTruncation);
                    }
                    break;

                case SymbolKind.IntrinsicVectorType:
                    switch (targetType.Kind)
                    {
                    case SymbolKind.IntrinsicMatrixType:         // float1 => float1x1
                        return(ConversionTypes.SameSizePromotion);

                    case SymbolKind.IntrinsicScalarType:         // float1 => float
                        return(ConversionTypes.SameSizeTruncation);
                    }
                    break;

                case SymbolKind.IntrinsicScalarType:
                    switch (targetType.Kind)
                    {
                    case SymbolKind.IntrinsicMatrixType:         // float => float1x1
                    case SymbolKind.IntrinsicVectorType:         // float => float1
                        return(ConversionTypes.SameSizePromotion);
                    }
                    break;
                }
            }
            else if ((sourceDim0 == targetDim1 && sourceDim1 == targetDim0) || (sourceDim1 == targetDim0 && sourceDim0 == targetDim1))
            {
                switch (sourceType.Kind)
                {
                case SymbolKind.IntrinsicMatrixType:
                    switch (targetType.Kind)
                    {
                    case SymbolKind.IntrinsicVectorType:         // float3x1 => float1
                        return(ConversionTypes.DimensionTruncation);
                    }
                    break;

                case SymbolKind.IntrinsicVectorType:
                    switch (targetType.Kind)
                    {
                    case SymbolKind.IntrinsicMatrixType:         // float3 => float3x1
                        return(ConversionTypes.ScalarPromotion);
                    }
                    break;
                }
            }
            else if (sourceDim0 == 1 && sourceDim1 == 1)
            {
                // float => float2x4
                // float => float2
                // float1 => float2
                return(ConversionTypes.ScalarPromotion);
            }
            else if ((sourceDim0 >= targetDim0 && sourceDim1 >= targetDim1) || (sourceDim1 >= targetDim0 && sourceDim0 >= targetDim1))
            {
                switch (sourceType.Kind)
                {
                case SymbolKind.IntrinsicMatrixType:
                    switch (targetType.Kind)
                    {
                    case SymbolKind.IntrinsicMatrixType:
                        if (sourceDim0 > targetDim0 && sourceDim1 > targetDim1)         // float4x4 => float3x3
                        {
                            return(ConversionTypes.RankTruncation2);
                        }
                        if (sourceDim0 > targetDim0 || sourceDim1 > targetDim1)         // float4x4 => float4x3
                        {
                            return(ConversionTypes.RankTruncation);
                        }
                        return(ConversionTypes.None);

                    case SymbolKind.IntrinsicVectorType:         // float4x4 => float3
                        return(ConversionTypes.RankTruncation2);

                    case SymbolKind.IntrinsicScalarType:         // float3x4 => float
                        return(ConversionTypes.RankTruncation2);

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                case SymbolKind.IntrinsicVectorType:
                    switch (targetType.Kind)
                    {
                    case SymbolKind.IntrinsicMatrixType:         // float4 => float4x3
                        return(ConversionTypes.RankTruncation);

                    case SymbolKind.IntrinsicVectorType:         // float4 => float3
                        return(ConversionTypes.RankTruncation2);

                    case SymbolKind.IntrinsicScalarType:         // float4 => float
                        return(ConversionTypes.RankTruncation2);

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            return(ConversionTypes.None);
        }
 protected bool Equals(IntrinsicNumericTypeSymbol other)
 {
     return base.Equals(other) && ScalarType == other.ScalarType;
 }