2005-08-02 Marek Safar <marek.safar@seznam.cz>
[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         //
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                 public override string GetSignatureForError()
100                 {
101                         return "null";
102                 }
103
104                 public override void Error_ConstantValueCannotBeConverted (Location loc, Type t)
105                 {
106                         Report.Error (37, loc, "Cannot convert null to `{0}' because it is a value type",
107                                 TypeManager.CSharpName (t));
108                 }
109         }
110
111         //
112         // A null literal in a pointer context
113         //
114         public class NullPointer : NullLiteral {
115                 public new static readonly NullLiteral Null;
116
117                 static NullPointer ()
118                 {
119                         Null = new NullPointer ();
120                 }
121
122                 private NullPointer ()
123                 {
124                         type = TypeManager.object_type;
125                 }
126
127                 public override void Emit (EmitContext ec)
128                 {
129                         ILGenerator ig = ec.ig;
130                                 
131                         ig.Emit (OpCodes.Ldc_I4_0);
132                         ig.Emit (OpCodes.Conv_U);
133                 }
134         }
135
136         public class BoolLiteral : BoolConstant {
137                 public BoolLiteral (bool val) : base (val)
138                 {
139                 }
140
141                 public override Expression DoResolve (EmitContext ec)
142                 {
143                         type = TypeManager.bool_type;
144                         return this;
145                 }
146         }
147
148         public class CharLiteral : CharConstant {
149                 public CharLiteral (char c) : base (c)
150                 {
151                 }
152
153                 public override Expression DoResolve (EmitContext ec)
154                 {
155                         type = TypeManager.char_type;
156                         return this;
157                 }
158         }
159
160         public class IntLiteral : IntConstant {
161                 public static IntLiteral One, Zero;
162                 
163                 static IntLiteral ()
164                 {
165                         Zero = new IntLiteral (0);
166                         One = new IntLiteral (1);
167                 }
168                 
169                 public IntLiteral (int l) : base (l)
170                 {
171                 }
172
173                 public override Expression DoResolve (EmitContext ec)
174                 {
175                         type = TypeManager.int32_type;
176                         return this;
177                 }
178         }
179
180         public class UIntLiteral : UIntConstant {
181                 public UIntLiteral (uint l) : base (l)
182                 {
183                 }
184
185                 public override Expression DoResolve (EmitContext ec)
186                 {
187                         type = TypeManager.uint32_type;
188                         return this;
189                 }
190         }
191         
192         public class LongLiteral : LongConstant {
193                 public LongLiteral (long l) : base (l)
194                 {
195                 }
196
197                 public override Expression DoResolve (EmitContext ec)
198                 {
199                         type = TypeManager.int64_type;
200
201                         return this;
202                 }
203         }
204
205         public class ULongLiteral : ULongConstant {
206                 public ULongLiteral (ulong l) : base (l)
207                 {
208                 }
209
210                 public override Expression DoResolve (EmitContext ec)
211                 {
212                         type = TypeManager.uint64_type;
213                         return this;
214                 }
215         }
216         
217         public class FloatLiteral : FloatConstant {
218                 
219                 public FloatLiteral (float f) : base (f)
220                 {
221                 }
222
223                 public override Expression DoResolve (EmitContext ec)
224                 {
225                         type = TypeManager.float_type;
226                         return this;
227                 }
228         }
229
230         public class DoubleLiteral : DoubleConstant {
231                 public DoubleLiteral (double d) : base (d)
232                 {
233                 }
234
235                 public override Expression DoResolve (EmitContext ec)
236                 {
237                         type = TypeManager.double_type;
238
239                         return this;
240                 }
241         }
242
243         public class DecimalLiteral : DecimalConstant {
244                 public DecimalLiteral (decimal d) : base (d)
245                 {
246                 }
247
248                 public override Expression DoResolve (EmitContext ec)
249                 {
250                         type = TypeManager.decimal_type;
251                         return this;
252                 }
253         }
254
255         public class StringLiteral : StringConstant {
256                 public StringLiteral (string s) : base (s)
257                 {
258                 }
259
260                 public override Expression DoResolve (EmitContext ec)
261                 {
262                         type = TypeManager.string_type;
263
264                         return this;
265                 }
266         }
267 }