ABT.TypeCast.UnsignedIntegralToArith C# (CSharp) Method

UnsignedIntegralToArith() public static method

From: uchar, ushort, ulong To: char, uchar, short, ushort, long, ulong, float, double
Aaccording to MSDN "Conversions from Unsigned Integral Types", unsigned long converts directly to double. However, I just treat unsigned long as long.
public static UnsignedIntegralToArith ( Expr expr, ExprType type ) : Expr
expr Expr
type ExprType
return Expr
        public static Expr UnsignedIntegralToArith(Expr expr, ExprType type) {
            ExprTypeKind from = expr.Type.Kind;
            ExprTypeKind to = type.Kind;

            Env env = expr.Env;

            switch (from) {
                case ExprTypeKind.UCHAR:
                    switch (to) {
                        case ExprTypeKind.CHAR:
                            return new TypeCast(TypeCastType.NOP, expr, type);

                        case ExprTypeKind.SHORT:
                        case ExprTypeKind.USHORT:
                            return new TypeCast(TypeCastType.UINT8_TO_UINT16, expr, type);

                        case ExprTypeKind.LONG:
                        case ExprTypeKind.ULONG:
                            return new TypeCast(TypeCastType.UINT8_TO_UINT32, expr, type);

                        case ExprTypeKind.FLOAT:
                            // uchar -> ulong -> long -> float
                            return new TypeCast(TypeCastType.INT32_TO_FLOAT, new TypeCast(TypeCastType.UINT8_TO_UINT32, expr, new LongType(type.IsConst, type.IsVolatile)), type);

                        case ExprTypeKind.DOUBLE:
                            // uchar -> ulong -> long -> double
                            return new TypeCast(TypeCastType.INT32_TO_DOUBLE, new TypeCast(TypeCastType.UINT8_TO_UINT32, expr, new LongType(type.IsConst, type.IsVolatile)), type);

                        default:
                            Debug.Assert(false);
                            return null;
                    }

                case ExprTypeKind.USHORT:
                    switch (to) {
                        case ExprTypeKind.CHAR:
                        case ExprTypeKind.UCHAR:
                            return new TypeCast(TypeCastType.PRESERVE_INT8, expr, type);

                        case ExprTypeKind.USHORT:
                            return new TypeCast(TypeCastType.NOP, expr, type);

                        case ExprTypeKind.LONG:
                        case ExprTypeKind.ULONG:
                            return new TypeCast(TypeCastType.UINT16_TO_UINT32, expr, type);

                        case ExprTypeKind.FLOAT:
                            // ushort -> ulong -> long -> float
                            return new TypeCast(TypeCastType.INT32_TO_FLOAT, new TypeCast(TypeCastType.UINT16_TO_UINT32, expr, new LongType(type.IsConst, type.IsVolatile)), type);

                        case ExprTypeKind.DOUBLE:
                            // ushort -> ulong -> long -> double
                            return new TypeCast(TypeCastType.INT32_TO_DOUBLE, new TypeCast(TypeCastType.UINT16_TO_UINT32, expr, new LongType(type.IsConst, type.IsVolatile)), type);

                        default:
                            Debug.Assert(false);
                            return null;
                    }

                case ExprTypeKind.ULONG:
                    switch (to) {
                        case ExprTypeKind.CHAR:
                            if (expr.IsConstExpr) {
                                return new ConstLong((SByte)((ConstULong)expr).Value, env);
                            }
                            return new TypeCast(TypeCastType.PRESERVE_INT8, expr, type);

                        case ExprTypeKind.UCHAR:
                            if (expr.IsConstExpr) {
                                return new ConstULong((Byte)((ConstULong)expr).Value, env);
                            }
                            return new TypeCast(TypeCastType.PRESERVE_INT8, expr, type);

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

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

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

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

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

                        default:
                            Debug.Assert(false);
                            return null;
                    }

                default:
                    Debug.Assert(false);
                    return null;
            }
        }