2 // literal.cs: Literal representation for the IL tree.
5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) 2001 Ximian, Inc.
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.
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
31 // Represents the Null Type, just used as a placeholder for the type in NullLiteral
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 static readonly NullLiteral Null
;
54 Null
= new NullLiteral ();
59 eclass
= ExprClass
.Value
;
62 override public string AsString ()
67 public override object GetValue ()
72 public override Expression
DoResolve (EmitContext ec
)
74 type
= TypeManager
.null_type
;
78 public override void Emit (EmitContext ec
)
80 ec
.ig
.Emit (OpCodes
.Ldnull
);
83 public override bool IsNegative
{
89 public override bool IsZeroInteger
{
95 // A null literal in a pointer context
97 public class NullPointer
: NullLiteral
{
98 public new static readonly NullLiteral Null
;
100 static NullPointer ()
102 Null
= new NullPointer ();
105 private NullPointer ()
107 type
= TypeManager
.object_type
;
110 public override void Emit (EmitContext ec
)
112 ILGenerator ig
= ec
.ig
;
114 ig
.Emit (OpCodes
.Ldc_I4_0
);
115 ig
.Emit (OpCodes
.Conv_U
);
119 public class BoolLiteral
: BoolConstant
{
120 public BoolLiteral (bool val
) : base (val
)
124 public override Expression
DoResolve (EmitContext ec
)
126 type
= TypeManager
.bool_type
;
131 public class CharLiteral
: CharConstant
{
132 public CharLiteral (char c
) : base (c
)
136 public override Expression
DoResolve (EmitContext ec
)
138 type
= TypeManager
.char_type
;
143 public class IntLiteral
: IntConstant
{
144 public static IntLiteral One
, Zero
;
148 Zero
= new IntLiteral (0);
149 One
= new IntLiteral (1);
152 public IntLiteral (int l
) : base (l
)
156 public override Expression
DoResolve (EmitContext ec
)
158 type
= TypeManager
.int32_type
;
163 public class UIntLiteral
: UIntConstant
{
164 public UIntLiteral (uint l
) : base (l
)
168 public override Expression
DoResolve (EmitContext ec
)
170 type
= TypeManager
.uint32_type
;
175 public class LongLiteral
: LongConstant
{
176 public LongLiteral (long l
) : base (l
)
180 public override Expression
DoResolve (EmitContext ec
)
182 type
= TypeManager
.int64_type
;
188 public class ULongLiteral
: ULongConstant
{
189 public ULongLiteral (ulong l
) : base (l
)
193 public override Expression
DoResolve (EmitContext ec
)
195 type
= TypeManager
.uint64_type
;
200 public class FloatLiteral
: FloatConstant
{
202 public FloatLiteral (float f
) : base (f
)
206 public override Expression
DoResolve (EmitContext ec
)
208 type
= TypeManager
.float_type
;
213 public class DoubleLiteral
: DoubleConstant
{
214 public DoubleLiteral (double d
) : base (d
)
218 public override Expression
DoResolve (EmitContext ec
)
220 type
= TypeManager
.double_type
;
226 public class DecimalLiteral
: DecimalConstant
{
227 public DecimalLiteral (decimal d
) : base (d
)
231 public override Expression
DoResolve (EmitContext ec
)
233 type
= TypeManager
.decimal_type
;
238 public class StringLiteral
: StringConstant
{
239 public StringLiteral (string s
) : base (s
)
243 public override Expression
DoResolve (EmitContext ec
)
245 type
= TypeManager
.string_type
;