2004-09-07 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / literal.cs
1 //
2 // literal.cs: Literal representation for the IL tree.
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.
8 //
9 //
10 // Notice that during parsing we create objects of type Literal, but the
11 // types are not loaded (thats why the Resolve method has to assign the
12 // type at that point).
13 //
14 // Literals differ from the constants in that we know we encountered them
15 // as a literal in the source code (and some extra rules apply there) and
16 // they have to be resolved (since during parsing we have not loaded the
17 // types yet) while constants are created only after types have been loaded
18 // and are fully resolved when born.
19 //
20
21 using System;
22 using System.Reflection;
23 using System.Reflection.Emit;
24
25 //
26 // I put System.Null just so we do not have to special case it on 
27 // TypeManager.CSharpName
28 //
29 namespace System {
30         //
31         // Represents the Null Type, just used as a placeholder for the type in NullLiteral
32         //
33         public class Null {
34         }
35 }
36         
37 namespace Mono.CSharp {
38
39         public class NullLiteral : Constant {
40                 public static readonly NullLiteral Null;
41
42                 static NullLiteral ()
43                 {
44                         Null = new NullLiteral ();
45                 }
46                         
47                 public NullLiteral ()
48                 {
49                         eclass = ExprClass.Value;
50                 }
51                 
52                 override public string AsString ()
53                 {
54                         return "null";
55                 }
56
57                 public override object GetValue ()
58                 {
59                         return null;
60                 }
61
62                 public override Expression DoResolve (EmitContext ec)
63                 {
64                         type = typeof (System.Null); 
65                         return this;
66                 }
67
68                 public override void Emit (EmitContext ec)
69                 {
70                         ec.ig.Emit (OpCodes.Ldnull);
71                 }
72                 
73                 public override bool IsZeroInteger {
74                         get { return true; }
75                 }
76         }
77
78         //
79         // A null literal in a pointer context
80         //
81         public class NullPointer : NullLiteral {
82                 public new static readonly NullLiteral Null;
83
84                 static NullPointer ()
85                 {
86                         Null = new NullPointer ();
87                 }
88
89                 private NullPointer ()
90                 {
91                         type = TypeManager.object_type;
92                 }
93
94                 public override void Emit (EmitContext ec)
95                 {
96                         ILGenerator ig = ec.ig;
97                                 
98                         ig.Emit (OpCodes.Ldc_I4_0);
99                         ig.Emit (OpCodes.Conv_U);
100                 }
101         }
102
103         public class BoolLiteral : BoolConstant {
104                 public BoolLiteral (bool val) : base (val)
105                 {
106                 }
107
108                 public override Expression DoResolve (EmitContext ec)
109                 {
110                         type = TypeManager.bool_type;
111                         return this;
112                 }
113         }
114
115         public class CharLiteral : CharConstant {
116                 public CharLiteral (char c) : base (c)
117                 {
118                 }
119
120                 public override Expression DoResolve (EmitContext ec)
121                 {
122                         type = TypeManager.char_type;
123                         return this;
124                 }
125         }
126
127         public class IntLiteral : IntConstant {
128                 public static IntLiteral One, Zero;
129                 
130                 static IntLiteral ()
131                 {
132                         Zero = new IntLiteral (0);
133                         One = new IntLiteral (1);
134                 }
135                 
136                 public IntLiteral (int l) : base (l)
137                 {
138                 }
139
140                 public override Expression DoResolve (EmitContext ec)
141                 {
142                         type = TypeManager.int32_type;
143                         return this;
144                 }
145         }
146
147         public class UIntLiteral : UIntConstant {
148                 public UIntLiteral (uint l) : base (l)
149                 {
150                 }
151
152                 public override Expression DoResolve (EmitContext ec)
153                 {
154                         type = TypeManager.uint32_type;
155                         return this;
156                 }
157         }
158         
159         public class LongLiteral : LongConstant {
160                 public LongLiteral (long l) : base (l)
161                 {
162                 }
163
164                 public override Expression DoResolve (EmitContext ec)
165                 {
166                         type = TypeManager.int64_type;
167
168                         return this;
169                 }
170         }
171
172         public class ULongLiteral : ULongConstant {
173                 public ULongLiteral (ulong l) : base (l)
174                 {
175                 }
176
177                 public override Expression DoResolve (EmitContext ec)
178                 {
179                         type = TypeManager.uint64_type;
180                         return this;
181                 }
182         }
183         
184         public class FloatLiteral : FloatConstant {
185                 
186                 public FloatLiteral (float f) : base (f)
187                 {
188                 }
189
190                 public override Expression DoResolve (EmitContext ec)
191                 {
192                         type = TypeManager.float_type;
193                         return this;
194                 }
195         }
196
197         public class DoubleLiteral : DoubleConstant {
198                 public DoubleLiteral (double d) : base (d)
199                 {
200                 }
201
202                 public override Expression DoResolve (EmitContext ec)
203                 {
204                         type = TypeManager.double_type;
205
206                         return this;
207                 }
208         }
209
210         public class DecimalLiteral : DecimalConstant {
211                 public DecimalLiteral (decimal d) : base (d)
212                 {
213                 }
214
215                 public override Expression DoResolve (EmitContext ec)
216                 {
217                         type = TypeManager.decimal_type;
218                         return this;
219                 }
220         }
221
222         public class StringLiteral : StringConstant {
223                 public StringLiteral (string s) : base (s)
224                 {
225                 }
226
227                 public override Expression DoResolve (EmitContext ec)
228                 {
229                         type = TypeManager.string_type;
230
231                         return this;
232                 }
233         }
234 }