//
// (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;
+//
+// 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 {
- /// <summary>
- /// Base class for literals
- /// </summary>
- public abstract class Literal : Expression {
- /// <remarks>
- /// This is different from ToString in that ToString
- /// is supposed to be there for debugging purposes,
- /// and is not guaranteed 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.
- /// </remarks>
- public abstract string AsString ();
-
- override public string ToString ()
- {
- return AsString ();
- }
-
- /// <summary>
- /// This is used to obtain the actual value of the literal
- /// cast into an object.
- /// </summary>
- public abstract object GetValue ();
-
- 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 ();
- }
-
- 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 static readonly NullLiteral Null;
-
- static NullLiteral ()
- {
- Null = new NullLiteral ();
- }
-
- public NullLiteral ()
+ //
+ // The null Literal constant
+ //
+ public class NullLiteral : Constant {
+ public NullLiteral (Location loc):
+ base (loc)
{
- if (Null != null)
- throw new Exception ("More than one null has been created!");
+ eclass = ExprClass.Value;
}
override public string AsString ()
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 {
- public readonly bool Value;
-
- public BoolLiteral (bool val)
+ public override Constant Increment ()
{
- Value = val;
+ throw new NotSupportedException ();
}
- override public string AsString ()
- {
- return Value ? "true" : "false";
+ public override bool IsDefaultValue {
+ get {
+ return true;
+ }
}
- public override object GetValue ()
- {
- return (object) Value;
+ public override bool IsNegative {
+ get {
+ return false;
+ }
}
-
-
- public override Expression DoResolve (EmitContext ec)
- {
- type = TypeManager.bool_type;
- return this;
+ public override bool IsZeroInteger {
+ get { return true; }
}
- public override void Emit (EmitContext ec)
+ public override string GetSignatureForError()
{
- if (Value)
- ec.ig.Emit (OpCodes.Ldc_I4_1);
- else
- ec.ig.Emit (OpCodes.Ldc_I4_0);
+ return "null";
}
- }
- public class CharLiteral : Literal {
- char c;
-
- public CharLiteral (char c)
+ public override void Error_ValueCannotBeConverted (Location loc, Type t, bool expl)
{
- this.c = c;
+ Report.Error (37, loc, "Cannot convert null to `{0}' because it is a value type",
+ TypeManager.CSharpName (t));
}
- override public string AsString ()
+ public override Constant ToType (Type type, Location loc)
{
- return "\"" + descape (c) + "\"";
- }
+ if (!type.IsValueType && !TypeManager.IsEnumType (type))
+ return this;
- public override object GetValue ()
- {
- return (object) c;
+ return base.ToType (type, loc);
}
-
- public override Expression DoResolve (EmitContext ec)
- {
- type = TypeManager.char_type;
- return this;
- }
+ }
- public override void Emit (EmitContext ec)
+ //
+ // A null literal in a pointer context
+ //
+ public class NullPointer : NullLiteral {
+ public static readonly NullLiteral Null;
+
+ static NullPointer ()
{
- IntLiteral.EmitInt (ec.ig, c);
+ Null = new NullPointer ();
}
- }
- public class IntLiteral : Literal {
- public readonly int Value;
-
- public IntLiteral (int l)
+ private NullPointer ():
+ base (Location.Null)
{
- Value = l;
+ type = TypeManager.object_type;
}
- override public string AsString ()
+ public override void Emit (EmitContext ec)
{
- return Value.ToString ();
+ ILGenerator ig = ec.ig;
+
+ ig.Emit (OpCodes.Ldc_I4_0);
+ ig.Emit (OpCodes.Conv_U);
}
+ }
- public override object GetValue ()
+ public class BoolLiteral : BoolConstant {
+ public BoolLiteral (bool val, Location loc) : base (val, loc)
{
- if (Value <= System.Int32.MaxValue &&
- Value >= System.Int32.MinValue)
- return (object) Value;
- else
- return null;
}
public override Expression DoResolve (EmitContext ec)
{
- type = TypeManager.int32_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;
-
- EmitInt (ig, Value);
}
- static public void EmitInt (ILGenerator ig, int i)
+ public override Expression DoResolve (EmitContext ec)
{
- 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;
- }
+ type = TypeManager.char_type;
+ return this;
}
}
- public class UIntLiteral : Literal {
- public readonly uint Value;
-
- public UIntLiteral (uint l)
+ public class IntLiteral : IntConstant {
+ public IntLiteral (int l, Location loc) : base (l, loc)
{
- Value = l;
}
- override public string AsString ()
+ public override Expression DoResolve (EmitContext ec)
{
- return Value.ToString ();
+ type = TypeManager.int32_type;
+ return this;
}
+ }
- public override object GetValue ()
+ public class UIntLiteral : UIntConstant {
+ public UIntLiteral (uint l, Location loc) : base (l, loc)
{
- if (Value <= System.UInt32.MaxValue &&
- Value >= System.UInt32.MinValue)
- return (object) Value;
- else
- return null;
-
}
-
+
public override Expression DoResolve (EmitContext ec)
{
type = TypeManager.uint32_type;
-
return this;
}
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- IntLiteral.EmitInt (ig, unchecked ((int) Value));
- }
-
}
- public class LongLiteral : Literal {
- public readonly long Value;
-
- public LongLiteral (long l)
+ public class LongLiteral : LongConstant {
+ public LongLiteral (long l, Location loc) : base (l, loc)
{
- Value = l;
}
- override public string AsString ()
- {
- return Value.ToString ();
- }
-
- public override object GetValue ()
- {
- if (Value <= System.Int64.MaxValue &&
- Value >= System.Int64.MinValue)
- return (object) Value;
- else
- return null;
- }
-
public override Expression DoResolve (EmitContext ec)
{
type = TypeManager.int64_type;
return this;
}
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- EmitLong (ig, Value);
- }
-
- static public void EmitLong (ILGenerator ig, long l)
- {
- ig.Emit (OpCodes.Ldc_I8, l);
- }
}
- public class ULongLiteral : Literal {
- public readonly ulong Value;
-
- public ULongLiteral (ulong l)
+ public class ULongLiteral : ULongConstant {
+ public ULongLiteral (ulong l, Location loc) : base (l, loc)
{
- Value = l;
- }
-
- override public string AsString ()
- {
- return Value.ToString ();
- }
-
- public override object GetValue ()
- {
- if (Value <= System.UInt64.MaxValue &&
- Value >= System.UInt64.MinValue)
- return (object) Value;
- else
- return null;
}
public override Expression DoResolve (EmitContext ec)
{
type = TypeManager.uint64_type;
-
return this;
}
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- LongLiteral.EmitLong (ig, unchecked ((long) Value));
- }
}
- public class FloatLiteral : Literal {
- public readonly float Value;
-
- public FloatLiteral (float f)
- {
- Value = f;
- }
-
- override public string AsString ()
+ public class FloatLiteral : FloatConstant {
+
+ public FloatLiteral (float f, Location loc) : base (f, loc)
{
- return Value.ToString ();
}
- public override object GetValue ()
- {
- return (object) Value;
- }
-
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)
- {
- Value = d;
- }
-
- override public string AsString ()
+ public class DoubleLiteral : DoubleConstant {
+ public DoubleLiteral (double d, Location loc) : base (d, loc)
{
- return Value.ToString ();
}
- public override object GetValue ()
- {
- return (object) Value;
- }
-
public override Expression DoResolve (EmitContext ec)
{
type = TypeManager.double_type;
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 object GetValue ()
- {
- return (object) Value;
}
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 {
- public readonly string Value;
-
- public StringLiteral (string s)
+ public class StringLiteral : StringConstant {
+ public StringLiteral (string s, Location loc) : base (s, loc)
{
- Value = s;
}
- // FIXME: Escape the string.
- override public string AsString ()
- {
- return "\"" + Value + "\"";
- }
-
- public override object GetValue ()
- {
- return (object) Value;
- }
-
public override Expression DoResolve (EmitContext ec)
{
type = TypeManager.string_type;
return this;
}
-
- public override void Emit (EmitContext ec)
- {
- ec.ig.Emit (OpCodes.Ldstr, Value);
- }
}
}