2006-04-27 Jonathan Chambers <jonathan.chambers@ansys.com>
[mcs.git] / gmcs / literal.cs
bloba5668dbeb5c2e38e2dda7e0135c3cff7bee99e0e
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 // Notice that during parsing we create objects of type Literal, but the
11 // types are not loaded (thats why the Resolve method has to assign the
12 // type at that point).
14 // Literals differ from the constants in that we know we encountered them
15 // as a literal in the source code (and some extra rules apply there) and
16 // they have to be resolved (since during parsing we have not loaded the
17 // types yet) while constants are created only after types have been loaded
18 // and are fully resolved when born.
21 using System;
22 using System.Reflection;
23 using System.Reflection.Emit;
26 // I put System.Null just so we do not have to special case it on
27 // TypeManager.CSharpName
29 namespace System {
31 // Represents the Null Type, just used as a placeholder for the type in NullLiteral
33 public class Null {
37 namespace Mono.CSharp {
40 // The NullType just exists to compare type equality, and for
41 // expressions that might have the `null type'
43 public class NullType {
47 // The null Literal constant
49 public class NullLiteral : Constant {
50 public NullLiteral (Location loc):
51 base (loc)
53 eclass = ExprClass.Value;
56 override public string AsString ()
58 return "null";
61 public override object GetValue ()
63 return null;
66 public override Expression DoResolve (EmitContext ec)
68 type = TypeManager.null_type;
69 return this;
72 public override void Emit (EmitContext ec)
74 ec.ig.Emit (OpCodes.Ldnull);
77 public override Constant Increment ()
79 throw new NotSupportedException ();
82 public override bool IsDefaultValue {
83 get {
84 return true;
88 public override bool IsNegative {
89 get {
90 return false;
94 public override bool IsZeroInteger {
95 get { return true; }
98 public override string GetSignatureForError()
100 return "null";
103 public override void Error_ValueCannotBeConverted (Location loc, Type t, bool expl)
105 Report.Error (37, loc, "Cannot convert null to `{0}' because it is a value type",
106 TypeManager.CSharpName (t));
109 public override Constant ToType (Type type, Location loc)
111 if (!type.IsValueType && !TypeManager.IsEnumType (type))
112 return this;
114 return base.ToType (type, loc);
117 public override Constant Reduce(bool inCheckedContext, Type target_type)
119 if (!TypeManager.IsValueType (target_type))
120 return new NullCast (this, target_type);
122 return null;
127 // A null literal in a pointer context
129 public class NullPointer : NullLiteral {
130 public static readonly NullLiteral Null;
132 static NullPointer ()
134 Null = new NullPointer ();
137 private NullPointer ():
138 base (Location.Null)
140 type = TypeManager.object_type;
143 public override void Emit (EmitContext ec)
145 ILGenerator ig = ec.ig;
147 ig.Emit (OpCodes.Ldc_I4_0);
148 ig.Emit (OpCodes.Conv_U);
152 public class BoolLiteral : BoolConstant {
153 public BoolLiteral (bool val, Location loc) : base (val, loc)
157 public override Expression DoResolve (EmitContext ec)
159 type = TypeManager.bool_type;
160 return this;
164 public class CharLiteral : CharConstant {
165 public CharLiteral (char c, Location loc) : base (c, loc)
169 public override Expression DoResolve (EmitContext ec)
171 type = TypeManager.char_type;
172 return this;
176 public class IntLiteral : IntConstant {
177 public IntLiteral (int l, Location loc) : base (l, loc)
181 public override Expression DoResolve (EmitContext ec)
183 type = TypeManager.int32_type;
184 return this;
188 public class UIntLiteral : UIntConstant {
189 public UIntLiteral (uint l, Location loc) : base (l, loc)
193 public override Expression DoResolve (EmitContext ec)
195 type = TypeManager.uint32_type;
196 return this;
200 public class LongLiteral : LongConstant {
201 public LongLiteral (long l, Location loc) : base (l, loc)
205 public override Expression DoResolve (EmitContext ec)
207 type = TypeManager.int64_type;
209 return this;
213 public class ULongLiteral : ULongConstant {
214 public ULongLiteral (ulong l, Location loc) : base (l, loc)
218 public override Expression DoResolve (EmitContext ec)
220 type = TypeManager.uint64_type;
221 return this;
225 public class FloatLiteral : FloatConstant {
227 public FloatLiteral (float f, Location loc) : base (f, loc)
231 public override Expression DoResolve (EmitContext ec)
233 type = TypeManager.float_type;
234 return this;
238 public class DoubleLiteral : DoubleConstant {
239 public DoubleLiteral (double d, Location loc) : base (d, loc)
243 public override Expression DoResolve (EmitContext ec)
245 type = TypeManager.double_type;
247 return this;
250 public override void Error_ValueCannotBeConverted (Location loc, Type target, bool expl)
252 if (target == TypeManager.float_type) {
253 Error_664 (loc, "float", "f");
254 return;
257 if (target == TypeManager.decimal_type) {
258 Error_664 (loc, "decimal", "m");
259 return;
262 base.Error_ValueCannotBeConverted (loc, target, expl);
265 static void Error_664 (Location loc, string type, string suffix)
267 Report.Error (664, loc,
268 "Literal of type double cannot be implicitly converted to type `{0}'. Add suffix `{1}' to create a literal of this type",
269 type, suffix);
273 public class DecimalLiteral : DecimalConstant {
274 public DecimalLiteral (decimal d, Location loc) : base (d, loc)
278 public override Expression DoResolve (EmitContext ec)
280 type = TypeManager.decimal_type;
281 return this;
285 public class StringLiteral : StringConstant {
286 public StringLiteral (string s, Location loc) : base (s, loc)
290 public override Expression DoResolve (EmitContext ec)
292 type = TypeManager.string_type;
294 return this;