2001-10-31 Ravi Pratap <ravi@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 DoResolve (EmitContext ec)
77                 {
78                         type = TypeManager.object_type;
79                         eclass = ExprClass.Value;
80                         return this;
81                 }
82
83                 public override void Emit (EmitContext ec)
84                 {
85                         ec.ig.Emit (OpCodes.Ldnull);
86                 }
87         }
88
89         public class BoolLiteral : Literal {
90                 bool val;
91                 
92                 public BoolLiteral (bool val)
93                 {
94                         this.val = val;
95                 }
96
97                 override public string AsString ()
98                 {
99                         return val ? "true" : "false";
100                 }
101
102                 public override Expression DoResolve (EmitContext ec)
103                 {
104                         type = TypeManager.bool_type;
105
106                         return this;
107                 }
108
109                 public override void Emit (EmitContext ec)
110                 {
111                         if (val)
112                                 ec.ig.Emit (OpCodes.Ldc_I4_1);
113                         else
114                                 ec.ig.Emit (OpCodes.Ldc_I4_0);
115                 }
116         }
117
118         public class CharLiteral : Literal {
119                 char c;
120                 
121                 public CharLiteral (char c)
122                 {
123                         this.c = c;
124                 }
125
126                 override public string AsString ()
127                 {
128                         return "\"" + descape (c) + "\"";
129                 }
130
131                 public override Expression DoResolve (EmitContext ec)
132                 {
133                         type = TypeManager.char_type;
134
135                         return this;
136                 }
137
138                 public override void Emit (EmitContext ec)
139                 {
140                         IntLiteral.EmitInt (ec.ig, c);
141                 }
142         }
143
144         public class IntLiteral : Literal {
145                 public readonly int Value;
146
147                 public IntLiteral (int l)
148                 {
149                         Value = l;
150                 }
151
152                 override public string AsString ()
153                 {
154                         return Value.ToString ();
155                 }
156
157                 public override Expression DoResolve (EmitContext ec)
158                 {
159                         type = TypeManager.int32_type;
160
161                         return this;
162                 }
163
164                 public override void Emit (EmitContext ec)
165                 {
166                         ILGenerator ig = ec.ig;
167
168                         EmitInt (ig, Value);
169                 }
170
171                 static public void EmitInt (ILGenerator ig, int i)
172                 {
173                         switch (i){
174                         case -1:
175                                 ig.Emit (OpCodes.Ldc_I4_M1);
176                                 break;
177                                 
178                         case 0:
179                                 ig.Emit (OpCodes.Ldc_I4_0);
180                                 break;
181                                 
182                         case 1:
183                                 ig.Emit (OpCodes.Ldc_I4_1);
184                                 break;
185                                 
186                         case 2:
187                                 ig.Emit (OpCodes.Ldc_I4_2);
188                                 break;
189                                 
190                         case 3:
191                                 ig.Emit (OpCodes.Ldc_I4_3);
192                                 break;
193                                 
194                         case 4:
195                                 ig.Emit (OpCodes.Ldc_I4_4);
196                                 break;
197                                 
198                         case 5:
199                                 ig.Emit (OpCodes.Ldc_I4_5);
200                                 break;
201                                 
202                         case 6:
203                                 ig.Emit (OpCodes.Ldc_I4_6);
204                                 break;
205                                 
206                         case 7:
207                                 ig.Emit (OpCodes.Ldc_I4_7);
208                                 break;
209                                 
210                         case 8:
211                                 ig.Emit (OpCodes.Ldc_I4_8);
212                                 break;
213
214                         default:
215                                 if (i > 0 && i < 127){
216                                         ig.Emit (OpCodes.Ldc_I4_S, (sbyte) i);
217                                 } else
218                                         ig.Emit (OpCodes.Ldc_I4, i);
219                                 break;
220                         }
221                 }
222         }
223
224         public class UIntLiteral : Literal {
225                 public readonly uint Value;
226
227                 public UIntLiteral (uint l)
228                 {
229                         Value = l;
230                 }
231
232                 override public string AsString ()
233                 {
234                         return Value.ToString ();
235                 }
236
237                 public override Expression DoResolve (EmitContext ec)
238                 {
239                         type = TypeManager.uint32_type;
240
241                         return this;
242                 }
243
244                 public override void Emit (EmitContext ec)
245                 {
246                         ILGenerator ig = ec.ig;
247
248                         IntLiteral.EmitInt (ig, unchecked ((int) Value));
249                 }
250
251         }
252         
253         public class LongLiteral : Literal {
254                 public readonly long Value;
255
256                 public LongLiteral (long l)
257                 {
258                         Value = l;
259                 }
260
261                 override public string AsString ()
262                 {
263                         return Value.ToString ();
264                 }
265
266                 public override Expression DoResolve (EmitContext ec)
267                 {
268                         type = TypeManager.int64_type;
269
270                         return this;
271                 }
272
273                 public override void Emit (EmitContext ec)
274                 {
275                         ILGenerator ig = ec.ig;
276
277                         EmitLong (ig, Value);
278                 }
279
280                 static public void EmitLong (ILGenerator ig, long l)
281                 {
282                         ig.Emit (OpCodes.Ldc_I8, l);
283                 }
284         }
285
286         public class ULongLiteral : Literal {
287                 public readonly ulong Value;
288
289                 public ULongLiteral (ulong l)
290                 {
291                         Value = l;
292                 }
293
294                 override public string AsString ()
295                 {
296                         return Value.ToString ();
297                 }
298
299                 public override Expression DoResolve (EmitContext ec)
300                 {
301                         type = TypeManager.uint64_type;
302
303                         return this;
304                 }
305
306                 public override void Emit (EmitContext ec)
307                 {
308                         ILGenerator ig = ec.ig;
309
310                         LongLiteral.EmitLong (ig, unchecked ((long) Value));
311                 }
312         }
313         
314         public class FloatLiteral : Literal {
315                 public readonly float Value;
316
317                 public FloatLiteral (float f)
318                 {
319                         Value = f;
320                 }
321
322                 override public string AsString ()
323                 {
324                         return Value.ToString ();
325                 }
326
327                 public override Expression DoResolve (EmitContext ec)
328                 {
329                         type = TypeManager.float_type;
330
331                         return this;
332                 }
333
334                 public override void Emit (EmitContext ec)
335                 {
336                         ec.ig.Emit (OpCodes.Ldc_R4, Value);
337                 }
338         }
339
340         public class DoubleLiteral : Literal {
341                 public readonly double Value;
342
343                 public DoubleLiteral (double d)
344                 {
345                         Value = d;
346                 }
347
348                 override public string AsString ()
349                 {
350                         return Value.ToString ();
351                 }
352
353                 public override Expression DoResolve (EmitContext ec)
354                 {
355                         type = TypeManager.double_type;
356
357                         return this;
358                 }
359
360                 public override void Emit (EmitContext ec)
361                 {
362                         ec.ig.Emit (OpCodes.Ldc_R8, Value);
363                 }
364         }
365
366         public class DecimalLiteral : Literal {
367                 public readonly decimal Value;
368
369                 public DecimalLiteral (decimal d)
370                 {
371                         Value = d;
372                 }
373
374                 override public string AsString ()
375                 {
376                         return Value.ToString ();
377                 }
378
379                 public override Expression DoResolve (EmitContext ec)
380                 {
381                         type = TypeManager.decimal_type;
382
383                         return this;
384                 }
385
386                 public override void Emit (EmitContext ec)
387                 {
388                         throw new Exception ("Implement me");
389                 }
390         }
391
392         public class StringLiteral : Literal {
393                 string s;
394
395                 public StringLiteral (string s)
396                 {
397                         this.s = s;
398                 }
399
400                 // FIXME: Escape the string.
401                 override public string AsString ()
402                 {
403                         return "\"" + s + "\"";
404                 }
405
406                 public override Expression DoResolve (EmitContext ec)
407                 {
408                         type = TypeManager.string_type;
409
410                         return this;
411                 }
412
413                 public override void Emit (EmitContext ec)
414                 {
415                         ec.ig.Emit (OpCodes.Ldstr, s);
416                 }
417         }
418 }