+
+ public override Constant ConvertImplicitly (Type type)
+ {
+ if (this.type == type)
+ return this;
+
+ Constant c = TryImplicitIntConversion (type);
+ if (c != null)
+ return c;
+
+ return base.ConvertImplicitly (type);
+ }
+
+ /// <summary>
+ /// Attempts to perform an implicit constant conversion of the IntConstant
+ /// into a different data type using casts (See Implicit Constant
+ /// Expression Conversions)
+ /// </summary>
+ Constant TryImplicitIntConversion (Type target_type)
+ {
+ if (target_type == TypeManager.sbyte_type) {
+ if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
+ return new SByteConstant ((sbyte) Value, loc);
+ }
+ else if (target_type == TypeManager.byte_type) {
+ if (Value >= Byte.MinValue && Value <= Byte.MaxValue)
+ return new ByteConstant ((byte) Value, loc);
+ }
+ else if (target_type == TypeManager.short_type) {
+ if (Value >= Int16.MinValue && Value <= Int16.MaxValue)
+ return new ShortConstant ((short) Value, loc);
+ }
+ else if (target_type == TypeManager.ushort_type) {
+ if (Value >= UInt16.MinValue && Value <= UInt16.MaxValue)
+ return new UShortConstant ((ushort) Value, loc);
+ }
+ else if (target_type == TypeManager.uint32_type) {
+ if (Value >= 0)
+ return new UIntConstant ((uint) Value, loc);
+ }
+ else if (target_type == TypeManager.uint64_type) {
+ //
+ // we can optimize this case: a positive int32
+ // always fits on a uint64. But we need an opcode
+ // to do it.
+ //
+ if (Value >= 0)
+ return new ULongConstant ((ulong) Value, loc);
+ }
+ else if (target_type == TypeManager.double_type)
+ return new DoubleConstant ((double) Value, loc);
+ else if (target_type == TypeManager.float_type)
+ return new FloatConstant ((float) Value, loc);
+
+ return null;
+ }