2004-09-22 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         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 IsNegative {
74                         get {
75                                 return false;
76                         }
77                 }
78
79                 public override bool IsZeroInteger {
80                         get { return true; }
81                 }
82         }
83
84         //
85         // A null literal in a pointer context
86         //
87         public class NullPointer : NullLiteral {
88                 public new static readonly NullLiteral Null;
89
90                 static NullPointer ()
91                 {
92                         Null = new NullPointer ();
93                 }
94
95                 private NullPointer ()
96                 {
97                         type = TypeManager.object_type;
98                 }
99
100                 public override void Emit (EmitContext ec)
101                 {
102                         ILGenerator ig = ec.ig;
103                                 
104                         ig.Emit (OpCodes.Ldc_I4_0);
105                         ig.Emit (OpCodes.Conv_U);
106                 }
107         }
108
109         public class BoolLiteral : BoolConstant {
110                 public BoolLiteral (bool val) : base (val)
111                 {
112                 }
113
114                 public override Expression DoResolve (EmitContext ec)
115                 {
116                         type = TypeManager.bool_type;
117                         return this;
118                 }
119         }
120
121         public class CharLiteral : CharConstant {
122                 public CharLiteral (char c) : base (c)
123                 {
124                 }
125
126                 public override Expression DoResolve (EmitContext ec)
127                 {
128                         type = TypeManager.char_type;
129                         return this;
130                 }
131         }
132
133         public class IntLiteral : IntConstant {
134                 public static IntLiteral One, Zero;
135                 
136                 static IntLiteral ()
137                 {
138                         Zero = new IntLiteral (0);
139                         One = new IntLiteral (1);
140                 }
141                 
142                 public IntLiteral (int l) : base (l)
143                 {
144                 }
145
146                 public override Expression DoResolve (EmitContext ec)
147                 {
148                         type = TypeManager.int32_type;
149                         return this;
150                 }
151         }
152
153         public class UIntLiteral : UIntConstant {
154                 public UIntLiteral (uint l) : base (l)
155                 {
156                 }
157
158                 public override Expression DoResolve (EmitContext ec)
159                 {
160                         type = TypeManager.uint32_type;
161                         return this;
162                 }
163         }
164         
165         public class LongLiteral : LongConstant {
166                 public LongLiteral (long l) : base (l)
167                 {
168                 }
169
170                 public override Expression DoResolve (EmitContext ec)
171                 {
172                         type = TypeManager.int64_type;
173
174                         return this;
175                 }
176         }
177
178         public class ULongLiteral : ULongConstant {
179                 public ULongLiteral (ulong l) : base (l)
180                 {
181                 }
182
183                 public override Expression DoResolve (EmitContext ec)
184                 {
185                         type = TypeManager.uint64_type;
186                         return this;
187                 }
188         }
189         
190         public class FloatLiteral : FloatConstant {
191                 
192                 public FloatLiteral (float f) : base (f)
193                 {
194                 }
195
196                 public override Expression DoResolve (EmitContext ec)
197                 {
198                         type = TypeManager.float_type;
199                         return this;
200                 }
201         }
202
203         public class DoubleLiteral : DoubleConstant {
204                 public DoubleLiteral (double d) : base (d)
205                 {
206                 }
207
208                 public override Expression DoResolve (EmitContext ec)
209                 {
210                         type = TypeManager.double_type;
211
212                         return this;
213                 }
214         }
215
216         public class DecimalLiteral : DecimalConstant {
217                 public DecimalLiteral (decimal d) : base (d)
218                 {
219                 }
220
221                 public override Expression DoResolve (EmitContext ec)
222                 {
223                         type = TypeManager.decimal_type;
224                         return this;
225                 }
226         }
227
228         public class StringLiteral : StringConstant {
229                 public StringLiteral (string s) : base (s)
230                 {
231                 }
232
233                 public override Expression DoResolve (EmitContext ec)
234                 {
235                         type = TypeManager.string_type;
236
237                         return this;
238                 }
239         }
240 }