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