2001-09-07 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
61         public class NullLiteral : Literal {
62                 public NullLiteral ()
63                 {
64                 }
65                 
66                 override public string AsString ()
67                 {
68                         return "null";
69                 }
70
71                 public override Expression Resolve (TypeContainer tc)
72                 {
73                         eclass = ExprClass.Value;
74                         type = TypeManager.object_type;
75
76                         return this;
77                 }
78
79                 public override void Emit (EmitContext ec)
80                 {
81                         ec.ig.Emit (OpCodes.Ldnull);
82                 }
83         }
84
85         public class BoolLiteral : Literal {
86                 static Type bool_type = Type.GetType ("System.Bool");
87                 bool val;
88                 
89                 public BoolLiteral (bool val)
90                 {
91                         this.val = val;
92                 }
93
94                 override public string AsString ()
95                 {
96                         return val ? "true" : "false";
97                 }
98
99                 public override Expression Resolve (TypeContainer tc)
100                 {
101                         eclass = ExprClass.Value;
102                         type = bool_type;
103
104                         return this;
105                 }
106
107                 public override void Emit (EmitContext ec)
108                 {
109                         if (val)
110                                 ec.ig.Emit (OpCodes.Ldc_I4_1);
111                         else
112                                 ec.ig.Emit (OpCodes.Ldc_I4_0);
113                 }
114         }
115
116         public class CharLiteral : Literal {
117                 char c;
118                 
119                 public CharLiteral (char c)
120                 {
121                         this.c = c;
122                 }
123
124                 override public string AsString ()
125                 {
126                         return "\"" + descape (c) + "\"";
127                 }
128
129                 public override Expression Resolve (TypeContainer tc)
130                 {
131                         eclass = ExprClass.Value;
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                 int i;
145
146                 public IntLiteral (int l)
147                 {
148                         i = l;
149                 }
150
151                 override public string AsString ()
152                 {
153                         return i.ToString ();
154                 }
155
156                 public override Expression Resolve (TypeContainer tc)
157                 {
158                         eclass = ExprClass.Value;
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, i);
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 < 255)
216                                         ig.Emit (OpCodes.Ldc_I4_S, i);
217                                 else
218                                         ig.Emit (OpCodes.Ldc_I4, i);
219                                 break;
220                         }
221                 }
222         }
223
224         public class FloatLiteral : Literal {
225                 float f;
226
227                 public FloatLiteral (float f)
228                 {
229                         this.f = f;
230                 }
231
232                 override public string AsString ()
233                 {
234                         return f.ToString ();
235                 }
236
237                 public override Expression Resolve (TypeContainer tc)
238                 {
239                         eclass = ExprClass.Value;
240                         type = TypeManager.float_type;
241
242                         return this;
243                 }
244
245                 public override void Emit (EmitContext ec)
246                 {
247                         ec.ig.Emit (OpCodes.Ldc_R4, f);
248                 }
249         }
250
251         public class DoubleLiteral : Literal {
252                 double d;
253
254                 public DoubleLiteral (double d)
255                 {
256                         this.d = d;
257                 }
258
259                 override public string AsString ()
260                 {
261                         return d.ToString ();
262                 }
263
264                 public override Expression Resolve (TypeContainer tc)
265                 {
266                         eclass = ExprClass.Value;
267                         type = TypeManager.double_type;
268
269                         return this;
270                 }
271
272                 public override void Emit (EmitContext ec)
273                 {
274                         ec.ig.Emit (OpCodes.Ldc_R8, d);
275                 }
276         }
277
278         public class DecimalLiteral : Literal {
279                 decimal d;
280
281                 public DecimalLiteral (decimal d)
282                 {
283                         this.d = d;
284                 }
285
286                 override public string AsString ()
287                 {
288                         return d.ToString ();
289                 }
290
291                 public override Expression Resolve (TypeContainer tc)
292                 {
293                         eclass = ExprClass.Value;
294                         type = TypeManager.decimal_type;
295
296                         return this;
297                 }
298
299                 public override void Emit (EmitContext ec)
300                 {
301                 }
302         }
303
304         public class StringLiteral : Literal {
305                 string s;
306
307                 public StringLiteral (string s)
308                 {
309                         this.s = s;
310                 }
311
312                 // FIXME: Escape the string.
313                 override public string AsString ()
314                 {
315                         return "\"" + s + "\"";
316                 }
317
318                 public override Expression Resolve (TypeContainer tc)
319                 {
320                         eclass = ExprClass.Value;
321                         type = TypeManager.string_type;
322
323                         return this;
324                 }
325
326                 public override void Emit (EmitContext ec)
327                 {
328                         ec.ig.Emit (OpCodes.Ldstr, s);
329                 }
330         }
331 }