2005-10-06 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[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 NullLiteral (Location loc):
51                         base (loc)
52                 {
53                         eclass = ExprClass.Value;
54                 }
55                 
56                 override public string AsString ()
57                 {
58                         return "null";
59                 }
60
61                 public override object GetValue ()
62                 {
63                         return null;
64                 }
65
66                 public override Expression DoResolve (EmitContext ec)
67                 {
68                         type = TypeManager.null_type;
69                         return this;
70                 }
71
72                 public override void Emit (EmitContext ec)
73                 {
74                         ec.ig.Emit (OpCodes.Ldnull);
75                 }
76
77                 public override Constant Increment ()
78                 {
79                         throw new NotSupportedException ();
80                 }
81
82                 public override bool IsDefaultValue {
83                         get {
84                                 return true;
85                         }
86                 }
87
88                 public override bool IsNegative {
89                         get {
90                                 return false;
91                         }
92                 }
93
94                 public override bool IsZeroInteger {
95                         get { return true; }
96                 }
97
98                 public override string GetSignatureForError()
99                 {
100                         return "null";
101                 }
102
103                 public override void Error_ValueCannotBeConverted (Location loc, Type t)
104                 {
105                         Report.Error (37, loc, "Cannot convert null to `{0}' because it is a value type",
106                                 TypeManager.CSharpName (t));
107                 }
108
109                 public override Constant ToType (Type type, Location loc)
110                 {
111                         if (!type.IsValueType && !TypeManager.IsEnumType (type))
112                                 return this;
113
114                         return base.ToType (type, loc);
115                 }
116
117         }
118
119         //
120         // A null literal in a pointer context
121         //
122         public class NullPointer : NullLiteral {
123                 public static readonly NullLiteral Null;
124
125                 static NullPointer ()
126                 {
127                         Null = new NullPointer ();
128                 }
129                 
130                 private NullPointer ():
131                         base (Location.Null)
132                 {
133                         type = TypeManager.object_type;
134                 }
135
136                 public override void Emit (EmitContext ec)
137                 {
138                         ILGenerator ig = ec.ig;
139                                 
140                         ig.Emit (OpCodes.Ldc_I4_0);
141                         ig.Emit (OpCodes.Conv_U);
142                 }
143         }
144
145         public class BoolLiteral : BoolConstant {
146                 public BoolLiteral (bool val, Location loc) : base (val, loc)
147                 {
148                 }
149
150                 public override Expression DoResolve (EmitContext ec)
151                 {
152                         type = TypeManager.bool_type;
153                         return this;
154                 }
155         }
156
157         public class CharLiteral : CharConstant {
158                 public CharLiteral (char c, Location loc) : base (c, loc)
159                 {
160                 }
161
162                 public override Expression DoResolve (EmitContext ec)
163                 {
164                         type = TypeManager.char_type;
165                         return this;
166                 }
167         }
168
169         public class IntLiteral : IntConstant {
170                 public IntLiteral (int l, Location loc) : base (l, loc)
171                 {
172                 }
173
174                 public override Expression DoResolve (EmitContext ec)
175                 {
176                         type = TypeManager.int32_type;
177                         return this;
178                 }
179         }
180
181         public class UIntLiteral : UIntConstant {
182                 public UIntLiteral (uint l, Location loc) : base (l, loc)
183                 {
184                 }
185
186                 public override Expression DoResolve (EmitContext ec)
187                 {
188                         type = TypeManager.uint32_type;
189                         return this;
190                 }
191         }
192         
193         public class LongLiteral : LongConstant {
194                 public LongLiteral (long l, Location loc) : base (l, loc)
195                 {
196                 }
197
198                 public override Expression DoResolve (EmitContext ec)
199                 {
200                         type = TypeManager.int64_type;
201
202                         return this;
203                 }
204         }
205
206         public class ULongLiteral : ULongConstant {
207                 public ULongLiteral (ulong l, Location loc) : base (l, loc)
208                 {
209                 }
210
211                 public override Expression DoResolve (EmitContext ec)
212                 {
213                         type = TypeManager.uint64_type;
214                         return this;
215                 }
216         }
217         
218         public class FloatLiteral : FloatConstant {
219                 
220                 public FloatLiteral (float f, Location loc) : base (f, loc)
221                 {
222                 }
223
224                 public override Expression DoResolve (EmitContext ec)
225                 {
226                         type = TypeManager.float_type;
227                         return this;
228                 }
229         }
230
231         public class DoubleLiteral : DoubleConstant {
232                 public DoubleLiteral (double d, Location loc) : base (d, loc)
233                 {
234                 }
235
236                 public override Expression DoResolve (EmitContext ec)
237                 {
238                         type = TypeManager.double_type;
239
240                         return this;
241                 }
242         }
243
244         public class DecimalLiteral : DecimalConstant {
245                 public DecimalLiteral (decimal d, Location loc) : base (d, loc)
246                 {
247                 }
248
249                 public override Expression DoResolve (EmitContext ec)
250                 {
251                         type = TypeManager.decimal_type;
252                         return this;
253                 }
254         }
255
256         public class StringLiteral : StringConstant {
257                 public StringLiteral (string s, Location loc) : base (s, loc)
258                 {
259                 }
260
261                 public override Expression DoResolve (EmitContext ec)
262                 {
263                         type = TypeManager.string_type;
264
265                         return this;
266                 }
267         }
268 }