2006-03-05 Senganal T <tsenganal@novell.com>
[mono.git] / mcs / bmcs / constant.cs
1 //
2 // constant.cs: Constants.
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.
8 //
9 //
10
11 namespace Mono.CSharp {
12
13         using System;
14         using System.Reflection.Emit;
15
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 ();
29
30                 override public string ToString ()
31                 {
32                         return this.GetType ().Name + " (" + AsString () + ")";
33                 }
34
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 ();
40
41                 /// <summary>
42                 ///   Constants are always born in a fully resolved state
43                 /// </summary>
44                 public override Expression DoResolve (EmitContext ec)
45                 {
46                         return this;
47                 }
48
49                 //
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.   
53                 //
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).
59                 //
60                 public DoubleConstant ToDouble (Location loc)
61                 {
62                         DoubleConstant c = ConvertToDouble ();
63
64                         if (c == null)
65                                 Convert.Error_CannotWideningConversion (loc, Type, TypeManager.double_type);
66
67                         return c;
68                 }
69
70                 public FloatConstant ToFloat (Location loc)
71                 {
72                         FloatConstant c = ConvertToFloat ();
73
74                         if (c == null)
75                                 Convert.Error_CannotWideningConversion (loc, Type, TypeManager.float_type);
76
77                         return c;
78                 }
79
80                 public ULongConstant ToULong (Location loc)
81                 {
82                         ULongConstant c = ConvertToULong ();
83
84                         if (c == null)
85                                 Convert.Error_CannotWideningConversion (loc, Type, TypeManager.uint64_type);
86
87                         return c;
88                 }
89
90                 public LongConstant ToLong (Location loc)
91                 {
92                         LongConstant c = ConvertToLong ();
93
94                         if (c == null)
95                                 Convert.Error_CannotWideningConversion (loc, Type, TypeManager.int64_type);
96
97                         return c;
98                 }
99                 
100                 public UIntConstant ToUInt (Location loc)
101                 {
102                         UIntConstant c = ConvertToUInt ();
103
104                         if (c == null)
105                                 Convert.Error_CannotWideningConversion (loc, Type, TypeManager.uint32_type);
106
107                         return c;
108                 }
109
110                 public IntConstant ToInt (Location loc)
111                 {
112                         IntConstant c = ConvertToInt ();
113
114                         if (c == null)
115                                 Convert.Error_CannotWideningConversion (loc, Type, TypeManager.int32_type);
116
117                         return c;
118                 }
119
120                 public DecimalConstant ToDecimal (Location loc)
121                 {
122                         DecimalConstant c = ConvertToDecimal ();
123
124                         if (c == null)
125                                 Convert.Error_CannotConvertType (loc, Type, TypeManager.decimal_type);
126
127                         return c;
128                 }
129
130                 public ShortConstant ToShort (Location loc)
131                 {
132                         ShortConstant c = ConvertToShort ();
133
134                         if (c == null)
135                                 Convert.Error_CannotConvertType (loc, Type, TypeManager.short_type);
136
137                         return c;
138                 }
139
140                 public ByteConstant ToByte (Location loc)
141                 {
142                         ByteConstant c = ConvertToByte ();
143
144                         if (c == null)
145                                 Convert.Error_CannotConvertType (loc, Type, TypeManager.byte_type);
146
147                         return c;
148                 }
149
150                 public BoolConstant ToBoolean (Location loc)
151                 {
152                         BoolConstant c = ConvertToBoolean ();
153
154                         if (c == null)
155                                 Convert.Error_CannotConvertType (loc, Type, TypeManager.bool_type);
156
157                         return c;
158                 }
159
160                 public CharConstant ToChar (Location loc)
161                 {
162                         CharConstant c = ConvertToChar ();
163
164                         if (c == null)
165                                 Convert.Error_CannotConvertType (loc, Type, TypeManager.char_type);
166
167                         return c;
168                 }
169
170                 public virtual CharConstant ConvertToChar ()
171                 {
172                         return null;
173                 }
174                 
175                 public virtual BoolConstant ConvertToBoolean ()
176                 {
177                         return null;
178                 }
179
180                 public virtual ByteConstant ConvertToByte ()
181                 {
182                         return null;
183                 }
184
185                 public virtual ShortConstant ConvertToShort ()
186                 {
187                         return null;
188                 }
189
190                 public virtual DecimalConstant ConvertToDecimal ()
191                 {
192                         return null;
193                 }
194                 
195                 public virtual DoubleConstant ConvertToDouble ()
196                 {
197                         return null;
198                 }
199
200                 public virtual FloatConstant ConvertToFloat ()
201                 {
202                         return null;
203                 }
204
205                 public virtual ULongConstant ConvertToULong ()
206                 {
207                         return null;
208                 }
209
210                 public virtual LongConstant ConvertToLong ()
211                 {
212                         return null;
213                 }
214
215                 public virtual UIntConstant ConvertToUInt ()
216                 {
217                         return null;
218                 }
219
220                 public virtual IntConstant ConvertToInt ()
221                 {
222                         return null;
223                 }
224                 
225                 public abstract bool IsNegative {
226                         get;
227                 }
228
229                 //
230                 // Returns true iff 1) the stack type of this is one of Object, 
231                 // int32, int64 and 2) this == 0 or this == null.
232                 //
233                 public virtual bool IsZeroInteger {
234                         get { return false; }
235                 }
236         }
237         
238         public class BoolConstant : Constant {
239                 public readonly bool Value;
240                 
241                 public BoolConstant (bool val)
242                 {
243                         type = TypeManager.bool_type;
244                         eclass = ExprClass.Value;
245
246                         Value = val;
247                 }
248
249                 override public string AsString ()
250                 {
251                         return Value ? "true" : "false";
252                 }
253
254                 public override object GetValue ()
255                 {
256                         return (object) Value;
257                 }
258                                 
259                 
260                 public override void Emit (EmitContext ec)
261                 {
262                         if (Value)
263                                 ec.ig.Emit (OpCodes.Ldc_I4_1);
264                         else
265                                 ec.ig.Emit (OpCodes.Ldc_I4_0);
266                 }
267
268                 public override DecimalConstant ConvertToDecimal ()
269                 {
270                         return Value ? new DecimalConstant (0) : new DecimalConstant (-1);
271                 }
272                 
273                 public override DoubleConstant ConvertToDouble ()
274                 {
275                         return Value ? new DoubleConstant (0) : new DoubleConstant (-1);
276                 }
277
278                 public override FloatConstant ConvertToFloat ()
279                 {
280                         return Value ? new FloatConstant (0) : new FloatConstant (-1);
281                 }
282
283                 public override LongConstant ConvertToLong ()
284                 {
285                         return Value ? new LongConstant (0) : new LongConstant (-1);
286                 }
287
288                 public override IntConstant ConvertToInt ()
289                 {
290                         return Value ? new IntConstant (0) : new IntConstant (-1);
291                 }
292
293                 public override ShortConstant ConvertToShort ()
294                 {
295                         return Value ? new ShortConstant (0) : new ShortConstant (-1);
296                 }
297
298                 public override ByteConstant ConvertToByte ()
299                 {
300                         return Value ? new ByteConstant (0) : new ByteConstant (255);
301                 }
302
303                 public override BoolConstant ConvertToBoolean ()
304                 {
305                         return this;
306                 }
307                 
308                 public override bool IsNegative {
309                         get {
310                                 return false;
311                         }
312                 }
313         
314                 public override bool IsZeroInteger {
315                         get { return Value == false; }
316                 }
317         }
318
319         public class ByteConstant : Constant {
320                 public readonly byte Value;
321
322                 public ByteConstant (byte v)
323                 {
324                         type = TypeManager.byte_type;
325                         eclass = ExprClass.Value;
326                         Value = v;
327                 }
328
329                 public override void Emit (EmitContext ec)
330                 {
331                         IntLiteral.EmitInt (ec.ig, Value);
332                 }
333
334                 public override string AsString ()
335                 {
336                         return Value.ToString ();
337                 }
338
339                 public override object GetValue ()
340                 {
341                         return Value;
342                 }
343
344                 public override DoubleConstant ConvertToDouble ()
345                 {
346                         return new DoubleConstant (Value);
347                 }
348
349                 public override FloatConstant ConvertToFloat ()
350                 {
351                         return new FloatConstant (Value);
352                 }
353
354                 public override LongConstant ConvertToLong ()
355                 {
356                         return new LongConstant (Value);
357                 }
358
359                 public override ShortConstant ConvertToShort ()
360                 {
361                         return new ShortConstant (Value);
362                 }
363
364                 public override ByteConstant ConvertToByte ()
365                 {
366                         return this;
367                 }
368
369                 public override DecimalConstant ConvertToDecimal ()
370                 {
371                         return new DecimalConstant (Value);
372                 }
373
374                 public override IntConstant ConvertToInt ()
375                 {
376                         return new IntConstant (Value);
377                 }
378
379                 public override BoolConstant ConvertToBoolean ()
380                 {
381                         return new BoolConstant (Value != 0);
382                 }
383                 
384                 public override bool IsNegative {
385                         get {
386                                 return false;
387                         }
388                 }
389
390                 public override bool IsZeroInteger {
391                         get { return Value == 0; }
392                 }
393         }
394
395         public class CharConstant : Constant {
396                 public readonly char Value;
397
398                 public CharConstant (char v)
399                 {
400                         type = TypeManager.char_type;
401                         eclass = ExprClass.Value;
402                         Value = v;
403                 }
404
405                 public override void Emit (EmitContext ec)
406                 {
407                         IntLiteral.EmitInt (ec.ig, Value);
408                 }
409
410                 static public string descape (char c)
411                 {
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 "\\\'"; 
435                         }
436                         return c.ToString ();
437                 }
438
439                 public override string AsString ()
440                 {
441                         return "\"" + descape (Value) + "\"";
442                 }
443
444                 public override object GetValue ()
445                 {
446                         return Value;
447                 }
448
449                 public override DoubleConstant ConvertToDouble ()
450                 {
451                         return new DoubleConstant (Value);
452                 }
453
454                 public override FloatConstant ConvertToFloat ()
455                 {
456                         return new FloatConstant (Value);
457                 }
458
459                 public override ULongConstant ConvertToULong ()
460                 {
461                         return new ULongConstant (Value);
462                 }
463
464                 public override LongConstant ConvertToLong ()
465                 {
466                         return new LongConstant (Value);
467                 }
468
469                 public override UIntConstant ConvertToUInt ()
470                 {
471                         return new UIntConstant (Value);
472                 }
473
474                 public override IntConstant ConvertToInt ()
475                 {
476                         return new IntConstant (Value);
477                 }
478                 
479                 public override bool IsNegative {
480                         get {
481                                 return false;
482                         }
483                 }
484
485                 public override bool IsZeroInteger {
486                         get { return Value == '\0'; }
487                 }
488         }
489
490         public class SByteConstant : Constant {
491                 public readonly sbyte Value;
492
493                 public SByteConstant (sbyte v)
494                 {
495                         type = TypeManager.sbyte_type;
496                         eclass = ExprClass.Value;
497                         Value = v;
498                 }
499
500                 public override void Emit (EmitContext ec)
501                 {
502                         IntLiteral.EmitInt (ec.ig, Value);
503                 }
504
505                 public override string AsString ()
506                 {
507                         return Value.ToString ();
508                 }
509
510                 public override object GetValue ()
511                 {
512                         return Value;
513                 }
514
515                 public override DoubleConstant ConvertToDouble ()
516                 {
517                         return new DoubleConstant (Value);
518                 }
519
520                 public override FloatConstant ConvertToFloat ()
521                 {
522                         return new FloatConstant (Value);
523                 }
524
525                 public override ULongConstant ConvertToULong ()
526                 {
527                         if (Value >= 0)
528                                 return new ULongConstant ((ulong) Value);
529                         
530                         return null;
531                 }
532
533                 public override LongConstant ConvertToLong ()
534                 {
535                         return new LongConstant (Value);
536                 }
537
538                 public override UIntConstant ConvertToUInt ()
539                 {
540                         return null;
541                 }
542
543                 public override IntConstant ConvertToInt ()
544                 {
545                         return new IntConstant (Value);
546                 }
547                 
548                 public override bool IsNegative {
549                         get {
550                                 return Value < 0;
551                         }
552                 }
553                 
554                 public override bool IsZeroInteger {
555                         get { return Value == 0; }
556                 }
557         }
558
559         public class ShortConstant : Constant {
560                 public readonly short Value;
561
562                 public ShortConstant (short v)
563                 {
564                         type = TypeManager.short_type;
565                         eclass = ExprClass.Value;
566                         Value = v;
567                 }
568
569                 public override void Emit (EmitContext ec)
570                 {
571                         IntLiteral.EmitInt (ec.ig, Value);
572                 }
573
574                 public override string AsString ()
575                 {
576                         return Value.ToString ();
577                 }
578
579                 public override object GetValue ()
580                 {
581                         return Value;
582                 }
583
584                 public override DoubleConstant ConvertToDouble ()
585                 {
586                         return new DoubleConstant (Value);
587                 }
588
589                 public override FloatConstant ConvertToFloat ()
590                 {
591                         return new FloatConstant (Value);
592                 }
593
594                 public override LongConstant ConvertToLong ()
595                 {
596                         return new LongConstant (Value);
597                 }
598
599                 public override ShortConstant ConvertToShort ()
600                 {
601                         return this;
602                 }
603
604                 public override IntConstant ConvertToInt ()
605                 {
606                         return new IntConstant (Value);
607                 }
608
609                 public override DecimalConstant ConvertToDecimal ()
610                 {
611                         return new DecimalConstant (Value);
612                 }
613
614                 public override ByteConstant ConvertToByte ()
615                 {
616                         byte val;
617                         
618                         try {
619                                 val = System.Convert.ToByte (Value);
620                         } catch (Exception ex) {
621                                 return null;
622                         }
623
624                         return new ByteConstant (val);
625                 }
626
627                 public override BoolConstant ConvertToBoolean ()
628                 {
629                         return new BoolConstant (Value != 0);
630                 }
631                 
632                 public override bool IsZeroInteger {
633                         get { return Value == 0; }
634                 }
635
636                 public override bool IsNegative {
637                         get {
638                                 return Value < 0;
639                         }
640                 }
641         }
642
643         public class UShortConstant : Constant {
644                 public readonly ushort Value;
645
646                 public UShortConstant (ushort v)
647                 {
648                         type = TypeManager.ushort_type;
649                         eclass = ExprClass.Value;
650                         Value = v;
651                 }
652
653                 public override void Emit (EmitContext ec)
654                 {
655                         IntLiteral.EmitInt (ec.ig, Value);
656                 }
657
658                 public override string AsString ()
659                 {
660                         return Value.ToString ();
661                 }
662
663                 public override object GetValue ()
664                 {
665                         return Value;
666                 }
667
668                 public override DoubleConstant ConvertToDouble ()
669                 {
670                         return new DoubleConstant (Value);
671                 }
672
673                 public override FloatConstant ConvertToFloat ()
674                 {
675                         return new FloatConstant (Value);
676                 }
677
678                 public override ULongConstant ConvertToULong ()
679                 {
680                         return new ULongConstant (Value);
681                 }
682
683                 public override LongConstant ConvertToLong ()
684                 {
685                         return new LongConstant (Value);
686                 }
687
688                 public override UIntConstant ConvertToUInt ()
689                 {
690                         return new UIntConstant (Value);
691                 }
692
693                 public override IntConstant ConvertToInt ()
694                 {
695                         return new IntConstant (Value);
696                 }
697                 
698                 public override bool IsNegative {
699                         get {
700                                 return false;
701                         }
702                 }
703         
704                 public override bool IsZeroInteger {
705                         get { return Value == 0; }
706                 }
707         }
708
709         public class IntConstant : Constant {
710                 public readonly int Value;
711
712                 public IntConstant (int v)
713                 {
714                         type = TypeManager.int32_type;
715                         eclass = ExprClass.Value;
716                         Value = v;
717                 }
718
719                 static public void EmitInt (ILGenerator ig, int i)
720                 {
721                         switch (i){
722                         case -1:
723                                 ig.Emit (OpCodes.Ldc_I4_M1);
724                                 break;
725                                 
726                         case 0:
727                                 ig.Emit (OpCodes.Ldc_I4_0);
728                                 break;
729                                 
730                         case 1:
731                                 ig.Emit (OpCodes.Ldc_I4_1);
732                                 break;
733                                 
734                         case 2:
735                                 ig.Emit (OpCodes.Ldc_I4_2);
736                                 break;
737                                 
738                         case 3:
739                                 ig.Emit (OpCodes.Ldc_I4_3);
740                                 break;
741                                 
742                         case 4:
743                                 ig.Emit (OpCodes.Ldc_I4_4);
744                                 break;
745                                 
746                         case 5:
747                                 ig.Emit (OpCodes.Ldc_I4_5);
748                                 break;
749                                 
750                         case 6:
751                                 ig.Emit (OpCodes.Ldc_I4_6);
752                                 break;
753                                 
754                         case 7:
755                                 ig.Emit (OpCodes.Ldc_I4_7);
756                                 break;
757                                 
758                         case 8:
759                                 ig.Emit (OpCodes.Ldc_I4_8);
760                                 break;
761
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;
768                         }
769                 }
770
771                 public override void Emit (EmitContext ec)
772                 {
773                         EmitInt (ec.ig, Value);
774                 }
775
776                 public override string AsString ()
777                 {
778                         return Value.ToString ();
779                 }
780
781                 public override object GetValue ()
782                 {
783                         return Value;
784                 }
785
786                 public override DecimalConstant ConvertToDecimal()
787                 {
788                         return new DecimalConstant (Value);
789                 }
790
791                 public override DoubleConstant ConvertToDouble ()
792                 {
793                         return new DoubleConstant (Value);
794                 }
795
796                 public override FloatConstant ConvertToFloat ()
797                 {
798                         return new FloatConstant (Value);
799                 }
800
801                 public override LongConstant ConvertToLong ()
802                 {
803                         return new LongConstant (Value);
804                 }
805
806                 public override IntConstant ConvertToInt ()
807                 {
808                         return this;
809                 }
810
811                 public override ShortConstant ConvertToShort ()
812                 {
813                         short val;
814                         
815                         try {
816                                 val = System.Convert.ToInt16 (Value);
817                         } catch (Exception ex) {
818                                 return null;
819                         }
820
821                         return new ShortConstant (val);
822                 }
823
824                 public override ByteConstant ConvertToByte ()
825                 {
826                         byte val;
827                         
828                         try {
829                                 val = System.Convert.ToByte (Value);
830                         } catch (Exception ex) {
831                                 return null;
832                         }
833
834                         return new ByteConstant (val);
835                 }
836
837                 public override BoolConstant ConvertToBoolean ()
838                 {
839                         return new BoolConstant (Value != 0);
840                 }
841                 
842                 public override bool IsNegative {
843                         get {
844                                 return Value < 0;
845                         }
846                 }
847
848                 public override bool IsZeroInteger {
849                         get { return Value == 0; }
850                 }
851         }
852
853         public class UIntConstant : Constant {
854                 public readonly uint Value;
855
856                 public UIntConstant (uint v)
857                 {
858                         type = TypeManager.uint32_type;
859                         eclass = ExprClass.Value;
860                         Value = v;
861                 }
862
863                 public override void Emit (EmitContext ec)
864                 {
865                         IntLiteral.EmitInt (ec.ig, unchecked ((int) Value));
866                 }
867
868                 public override string AsString ()
869                 {
870                         return Value.ToString ();
871                 }
872
873                 public override object GetValue ()
874                 {
875                         return Value;
876                 }
877
878                 public override DoubleConstant ConvertToDouble ()
879                 {
880                         return new DoubleConstant (Value);
881                 }
882
883                 public override FloatConstant ConvertToFloat ()
884                 {
885                         return new FloatConstant (Value);
886                 }
887
888                 public override ULongConstant ConvertToULong ()
889                 {
890                         return new ULongConstant (Value);
891                 }
892
893                 public override LongConstant ConvertToLong ()
894                 {
895                         return new LongConstant (Value);
896                 }
897
898                 public override UIntConstant ConvertToUInt ()
899                 {
900                         return this;
901                 }
902
903                 public override IntConstant ConvertToInt ()
904                 {
905                         return null;
906                 }
907                 
908                 public override bool IsNegative {
909                         get {
910                                 return false;
911                         }
912                 }
913
914                 public override bool IsZeroInteger {
915                         get { return Value == 0; }
916                 }
917         }
918
919         public class LongConstant : Constant {
920                 public readonly long Value;
921
922                 public LongConstant (long v)
923                 {
924                         type = TypeManager.int64_type;
925                         eclass = ExprClass.Value;
926                         Value = v;
927                 }
928
929                 public override void Emit (EmitContext ec)
930                 {
931                         ILGenerator ig = ec.ig;
932
933                         EmitLong (ig, Value);
934                 }
935
936                 static public void EmitLong (ILGenerator ig, long l)
937                 {
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);
943                         }
944                 }
945
946                 public override string AsString ()
947                 {
948                         return Value.ToString ();
949                 }
950
951                 public override object GetValue ()
952                 {
953                         return Value;
954                 }
955
956                 public override DoubleConstant ConvertToDouble ()
957                 {
958                         return new DoubleConstant (Value);
959                 }
960
961                 public override FloatConstant ConvertToFloat ()
962                 {
963                         return new FloatConstant (Value);
964                 }
965
966                 public override DecimalConstant ConvertToDecimal()
967                 {
968                         return new DecimalConstant (Value);
969                 }
970
971                 public override LongConstant ConvertToLong ()
972                 {
973                         return this;
974                 }
975
976                 public override IntConstant ConvertToInt ()
977                 {
978                         int val;
979                         
980                         try {
981                                 val = System.Convert.ToInt32 (Value);
982                         } catch (Exception ex) {
983                                 return null;
984                         }
985
986                         return new IntConstant (val);
987                 }
988
989                 public override ShortConstant ConvertToShort ()
990                 {
991                         short val;
992                         
993                         try {
994                                 val = System.Convert.ToInt16 (Value);
995                         } catch (Exception ex) {
996                                 return null;
997                         }
998
999                         return new ShortConstant (val);
1000                 }
1001
1002                 public override ByteConstant ConvertToByte ()
1003                 {
1004                         byte val;
1005                         
1006                         try {
1007                                 val = System.Convert.ToByte (Value);
1008                         } catch (Exception ex) {
1009                                 return null;
1010                         }
1011
1012                         return new ByteConstant (val);
1013                 }
1014
1015                 public override BoolConstant ConvertToBoolean ()
1016                 {
1017                         return new BoolConstant (Value != 0);
1018                 }
1019                 
1020                 public override bool IsNegative {
1021                         get {
1022                                 return Value < 0;
1023                         }
1024                 }
1025
1026                 public override bool IsZeroInteger {
1027                         get { return Value == 0; }
1028                 }
1029         }
1030
1031         public class ULongConstant : Constant {
1032                 public readonly ulong Value;
1033
1034                 public ULongConstant (ulong v)
1035                 {
1036                         type = TypeManager.uint64_type;
1037                         eclass = ExprClass.Value;
1038                         Value = v;
1039                 }
1040
1041                 public override void Emit (EmitContext ec)
1042                 {
1043                         ILGenerator ig = ec.ig;
1044
1045                         LongLiteral.EmitLong (ig, unchecked ((long) Value));
1046                 }
1047
1048                 public override string AsString ()
1049                 {
1050                         return Value.ToString ();
1051                 }
1052
1053                 public override object GetValue ()
1054                 {
1055                         return Value;
1056                 }
1057
1058                 public override DoubleConstant ConvertToDouble ()
1059                 {
1060                         return new DoubleConstant (Value);
1061                 }
1062
1063                 public override FloatConstant ConvertToFloat ()
1064                 {
1065                         return new FloatConstant (Value);
1066                 }
1067
1068                 public override ULongConstant ConvertToULong ()
1069                 {
1070                         return this;
1071                 }
1072
1073                 public override LongConstant ConvertToLong ()
1074                 {
1075                         return null;
1076                 }
1077
1078                 public override UIntConstant ConvertToUInt ()
1079                 {
1080                         return null;
1081                 }
1082
1083                 public override IntConstant ConvertToInt ()
1084                 {
1085                         return null;
1086                 }
1087                 
1088                 public override bool IsNegative {
1089                         get {
1090                                 return false;
1091                         }
1092                 }
1093
1094                 public override bool IsZeroInteger {
1095                         get { return Value == 0; }
1096                 }
1097         }
1098
1099         public class FloatConstant : Constant {
1100                 public readonly float Value;
1101
1102                 public FloatConstant (float v)
1103                 {
1104                         type = TypeManager.float_type;
1105                         eclass = ExprClass.Value;
1106                         Value = v;
1107                 }
1108
1109                 public override void Emit (EmitContext ec)
1110                 {
1111                         ec.ig.Emit (OpCodes.Ldc_R4, Value);
1112                 }
1113
1114                 public override string AsString ()
1115                 {
1116                         return Value.ToString ();
1117                 }
1118
1119                 public override object GetValue ()
1120                 {
1121                         return Value;
1122                 }
1123
1124                 public override DoubleConstant ConvertToDouble ()
1125                 {
1126                         return new DoubleConstant (Value);
1127                 }
1128
1129                 public override FloatConstant ConvertToFloat ()
1130                 {
1131                         return this;
1132                 }
1133
1134                 public override DecimalConstant ConvertToDecimal ()
1135                 {
1136                         return new DecimalConstant (new System.Decimal (Value));
1137                 }
1138
1139                 public override LongConstant ConvertToLong ()
1140                 {
1141                         long val;
1142                         
1143                         try {
1144                                 val = System.Convert.ToInt64 (System.Math.Round (Value));
1145                         } catch (Exception ex) {
1146                                 return null;
1147                         }
1148
1149                         return new LongConstant (val);
1150                         
1151                 }
1152
1153                 public override IntConstant ConvertToInt ()
1154                 {
1155                         int val;
1156                         
1157                         try {
1158                                 val = System.Convert.ToInt32 (System.Math.Round (Value));
1159                         } catch (Exception ex) {
1160                                 return null;
1161                         }
1162
1163                         return new IntConstant (val);
1164                 }
1165
1166                 public override ShortConstant ConvertToShort ()
1167                 {
1168                         short val;
1169                         
1170                         try {
1171                                 val = System.Convert.ToInt16 (System.Math.Round (Value));
1172                         } catch (Exception ex) {
1173                                 return null;
1174                         }
1175
1176                         return new ShortConstant (val);
1177                 }
1178
1179                 public override ByteConstant ConvertToByte ()
1180                 {
1181                         byte val;
1182                         
1183                         try {
1184                                 val = System.Convert.ToByte (System.Math.Round (Value));
1185                         } catch (Exception ex) {
1186                                 return null;
1187                         }
1188
1189                         return new ByteConstant (val);
1190                 }
1191
1192                 public override BoolConstant ConvertToBoolean ()
1193                 {
1194                         return new BoolConstant (Value != 0);
1195                 }
1196
1197                 public override bool IsNegative {
1198                         get {
1199                                 return Value < 0;
1200                         }
1201                 }
1202         }
1203
1204         public class DoubleConstant : Constant {
1205                 public readonly double Value;
1206
1207                 public DoubleConstant (double v)
1208                 {
1209                         type = TypeManager.double_type;
1210                         eclass = ExprClass.Value;
1211                         Value = v;
1212                 }
1213
1214                 public override void Emit (EmitContext ec)
1215                 {
1216                         ec.ig.Emit (OpCodes.Ldc_R8, Value);
1217                 }
1218
1219                 public override string AsString ()
1220                 {
1221                         return Value.ToString ();
1222                 }
1223
1224                 public override object GetValue ()
1225                 {
1226                         return Value;
1227                 }
1228
1229                 public override DoubleConstant ConvertToDouble ()
1230                 {
1231                         return this;
1232                 }
1233
1234                 public override FloatConstant ConvertToFloat ()
1235                 {
1236                         float val;
1237                         
1238                         try {
1239                                 val = System.Convert.ToSingle (Value);
1240                         } catch (Exception ex) {
1241                                 return null;
1242                         }
1243
1244                         return new FloatConstant (val);
1245                 }
1246
1247                 public override DecimalConstant ConvertToDecimal ()
1248                 {
1249                         return new DecimalConstant (new System.Decimal (Value));
1250                 }
1251
1252                 public override LongConstant ConvertToLong ()
1253                 {
1254                         long val;
1255                         
1256                         try {
1257                                 val = System.Convert.ToInt64 (System.Math.Round (Value));
1258                         } catch (Exception ex) {
1259                                 return null;
1260                         }
1261
1262                         return new LongConstant (val);
1263                         
1264                 }
1265
1266                 public override IntConstant ConvertToInt ()
1267                 {
1268                         int val;
1269                         
1270                         try {
1271                                 val = System.Convert.ToInt32 (System.Math.Round (Value));
1272                         } catch (Exception ex) {
1273                                 return null;
1274                         }
1275
1276                         return new IntConstant (val);
1277                 }
1278
1279                 public override ShortConstant ConvertToShort ()
1280                 {
1281                         short val;
1282                         
1283                         try {
1284                                 val = System.Convert.ToInt16 (System.Math.Round (Value));
1285                         } catch (Exception ex) {
1286                                 return null;
1287                         }
1288
1289                         return new ShortConstant (val);
1290                 }
1291
1292                 public override ByteConstant ConvertToByte ()
1293                 {
1294                         byte val;
1295                         
1296                         try {
1297                                 val = System.Convert.ToByte (System.Math.Round (Value));
1298                         } catch (Exception ex) {
1299                                 return null;
1300                         }
1301
1302                         return new ByteConstant (val);
1303                 }
1304
1305                 public override BoolConstant ConvertToBoolean ()
1306                 {
1307                         return new BoolConstant (Value != 0);
1308                 }
1309
1310                 public override bool IsNegative {
1311                         get {
1312                                 return Value < 0;
1313                         }
1314                 }
1315         }
1316
1317         public class DecimalConstant : Constant {
1318                 public readonly decimal Value;
1319
1320                 public DecimalConstant (decimal d)
1321                 {
1322                         type = TypeManager.decimal_type;
1323                         eclass = ExprClass.Value;
1324                         Value = d;
1325                 }
1326
1327                 override public string AsString ()
1328                 {
1329                         return Value.ToString ();
1330                 }
1331
1332                 public override object GetValue ()
1333                 {
1334                         return (object) Value;
1335                 }
1336
1337                 public override void Emit (EmitContext ec)
1338                 {
1339                         ILGenerator ig = ec.ig;
1340
1341                         int [] words = Decimal.GetBits (Value);
1342                         int power = (words [3] >> 16) & 0xff;
1343
1344                         if (power == 0 && Value <= int.MaxValue && Value >= int.MinValue)
1345                         {
1346                                 IntConstant.EmitInt (ig, (int)Value);
1347                                 ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_int_arg);
1348                                 return;
1349                         }
1350
1351                         
1352                         //
1353                         // FIXME: we could optimize this, and call a better 
1354                         // constructor
1355                         //
1356
1357                         IntConstant.EmitInt (ig, words [0]);
1358                         IntConstant.EmitInt (ig, words [1]);
1359                         IntConstant.EmitInt (ig, words [2]);
1360
1361                         // sign
1362                         IntConstant.EmitInt (ig, words [3] >> 31);
1363
1364                         // power
1365                         IntConstant.EmitInt (ig, power);
1366
1367                         ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
1368                 }
1369
1370                 public override DoubleConstant ConvertToDouble ()
1371                 {
1372                         double val;
1373                         
1374                         try {
1375                                 val = System.Convert.ToDouble (Value);
1376                         } catch (Exception ex) {
1377                                 return null;
1378                         }
1379
1380                         return new DoubleConstant (val);
1381                 }
1382
1383                 public override FloatConstant ConvertToFloat ()
1384                 {
1385                         float val;
1386                         
1387                         try {
1388                                 val = System.Convert.ToSingle (Value);
1389                         } catch (Exception ex) {
1390                                 return null;
1391                         }
1392
1393                         return new FloatConstant (val);
1394                 }
1395
1396                 public override DecimalConstant ConvertToDecimal ()
1397                 {
1398                         return this;
1399                 }
1400
1401                 public override LongConstant ConvertToLong ()
1402                 {
1403                         long val;
1404                         
1405                         try {
1406                                 val = System.Convert.ToInt64 (Value);
1407                         } catch (Exception ex) {
1408                                 return null;
1409                         }
1410
1411                         return new LongConstant (val);
1412                 }
1413
1414                 public override IntConstant ConvertToInt ()
1415                 {
1416                         int val;
1417                         
1418                         try {
1419                                 val = System.Convert.ToInt32 (Value);
1420                         } catch (Exception ex) {
1421                                 return null;
1422                         }
1423
1424                         return new IntConstant (val);
1425                 }
1426
1427                 public override ShortConstant ConvertToShort ()
1428                 {
1429                         short val;
1430                         
1431                         try {
1432                                 val = System.Convert.ToInt16 (Value);
1433                         } catch (Exception ex) {
1434                                 return null;
1435                         }
1436
1437                         return new ShortConstant (val);
1438                 }
1439
1440                 public override ByteConstant ConvertToByte ()
1441                 {
1442                         byte val;
1443                         
1444                         try {
1445                                 val = System.Convert.ToByte (Value);
1446                         } catch (Exception ex) {
1447                                 return null;
1448                         }
1449
1450                         return new ByteConstant (val);
1451                 }
1452
1453                 public override BoolConstant ConvertToBoolean ()
1454                 {
1455                         return new BoolConstant (Value != 0);
1456                 }
1457
1458                 public override bool IsNegative {
1459                         get {
1460                                 return Value < 0;
1461                         }
1462                 }
1463         }
1464
1465         public class StringConstant : Constant {
1466                 public readonly string Value;
1467
1468                 public StringConstant (string s)
1469                 {
1470                         type = TypeManager.string_type;
1471                         eclass = ExprClass.Value;
1472                         Value = s;
1473                 }
1474
1475                 // FIXME: Escape the string.
1476                 override public string AsString ()
1477                 {
1478                         return "\"" + Value + "\"";
1479                 }
1480
1481                 public override object GetValue ()
1482                 {
1483                         return Value;
1484                 }
1485                 
1486                 public override void Emit (EmitContext ec)
1487                 {
1488                         if (Value == null)
1489                                 ec.ig.Emit (OpCodes.Ldnull);
1490                         else
1491                                 ec.ig.Emit (OpCodes.Ldstr, Value);
1492                 }
1493
1494                 public override bool IsNegative {
1495                         get {
1496                                 return false;
1497                         }
1498                 }
1499         }
1500
1501         //
1502         // VB.NET specific
1503         //
1504         public class DateConstant : Constant {
1505                 public readonly DateTime Value;
1506
1507                 public DateConstant (DateTime s)
1508                 {
1509                         type = TypeManager.date_type;
1510                         eclass = ExprClass.Value;
1511                         Value = s;
1512                 }
1513
1514                 override public string AsString ()
1515                 {
1516                         return "#" + Value.ToString() + "#";
1517                 }
1518
1519                 public override object GetValue ()
1520                 {
1521                         return Value;
1522                 }
1523                 
1524                 public override void Emit (EmitContext ec)
1525                 {
1526                         ec.ig.Emit (OpCodes.Ldc_I8, Value.Ticks);
1527                         ec.ig.Emit (OpCodes.Newobj, TypeManager.void_datetime_ctor_ticks_arg);
1528                 }
1529
1530                 // FIXME:
1531                 public override bool IsNegative {
1532                         get {
1533                                 return false;
1534                         }
1535                 }
1536         }
1537
1538 }
1539
1540