ABT.TypeCast.FloatToArith C# (CSharp) Method

FloatToArith() public static method

From: float, double To: char, uchar, short, ushort, long, ulong, float, double
According to MSDN "Conversions from Floating-Point Types", float cannot convert to unsigned char. I don't know why, but I follow it.
public static FloatToArith ( Expr expr, ExprType type ) : Expr
expr Expr
type ExprType
return Expr
        public static Expr FloatToArith(Expr expr, ExprType type) {

            ExprTypeKind from = expr.Type.Kind;
            ExprTypeKind to = type.Kind;
            Env env = expr.Env;

            switch (from) {
                case ExprTypeKind.FLOAT:
                    switch (to) {
                        case ExprTypeKind.CHAR:
                            if (expr.IsConstExpr) {
                                return new ConstLong((SByte)((ConstFloat)expr).Value, env);
                            }
                            return new TypeCast(TypeCastType.PRESERVE_INT8, new TypeCast(TypeCastType.FLOAT_TO_INT32, expr, new LongType(type.IsConst, type.IsVolatile)), type);

                        case ExprTypeKind.SHORT:
                            if (expr.IsConstExpr) {
                                return new ConstLong((Int16)((ConstFloat)expr).Value, env);
                            }
                            return new TypeCast(TypeCastType.PRESERVE_INT16, new TypeCast(TypeCastType.FLOAT_TO_INT32, expr, new LongType(type.IsConst, type.IsVolatile)), type);

                        case ExprTypeKind.USHORT:
                            if (expr.IsConstExpr) {
                                return new ConstULong((UInt16)((ConstFloat)expr).Value, env);
                            }
                            return new TypeCast(TypeCastType.PRESERVE_INT16, new TypeCast(TypeCastType.FLOAT_TO_INT32, expr, new LongType(type.IsConst, type.IsVolatile)), type);

                        case ExprTypeKind.LONG:
                            if (expr.IsConstExpr) {
                                return new ConstLong((Int32)((ConstFloat)expr).Value, env);
                            }
                            return new TypeCast(TypeCastType.FLOAT_TO_INT32, expr, type);

                        case ExprTypeKind.ULONG:
                            if (expr.IsConstExpr) {
                                return new ConstULong((UInt32)((ConstFloat)expr).Value, env);
                            }
                            return new TypeCast(TypeCastType.FLOAT_TO_INT32, expr, type);

                        case ExprTypeKind.DOUBLE:
                            if (expr.IsConstExpr) {
                                return new ConstDouble(((ConstFloat)expr).Value, env);
                            }
                            return new TypeCast(TypeCastType.FLOAT_TO_DOUBLE, expr, type);

                        default:
                            throw new InvalidProgramException();
                    }

                case ExprTypeKind.DOUBLE:
                    switch (to) {
                        case ExprTypeKind.CHAR:
                            // double -> float -> char
                            if (expr.IsConstExpr) {
                                return new ConstLong((SByte)((ConstDouble)expr).Value, env);
                            }
                            return FloatToArith(FloatToArith(expr, new FloatType(type.IsConst, type.IsVolatile)), new CharType(type.IsConst, type.IsVolatile));

                        case ExprTypeKind.SHORT:
                            // double -> float -> short
                            if (expr.IsConstExpr) {
                                return new ConstLong((Int16)((ConstDouble)expr).Value, env);
                            }
                            return FloatToArith(FloatToArith(expr, new FloatType(type.IsConst, type.IsVolatile)), new ShortType(type.IsConst, type.IsVolatile));

                        case ExprTypeKind.LONG:
                            // double -> float -> short
                            if (expr.IsConstExpr) {
                                return new ConstLong((Int32)((ConstDouble)expr).Value, env);
                            }
                            return new TypeCast(TypeCastType.DOUBLE_TO_INT32, expr, type);

                        case ExprTypeKind.ULONG:
                            if (expr.IsConstExpr) {
                                return new ConstULong((UInt32)((ConstDouble)expr).Value, env);
                            }
                            return new TypeCast(TypeCastType.DOUBLE_TO_INT32, expr, type);

                        case ExprTypeKind.USHORT:
                            // double -> long -> ushort
                            if (expr.IsConstExpr) {
                                return new ConstULong((UInt16)((ConstDouble)expr).Value, env);
                            }
                            return new TypeCast(TypeCastType.PRESERVE_INT16, new TypeCast(TypeCastType.DOUBLE_TO_INT32, expr, new LongType(type.IsConst, type.IsVolatile)), type);

                        case ExprTypeKind.FLOAT:
                            if (expr.IsConstExpr) {
                                return new ConstFloat((Single)((ConstDouble)expr).Value, env);
                            }
                            return new TypeCast(TypeCastType.DOUBLE_TO_FLOAT, expr, type);

                        default:
                            throw new InvalidProgramException();
                    }

                default:
                    throw new InvalidProgramException();
            }
        }