2001-09-27 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 using System;
11 using System.Reflection;
12 using System.Reflection.Emit;
13
14 namespace CIR {
15         public abstract class Literal : Expression {
16                 // <summary>
17                 //   This is different from ToString in that ToString
18                 //   is supposed to be there for debugging purposes,
19                 //   and is not guarantee to be useful for anything else,
20                 //   AsString() will provide something that can be used
21                 //   for round-tripping C# code.  Maybe it can be used
22                 //   for IL assembly as well.
23                 // </summary>
24                 public abstract string AsString ();
25
26                 override public string ToString ()
27                 {
28                         return AsString ();
29                 }
30
31                 static public string descape (char c)
32                 {
33                         switch (c){
34                         case '\a':
35                                 return "\\a"; 
36                         case '\b':
37                                 return "\\b"; 
38                         case '\n':
39                                 return "\\n"; 
40                         case '\t':
41                                 return "\\t"; 
42                         case '\v':
43                                 return "\\v"; 
44                         case '\r':
45                                 return "\\r"; 
46                         case '\\':
47                                 return "\\\\";
48                         case '\f':
49                                 return "\\f"; 
50                         case '\0':
51                                 return "\\0"; 
52                         case '"':
53                                 return "\\\""; 
54                         case '\'':
55                                 return "\\\'"; 
56                         }
57                         return c.ToString ();
58                 }
59
60                 protected Literal ()
61                 {
62                         eclass = ExprClass.Value;
63                 }
64         }
65
66         public class NullLiteral : Literal {
67                 public NullLiteral ()
68                 {
69                 }
70                 
71                 override public string AsString ()
72                 {
73                         return "null";
74                 }
75
76                 public override Expression Resolve (TypeContainer tc)
77                 {
78                         type = TypeManager.object_type;
79                         return this;
80                 }
81
82                 public override void Emit (EmitContext ec)
83                 {
84                         ec.ig.Emit (OpCodes.Ldnull);
85                 }
86         }
87
88         public class BoolLiteral : Literal {
89                 bool val;
90                 
91                 public BoolLiteral (bool val)
92                 {
93                         this.val = val;
94                 }
95
96                 override public string AsString ()
97                 {
98                         return val ? "true" : "false";
99                 }
100
101                 public override Expression Resolve (TypeContainer tc)
102                 {
103                         type = TypeManager.bool_type;
104
105                         return this;
106                 }
107
108                 public override void Emit (EmitContext ec)
109                 {
110                         if (val)
111                                 ec.ig.Emit (OpCodes.Ldc_I4_1);
112                         else
113                                 ec.ig.Emit (OpCodes.Ldc_I4_0);
114                 }
115         }
116
117         public class CharLiteral : Literal {
118                 char c;
119                 
120                 public CharLiteral (char c)
121                 {
122                         this.c = c;
123                 }
124
125                 override public string AsString ()
126                 {
127                         return "\"" + descape (c) + "\"";
128                 }
129
130                 public override Expression Resolve (TypeContainer tc)
131                 {
132                         type = TypeManager.char_type;
133
134                         return this;
135                 }
136
137                 public override void Emit (EmitContext ec)
138                 {
139                         IntLiteral.EmitInt (ec.ig, c);
140                 }
141         }
142
143         public class IntLiteral : Literal {
144                 public readonly int Value;
145
146                 public IntLiteral (int l)
147                 {
148                         Value = l;
149                 }
150
151                 override public string AsString ()
152                 {
153                         return Value.ToString ();
154                 }
155
156                 public override Expression Resolve (TypeContainer tc)
157                 {
158                         type = TypeManager.int32_type;
159
160                         return this;
161                 }
162
163                 public override void Emit (EmitContext ec)
164                 {
165                         ILGenerator ig = ec.ig;
166
167                         EmitInt (ig, Value);
168                 }
169
170                 static public void EmitInt (ILGenerator ig, int i)
171                 {
172                         switch (i){
173                         case -1:
174                                 ig.Emit (OpCodes.Ldc_I4_M1);
175                                 break;
176                                 
177                         case 0:
178                                 ig.Emit (OpCodes.Ldc_I4_0);
179                                 break;
180                                 
181                         case 1:
182                                 ig.Emit (OpCodes.Ldc_I4_1);
183                                 break;
184                                 
185                         case 2:
186                                 ig.Emit (OpCodes.Ldc_I4_2);
187                                 break;
188                                 
189                         case 3:
190                                 ig.Emit (OpCodes.Ldc_I4_3);
191                                 break;
192                                 
193                         case 4:
194                                 ig.Emit (OpCodes.Ldc_I4_4);
195                                 break;
196                                 
197                         case 5:
198                                 ig.Emit (OpCodes.Ldc_I4_5);
199                                 break;
200                                 
201                         case 6:
202                                 ig.Emit (OpCodes.Ldc_I4_6);
203                                 break;
204                                 
205                         case 7:
206                                 ig.Emit (OpCodes.Ldc_I4_7);
207                                 break;
208                                 
209                         case 8:
210                                 ig.Emit (OpCodes.Ldc_I4_8);
211                                 break;
212
213                         default:
214                                 if (i > 0 && i < 127){
215                                         ig.Emit (OpCodes.Ldc_I4_S, (sbyte) i);
216                                 } else
217                                         ig.Emit (OpCodes.Ldc_I4, i);
218                                 break;
219                         }
220                 }
221         }
222
223         public class UIntLiteral : Literal {
224                 public readonly uint Value;
225
226                 public UIntLiteral (uint l)
227                 {
228                         Value = l;
229                 }
230
231                 override public string AsString ()
232                 {
233                         return Value.ToString ();
234                 }
235
236                 public override Expression Resolve (TypeContainer tc)
237                 {
238                         type = TypeManager.uint32_type;
239
240                         return this;
241                 }
242
243                 public override void Emit (EmitContext ec)
244                 {
245                         ILGenerator ig = ec.ig;
246
247                         IntLiteral.EmitInt (ig, unchecked ((int) Value));
248                 }
249
250         }
251         
252         public class LongLiteral : Literal {
253                 public readonly long Value;
254
255                 public LongLiteral (long l)
256                 {
257                         Value = l;
258                 }
259
260                 override public string AsString ()
261                 {
262                         return Value.ToString ();
263                 }
264
265                 public override Expression Resolve (TypeContainer tc)
266                 {
267                         type = TypeManager.int64_type;
268
269                         return this;
270                 }
271
272                 public override void Emit (EmitContext ec)
273                 {
274                         ILGenerator ig = ec.ig;
275
276                         EmitLong (ig, Value);
277                 }
278
279                 static public void EmitLong (ILGenerator ig, long l)
280                 {
281                         if (l >= -1 || l < Int32.MaxValue)
282                                 IntLiteral.EmitInt (ig, (int) l);
283                         else
284                                 ig.Emit (OpCodes.Ldc_I8, l);
285                 }
286         }
287
288         public class FloatLiteral : Literal {
289                 public readonly float Value;
290
291                 public FloatLiteral (float f)
292                 {
293                         Value = f;
294                 }
295
296                 override public string AsString ()
297                 {
298                         return Value.ToString ();
299                 }
300
301                 public override Expression Resolve (TypeContainer tc)
302                 {
303                         type = TypeManager.float_type;
304
305                         return this;
306                 }
307
308                 public override void Emit (EmitContext ec)
309                 {
310                         ec.ig.Emit (OpCodes.Ldc_R4, Value);
311                 }
312         }
313
314         public class DoubleLiteral : Literal {
315                 public readonly double Value;
316
317                 public DoubleLiteral (double d)
318                 {
319                         Value = d;
320                 }
321
322                 override public string AsString ()
323                 {
324                         return Value.ToString ();
325                 }
326
327                 public override Expression Resolve (TypeContainer tc)
328                 {
329                         type = TypeManager.double_type;
330
331                         return this;
332                 }
333
334                 public override void Emit (EmitContext ec)
335                 {
336                         ec.ig.Emit (OpCodes.Ldc_R8, Value);
337                 }
338         }
339
340         public class DecimalLiteral : Literal {
341                 public readonly decimal Value;
342
343                 public DecimalLiteral (decimal d)
344                 {
345                         Value = d;
346                 }
347
348                 override public string AsString ()
349                 {
350                         return Value.ToString ();
351                 }
352
353                 public override Expression Resolve (TypeContainer tc)
354                 {
355                         type = TypeManager.decimal_type;
356
357                         return this;
358                 }
359
360                 public override void Emit (EmitContext ec)
361                 {
362                         throw new Exception ("Implement me");
363                 }
364         }
365
366         public class StringLiteral : Literal {
367                 string s;
368
369                 public StringLiteral (string s)
370                 {
371                         this.s = s;
372                 }
373
374                 // FIXME: Escape the string.
375                 override public string AsString ()
376                 {
377                         return "\"" + s + "\"";
378                 }
379
380                 public override Expression Resolve (TypeContainer tc)
381                 {
382                         type = TypeManager.string_type;
383
384                         return this;
385                 }
386
387                 public override void Emit (EmitContext ec)
388                 {
389                         ec.ig.Emit (OpCodes.Ldstr, s);
390                 }
391         }
392 }