Add new test
[mono.git] / mcs / mcs / constant.cs
1 //
2 // constant.cs: Constants.
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.
8 //
9 //
10
11 namespace Mono.CSharp {
12
13         using System;
14         using System.Reflection.Emit;
15
16         /// <summary>
17         ///   Base class for constants and literals.
18         /// </summary>
19         public abstract class Constant : Expression {
20
21                 protected Constant ()
22                 {
23                         eclass = ExprClass.Value;
24                 }
25
26                 /// <remarks>
27                 ///   This is different from ToString in that ToString
28                 ///   is supposed to be there for debugging purposes,
29                 ///   and is not guaranteed to be useful for anything else,
30                 ///   AsString() will provide something that can be used
31                 ///   for round-tripping C# code.  Maybe it can be used
32                 ///   for IL assembly as well.
33                 /// </remarks>
34                 public abstract string AsString ();
35
36                 override public string ToString ()
37                 {
38                         return AsString ();
39                 }
40
41                 /// <summary>
42                 ///  This is used to obtain the actual value of the literal
43                 ///  cast into an object.
44                 /// </summary>
45                 public abstract object GetValue ();
46
47                 /// <summary>
48                 ///   Constants are always born in a fully resolved state
49                 /// </summary>
50                 public override Expression DoResolve (EmitContext ec)
51                 {
52                         return this;
53                 }
54         }
55
56         public class BoolConstant : Constant {
57                 public readonly bool Value;
58                 
59                 public BoolConstant (bool val)
60                 {
61                         type = TypeManager.bool_type;
62
63                         Value = val;
64                 }
65
66                 override public string AsString ()
67                 {
68                         return Value ? "true" : "false";
69                 }
70
71                 public override object GetValue ()
72                 {
73                         return (object) Value;
74                 }
75                                 
76                 
77                 public override void Emit (EmitContext ec)
78                 {
79                         if (Value)
80                                 ec.ig.Emit (OpCodes.Ldc_I4_1);
81                         else
82                                 ec.ig.Emit (OpCodes.Ldc_I4_0);
83                 }
84         }
85
86         public class ByteConstant : Constant {
87                 public readonly byte Value;
88
89                 public ByteConstant (byte v)
90                 {
91                         type = TypeManager.byte_type;
92                         Value = v;
93                 }
94
95                 public override void Emit (EmitContext ec)
96                 {
97                         IntLiteral.EmitInt (ec.ig, Value);
98                 }
99
100                 public override string AsString ()
101                 {
102                         return Value.ToString ();
103                 }
104
105                 public override object GetValue ()
106                 {
107                         return Value;
108                 }
109         }
110
111         public class CharConstant : Constant {
112                 public readonly char Value;
113
114                 public CharConstant (char v)
115                 {
116                         type = TypeManager.char_type;
117                         Value = v;
118                 }
119
120                 public override void Emit (EmitContext ec)
121                 {
122                         IntLiteral.EmitInt (ec.ig, Value);
123                 }
124
125                 static public string descape (char c)
126                 {
127                         switch (c){
128                         case '\a':
129                                 return "\\a"; 
130                         case '\b':
131                                 return "\\b"; 
132                         case '\n':
133                                 return "\\n"; 
134                         case '\t':
135                                 return "\\t"; 
136                         case '\v':
137                                 return "\\v"; 
138                         case '\r':
139                                 return "\\r"; 
140                         case '\\':
141                                 return "\\\\";
142                         case '\f':
143                                 return "\\f"; 
144                         case '\0':
145                                 return "\\0"; 
146                         case '"':
147                                 return "\\\""; 
148                         case '\'':
149                                 return "\\\'"; 
150                         }
151                         return c.ToString ();
152                 }
153
154                 public override string AsString ()
155                 {
156                         return "\"" + descape (Value) + "\"";
157                 }
158
159                 public override object GetValue ()
160                 {
161                         return Value;
162                 }
163         }
164
165         public class SByteConstant : Constant {
166                 public readonly sbyte Value;
167
168                 public SByteConstant (sbyte v)
169                 {
170                         type = TypeManager.sbyte_type;
171                         Value = v;
172                 }
173
174                 public override void Emit (EmitContext ec)
175                 {
176                         IntLiteral.EmitInt (ec.ig, Value);
177                 }
178
179                 public override string AsString ()
180                 {
181                         return Value.ToString ();
182                 }
183
184                 public override object GetValue ()
185                 {
186                         return Value;
187                 }
188         }
189
190         public class ShortConstant : Constant {
191                 public readonly short Value;
192
193                 public ShortConstant (short v)
194                 {
195                         type = TypeManager.short_type;
196                         Value = v;
197                 }
198
199                 public override void Emit (EmitContext ec)
200                 {
201                         IntLiteral.EmitInt (ec.ig, Value);
202                 }
203
204                 public override string AsString ()
205                 {
206                         return Value.ToString ();
207                 }
208
209                 public override object GetValue ()
210                 {
211                         return Value;
212                 }
213         }
214
215         public class UShortConstant : Constant {
216                 public readonly ushort Value;
217
218                 public UShortConstant (ushort v)
219                 {
220                         type = TypeManager.ushort_type;
221                         Value = v;
222                 }
223
224                 public override void Emit (EmitContext ec)
225                 {
226                         IntLiteral.EmitInt (ec.ig, Value);
227                 }
228
229                 public override string AsString ()
230                 {
231                         return Value.ToString ();
232                 }
233
234                 public override object GetValue ()
235                 {
236                         return Value;
237                 }
238         }
239
240         public class IntConstant : Constant {
241                 public readonly int Value;
242
243                 public IntConstant (int v)
244                 {
245                         type = TypeManager.int32_type;
246                         Value = v;
247                 }
248
249                 static public void EmitInt (ILGenerator ig, int i)
250                 {
251                         switch (i){
252                         case -1:
253                                 ig.Emit (OpCodes.Ldc_I4_M1);
254                                 break;
255                                 
256                         case 0:
257                                 ig.Emit (OpCodes.Ldc_I4_0);
258                                 break;
259                                 
260                         case 1:
261                                 ig.Emit (OpCodes.Ldc_I4_1);
262                                 break;
263                                 
264                         case 2:
265                                 ig.Emit (OpCodes.Ldc_I4_2);
266                                 break;
267                                 
268                         case 3:
269                                 ig.Emit (OpCodes.Ldc_I4_3);
270                                 break;
271                                 
272                         case 4:
273                                 ig.Emit (OpCodes.Ldc_I4_4);
274                                 break;
275                                 
276                         case 5:
277                                 ig.Emit (OpCodes.Ldc_I4_5);
278                                 break;
279                                 
280                         case 6:
281                                 ig.Emit (OpCodes.Ldc_I4_6);
282                                 break;
283                                 
284                         case 7:
285                                 ig.Emit (OpCodes.Ldc_I4_7);
286                                 break;
287                                 
288                         case 8:
289                                 ig.Emit (OpCodes.Ldc_I4_8);
290                                 break;
291
292                         default:
293                                 if (i >= -128 && i <= 127){
294                                         ig.Emit (OpCodes.Ldc_I4_S, (sbyte) i);
295                                 } else
296                                         ig.Emit (OpCodes.Ldc_I4, i);
297                                 break;
298                         }
299                 }
300
301                 public override void Emit (EmitContext ec)
302                 {
303                         EmitInt (ec.ig, Value);
304                 }
305
306                 public override string AsString ()
307                 {
308                         return Value.ToString ();
309                 }
310
311                 public override object GetValue ()
312                 {
313                         return Value;
314                 }
315         }
316
317         public class UIntConstant : Constant {
318                 public readonly uint Value;
319
320                 public UIntConstant (uint v)
321                 {
322                         type = TypeManager.uint32_type;
323                         Value = v;
324                 }
325
326                 public override void Emit (EmitContext ec)
327                 {
328                         IntLiteral.EmitInt (ec.ig, unchecked ((int) Value));
329                 }
330
331                 public override string AsString ()
332                 {
333                         return Value.ToString ();
334                 }
335
336                 public override object GetValue ()
337                 {
338                         return Value;
339                 }
340         }
341
342         public class LongConstant : Constant {
343                 public readonly long Value;
344
345                 public LongConstant (long v)
346                 {
347                         type = TypeManager.int64_type;
348                         Value = v;
349                 }
350
351                 public override void Emit (EmitContext ec)
352                 {
353                         ILGenerator ig = ec.ig;
354
355                         EmitLong (ig, Value);
356                 }
357
358                 static public void EmitLong (ILGenerator ig, long l)
359                 {
360                         ig.Emit (OpCodes.Ldc_I8, l);
361                 }
362
363                 public override string AsString ()
364                 {
365                         return Value.ToString ();
366                 }
367
368                 public override object GetValue ()
369                 {
370                         return Value;
371                 }
372         }
373
374         public class ULongConstant : Constant {
375                 public readonly ulong Value;
376
377                 public ULongConstant (ulong v)
378                 {
379                         type = TypeManager.uint64_type;
380                         Value = v;
381                 }
382
383                 public override void Emit (EmitContext ec)
384                 {
385                         ILGenerator ig = ec.ig;
386
387                         LongLiteral.EmitLong (ig, unchecked ((long) Value));
388                 }
389
390                 public override string AsString ()
391                 {
392                         return Value.ToString ();
393                 }
394
395                 public override object GetValue ()
396                 {
397                         return Value;
398                 }
399         }
400
401         public class FloatConstant : Constant {
402                 public readonly float Value;
403
404                 public FloatConstant (float v)
405                 {
406                         type = TypeManager.float_type;
407                         Value = v;
408                 }
409
410                 public override void Emit (EmitContext ec)
411                 {
412                         ec.ig.Emit (OpCodes.Ldc_R4, Value);
413                 }
414
415                 public override string AsString ()
416                 {
417                         return Value.ToString ();
418                 }
419
420                 public override object GetValue ()
421                 {
422                         return Value;
423                 }
424         }
425
426         public class DoubleConstant : Constant {
427                 public readonly double Value;
428
429                 public DoubleConstant (double v)
430                 {
431                         type = TypeManager.double_type;
432                         Value = v;
433                 }
434
435                 public override void Emit (EmitContext ec)
436                 {
437                         ec.ig.Emit (OpCodes.Ldc_R8, Value);
438                 }
439
440                 public override string AsString ()
441                 {
442                         return Value.ToString ();
443                 }
444
445                 public override object GetValue ()
446                 {
447                         return Value;
448                 }
449         }
450
451         public class DecimalConstant : Constant {
452                 public readonly decimal Value;
453
454                 public DecimalConstant (decimal d)
455                 {
456                         type = TypeManager.decimal_type;
457                         Value = d;
458                 }
459
460                 override public string AsString ()
461                 {
462                         return Value.ToString ();
463                 }
464
465                 public override object GetValue ()
466                 {
467                         return (object) Value;
468                 }
469
470                 public override void Emit (EmitContext ec)
471                 {
472                         throw new Exception ("Implement me");
473                 }
474         }
475
476         public class StringConstant : Constant {
477                 public readonly string Value;
478
479                 public StringConstant (string s)
480                 {
481                         type = TypeManager.string_type;
482                         Value = s;
483                 }
484
485                 // FIXME: Escape the string.
486                 override public string AsString ()
487                 {
488                         return "\"" + Value + "\"";
489                 }
490
491                 public override object GetValue ()
492                 {
493                         return Value;
494                 }
495                 
496                 public override void Emit (EmitContext ec)
497                 {
498                         ec.ig.Emit (OpCodes.Ldstr, Value);
499                 }
500         }
501
502 }
503
504