2001-11-05 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                 // <summary>
32                 //  This is used to obtain the actual value of the literal
33                 //  cast into an object.
34                 // </summary>
35                 public abstract object GetValue ();
36
37                 static public string descape (char c)
38                 {
39                         switch (c){
40                         case '\a':
41                                 return "\\a"; 
42                         case '\b':
43                                 return "\\b"; 
44                         case '\n':
45                                 return "\\n"; 
46                         case '\t':
47                                 return "\\t"; 
48                         case '\v':
49                                 return "\\v"; 
50                         case '\r':
51                                 return "\\r"; 
52                         case '\\':
53                                 return "\\\\";
54                         case '\f':
55                                 return "\\f"; 
56                         case '\0':
57                                 return "\\0"; 
58                         case '"':
59                                 return "\\\""; 
60                         case '\'':
61                                 return "\\\'"; 
62                         }
63                         return c.ToString ();
64                 }
65
66                 protected Literal ()
67                 {
68                         eclass = ExprClass.Value;
69                 }
70         }
71
72         public class NullLiteral : Literal {
73                 public NullLiteral ()
74                 {
75                 }
76                 
77                 override public string AsString ()
78                 {
79                         return "null";
80                 }
81
82                 public override object GetValue ()
83                 {
84                         return null;
85                 }
86
87                 public override Expression DoResolve (EmitContext ec)
88                 {
89                         type = TypeManager.object_type;
90                         eclass = ExprClass.Value;
91                         return this;
92                 }
93
94                 public override void Emit (EmitContext ec)
95                 {
96                         ec.ig.Emit (OpCodes.Ldnull);
97                 }
98         }
99
100         public class BoolLiteral : Literal {
101                 bool val;
102                 
103                 public BoolLiteral (bool val)
104                 {
105                         this.val = val;
106                 }
107
108                 override public string AsString ()
109                 {
110                         return val ? "true" : "false";
111                 }
112
113                 public override object GetValue ()
114                 {
115                         return (object) val;
116                 }
117                                 
118                 
119                 public override Expression DoResolve (EmitContext ec)
120                 {
121                         type = TypeManager.bool_type;
122
123                         return this;
124                 }
125
126                 public override void Emit (EmitContext ec)
127                 {
128                         if (val)
129                                 ec.ig.Emit (OpCodes.Ldc_I4_1);
130                         else
131                                 ec.ig.Emit (OpCodes.Ldc_I4_0);
132                 }
133         }
134
135         public class CharLiteral : Literal {
136                 char c;
137                 
138                 public CharLiteral (char c)
139                 {
140                         this.c = c;
141                 }
142
143                 override public string AsString ()
144                 {
145                         return "\"" + descape (c) + "\"";
146                 }
147
148                 public override object GetValue ()
149                 {
150                         return (object) c;
151                 }
152                 
153                 public override Expression DoResolve (EmitContext ec)
154                 {
155                         type = TypeManager.char_type;
156
157                         return this;
158                 }
159
160                 public override void Emit (EmitContext ec)
161                 {
162                         IntLiteral.EmitInt (ec.ig, c);
163                 }
164         }
165
166         public class IntLiteral : Literal {
167                 public readonly int Value;
168
169                 public IntLiteral (int l)
170                 {
171                         Value = l;
172                 }
173
174                 override public string AsString ()
175                 {
176                         return Value.ToString ();
177                 }
178
179                 public override object GetValue ()
180                 {
181                         return (object) Value;
182                 }
183
184                 public override Expression DoResolve (EmitContext ec)
185                 {
186                         type = TypeManager.int32_type;
187
188                         return this;
189                 }
190
191                 public override void Emit (EmitContext ec)
192                 {
193                         ILGenerator ig = ec.ig;
194
195                         EmitInt (ig, Value);
196                 }
197
198                 static public void EmitInt (ILGenerator ig, int i)
199                 {
200                         switch (i){
201                         case -1:
202                                 ig.Emit (OpCodes.Ldc_I4_M1);
203                                 break;
204                                 
205                         case 0:
206                                 ig.Emit (OpCodes.Ldc_I4_0);
207                                 break;
208                                 
209                         case 1:
210                                 ig.Emit (OpCodes.Ldc_I4_1);
211                                 break;
212                                 
213                         case 2:
214                                 ig.Emit (OpCodes.Ldc_I4_2);
215                                 break;
216                                 
217                         case 3:
218                                 ig.Emit (OpCodes.Ldc_I4_3);
219                                 break;
220                                 
221                         case 4:
222                                 ig.Emit (OpCodes.Ldc_I4_4);
223                                 break;
224                                 
225                         case 5:
226                                 ig.Emit (OpCodes.Ldc_I4_5);
227                                 break;
228                                 
229                         case 6:
230                                 ig.Emit (OpCodes.Ldc_I4_6);
231                                 break;
232                                 
233                         case 7:
234                                 ig.Emit (OpCodes.Ldc_I4_7);
235                                 break;
236                                 
237                         case 8:
238                                 ig.Emit (OpCodes.Ldc_I4_8);
239                                 break;
240
241                         default:
242                                 if (i > 0 && i < 127){
243                                         ig.Emit (OpCodes.Ldc_I4_S, (sbyte) i);
244                                 } else
245                                         ig.Emit (OpCodes.Ldc_I4, i);
246                                 break;
247                         }
248                 }
249         }
250
251         public class UIntLiteral : Literal {
252                 public readonly uint Value;
253
254                 public UIntLiteral (uint l)
255                 {
256                         Value = l;
257                 }
258
259                 override public string AsString ()
260                 {
261                         return Value.ToString ();
262                 }
263
264                 public override object GetValue ()
265                 {
266                         return (object) Value;
267                 }
268                 
269                 public override Expression DoResolve (EmitContext ec)
270                 {
271                         type = TypeManager.uint32_type;
272
273                         return this;
274                 }
275
276                 public override void Emit (EmitContext ec)
277                 {
278                         ILGenerator ig = ec.ig;
279
280                         IntLiteral.EmitInt (ig, unchecked ((int) Value));
281                 }
282
283         }
284         
285         public class LongLiteral : Literal {
286                 public readonly long Value;
287
288                 public LongLiteral (long l)
289                 {
290                         Value = l;
291                 }
292
293                 override public string AsString ()
294                 {
295                         return Value.ToString ();
296                 }
297
298                 public override object GetValue ()
299                 {
300                         return (object) Value;
301                 }
302                 
303                 public override Expression DoResolve (EmitContext ec)
304                 {
305                         type = TypeManager.int64_type;
306
307                         return this;
308                 }
309
310                 public override void Emit (EmitContext ec)
311                 {
312                         ILGenerator ig = ec.ig;
313
314                         EmitLong (ig, Value);
315                 }
316
317                 static public void EmitLong (ILGenerator ig, long l)
318                 {
319                         ig.Emit (OpCodes.Ldc_I8, l);
320                 }
321         }
322
323         public class ULongLiteral : Literal {
324                 public readonly ulong Value;
325
326                 public ULongLiteral (ulong l)
327                 {
328                         Value = l;
329                 }
330
331                 override public string AsString ()
332                 {
333                         return Value.ToString ();
334                 }
335
336                 public override object GetValue ()
337                 {
338                         return (object) Value;
339                 }
340
341                 public override Expression DoResolve (EmitContext ec)
342                 {
343                         type = TypeManager.uint64_type;
344
345                         return this;
346                 }
347
348                 public override void Emit (EmitContext ec)
349                 {
350                         ILGenerator ig = ec.ig;
351
352                         LongLiteral.EmitLong (ig, unchecked ((long) Value));
353                 }
354         }
355         
356         public class FloatLiteral : Literal {
357                 public readonly float Value;
358
359                 public FloatLiteral (float f)
360                 {
361                         Value = f;
362                 }
363
364                 override public string AsString ()
365                 {
366                         return Value.ToString ();
367                 }
368
369                 public override object GetValue ()
370                 {
371                         return (object) Value;
372                 }
373                 
374                 public override Expression DoResolve (EmitContext ec)
375                 {
376                         type = TypeManager.float_type;
377
378                         return this;
379                 }
380
381                 public override void Emit (EmitContext ec)
382                 {
383                         ec.ig.Emit (OpCodes.Ldc_R4, Value);
384                 }
385         }
386
387         public class DoubleLiteral : Literal {
388                 public readonly double Value;
389
390                 public DoubleLiteral (double d)
391                 {
392                         Value = d;
393                 }
394
395                 override public string AsString ()
396                 {
397                         return Value.ToString ();
398                 }
399
400                 public override object GetValue ()
401                 {
402                         return (object) Value;
403                 }
404                 
405                 public override Expression DoResolve (EmitContext ec)
406                 {
407                         type = TypeManager.double_type;
408
409                         return this;
410                 }
411
412                 public override void Emit (EmitContext ec)
413                 {
414                         ec.ig.Emit (OpCodes.Ldc_R8, Value);
415                 }
416         }
417
418         public class DecimalLiteral : Literal {
419                 public readonly decimal Value;
420
421                 public DecimalLiteral (decimal d)
422                 {
423                         Value = d;
424                 }
425
426                 override public string AsString ()
427                 {
428                         return Value.ToString ();
429                 }
430
431                 public override object GetValue ()
432                 {
433                         return (object) Value;
434                 }
435
436                 public override Expression DoResolve (EmitContext ec)
437                 {
438                         type = TypeManager.decimal_type;
439
440                         return this;
441                 }
442
443                 public override void Emit (EmitContext ec)
444                 {
445                         throw new Exception ("Implement me");
446                 }
447         }
448
449         public class StringLiteral : Literal {
450                 string s;
451
452                 public StringLiteral (string s)
453                 {
454                         this.s = s;
455                 }
456
457                 // FIXME: Escape the string.
458                 override public string AsString ()
459                 {
460                         return "\"" + s + "\"";
461                 }
462
463                 public override object GetValue ()
464                 {
465                         return (object) s;
466                 }
467                 
468                 public override Expression DoResolve (EmitContext ec)
469                 {
470                         type = TypeManager.string_type;
471
472                         return this;
473                 }
474
475                 public override void Emit (EmitContext ec)
476                 {
477                         ec.ig.Emit (OpCodes.Ldstr, s);
478                 }
479         }
480 }