2005-06-27 Geoff Norton <gnorton@customerdna.com>
[mono-project.git] / mcs / bmcs / constant.cs
blob63c8751b8302000ee532b5cb76ccbc6240fd3575
1 //
2 // constant.cs: Constants.
3 //
4 // Author:
5 // Miguel de Icaza (miguel@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.
8 //
9 //
11 namespace Mono.CSharp {
13 using System;
14 using System.Reflection.Emit;
16 /// <summary>
17 /// Base class for constants and literals.
18 /// </summary>
19 public abstract class Constant : Expression {
20 /// <remarks>
21 /// This is different from ToString in that ToString
22 /// is supposed to be there for debugging purposes,
23 /// and is not guaranteed to be useful for anything else,
24 /// AsString() will provide something that can be used
25 /// for round-tripping C# code. Maybe it can be used
26 /// for IL assembly as well.
27 /// </remarks>
28 public abstract string AsString ();
30 override public string ToString ()
32 return this.GetType ().Name + " (" + AsString () + ")";
35 /// <summary>
36 /// This is used to obtain the actual value of the literal
37 /// cast into an object.
38 /// </summary>
39 public abstract object GetValue ();
41 /// <summary>
42 /// Constants are always born in a fully resolved state
43 /// </summary>
44 public override Expression DoResolve (EmitContext ec)
46 return this;
50 // The various ToXXXX conversion functions are used by the constant
51 // folding evaluator. A null value is returned if the conversion is
52 // not possible.
54 // Note: not all the patterns for catching `implicit_conv' are the same.
55 // some implicit conversions can never be performed between two types
56 // even if the conversion would be lossless (for example short to uint),
57 // but some conversions are explicitly permitted by the standard provided
58 // that there will be no loss of information (for example, int to uint).
60 public DoubleConstant ToDouble (Location loc)
62 DoubleConstant c = ConvertToDouble ();
64 if (c == null)
65 Convert.Error_CannotWideningConversion (loc, Type, TypeManager.double_type);
67 return c;
70 public FloatConstant ToFloat (Location loc)
72 FloatConstant c = ConvertToFloat ();
74 if (c == null)
75 Convert.Error_CannotWideningConversion (loc, Type, TypeManager.float_type);
77 return c;
80 public ULongConstant ToULong (Location loc)
82 ULongConstant c = ConvertToULong ();
84 if (c == null)
85 Convert.Error_CannotWideningConversion (loc, Type, TypeManager.uint64_type);
87 return c;
90 public LongConstant ToLong (Location loc)
92 LongConstant c = ConvertToLong ();
94 if (c == null)
95 Convert.Error_CannotWideningConversion (loc, Type, TypeManager.int64_type);
97 return c;
100 public UIntConstant ToUInt (Location loc)
102 UIntConstant c = ConvertToUInt ();
104 if (c == null)
105 Convert.Error_CannotWideningConversion (loc, Type, TypeManager.uint32_type);
107 return c;
110 public IntConstant ToInt (Location loc)
112 IntConstant c = ConvertToInt ();
114 if (c == null)
115 Convert.Error_CannotWideningConversion (loc, Type, TypeManager.int32_type);
117 return c;
120 public DecimalConstant ToDecimal (Location loc)
122 DecimalConstant c = ConvertToDecimal ();
124 if (c == null)
125 Convert.Error_CannotConvertType (loc, Type, TypeManager.decimal_type);
127 return c;
130 public ShortConstant ToShort (Location loc)
132 ShortConstant c = ConvertToShort ();
134 if (c == null)
135 Convert.Error_CannotConvertType (loc, Type, TypeManager.short_type);
137 return c;
140 public ByteConstant ToByte (Location loc)
142 ByteConstant c = ConvertToByte ();
144 if (c == null)
145 Convert.Error_CannotConvertType (loc, Type, TypeManager.byte_type);
147 return c;
150 public BoolConstant ToBoolean (Location loc)
152 BoolConstant c = ConvertToBoolean ();
154 if (c == null)
155 Convert.Error_CannotConvertType (loc, Type, TypeManager.bool_type);
157 return c;
160 public CharConstant ToChar (Location loc)
162 CharConstant c = ConvertToChar ();
164 if (c == null)
165 Convert.Error_CannotConvertType (loc, Type, TypeManager.char_type);
167 return c;
170 public virtual CharConstant ConvertToChar ()
172 return null;
175 public virtual BoolConstant ConvertToBoolean ()
177 return null;
180 public virtual ByteConstant ConvertToByte ()
182 return null;
185 public virtual ShortConstant ConvertToShort ()
187 return null;
190 public virtual DecimalConstant ConvertToDecimal ()
192 return null;
195 public virtual DoubleConstant ConvertToDouble ()
197 return null;
200 public virtual FloatConstant ConvertToFloat ()
202 return null;
205 public virtual ULongConstant ConvertToULong ()
207 return null;
210 public virtual LongConstant ConvertToLong ()
212 return null;
215 public virtual UIntConstant ConvertToUInt ()
217 return null;
220 public virtual IntConstant ConvertToInt ()
222 return null;
225 public abstract bool IsNegative {
226 get;
230 // Returns true iff 1) the stack type of this is one of Object,
231 // int32, int64 and 2) this == 0 or this == null.
233 public virtual bool IsZeroInteger {
234 get { return false; }
238 public class BoolConstant : Constant {
239 public readonly bool Value;
241 public BoolConstant (bool val)
243 type = TypeManager.bool_type;
244 eclass = ExprClass.Value;
246 Value = val;
249 override public string AsString ()
251 return Value ? "true" : "false";
254 public override object GetValue ()
256 return (object) Value;
260 public override void Emit (EmitContext ec)
262 if (Value)
263 ec.ig.Emit (OpCodes.Ldc_I4_1);
264 else
265 ec.ig.Emit (OpCodes.Ldc_I4_0);
268 public override DecimalConstant ConvertToDecimal ()
270 return Value ? new DecimalConstant (0) : new DecimalConstant (-1);
273 public override DoubleConstant ConvertToDouble ()
275 return Value ? new DoubleConstant (0) : new DoubleConstant (-1);
278 public override FloatConstant ConvertToFloat ()
280 return Value ? new FloatConstant (0) : new FloatConstant (-1);
283 public override LongConstant ConvertToLong ()
285 return Value ? new LongConstant (0) : new LongConstant (-1);
288 public override IntConstant ConvertToInt ()
290 return Value ? new IntConstant (0) : new IntConstant (-1);
293 public override ShortConstant ConvertToShort ()
295 return Value ? new ShortConstant (0) : new ShortConstant (-1);
298 public override ByteConstant ConvertToByte ()
300 return Value ? new ByteConstant (0) : new ByteConstant (255);
303 public override BoolConstant ConvertToBoolean ()
305 return this;
308 public override bool IsNegative {
309 get {
310 return false;
314 public override bool IsZeroInteger {
315 get { return Value == false; }
319 public class ByteConstant : Constant {
320 public readonly byte Value;
322 public ByteConstant (byte v)
324 type = TypeManager.byte_type;
325 eclass = ExprClass.Value;
326 Value = v;
329 public override void Emit (EmitContext ec)
331 IntLiteral.EmitInt (ec.ig, Value);
334 public override string AsString ()
336 return Value.ToString ();
339 public override object GetValue ()
341 return Value;
344 public override DoubleConstant ConvertToDouble ()
346 return new DoubleConstant (Value);
349 public override FloatConstant ConvertToFloat ()
351 return new FloatConstant (Value);
354 public override LongConstant ConvertToLong ()
356 return new LongConstant (Value);
359 public override ShortConstant ConvertToShort ()
361 return new ShortConstant (Value);
364 public override ByteConstant ConvertToByte ()
366 return this;
369 public override DecimalConstant ConvertToDecimal ()
371 return new DecimalConstant (Value);
374 public override IntConstant ConvertToInt ()
376 return new IntConstant (Value);
379 public override BoolConstant ConvertToBoolean ()
381 return new BoolConstant (Value != 0);
384 public override bool IsNegative {
385 get {
386 return false;
390 public override bool IsZeroInteger {
391 get { return Value == 0; }
395 public class CharConstant : Constant {
396 public readonly char Value;
398 public CharConstant (char v)
400 type = TypeManager.char_type;
401 eclass = ExprClass.Value;
402 Value = v;
405 public override void Emit (EmitContext ec)
407 IntLiteral.EmitInt (ec.ig, Value);
410 static public string descape (char c)
412 switch (c){
413 case '\a':
414 return "\\a";
415 case '\b':
416 return "\\b";
417 case '\n':
418 return "\\n";
419 case '\t':
420 return "\\t";
421 case '\v':
422 return "\\v";
423 case '\r':
424 return "\\r";
425 case '\\':
426 return "\\\\";
427 case '\f':
428 return "\\f";
429 case '\0':
430 return "\\0";
431 case '"':
432 return "\\\"";
433 case '\'':
434 return "\\\'";
436 return c.ToString ();
439 public override string AsString ()
441 return "\"" + descape (Value) + "\"";
444 public override object GetValue ()
446 return Value;
449 public override DoubleConstant ConvertToDouble ()
451 return new DoubleConstant (Value);
454 public override FloatConstant ConvertToFloat ()
456 return new FloatConstant (Value);
459 public override ULongConstant ConvertToULong ()
461 return new ULongConstant (Value);
464 public override LongConstant ConvertToLong ()
466 return new LongConstant (Value);
469 public override UIntConstant ConvertToUInt ()
471 return new UIntConstant (Value);
474 public override IntConstant ConvertToInt ()
476 return new IntConstant (Value);
479 public override bool IsNegative {
480 get {
481 return false;
485 public override bool IsZeroInteger {
486 get { return Value == '\0'; }
490 public class SByteConstant : Constant {
491 public readonly sbyte Value;
493 public SByteConstant (sbyte v)
495 type = TypeManager.sbyte_type;
496 eclass = ExprClass.Value;
497 Value = v;
500 public override void Emit (EmitContext ec)
502 IntLiteral.EmitInt (ec.ig, Value);
505 public override string AsString ()
507 return Value.ToString ();
510 public override object GetValue ()
512 return Value;
515 public override DoubleConstant ConvertToDouble ()
517 return new DoubleConstant (Value);
520 public override FloatConstant ConvertToFloat ()
522 return new FloatConstant (Value);
525 public override ULongConstant ConvertToULong ()
527 if (Value >= 0)
528 return new ULongConstant ((ulong) Value);
530 return null;
533 public override LongConstant ConvertToLong ()
535 return new LongConstant (Value);
538 public override UIntConstant ConvertToUInt ()
540 return null;
543 public override IntConstant ConvertToInt ()
545 return new IntConstant (Value);
548 public override bool IsNegative {
549 get {
550 return Value < 0;
554 public override bool IsZeroInteger {
555 get { return Value == 0; }
559 public class ShortConstant : Constant {
560 public readonly short Value;
562 public ShortConstant (short v)
564 type = TypeManager.short_type;
565 eclass = ExprClass.Value;
566 Value = v;
569 public override void Emit (EmitContext ec)
571 IntLiteral.EmitInt (ec.ig, Value);
574 public override string AsString ()
576 return Value.ToString ();
579 public override object GetValue ()
581 return Value;
584 public override DoubleConstant ConvertToDouble ()
586 return new DoubleConstant (Value);
589 public override FloatConstant ConvertToFloat ()
591 return new FloatConstant (Value);
594 public override LongConstant ConvertToLong ()
596 return new LongConstant (Value);
599 public override ShortConstant ConvertToShort ()
601 return this;
604 public override IntConstant ConvertToInt ()
606 return new IntConstant (Value);
609 public override DecimalConstant ConvertToDecimal ()
611 return new DecimalConstant (Value);
614 public override ByteConstant ConvertToByte ()
616 byte val;
618 try {
619 val = System.Convert.ToByte (Value);
620 } catch (Exception ex) {
621 return null;
624 return new ByteConstant (val);
627 public override BoolConstant ConvertToBoolean ()
629 return new BoolConstant (Value != 0);
632 public override bool IsZeroInteger {
633 get { return Value == 0; }
636 public override bool IsNegative {
637 get {
638 return Value < 0;
643 public class UShortConstant : Constant {
644 public readonly ushort Value;
646 public UShortConstant (ushort v)
648 type = TypeManager.ushort_type;
649 eclass = ExprClass.Value;
650 Value = v;
653 public override void Emit (EmitContext ec)
655 IntLiteral.EmitInt (ec.ig, Value);
658 public override string AsString ()
660 return Value.ToString ();
663 public override object GetValue ()
665 return Value;
668 public override DoubleConstant ConvertToDouble ()
670 return new DoubleConstant (Value);
673 public override FloatConstant ConvertToFloat ()
675 return new FloatConstant (Value);
678 public override ULongConstant ConvertToULong ()
680 return new ULongConstant (Value);
683 public override LongConstant ConvertToLong ()
685 return new LongConstant (Value);
688 public override UIntConstant ConvertToUInt ()
690 return new UIntConstant (Value);
693 public override IntConstant ConvertToInt ()
695 return new IntConstant (Value);
698 public override bool IsNegative {
699 get {
700 return false;
704 public override bool IsZeroInteger {
705 get { return Value == 0; }
709 public class IntConstant : Constant {
710 public readonly int Value;
712 public IntConstant (int v)
714 type = TypeManager.int32_type;
715 eclass = ExprClass.Value;
716 Value = v;
719 static public void EmitInt (ILGenerator ig, int i)
721 switch (i){
722 case -1:
723 ig.Emit (OpCodes.Ldc_I4_M1);
724 break;
726 case 0:
727 ig.Emit (OpCodes.Ldc_I4_0);
728 break;
730 case 1:
731 ig.Emit (OpCodes.Ldc_I4_1);
732 break;
734 case 2:
735 ig.Emit (OpCodes.Ldc_I4_2);
736 break;
738 case 3:
739 ig.Emit (OpCodes.Ldc_I4_3);
740 break;
742 case 4:
743 ig.Emit (OpCodes.Ldc_I4_4);
744 break;
746 case 5:
747 ig.Emit (OpCodes.Ldc_I4_5);
748 break;
750 case 6:
751 ig.Emit (OpCodes.Ldc_I4_6);
752 break;
754 case 7:
755 ig.Emit (OpCodes.Ldc_I4_7);
756 break;
758 case 8:
759 ig.Emit (OpCodes.Ldc_I4_8);
760 break;
762 default:
763 if (i >= -128 && i <= 127){
764 ig.Emit (OpCodes.Ldc_I4_S, (sbyte) i);
765 } else
766 ig.Emit (OpCodes.Ldc_I4, i);
767 break;
771 public override void Emit (EmitContext ec)
773 EmitInt (ec.ig, Value);
776 public override string AsString ()
778 return Value.ToString ();
781 public override object GetValue ()
783 return Value;
786 public override DecimalConstant ConvertToDecimal()
788 return new DecimalConstant (Value);
791 public override DoubleConstant ConvertToDouble ()
793 return new DoubleConstant (Value);
796 public override FloatConstant ConvertToFloat ()
798 return new FloatConstant (Value);
801 public override LongConstant ConvertToLong ()
803 return new LongConstant (Value);
806 public override IntConstant ConvertToInt ()
808 return this;
811 public override ShortConstant ConvertToShort ()
813 short val;
815 try {
816 val = System.Convert.ToInt16 (Value);
817 } catch (Exception ex) {
818 return null;
821 return new ShortConstant (val);
824 public override ByteConstant ConvertToByte ()
826 byte val;
828 try {
829 val = System.Convert.ToByte (Value);
830 } catch (Exception ex) {
831 return null;
834 return new ByteConstant (val);
837 public override BoolConstant ConvertToBoolean ()
839 return new BoolConstant (Value != 0);
842 public override bool IsNegative {
843 get {
844 return Value < 0;
848 public override bool IsZeroInteger {
849 get { return Value == 0; }
853 public class UIntConstant : Constant {
854 public readonly uint Value;
856 public UIntConstant (uint v)
858 type = TypeManager.uint32_type;
859 eclass = ExprClass.Value;
860 Value = v;
863 public override void Emit (EmitContext ec)
865 IntLiteral.EmitInt (ec.ig, unchecked ((int) Value));
868 public override string AsString ()
870 return Value.ToString ();
873 public override object GetValue ()
875 return Value;
878 public override DoubleConstant ConvertToDouble ()
880 return new DoubleConstant (Value);
883 public override FloatConstant ConvertToFloat ()
885 return new FloatConstant (Value);
888 public override ULongConstant ConvertToULong ()
890 return new ULongConstant (Value);
893 public override LongConstant ConvertToLong ()
895 return new LongConstant (Value);
898 public override UIntConstant ConvertToUInt ()
900 return this;
903 public override IntConstant ConvertToInt ()
905 return null;
908 public override bool IsNegative {
909 get {
910 return false;
914 public override bool IsZeroInteger {
915 get { return Value == 0; }
919 public class LongConstant : Constant {
920 public readonly long Value;
922 public LongConstant (long v)
924 type = TypeManager.int64_type;
925 eclass = ExprClass.Value;
926 Value = v;
929 public override void Emit (EmitContext ec)
931 ILGenerator ig = ec.ig;
933 EmitLong (ig, Value);
936 static public void EmitLong (ILGenerator ig, long l)
938 if ((l >> 32) == 0){
939 IntLiteral.EmitInt (ig, unchecked ((int) l));
940 ig.Emit (OpCodes.Conv_U8);
941 } else {
942 ig.Emit (OpCodes.Ldc_I8, l);
946 public override string AsString ()
948 return Value.ToString ();
951 public override object GetValue ()
953 return Value;
956 public override DoubleConstant ConvertToDouble ()
958 return new DoubleConstant (Value);
961 public override FloatConstant ConvertToFloat ()
963 return new FloatConstant (Value);
966 public override DecimalConstant ConvertToDecimal()
968 return new DecimalConstant (Value);
971 public override LongConstant ConvertToLong ()
973 return this;
976 public override IntConstant ConvertToInt ()
978 int val;
980 try {
981 val = System.Convert.ToInt32 (Value);
982 } catch (Exception ex) {
983 return null;
986 return new IntConstant (val);
989 public override ShortConstant ConvertToShort ()
991 short val;
993 try {
994 val = System.Convert.ToInt16 (Value);
995 } catch (Exception ex) {
996 return null;
999 return new ShortConstant (val);
1002 public override ByteConstant ConvertToByte ()
1004 byte val;
1006 try {
1007 val = System.Convert.ToByte (Value);
1008 } catch (Exception ex) {
1009 return null;
1012 return new ByteConstant (val);
1015 public override BoolConstant ConvertToBoolean ()
1017 return new BoolConstant (Value != 0);
1020 public override bool IsNegative {
1021 get {
1022 return Value < 0;
1026 public override bool IsZeroInteger {
1027 get { return Value == 0; }
1031 public class ULongConstant : Constant {
1032 public readonly ulong Value;
1034 public ULongConstant (ulong v)
1036 type = TypeManager.uint64_type;
1037 eclass = ExprClass.Value;
1038 Value = v;
1041 public override void Emit (EmitContext ec)
1043 ILGenerator ig = ec.ig;
1045 LongLiteral.EmitLong (ig, unchecked ((long) Value));
1048 public override string AsString ()
1050 return Value.ToString ();
1053 public override object GetValue ()
1055 return Value;
1058 public override DoubleConstant ConvertToDouble ()
1060 return new DoubleConstant (Value);
1063 public override FloatConstant ConvertToFloat ()
1065 return new FloatConstant (Value);
1068 public override ULongConstant ConvertToULong ()
1070 return this;
1073 public override LongConstant ConvertToLong ()
1075 return null;
1078 public override UIntConstant ConvertToUInt ()
1080 return null;
1083 public override IntConstant ConvertToInt ()
1085 return null;
1088 public override bool IsNegative {
1089 get {
1090 return false;
1094 public override bool IsZeroInteger {
1095 get { return Value == 0; }
1099 public class FloatConstant : Constant {
1100 public readonly float Value;
1102 public FloatConstant (float v)
1104 type = TypeManager.float_type;
1105 eclass = ExprClass.Value;
1106 Value = v;
1109 public override void Emit (EmitContext ec)
1111 ec.ig.Emit (OpCodes.Ldc_R4, Value);
1114 public override string AsString ()
1116 return Value.ToString ();
1119 public override object GetValue ()
1121 return Value;
1124 public override DoubleConstant ConvertToDouble ()
1126 return new DoubleConstant (Value);
1129 public override FloatConstant ConvertToFloat ()
1131 return this;
1134 public override DecimalConstant ConvertToDecimal ()
1136 return new DecimalConstant (new System.Decimal (Value));
1139 public override LongConstant ConvertToLong ()
1141 long val;
1143 try {
1144 val = System.Convert.ToInt64 (System.Math.Round (Value));
1145 } catch (Exception ex) {
1146 return null;
1149 return new LongConstant (val);
1153 public override IntConstant ConvertToInt ()
1155 int val;
1157 try {
1158 val = System.Convert.ToInt32 (System.Math.Round (Value));
1159 } catch (Exception ex) {
1160 return null;
1163 return new IntConstant (val);
1166 public override ShortConstant ConvertToShort ()
1168 short val;
1170 try {
1171 val = System.Convert.ToInt16 (System.Math.Round (Value));
1172 } catch (Exception ex) {
1173 return null;
1176 return new ShortConstant (val);
1179 public override ByteConstant ConvertToByte ()
1181 byte val;
1183 try {
1184 val = System.Convert.ToByte (System.Math.Round (Value));
1185 } catch (Exception ex) {
1186 return null;
1189 return new ByteConstant (val);
1192 public override BoolConstant ConvertToBoolean ()
1194 return new BoolConstant (Value != 0);
1197 public override bool IsNegative {
1198 get {
1199 return Value < 0;
1204 public class DoubleConstant : Constant {
1205 public readonly double Value;
1207 public DoubleConstant (double v)
1209 type = TypeManager.double_type;
1210 eclass = ExprClass.Value;
1211 Value = v;
1214 public override void Emit (EmitContext ec)
1216 ec.ig.Emit (OpCodes.Ldc_R8, Value);
1219 public override string AsString ()
1221 return Value.ToString ();
1224 public override object GetValue ()
1226 return Value;
1229 public override DoubleConstant ConvertToDouble ()
1231 return this;
1234 public override FloatConstant ConvertToFloat ()
1236 float val;
1238 try {
1239 val = System.Convert.ToSingle (Value);
1240 } catch (Exception ex) {
1241 return null;
1244 return new FloatConstant (val);
1247 public override DecimalConstant ConvertToDecimal ()
1249 return new DecimalConstant (new System.Decimal (Value));
1252 public override LongConstant ConvertToLong ()
1254 long val;
1256 try {
1257 val = System.Convert.ToInt64 (System.Math.Round (Value));
1258 } catch (Exception ex) {
1259 return null;
1262 return new LongConstant (val);
1266 public override IntConstant ConvertToInt ()
1268 int val;
1270 try {
1271 val = System.Convert.ToInt32 (System.Math.Round (Value));
1272 } catch (Exception ex) {
1273 return null;
1276 return new IntConstant (val);
1279 public override ShortConstant ConvertToShort ()
1281 short val;
1283 try {
1284 val = System.Convert.ToInt16 (System.Math.Round (Value));
1285 } catch (Exception ex) {
1286 return null;
1289 return new ShortConstant (val);
1292 public override ByteConstant ConvertToByte ()
1294 byte val;
1296 try {
1297 val = System.Convert.ToByte (System.Math.Round (Value));
1298 } catch (Exception ex) {
1299 return null;
1302 return new ByteConstant (val);
1305 public override BoolConstant ConvertToBoolean ()
1307 return new BoolConstant (Value != 0);
1310 public override bool IsNegative {
1311 get {
1312 return Value < 0;
1317 public class DecimalConstant : Constant {
1318 public readonly decimal Value;
1320 public DecimalConstant (decimal d)
1322 type = TypeManager.decimal_type;
1323 eclass = ExprClass.Value;
1324 Value = d;
1327 override public string AsString ()
1329 return Value.ToString ();
1332 public override object GetValue ()
1334 return (object) Value;
1337 public override void Emit (EmitContext ec)
1339 ILGenerator ig = ec.ig;
1341 int [] words = Decimal.GetBits (Value);
1342 int power = (words [3] >> 16) & 0xff;
1344 if (power == 0 && Value <= int.MaxValue && Value >= int.MinValue)
1346 IntConstant.EmitInt (ig, (int)Value);
1347 ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_int_arg);
1348 return;
1353 // FIXME: we could optimize this, and call a better
1354 // constructor
1357 IntConstant.EmitInt (ig, words [0]);
1358 IntConstant.EmitInt (ig, words [1]);
1359 IntConstant.EmitInt (ig, words [2]);
1361 // sign
1362 IntConstant.EmitInt (ig, words [3] >> 31);
1364 // power
1365 IntConstant.EmitInt (ig, power);
1367 ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
1370 public override DoubleConstant ConvertToDouble ()
1372 double val;
1374 try {
1375 val = System.Convert.ToDouble (Value);
1376 } catch (Exception ex) {
1377 return null;
1380 return new DoubleConstant (val);
1383 public override FloatConstant ConvertToFloat ()
1385 float val;
1387 try {
1388 val = System.Convert.ToSingle (Value);
1389 } catch (Exception ex) {
1390 return null;
1393 return new FloatConstant (val);
1396 public override DecimalConstant ConvertToDecimal ()
1398 return this;
1401 public override LongConstant ConvertToLong ()
1403 long val;
1405 try {
1406 val = System.Convert.ToInt64 (Value);
1407 } catch (Exception ex) {
1408 return null;
1411 return new LongConstant (val);
1414 public override IntConstant ConvertToInt ()
1416 int val;
1418 try {
1419 val = System.Convert.ToInt32 (Value);
1420 } catch (Exception ex) {
1421 return null;
1424 return new IntConstant (val);
1427 public override ShortConstant ConvertToShort ()
1429 short val;
1431 try {
1432 val = System.Convert.ToInt16 (Value);
1433 } catch (Exception ex) {
1434 return null;
1437 return new ShortConstant (val);
1440 public override ByteConstant ConvertToByte ()
1442 byte val;
1444 try {
1445 val = System.Convert.ToByte (Value);
1446 } catch (Exception ex) {
1447 return null;
1450 return new ByteConstant (val);
1453 public override BoolConstant ConvertToBoolean ()
1455 return new BoolConstant (Value != 0);
1458 public override bool IsNegative {
1459 get {
1460 return Value < 0;
1465 public class StringConstant : Constant {
1466 public readonly string Value;
1468 public StringConstant (string s)
1470 type = TypeManager.string_type;
1471 eclass = ExprClass.Value;
1472 Value = s;
1475 // FIXME: Escape the string.
1476 override public string AsString ()
1478 return "\"" + Value + "\"";
1481 public override object GetValue ()
1483 return Value;
1486 public override void Emit (EmitContext ec)
1488 if (Value == null)
1489 ec.ig.Emit (OpCodes.Ldnull);
1490 else
1491 ec.ig.Emit (OpCodes.Ldstr, Value);
1494 public override bool IsNegative {
1495 get {
1496 return false;
1502 // VB.NET specific
1504 public class DateConstant : Constant {
1505 public readonly DateTime Value;
1507 public DateConstant (DateTime s)
1509 type = TypeManager.date_type;
1510 eclass = ExprClass.Value;
1511 Value = s;
1514 override public string AsString ()
1516 return "#" + Value.ToString() + "#";
1519 public override object GetValue ()
1521 return Value;
1524 public override void Emit (EmitContext ec)
1526 ec.ig.Emit (OpCodes.Ldc_I8, Value.Ticks);
1527 ec.ig.Emit (OpCodes.Newobj, TypeManager.void_datetime_ctor_ticks_arg);
1530 // FIXME:
1531 public override bool IsNegative {
1532 get {
1533 return false;