**** Merged r40732-r40872 from MCS ****
[mono.git] / mcs / gmcs / 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         //
40         // The NullType just exists to compare type equality, and for
41         // expressions that might have the `null type'
42         //
43         public class NullType {
44         }
45
46         //
47         // The null Literal constant
48         //
49         public class NullLiteral : Constant {
50                 public static readonly NullLiteral Null;
51
52                 static NullLiteral ()
53                 {
54                         Null = new NullLiteral ();
55                 }
56                         
57                 public NullLiteral ()
58                 {
59                         eclass = ExprClass.Value;
60                 }
61                 
62                 override public string AsString ()
63                 {
64                         return "null";
65                 }
66
67                 public override object GetValue ()
68                 {
69                         return null;
70                 }
71
72                 public override Expression DoResolve (EmitContext ec)
73                 {
74                         type = TypeManager.null_type;
75                         return this;
76                 }
77
78                 public override void Emit (EmitContext ec)
79                 {
80                         ec.ig.Emit (OpCodes.Ldnull);
81                 }
82
83                 public override bool IsDefaultValue {
84                         get {
85                                 return true;
86                         }
87                 }
88
89                 public override bool IsNegative {
90                         get {
91                                 return false;
92                         }
93                 }
94
95                 public override bool IsZeroInteger {
96                         get { return true; }
97                 }
98         }
99
100         //
101         // A null literal in a pointer context
102         //
103         public class NullPointer : NullLiteral {
104                 public new static readonly NullLiteral Null;
105
106                 static NullPointer ()
107                 {
108                         Null = new NullPointer ();
109                 }
110                 
111                 private NullPointer ()
112                 {
113                         type = TypeManager.object_type;
114                 }
115
116                 public override void Emit (EmitContext ec)
117                 {
118                         ILGenerator ig = ec.ig;
119                                 
120                         ig.Emit (OpCodes.Ldc_I4_0);
121                         ig.Emit (OpCodes.Conv_U);
122                 }
123         }
124
125         public class BoolLiteral : BoolConstant {
126                 public BoolLiteral (bool val) : base (val)
127                 {
128                 }
129
130                 public override Expression DoResolve (EmitContext ec)
131                 {
132                         type = TypeManager.bool_type;
133                         return this;
134                 }
135         }
136
137         public class CharLiteral : CharConstant {
138                 public CharLiteral (char c) : base (c)
139                 {
140                 }
141
142                 public override Expression DoResolve (EmitContext ec)
143                 {
144                         type = TypeManager.char_type;
145                         return this;
146                 }
147         }
148
149         public class IntLiteral : IntConstant {
150                 public static IntLiteral One, Zero;
151                 
152                 static IntLiteral ()
153                 {
154                         Zero = new IntLiteral (0);
155                         One = new IntLiteral (1);
156                 }
157                 
158                 public IntLiteral (int l) : base (l)
159                 {
160                 }
161
162                 public override Expression DoResolve (EmitContext ec)
163                 {
164                         type = TypeManager.int32_type;
165                         return this;
166                 }
167         }
168
169         public class UIntLiteral : UIntConstant {
170                 public UIntLiteral (uint l) : base (l)
171                 {
172                 }
173
174                 public override Expression DoResolve (EmitContext ec)
175                 {
176                         type = TypeManager.uint32_type;
177                         return this;
178                 }
179         }
180         
181         public class LongLiteral : LongConstant {
182                 public LongLiteral (long l) : base (l)
183                 {
184                 }
185
186                 public override Expression DoResolve (EmitContext ec)
187                 {
188                         type = TypeManager.int64_type;
189
190                         return this;
191                 }
192         }
193
194         public class ULongLiteral : ULongConstant {
195                 public ULongLiteral (ulong l) : base (l)
196                 {
197                 }
198
199                 public override Expression DoResolve (EmitContext ec)
200                 {
201                         type = TypeManager.uint64_type;
202                         return this;
203                 }
204         }
205         
206         public class FloatLiteral : FloatConstant {
207                 
208                 public FloatLiteral (float f) : base (f)
209                 {
210                 }
211
212                 public override Expression DoResolve (EmitContext ec)
213                 {
214                         type = TypeManager.float_type;
215                         return this;
216                 }
217         }
218
219         public class DoubleLiteral : DoubleConstant {
220                 public DoubleLiteral (double d) : base (d)
221                 {
222                 }
223
224                 public override Expression DoResolve (EmitContext ec)
225                 {
226                         type = TypeManager.double_type;
227
228                         return this;
229                 }
230         }
231
232         public class DecimalLiteral : DecimalConstant {
233                 public DecimalLiteral (decimal d) : base (d)
234                 {
235                 }
236
237                 public override Expression DoResolve (EmitContext ec)
238                 {
239                         type = TypeManager.decimal_type;
240                         return this;
241                 }
242         }
243
244         public class StringLiteral : StringConstant {
245                 public StringLiteral (string s) : base (s)
246                 {
247                 }
248
249                 public override Expression DoResolve (EmitContext ec)
250                 {
251                         type = TypeManager.string_type;
252
253                         return this;
254                 }
255         }
256 }