2 // constant.cs: Constants.
5 // Miguel de Icaza (miguel@ximian.com)
6 // Marek Safar (marek.safar@seznam.cz)
8 // (C) 2001 Ximian, Inc.
12 namespace Mono.CSharp {
15 using System.Reflection.Emit;
18 /// Base class for constants and literals.
20 public abstract class Constant : Expression {
22 protected Constant (Location loc)
28 /// This is different from ToString in that ToString
29 /// is supposed to be there for debugging purposes,
30 /// and is not guaranteed to be useful for anything else,
31 /// AsString() will provide something that can be used
32 /// for round-tripping C# code. Maybe it can be used
33 /// for IL assembly as well.
35 public abstract string AsString ();
37 override public string ToString ()
39 return this.GetType ().Name + " (" + AsString () + ")";
43 /// This is used to obtain the actual value of the literal
44 /// cast into an object.
46 public abstract object GetValue ();
48 public virtual object GetTypedValue ()
54 /// Constants are always born in a fully resolved state
56 public override Expression DoResolve (EmitContext ec)
62 // The various ToXXXX conversion functions are used by the constant
63 // folding evaluator. A null value is returned if the conversion is
66 // Note: not all the patterns for catching `implicit_conv' are the same.
67 // some implicit conversions can never be performed between two types
68 // even if the conversion would be lossless (for example short to uint),
69 // but some conversions are explicitly permitted by the standard provided
70 // that there will be no loss of information (for example, int to uint).
72 public DoubleConstant ToDouble (Location loc)
74 DoubleConstant c = ConvertToDouble ();
77 Error_ValueCannotBeConverted (loc, TypeManager.double_type, false);
82 public FloatConstant ToFloat (Location loc)
84 FloatConstant c = ConvertToFloat ();
87 Error_ValueCannotBeConverted (loc, TypeManager.float_type, false);
92 public ULongConstant ToULong (Location loc)
94 ULongConstant c = ConvertToULong ();
97 Error_ValueCannotBeConverted (loc, TypeManager.uint64_type, false);
102 public LongConstant ToLong (Location loc)
104 LongConstant c = ConvertToLong ();
107 Error_ValueCannotBeConverted (loc, TypeManager.int64_type, false);
112 public UIntConstant ToUInt (Location loc)
114 UIntConstant c = ConvertToUInt ();
117 Error_ValueCannotBeConverted (loc, TypeManager.uint32_type, false);
122 public IntConstant ToInt (Location loc)
124 IntConstant c = ConvertToInt ();
127 Error_ValueCannotBeConverted (loc, TypeManager.int32_type, false);
132 public DecimalConstant ToDecimal (Location loc)
134 DecimalConstant c = ConvertToDecimal ();
137 Error_ValueCannotBeConverted (loc, TypeManager.decimal_type, false);
142 public virtual Constant ToType (Type type, Location loc)
147 if (type == TypeManager.object_type)
150 if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, this, type)){
151 Error_ValueCannotBeConverted (loc, type, false);
155 // Special-case: The 0 literal can be converted to an enum value,
156 // and ImplicitStandardConversionExists will return true in that case.
157 if (IsZeroInteger && Type == TypeManager.int32_type && TypeManager.IsEnumType (type)) {
158 return new EnumConstant (this, type);
162 object constant_value = TypeManager.ChangeType (GetValue (), type, out fail);
164 Error_ValueCannotBeConverted (loc, type, false);
167 // We should always catch the error before this is ever
168 // reached, by calling Convert.ImplicitStandardConversionExists
170 throw new Exception (
171 String.Format ("LookupConstantValue: This should never be reached {0} {1}", Type, type));
175 if (type == TypeManager.int32_type)
176 retval = new IntConstant ((int) constant_value, loc);
177 else if (type == TypeManager.uint32_type)
178 retval = new UIntConstant ((uint) constant_value, loc);
179 else if (type == TypeManager.int64_type)
180 retval = new LongConstant ((long) constant_value, loc);
181 else if (type == TypeManager.uint64_type)
182 retval = new ULongConstant ((ulong) constant_value, loc);
183 else if (type == TypeManager.float_type)
184 retval = new FloatConstant ((float) constant_value, loc);
185 else if (type == TypeManager.double_type)
186 retval = new DoubleConstant ((double) constant_value, loc);
187 else if (type == TypeManager.string_type)
188 retval = new StringConstant ((string) constant_value, loc);
189 else if (type == TypeManager.short_type)
190 retval = new ShortConstant ((short) constant_value, loc);
191 else if (type == TypeManager.ushort_type)
192 retval = new UShortConstant ((ushort) constant_value, loc);
193 else if (type == TypeManager.sbyte_type)
194 retval = new SByteConstant ((sbyte) constant_value, loc);
195 else if (type == TypeManager.byte_type)
196 retval = new ByteConstant ((byte) constant_value, loc);
197 else if (type == TypeManager.char_type)
198 retval = new CharConstant ((char) constant_value, loc);
199 else if (type == TypeManager.bool_type)
200 retval = new BoolConstant ((bool) constant_value, loc);
201 else if (type == TypeManager.decimal_type)
202 retval = new DecimalConstant ((decimal) constant_value, loc);
204 throw new Exception ("LookupConstantValue: Unhandled constant type: " + type);
209 protected void CheckRange (EmitContext ec, ulong value, Type type, ulong max)
211 if (!ec.ConstantCheckState)
215 throw new OverflowException ();
218 protected void CheckRange (EmitContext ec, double value, Type type, long min, long max)
220 if (!ec.ConstantCheckState)
223 if (((value < min) || (value > max)))
224 throw new OverflowException ();
227 protected void CheckUnsigned (EmitContext ec, long value, Type type)
229 if (!ec.ConstantCheckState)
233 throw new OverflowException ();
236 public abstract Constant Reduce (EmitContext ec, Type target_type);
239 /// Attempts to do a compile-time folding of a constant cast.
241 public Constant TryReduce (EmitContext ec, Type target_type, Location loc)
244 return TryReduce (ec, target_type);
246 catch (OverflowException) {
247 if (ec.ConstantCheckState) {
248 Report.Error (221, loc, "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
249 this.GetValue (), TypeManager.CSharpName (target_type));
255 Constant TryReduce (EmitContext ec, Type target_type)
257 if (Type == target_type)
260 if (TypeManager.IsEnumType (target_type)) {
261 Constant c = TryReduce (ec, TypeManager.EnumToUnderlying (target_type));
265 return new EnumConstant (c, target_type);
268 return Reduce (ec, target_type);
272 public virtual DecimalConstant ConvertToDecimal ()
277 public virtual DoubleConstant ConvertToDouble ()
282 public virtual FloatConstant ConvertToFloat ()
287 public virtual ULongConstant ConvertToULong ()
292 public virtual LongConstant ConvertToLong ()
297 public virtual UIntConstant ConvertToUInt ()
302 public virtual IntConstant ConvertToInt ()
307 public abstract Constant Increment ();
309 public abstract bool IsDefaultValue {
313 public abstract bool IsNegative {
318 // Returns true iff 1) the stack type of this is one of Object,
319 // int32, int64 and 2) this == 0 or this == null.
321 public virtual bool IsZeroInteger {
322 get { return false; }
326 public class BoolConstant : Constant {
327 public readonly bool Value;
329 public BoolConstant (bool val, Location loc):
332 type = TypeManager.bool_type;
333 eclass = ExprClass.Value;
338 override public string AsString ()
340 return Value ? "true" : "false";
343 public override object GetValue ()
345 return (object) Value;
349 public override void Emit (EmitContext ec)
352 ec.ig.Emit (OpCodes.Ldc_I4_1);
354 ec.ig.Emit (OpCodes.Ldc_I4_0);
357 public override Constant Increment ()
359 throw new NotSupportedException ();
362 public override bool IsDefaultValue {
368 public override bool IsNegative {
374 public override bool IsZeroInteger {
375 get { return Value == false; }
378 public override Constant Reduce (EmitContext ec, Type target_type)
385 public class ByteConstant : Constant {
386 public readonly byte Value;
388 public ByteConstant (byte v, Location loc):
391 type = TypeManager.byte_type;
392 eclass = ExprClass.Value;
396 public override void Emit (EmitContext ec)
398 IntLiteral.EmitInt (ec.ig, Value);
401 public override string AsString ()
403 return Value.ToString ();
406 public override object GetValue ()
411 public override DoubleConstant ConvertToDouble ()
413 return new DoubleConstant (Value, loc);
416 public override FloatConstant ConvertToFloat ()
418 return new FloatConstant (Value, loc);
421 public override ULongConstant ConvertToULong ()
423 return new ULongConstant (Value, loc);
426 public override LongConstant ConvertToLong ()
428 return new LongConstant (Value, loc);
431 public override UIntConstant ConvertToUInt ()
433 return new UIntConstant (Value, loc);
436 public override IntConstant ConvertToInt ()
438 return new IntConstant (Value, loc);
441 public override Constant Increment ()
443 return new ByteConstant (checked ((byte)(Value + 1)), loc);
446 public override bool IsDefaultValue {
452 public override bool IsNegative {
458 public override bool IsZeroInteger {
459 get { return Value == 0; }
462 public override Constant Reduce (EmitContext ec, Type target_type)
464 if (target_type == TypeManager.sbyte_type) {
465 CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue);
466 return new SByteConstant ((sbyte) Value, Location);
468 if (target_type == TypeManager.short_type)
469 return new ShortConstant ((short) Value, Location);
470 if (target_type == TypeManager.ushort_type)
471 return new UShortConstant ((ushort) Value, Location);
472 if (target_type == TypeManager.int32_type)
473 return new IntConstant ((int) Value, Location);
474 if (target_type == TypeManager.uint32_type)
475 return new UIntConstant ((uint) Value, Location);
476 if (target_type == TypeManager.int64_type)
477 return new LongConstant ((long) Value, Location);
478 if (target_type == TypeManager.uint64_type)
479 return new ULongConstant ((ulong) Value, Location);
480 if (target_type == TypeManager.float_type)
481 return new FloatConstant ((float) Value, Location);
482 if (target_type == TypeManager.double_type)
483 return new DoubleConstant ((double) Value, Location);
484 if (target_type == TypeManager.char_type)
485 return new CharConstant ((char) Value, Location);
486 if (target_type == TypeManager.decimal_type)
487 return new DecimalConstant ((decimal) Value, Location);
494 public class CharConstant : Constant {
495 public readonly char Value;
497 public CharConstant (char v, Location loc):
500 type = TypeManager.char_type;
501 eclass = ExprClass.Value;
505 public override void Emit (EmitContext ec)
507 IntLiteral.EmitInt (ec.ig, Value);
510 static public string descape (char c)
536 return c.ToString ();
539 public override string AsString ()
541 return "\"" + descape (Value) + "\"";
544 public override object GetValue ()
549 public override DoubleConstant ConvertToDouble ()
551 return new DoubleConstant (Value, loc);
554 public override FloatConstant ConvertToFloat ()
556 return new FloatConstant (Value, loc);
559 public override ULongConstant ConvertToULong ()
561 return new ULongConstant (Value, loc);
564 public override LongConstant ConvertToLong ()
566 return new LongConstant (Value, loc);
569 public override UIntConstant ConvertToUInt ()
571 return new UIntConstant (Value, loc);
574 public override IntConstant ConvertToInt ()
576 return new IntConstant (Value, loc);
579 public override Constant Increment ()
581 return new CharConstant (checked ((char)(Value + 1)), loc);
584 public override bool IsDefaultValue {
590 public override bool IsNegative {
596 public override bool IsZeroInteger {
597 get { return Value == '\0'; }
600 public override Constant Reduce (EmitContext ec, Type target_type)
602 if (target_type == TypeManager.byte_type) {
603 CheckRange (ec, Value, target_type, Byte.MinValue, Byte.MaxValue);
604 return new ByteConstant ((byte) Value, Location);
606 if (target_type == TypeManager.sbyte_type) {
607 CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue);
608 return new SByteConstant ((sbyte) Value, Location);
610 if (target_type == TypeManager.short_type) {
611 CheckRange (ec, Value, target_type, Int16.MinValue, Int16.MaxValue);
612 return new ShortConstant ((short) Value, Location);
614 if (target_type == TypeManager.int32_type)
615 return new IntConstant ((int) Value, Location);
616 if (target_type == TypeManager.uint32_type)
617 return new UIntConstant ((uint) Value, Location);
618 if (target_type == TypeManager.int64_type)
619 return new LongConstant ((long) Value, Location);
620 if (target_type == TypeManager.uint64_type)
621 return new ULongConstant ((ulong) Value, Location);
622 if (target_type == TypeManager.float_type)
623 return new FloatConstant ((float) Value, Location);
624 if (target_type == TypeManager.double_type)
625 return new DoubleConstant ((double) Value, Location);
626 if (target_type == TypeManager.decimal_type)
627 return new DecimalConstant ((decimal) Value, Location);
634 public class SByteConstant : Constant {
635 public readonly sbyte Value;
637 public SByteConstant (sbyte v, Location loc):
640 type = TypeManager.sbyte_type;
641 eclass = ExprClass.Value;
645 public override void Emit (EmitContext ec)
647 IntLiteral.EmitInt (ec.ig, Value);
650 public override string AsString ()
652 return Value.ToString ();
655 public override object GetValue ()
660 public override DoubleConstant ConvertToDouble ()
662 return new DoubleConstant (Value, loc);
665 public override FloatConstant ConvertToFloat ()
667 return new FloatConstant (Value, loc);
670 public override ULongConstant ConvertToULong ()
673 return new ULongConstant ((ulong) Value, loc);
678 public override LongConstant ConvertToLong ()
680 return new LongConstant (Value, loc);
683 public override UIntConstant ConvertToUInt ()
688 public override IntConstant ConvertToInt ()
690 return new IntConstant (Value, loc);
693 public override Constant Increment ()
695 return new SByteConstant (checked((sbyte)(Value + 1)), loc);
698 public override bool IsDefaultValue {
704 public override bool IsNegative {
710 public override bool IsZeroInteger {
711 get { return Value == 0; }
714 public override Constant Reduce (EmitContext ec, Type target_type)
716 if (target_type == TypeManager.byte_type) {
717 CheckUnsigned (ec, Value, target_type);
718 return new ByteConstant ((byte) Value, Location);
720 if (target_type == TypeManager.short_type)
721 return new ShortConstant ((short) Value, Location);
722 if (target_type == TypeManager.ushort_type) {
723 CheckUnsigned (ec, Value, target_type);
724 return new UShortConstant ((ushort) Value, Location);
725 } if (target_type == TypeManager.int32_type)
726 return new IntConstant ((int) Value, Location);
727 if (target_type == TypeManager.uint32_type) {
728 CheckUnsigned (ec, Value, target_type);
729 return new UIntConstant ((uint) Value, Location);
730 } if (target_type == TypeManager.int64_type)
731 return new LongConstant ((long) Value, Location);
732 if (target_type == TypeManager.uint64_type) {
733 CheckUnsigned (ec, Value, target_type);
734 return new ULongConstant ((ulong) Value, Location);
736 if (target_type == TypeManager.float_type)
737 return new FloatConstant ((float) Value, Location);
738 if (target_type == TypeManager.double_type)
739 return new DoubleConstant ((double) Value, Location);
740 if (target_type == TypeManager.char_type) {
741 CheckUnsigned (ec, Value, target_type);
742 return new CharConstant ((char) Value, Location);
744 if (target_type == TypeManager.decimal_type)
745 return new DecimalConstant ((decimal) Value, Location);
752 public class ShortConstant : Constant {
753 public readonly short Value;
755 public ShortConstant (short v, Location loc):
758 type = TypeManager.short_type;
759 eclass = ExprClass.Value;
763 public override void Emit (EmitContext ec)
765 IntLiteral.EmitInt (ec.ig, Value);
768 public override string AsString ()
770 return Value.ToString ();
773 public override object GetValue ()
778 public override DoubleConstant ConvertToDouble ()
780 return new DoubleConstant (Value, loc);
783 public override FloatConstant ConvertToFloat ()
785 return new FloatConstant (Value, loc);
788 public override ULongConstant ConvertToULong ()
793 public override LongConstant ConvertToLong ()
795 return new LongConstant (Value, loc);
798 public override UIntConstant ConvertToUInt ()
803 public override IntConstant ConvertToInt ()
805 return new IntConstant (Value, loc);
808 public override Constant Increment ()
810 return new ShortConstant (checked((short)(Value + 1)), loc);
813 public override bool IsDefaultValue {
819 public override bool IsZeroInteger {
820 get { return Value == 0; }
823 public override bool IsNegative {
829 public override Constant Reduce (EmitContext ec, Type target_type)
831 if (target_type == TypeManager.byte_type) {
832 CheckRange (ec, Value, target_type, Byte.MinValue, Byte.MaxValue);
833 return new ByteConstant ((byte) Value, Location);
835 if (target_type == TypeManager.sbyte_type) {
836 CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue);
837 return new SByteConstant ((sbyte) Value, Location);
839 if (target_type == TypeManager.ushort_type) {
840 CheckUnsigned (ec, Value, target_type);
841 return new UShortConstant ((ushort) Value, Location);
843 if (target_type == TypeManager.int32_type)
844 return new IntConstant ((int) Value, Location);
845 if (target_type == TypeManager.uint32_type) {
846 CheckUnsigned (ec, Value, target_type);
847 return new UIntConstant ((uint) Value, Location);
849 if (target_type == TypeManager.int64_type)
850 return new LongConstant ((long) Value, Location);
851 if (target_type == TypeManager.uint64_type) {
852 CheckUnsigned (ec, Value, target_type);
853 return new ULongConstant ((ulong) Value, Location);
855 if (target_type == TypeManager.float_type)
856 return new FloatConstant ((float) Value, Location);
857 if (target_type == TypeManager.double_type)
858 return new DoubleConstant ((double) Value, Location);
859 if (target_type == TypeManager.char_type) {
860 CheckRange (ec, Value, target_type, Char.MinValue, Char.MaxValue);
861 return new CharConstant ((char) Value, Location);
863 if (target_type == TypeManager.decimal_type)
864 return new DecimalConstant ((decimal) Value, Location);
871 public class UShortConstant : Constant {
872 public readonly ushort Value;
874 public UShortConstant (ushort v, Location loc):
877 type = TypeManager.ushort_type;
878 eclass = ExprClass.Value;
882 public override void Emit (EmitContext ec)
884 IntLiteral.EmitInt (ec.ig, Value);
887 public override string AsString ()
889 return Value.ToString ();
892 public override object GetValue ()
897 public override DoubleConstant ConvertToDouble ()
899 return new DoubleConstant (Value, loc);
902 public override FloatConstant ConvertToFloat ()
904 return new FloatConstant (Value, loc);
907 public override ULongConstant ConvertToULong ()
909 return new ULongConstant (Value, loc);
912 public override LongConstant ConvertToLong ()
914 return new LongConstant (Value, loc);
917 public override UIntConstant ConvertToUInt ()
919 return new UIntConstant (Value, loc);
922 public override IntConstant ConvertToInt ()
924 return new IntConstant (Value, loc);
927 public override Constant Increment ()
929 return new UShortConstant (checked((ushort)(Value + 1)), loc);
932 public override bool IsDefaultValue {
938 public override bool IsNegative {
944 public override bool IsZeroInteger {
945 get { return Value == 0; }
948 public override Constant Reduce (EmitContext ec, Type target_type)
950 if (target_type == TypeManager.byte_type) {
951 CheckRange (ec, Value, target_type, Byte.MinValue, Byte.MaxValue);
952 return new ByteConstant ((byte) Value, Location);
954 if (target_type == TypeManager.sbyte_type) {
955 CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue);
956 return new SByteConstant ((sbyte) Value, Location);
958 if (target_type == TypeManager.short_type) {
959 CheckRange (ec, Value, target_type, Int16.MinValue, Int16.MaxValue);
960 return new ShortConstant ((short) Value, Location);
962 if (target_type == TypeManager.int32_type)
963 return new IntConstant ((int) Value, Location);
964 if (target_type == TypeManager.uint32_type)
965 return new UIntConstant ((uint) Value, Location);
966 if (target_type == TypeManager.int64_type)
967 return new LongConstant ((long) Value, Location);
968 if (target_type == TypeManager.uint64_type)
969 return new ULongConstant ((ulong) Value, Location);
970 if (target_type == TypeManager.float_type)
971 return new FloatConstant ((float) Value, Location);
972 if (target_type == TypeManager.double_type)
973 return new DoubleConstant ((double) Value, Location);
974 if (target_type == TypeManager.char_type) {
975 CheckRange (ec, Value, target_type, Char.MinValue, Char.MaxValue);
976 return new CharConstant ((char) Value, Location);
978 if (target_type == TypeManager.decimal_type)
979 return new DecimalConstant ((decimal) Value, Location);
985 public class IntConstant : Constant {
986 public readonly int Value;
988 public IntConstant (int v, Location loc):
991 type = TypeManager.int32_type;
992 eclass = ExprClass.Value;
996 static public void EmitInt (ILGenerator ig, int i)
1000 ig.Emit (OpCodes.Ldc_I4_M1);
1004 ig.Emit (OpCodes.Ldc_I4_0);
1008 ig.Emit (OpCodes.Ldc_I4_1);
1012 ig.Emit (OpCodes.Ldc_I4_2);
1016 ig.Emit (OpCodes.Ldc_I4_3);
1020 ig.Emit (OpCodes.Ldc_I4_4);
1024 ig.Emit (OpCodes.Ldc_I4_5);
1028 ig.Emit (OpCodes.Ldc_I4_6);
1032 ig.Emit (OpCodes.Ldc_I4_7);
1036 ig.Emit (OpCodes.Ldc_I4_8);
1040 if (i >= -128 && i <= 127){
1041 ig.Emit (OpCodes.Ldc_I4_S, (sbyte) i);
1043 ig.Emit (OpCodes.Ldc_I4, i);
1048 public override void Emit (EmitContext ec)
1050 EmitInt (ec.ig, Value);
1053 public override string AsString ()
1055 return Value.ToString ();
1058 public override object GetValue ()
1063 public override DecimalConstant ConvertToDecimal()
1065 return new DecimalConstant (Value, loc);
1068 public override DoubleConstant ConvertToDouble ()
1070 return new DoubleConstant (Value, loc);
1073 public override FloatConstant ConvertToFloat ()
1075 return new FloatConstant (Value, loc);
1078 public override ULongConstant ConvertToULong ()
1083 return new ULongConstant ((ulong) Value, loc);
1086 public override LongConstant ConvertToLong ()
1088 return new LongConstant (Value, loc);
1091 public override UIntConstant ConvertToUInt ()
1096 return new UIntConstant ((uint) Value, loc);
1099 public override IntConstant ConvertToInt ()
1104 public override Constant Increment ()
1106 return new IntConstant (checked(Value + 1), loc);
1109 public override bool IsDefaultValue {
1115 public override bool IsNegative {
1121 public override bool IsZeroInteger {
1122 get { return Value == 0; }
1125 public override Constant Reduce (EmitContext ec, Type target_type)
1127 if (target_type == TypeManager.byte_type) {
1128 CheckRange (ec, Value, target_type, Byte.MinValue, Byte.MaxValue);
1129 return new ByteConstant ((byte) Value, Location);
1131 if (target_type == TypeManager.sbyte_type) {
1132 CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue);
1133 return new SByteConstant ((sbyte) Value, Location);
1135 if (target_type == TypeManager.short_type) {
1136 CheckRange (ec, Value, target_type, Int16.MinValue, Int16.MaxValue);
1137 return new ShortConstant ((short) Value, Location);
1139 if (target_type == TypeManager.ushort_type) {
1140 CheckRange (ec, Value, target_type, UInt16.MinValue, UInt16.MaxValue);
1141 return new UShortConstant ((ushort) Value, Location);
1143 if (target_type == TypeManager.uint32_type) {
1144 CheckRange (ec, Value, target_type, Int32.MinValue, Int32.MaxValue);
1145 return new UIntConstant ((uint) Value, Location);
1147 if (target_type == TypeManager.int64_type)
1148 return new LongConstant ((long) Value, Location);
1149 if (target_type == TypeManager.uint64_type) {
1150 CheckUnsigned (ec, Value, target_type);
1151 return new ULongConstant ((ulong) Value, Location);
1153 if (target_type == TypeManager.float_type)
1154 return new FloatConstant ((float) Value, Location);
1155 if (target_type == TypeManager.double_type)
1156 return new DoubleConstant ((double) Value, Location);
1157 if (target_type == TypeManager.char_type) {
1158 CheckRange (ec, Value, target_type, Char.MinValue, Char.MaxValue);
1159 return new CharConstant ((char) Value, Location);
1161 if (target_type == TypeManager.decimal_type)
1162 return new DecimalConstant ((decimal) Value, Location);
1168 public class UIntConstant : Constant {
1169 public readonly uint Value;
1171 public UIntConstant (uint v, Location loc):
1174 type = TypeManager.uint32_type;
1175 eclass = ExprClass.Value;
1179 public override void Emit (EmitContext ec)
1181 IntLiteral.EmitInt (ec.ig, unchecked ((int) Value));
1184 public override string AsString ()
1186 return Value.ToString ();
1189 public override object GetValue ()
1194 public override DoubleConstant ConvertToDouble ()
1196 return new DoubleConstant (Value, loc);
1199 public override FloatConstant ConvertToFloat ()
1201 return new FloatConstant (Value, loc);
1204 public override ULongConstant ConvertToULong ()
1206 return new ULongConstant (Value, loc);
1209 public override LongConstant ConvertToLong ()
1211 return new LongConstant (Value, loc);
1214 public override UIntConstant ConvertToUInt ()
1219 public override IntConstant ConvertToInt ()
1224 public override Constant Increment ()
1226 return new UIntConstant (checked(Value + 1), loc);
1229 public override bool IsDefaultValue {
1235 public override bool IsNegative {
1241 public override bool IsZeroInteger {
1242 get { return Value == 0; }
1245 public override Constant Reduce (EmitContext ec, Type target_type)
1247 if (target_type == TypeManager.byte_type) {
1248 CheckRange (ec, Value, target_type, Char.MinValue, Char.MaxValue);
1249 return new ByteConstant ((byte) Value, Location);
1251 if (target_type == TypeManager.sbyte_type) {
1252 CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue);
1253 return new SByteConstant ((sbyte) Value, Location);
1255 if (target_type == TypeManager.short_type) {
1256 CheckRange (ec, Value, target_type, Int16.MinValue, Int16.MaxValue);
1257 return new ShortConstant ((short) Value, Location);
1259 if (target_type == TypeManager.ushort_type) {
1260 CheckRange (ec, Value, target_type, UInt16.MinValue, UInt16.MaxValue);
1261 return new UShortConstant ((ushort) Value, Location);
1263 if (target_type == TypeManager.int32_type) {
1264 CheckRange (ec, Value, target_type, Int32.MinValue, Int32.MaxValue);
1265 return new IntConstant ((int) Value, Location);
1267 if (target_type == TypeManager.int64_type)
1268 return new LongConstant ((long) Value, Location);
1269 if (target_type == TypeManager.uint64_type)
1270 return new ULongConstant ((ulong) Value, Location);
1271 if (target_type == TypeManager.float_type)
1272 return new FloatConstant ((float) Value, Location);
1273 if (target_type == TypeManager.double_type)
1274 return new DoubleConstant ((double) Value, Location);
1275 if (target_type == TypeManager.char_type) {
1276 CheckRange (ec, Value, target_type, Char.MinValue, Char.MaxValue);
1277 return new CharConstant ((char) Value, Location);
1279 if (target_type == TypeManager.decimal_type)
1280 return new DecimalConstant ((decimal) Value, Location);
1287 public class LongConstant : Constant {
1288 public readonly long Value;
1290 public LongConstant (long v, Location loc):
1293 type = TypeManager.int64_type;
1294 eclass = ExprClass.Value;
1298 public override void Emit (EmitContext ec)
1300 ILGenerator ig = ec.ig;
1302 EmitLong (ig, Value);
1305 static public void EmitLong (ILGenerator ig, long l)
1307 if ((l >> 32) == 0){
1308 IntLiteral.EmitInt (ig, unchecked ((int) l));
1309 ig.Emit (OpCodes.Conv_U8);
1311 ig.Emit (OpCodes.Ldc_I8, l);
1315 public override string AsString ()
1317 return Value.ToString ();
1320 public override object GetValue ()
1325 public override DoubleConstant ConvertToDouble ()
1327 return new DoubleConstant (Value, loc);
1330 public override FloatConstant ConvertToFloat ()
1332 return new FloatConstant (Value, loc);
1335 public override ULongConstant ConvertToULong ()
1340 return new ULongConstant ((ulong) Value, loc);
1343 public override LongConstant ConvertToLong ()
1348 public override UIntConstant ConvertToUInt ()
1353 public override IntConstant ConvertToInt ()
1358 public override Constant Increment ()
1360 return new LongConstant (checked(Value + 1), loc);
1363 public override bool IsDefaultValue {
1369 public override bool IsNegative {
1375 public override bool IsZeroInteger {
1376 get { return Value == 0; }
1379 public override Constant Reduce (EmitContext ec, Type target_type)
1381 if (target_type == TypeManager.byte_type) {
1382 CheckRange (ec, Value, target_type, Byte.MinValue, Byte.MaxValue);
1383 return new ByteConstant ((byte) Value, Location);
1385 if (target_type == TypeManager.sbyte_type) {
1386 CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue);
1387 return new SByteConstant ((sbyte) Value, Location);
1389 if (target_type == TypeManager.short_type) {
1390 CheckRange (ec, Value, target_type, Int16.MinValue, Int16.MaxValue);
1391 return new ShortConstant ((short) Value, Location);
1393 if (target_type == TypeManager.ushort_type) {
1394 CheckRange (ec, Value, target_type, UInt16.MinValue, UInt16.MaxValue);
1395 return new UShortConstant ((ushort) Value, Location);
1397 if (target_type == TypeManager.int32_type) {
1398 CheckRange (ec, Value, target_type, Int32.MinValue, Int32.MaxValue);
1399 return new IntConstant ((int) Value, Location);
1401 if (target_type == TypeManager.uint32_type) {
1402 CheckRange (ec, Value, target_type, UInt32.MinValue, UInt32.MaxValue);
1403 return new UIntConstant ((uint) Value, Location);
1405 if (target_type == TypeManager.uint64_type) {
1406 CheckUnsigned (ec, Value, target_type);
1407 return new ULongConstant ((ulong) Value, Location);
1409 if (target_type == TypeManager.float_type)
1410 return new FloatConstant ((float) Value, Location);
1411 if (target_type == TypeManager.double_type)
1412 return new DoubleConstant ((double) Value, Location);
1413 if (target_type == TypeManager.char_type) {
1414 CheckRange (ec, Value, target_type, Char.MinValue, Char.MaxValue);
1415 return new CharConstant ((char) Value, Location);
1417 if (target_type == TypeManager.decimal_type)
1418 return new DecimalConstant ((decimal) Value, Location);
1425 public class ULongConstant : Constant {
1426 public readonly ulong Value;
1428 public ULongConstant (ulong v, Location loc):
1431 type = TypeManager.uint64_type;
1432 eclass = ExprClass.Value;
1436 public override void Emit (EmitContext ec)
1438 ILGenerator ig = ec.ig;
1440 LongLiteral.EmitLong (ig, unchecked ((long) Value));
1443 public override string AsString ()
1445 return Value.ToString ();
1448 public override object GetValue ()
1453 public override DoubleConstant ConvertToDouble ()
1455 return new DoubleConstant (Value, loc);
1458 public override FloatConstant ConvertToFloat ()
1460 return new FloatConstant (Value, loc);
1463 public override ULongConstant ConvertToULong ()
1468 public override LongConstant ConvertToLong ()
1473 public override UIntConstant ConvertToUInt ()
1478 public override IntConstant ConvertToInt ()
1483 public override Constant Increment ()
1485 return new ULongConstant (checked(Value + 1), loc);
1488 public override bool IsDefaultValue {
1494 public override bool IsNegative {
1500 public override bool IsZeroInteger {
1501 get { return Value == 0; }
1504 public override Constant Reduce (EmitContext ec, Type target_type)
1506 if (target_type == TypeManager.byte_type) {
1507 CheckRange (ec, Value, target_type, Byte.MaxValue);
1508 return new ByteConstant ((byte) Value, Location);
1510 if (target_type == TypeManager.sbyte_type) {
1511 CheckRange (ec, Value, target_type, (ulong) SByte.MaxValue);
1512 return new SByteConstant ((sbyte) Value, Location);
1514 if (target_type == TypeManager.short_type) {
1515 CheckRange (ec, Value, target_type, (ulong) Int16.MaxValue);
1516 return new ShortConstant ((short) Value, Location);
1518 if (target_type == TypeManager.ushort_type) {
1519 CheckRange (ec, Value, target_type, UInt16.MaxValue);
1520 return new UShortConstant ((ushort) Value, Location);
1522 if (target_type == TypeManager.int32_type) {
1523 CheckRange (ec, Value, target_type, Int32.MaxValue);
1524 return new IntConstant ((int) Value, Location);
1526 if (target_type == TypeManager.uint32_type) {
1527 CheckRange (ec, Value, target_type, UInt32.MaxValue);
1528 return new UIntConstant ((uint) Value, Location);
1530 if (target_type == TypeManager.int64_type) {
1531 CheckRange (ec, Value, target_type, (ulong) Int64.MaxValue);
1532 return new LongConstant ((long) Value, Location);
1534 if (target_type == TypeManager.float_type)
1535 return new FloatConstant ((float) Value, Location);
1536 if (target_type == TypeManager.double_type)
1537 return new DoubleConstant ((double) Value, Location);
1538 if (target_type == TypeManager.char_type) {
1539 CheckRange (ec, Value, target_type, Char.MaxValue);
1540 return new CharConstant ((char) Value, Location);
1542 if (target_type == TypeManager.decimal_type)
1543 return new DecimalConstant ((decimal) Value, Location);
1550 public class FloatConstant : Constant {
1551 public readonly float Value;
1553 public FloatConstant (float v, Location loc):
1556 type = TypeManager.float_type;
1557 eclass = ExprClass.Value;
1561 public override void Emit (EmitContext ec)
1563 ec.ig.Emit (OpCodes.Ldc_R4, Value);
1566 public override string AsString ()
1568 return Value.ToString ();
1571 public override object GetValue ()
1576 public override DoubleConstant ConvertToDouble ()
1578 return new DoubleConstant (Value, loc);
1581 public override FloatConstant ConvertToFloat ()
1586 public override LongConstant ConvertToLong ()
1591 public override UIntConstant ConvertToUInt ()
1596 public override IntConstant ConvertToInt ()
1601 public override Constant Increment ()
1603 return new FloatConstant (checked(Value + 1), loc);
1606 public override bool IsDefaultValue {
1612 public override bool IsNegative {
1618 public override Constant Reduce (EmitContext ec, Type target_type)
1620 if (target_type == TypeManager.byte_type)
1621 return new ByteConstant ((byte) Value, Location);
1622 if (target_type == TypeManager.sbyte_type)
1623 return new SByteConstant ((sbyte) Value, Location);
1624 if (target_type == TypeManager.short_type)
1625 return new ShortConstant ((short) Value, Location);
1626 if (target_type == TypeManager.ushort_type)
1627 return new UShortConstant ((ushort) Value, Location);
1628 if (target_type == TypeManager.int32_type)
1629 return new IntConstant ((int) Value, Location);
1630 if (target_type == TypeManager.uint32_type)
1631 return new UIntConstant ((uint) Value, Location);
1632 if (target_type == TypeManager.int64_type)
1633 return new LongConstant ((long) Value, Location);
1634 if (target_type == TypeManager.uint64_type)
1635 return new ULongConstant ((ulong) Value, Location);
1636 if (target_type == TypeManager.double_type)
1637 return new DoubleConstant ((double) Value, Location);
1638 if (target_type == TypeManager.char_type)
1639 return new CharConstant ((char) Value, Location);
1640 if (target_type == TypeManager.decimal_type)
1641 return new DecimalConstant ((decimal) Value, Location);
1648 public class DoubleConstant : Constant {
1649 public readonly double Value;
1651 public DoubleConstant (double v, Location loc):
1654 type = TypeManager.double_type;
1655 eclass = ExprClass.Value;
1659 public override void Emit (EmitContext ec)
1661 ec.ig.Emit (OpCodes.Ldc_R8, Value);
1664 public override string AsString ()
1666 return Value.ToString ();
1669 public override object GetValue ()
1674 public override DoubleConstant ConvertToDouble ()
1679 public override FloatConstant ConvertToFloat ()
1684 public override ULongConstant ConvertToULong ()
1689 public override LongConstant ConvertToLong ()
1694 public override UIntConstant ConvertToUInt ()
1699 public override IntConstant ConvertToInt ()
1704 public override Constant Increment ()
1706 return new DoubleConstant (checked(Value + 1), loc);
1709 public override bool IsDefaultValue {
1715 public override bool IsNegative {
1721 public override Constant Reduce (EmitContext ec, Type target_type)
1723 if (target_type == TypeManager.byte_type) {
1724 CheckRange (ec, Value, target_type, Byte.MinValue, Byte.MaxValue);
1725 return new ByteConstant ((byte) Value, Location);
1727 if (target_type == TypeManager.sbyte_type) {
1728 CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue);
1729 return new SByteConstant ((sbyte) Value, Location);
1731 if (target_type == TypeManager.short_type)
1732 return new ShortConstant ((short) Value, Location);
1733 if (target_type == TypeManager.ushort_type)
1734 return new UShortConstant ((ushort) Value, Location);
1735 if (target_type == TypeManager.int32_type)
1736 return new IntConstant ((int) Value, Location);
1737 if (target_type == TypeManager.uint32_type)
1738 return new UIntConstant ((uint) Value, Location);
1739 if (target_type == TypeManager.int64_type)
1740 return new LongConstant ((long) Value, Location);
1741 if (target_type == TypeManager.uint64_type)
1742 return new ULongConstant ((ulong) Value, Location);
1743 if (target_type == TypeManager.float_type)
1744 return new FloatConstant ((float) Value, Location);
1745 if (target_type == TypeManager.char_type) {
1746 CheckRange (ec, Value, target_type, char.MinValue, char.MaxValue);
1747 return new CharConstant ((char) Value, Location);
1749 if (target_type == TypeManager.decimal_type)
1750 return new DecimalConstant ((decimal) Value, Location);
1757 public class DecimalConstant : Constant {
1758 public readonly decimal Value;
1760 public DecimalConstant (decimal d, Location loc):
1763 type = TypeManager.decimal_type;
1764 eclass = ExprClass.Value;
1768 override public string AsString ()
1770 return Value.ToString ();
1773 public override object GetValue ()
1775 return (object) Value;
1778 public override void Emit (EmitContext ec)
1780 ILGenerator ig = ec.ig;
1782 int [] words = Decimal.GetBits (Value);
1783 int power = (words [3] >> 16) & 0xff;
1785 if (power == 0 && Value <= int.MaxValue && Value >= int.MinValue)
1787 IntConstant.EmitInt (ig, (int)Value);
1788 ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_int_arg);
1794 // FIXME: we could optimize this, and call a better
1798 IntConstant.EmitInt (ig, words [0]);
1799 IntConstant.EmitInt (ig, words [1]);
1800 IntConstant.EmitInt (ig, words [2]);
1803 IntConstant.EmitInt (ig, words [3] >> 31);
1806 IntConstant.EmitInt (ig, power);
1808 ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
1811 public override Constant Increment ()
1813 return new DecimalConstant (checked (Value + 1), loc);
1816 public override bool IsDefaultValue {
1822 public override bool IsNegative {
1828 public override Constant Reduce (EmitContext ec, Type target_type)
1830 if (target_type == TypeManager.sbyte_type)
1831 return new SByteConstant ((sbyte)Value, loc);
1832 if (target_type == TypeManager.byte_type)
1833 return new ByteConstant ((byte)Value, loc);
1834 if (target_type == TypeManager.short_type)
1835 return new ShortConstant ((short)Value, loc);
1836 if (target_type == TypeManager.ushort_type)
1837 return new UShortConstant ((ushort)Value, loc);
1838 if (target_type == TypeManager.int32_type)
1839 return new IntConstant ((int)Value, loc);
1840 if (target_type == TypeManager.uint32_type)
1841 return new UIntConstant ((uint)Value, loc);
1842 if (target_type == TypeManager.int64_type)
1843 return new LongConstant ((long)Value, loc);
1844 if (target_type == TypeManager.uint64_type)
1845 return new ULongConstant ((ulong)Value, loc);
1846 if (target_type == TypeManager.char_type)
1847 return new CharConstant ((char)Value, loc);
1848 if (target_type == TypeManager.float_type)
1849 return new FloatConstant ((float)Value, loc);
1850 if (target_type == TypeManager.double_type)
1851 return new DoubleConstant ((double)Value, loc);
1858 public class StringConstant : Constant {
1859 public readonly string Value;
1861 public StringConstant (string s, Location loc):
1864 type = TypeManager.string_type;
1865 eclass = ExprClass.Value;
1869 // FIXME: Escape the string.
1870 override public string AsString ()
1872 return "\"" + Value + "\"";
1875 public override object GetValue ()
1880 public override void Emit (EmitContext ec)
1883 ec.ig.Emit (OpCodes.Ldnull);
1885 ec.ig.Emit (OpCodes.Ldstr, Value);
1888 public override Constant Increment ()
1890 throw new NotSupportedException ();
1893 public override bool IsDefaultValue {
1895 return Value == null;
1899 public override bool IsNegative {
1905 public override Constant Reduce (EmitContext ec, Type target_type)