//
// (C) 2001 Ximian, Inc.
//
+//
+// Notice that during parsing we create objects of type Literal, but the
+// types are not loaded (thats why the Resolve method has to assign the
+// type at that point).
+//
+// Literals differ from the constants in that we know we encountered them
+// as a literal in the source code (and some extra rules apply there) and
+// they have to be resolved (since during parsing we have not loaded the
+// types yet) while constants are created only after types have been loaded
+// and are fully resolved when born.
+//
using System;
using System.Reflection;
using System.Reflection.Emit;
-namespace CIR {
- public abstract class Literal : Expression {
- // <summary>
- // This is different from ToString in that ToString
- // is supposed to be there for debugging purposes,
- // and is not guarantee to be useful for anything else,
- // AsString() will provide something that can be used
- // for round-tripping C# code. Maybe it can be used
- // for IL assembly as well.
- // </summary>
- public abstract string AsString ();
-
- override public string ToString ()
- {
- return AsString ();
- }
-
- static public string descape (char c)
- {
- switch (c){
- case '\a':
- return "\\a";
- case '\b':
- return "\\b";
- case '\n':
- return "\\n";
- case '\t':
- return "\\t";
- case '\v':
- return "\\v";
- case '\r':
- return "\\r";
- case '\\':
- return "\\\\";
- case '\f':
- return "\\f";
- case '\0':
- return "\\0";
- case '"':
- return "\\\"";
- case '\'':
- return "\\\'";
- }
- return c.ToString ();
- }
+//
+// I put System.Null just so we do not have to special case it on
+// TypeManager.CSharpName
+//
+namespace System {
+ //
+ // Represents the Null Type, just used as a placeholder for the type in NullLiteral
+ //
+ public class Null {
+ }
+}
+
+namespace Mono.CSharp {
- protected Literal ()
- {
- eclass = ExprClass.Value;
- }
+ //
+ // The NullType just exists to compare type equality, and for
+ // expressions that might have the `null type'
+ //
+ public class NullType {
}
- public class NullLiteral : Literal {
- public NullLiteral ()
+ //
+ // The null Literal constant
+ //
+ public class NullLiteral : Constant {
+ public NullLiteral (Location loc):
+ base (loc)
{
+ eclass = ExprClass.Value;
}
override public string AsString ()
return "null";
}
+ public override object GetValue ()
+ {
+ return null;
+ }
+
public override Expression DoResolve (EmitContext ec)
{
- type = TypeManager.object_type;
- eclass = ExprClass.Value;
+ type = TypeManager.null_type;
return this;
}
{
ec.ig.Emit (OpCodes.Ldnull);
}
- }
- public class BoolLiteral : Literal {
- bool val;
-
- public BoolLiteral (bool val)
+ public override Constant Increment ()
{
- this.val = val;
+ throw new NotSupportedException ();
}
- override public string AsString ()
- {
- return val ? "true" : "false";
+ public override bool IsDefaultValue {
+ get {
+ return true;
+ }
}
- public override Expression DoResolve (EmitContext ec)
- {
- type = TypeManager.bool_type;
-
- return this;
+ public override bool IsNegative {
+ get {
+ return false;
+ }
}
- public override void Emit (EmitContext ec)
- {
- if (val)
- ec.ig.Emit (OpCodes.Ldc_I4_1);
- else
- ec.ig.Emit (OpCodes.Ldc_I4_0);
+ public override bool IsZeroInteger {
+ get { return true; }
}
- }
- public class CharLiteral : Literal {
- char c;
-
- public CharLiteral (char c)
+ public override string GetSignatureForError()
{
- this.c = c;
+ return "null";
}
- override public string AsString ()
+ public override void Error_ValueCannotBeConverted (Location loc, Type t, bool expl)
{
- return "\"" + descape (c) + "\"";
+ Report.Error (37, loc, "Cannot convert null to `{0}' because it is a value type",
+ TypeManager.CSharpName (t));
}
- public override Expression DoResolve (EmitContext ec)
+ public override Constant ToType (Type type, Location loc)
{
- type = TypeManager.char_type;
+ if (!type.IsValueType && !TypeManager.IsEnumType (type))
+ return this;
- return this;
+ return base.ToType (type, loc);
}
- public override void Emit (EmitContext ec)
- {
- IntLiteral.EmitInt (ec.ig, c);
- }
}
- public class IntLiteral : Literal {
- public readonly int Value;
-
- public IntLiteral (int l)
- {
- Value = l;
- }
+ //
+ // A null literal in a pointer context
+ //
+ public class NullPointer : NullLiteral {
+ public static readonly NullLiteral Null;
- override public string AsString ()
+ static NullPointer ()
{
- return Value.ToString ();
+ Null = new NullPointer ();
}
- public override Expression DoResolve (EmitContext ec)
+ private NullPointer ():
+ base (Location.Null)
{
- type = TypeManager.int32_type;
-
- return this;
+ type = TypeManager.object_type;
}
public override void Emit (EmitContext ec)
{
ILGenerator ig = ec.ig;
-
- EmitInt (ig, Value);
- }
-
- static public void EmitInt (ILGenerator ig, int i)
- {
- switch (i){
- case -1:
- ig.Emit (OpCodes.Ldc_I4_M1);
- break;
-
- case 0:
- ig.Emit (OpCodes.Ldc_I4_0);
- break;
-
- case 1:
- ig.Emit (OpCodes.Ldc_I4_1);
- break;
- case 2:
- ig.Emit (OpCodes.Ldc_I4_2);
- break;
-
- case 3:
- ig.Emit (OpCodes.Ldc_I4_3);
- break;
-
- case 4:
- ig.Emit (OpCodes.Ldc_I4_4);
- break;
-
- case 5:
- ig.Emit (OpCodes.Ldc_I4_5);
- break;
-
- case 6:
- ig.Emit (OpCodes.Ldc_I4_6);
- break;
-
- case 7:
- ig.Emit (OpCodes.Ldc_I4_7);
- break;
-
- case 8:
- ig.Emit (OpCodes.Ldc_I4_8);
- break;
-
- default:
- if (i > 0 && i < 127){
- ig.Emit (OpCodes.Ldc_I4_S, (sbyte) i);
- } else
- ig.Emit (OpCodes.Ldc_I4, i);
- break;
- }
+ ig.Emit (OpCodes.Ldc_I4_0);
+ ig.Emit (OpCodes.Conv_U);
}
}
- public class UIntLiteral : Literal {
- public readonly uint Value;
-
- public UIntLiteral (uint l)
- {
- Value = l;
- }
-
- override public string AsString ()
+ public class BoolLiteral : BoolConstant {
+ public BoolLiteral (bool val, Location loc) : base (val, loc)
{
- return Value.ToString ();
}
public override Expression DoResolve (EmitContext ec)
{
- type = TypeManager.uint32_type;
-
+ type = TypeManager.bool_type;
return this;
}
+ }
- public override void Emit (EmitContext ec)
+ public class CharLiteral : CharConstant {
+ public CharLiteral (char c, Location loc) : base (c, loc)
{
- ILGenerator ig = ec.ig;
-
- IntLiteral.EmitInt (ig, unchecked ((int) Value));
}
- }
-
- public class LongLiteral : Literal {
- public readonly long Value;
-
- public LongLiteral (long l)
+ public override Expression DoResolve (EmitContext ec)
{
- Value = l;
+ type = TypeManager.char_type;
+ return this;
}
+ }
- override public string AsString ()
+ public class IntLiteral : IntConstant {
+ public IntLiteral (int l, Location loc) : base (l, loc)
{
- return Value.ToString ();
}
public override Expression DoResolve (EmitContext ec)
{
- type = TypeManager.int64_type;
-
+ type = TypeManager.int32_type;
return this;
}
+ }
- public override void Emit (EmitContext ec)
+ public class UIntLiteral : UIntConstant {
+ public UIntLiteral (uint l, Location loc) : base (l, loc)
{
- ILGenerator ig = ec.ig;
-
- EmitLong (ig, Value);
}
- static public void EmitLong (ILGenerator ig, long l)
+ public override Expression DoResolve (EmitContext ec)
{
- ig.Emit (OpCodes.Ldc_I8, l);
+ type = TypeManager.uint32_type;
+ return this;
}
}
-
- public class ULongLiteral : Literal {
- public readonly ulong Value;
-
- public ULongLiteral (ulong l)
- {
- Value = l;
- }
-
- override public string AsString ()
+
+ public class LongLiteral : LongConstant {
+ public LongLiteral (long l, Location loc) : base (l, loc)
{
- return Value.ToString ();
}
public override Expression DoResolve (EmitContext ec)
{
- type = TypeManager.uint64_type;
+ type = TypeManager.int64_type;
return this;
}
+ }
- public override void Emit (EmitContext ec)
+ public class ULongLiteral : ULongConstant {
+ public ULongLiteral (ulong l, Location loc) : base (l, loc)
{
- ILGenerator ig = ec.ig;
-
- LongLiteral.EmitLong (ig, unchecked ((long) Value));
}
- }
-
- public class FloatLiteral : Literal {
- public readonly float Value;
- public FloatLiteral (float f)
+ public override Expression DoResolve (EmitContext ec)
{
- Value = f;
+ type = TypeManager.uint64_type;
+ return this;
}
-
- override public string AsString ()
+ }
+
+ public class FloatLiteral : FloatConstant {
+
+ public FloatLiteral (float f, Location loc) : base (f, loc)
{
- return Value.ToString ();
}
public override Expression DoResolve (EmitContext ec)
{
type = TypeManager.float_type;
-
return this;
}
-
- public override void Emit (EmitContext ec)
- {
- ec.ig.Emit (OpCodes.Ldc_R4, Value);
- }
}
- public class DoubleLiteral : Literal {
- public readonly double Value;
-
- public DoubleLiteral (double d)
+ public class DoubleLiteral : DoubleConstant {
+ public DoubleLiteral (double d, Location loc) : base (d, loc)
{
- Value = d;
- }
-
- override public string AsString ()
- {
- return Value.ToString ();
}
public override Expression DoResolve (EmitContext ec)
return this;
}
-
- public override void Emit (EmitContext ec)
- {
- ec.ig.Emit (OpCodes.Ldc_R8, Value);
- }
}
- public class DecimalLiteral : Literal {
- public readonly decimal Value;
-
- public DecimalLiteral (decimal d)
+ public class DecimalLiteral : DecimalConstant {
+ public DecimalLiteral (decimal d, Location loc) : base (d, loc)
{
- Value = d;
- }
-
- override public string AsString ()
- {
- return Value.ToString ();
}
public override Expression DoResolve (EmitContext ec)
{
type = TypeManager.decimal_type;
-
return this;
}
-
- public override void Emit (EmitContext ec)
- {
- throw new Exception ("Implement me");
- }
}
- public class StringLiteral : Literal {
- string s;
-
- public StringLiteral (string s)
- {
- this.s = s;
- }
-
- // FIXME: Escape the string.
- override public string AsString ()
+ public class StringLiteral : StringConstant {
+ public StringLiteral (string s, Location loc) : base (s, loc)
{
- return "\"" + s + "\"";
}
public override Expression DoResolve (EmitContext ec)
return this;
}
-
- public override void Emit (EmitContext ec)
- {
- ec.ig.Emit (OpCodes.Ldstr, s);
- }
}
}