You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
333 lines
6.9 KiB
333 lines
6.9 KiB
// |
|
// literal.cs: Literal representation for the IL tree. |
|
// |
|
// Author: |
|
// Miguel de Icaza (miguel@ximian.com) |
|
// Marek Safar (marek.safar@seznam.cz) |
|
// |
|
// Copyright 2001 Ximian, Inc. |
|
// Copyright 2011 Xamarin 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. |
|
// |
|
|
|
#if STATIC |
|
using IKVM.Reflection.Emit; |
|
#else |
|
using System.Reflection.Emit; |
|
#endif |
|
|
|
namespace Mono.CSharp |
|
{ |
|
public interface ILiteralConstant |
|
{ |
|
#if FULL_AST |
|
char[] ParsedValue { get; set; } |
|
#endif |
|
} |
|
|
|
// |
|
// The null literal |
|
// |
|
// Note: C# specification null-literal is NullLiteral of NullType type |
|
// |
|
public class NullLiteral : NullConstant |
|
{ |
|
// |
|
// Default type of null is an object |
|
// |
|
public NullLiteral (Location loc) |
|
: base (InternalType.NullLiteral, loc) |
|
{ |
|
} |
|
|
|
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec t, bool expl) |
|
{ |
|
if (t.IsGenericParameter) { |
|
ec.Report.Error(403, loc, |
|
"Cannot convert null to the type parameter `{0}' because it could be a value " + |
|
"type. Consider using `default ({0})' instead", t.Name); |
|
return; |
|
} |
|
|
|
if (TypeSpec.IsValueType (t)) { |
|
ec.Report.Error(37, loc, "Cannot convert null to `{0}' because it is a value type", |
|
t.GetSignatureForError ()); |
|
return; |
|
} |
|
|
|
base.Error_ValueCannotBeConverted (ec, t, expl); |
|
} |
|
|
|
public override string GetValueAsLiteral () |
|
{ |
|
return "null"; |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx) |
|
{ |
|
return System.Linq.Expressions.Expression.Constant (null); |
|
} |
|
} |
|
|
|
public class BoolLiteral : BoolConstant, ILiteralConstant |
|
{ |
|
public BoolLiteral (BuiltinTypes types, bool val, Location loc) |
|
: base (types, val, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
#if FULL_AST |
|
public char[] ParsedValue { get; set; } |
|
#endif |
|
|
|
public override object Accept (StructuralVisitor visitor) |
|
{ |
|
return visitor.Visit (this); |
|
} |
|
} |
|
|
|
public class CharLiteral : CharConstant, ILiteralConstant |
|
{ |
|
public CharLiteral (BuiltinTypes types, char c, Location loc) |
|
: base (types, c, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
#if FULL_AST |
|
public char[] ParsedValue { get; set; } |
|
#endif |
|
|
|
public override object Accept (StructuralVisitor visitor) |
|
{ |
|
return visitor.Visit (this); |
|
} |
|
} |
|
|
|
public class IntLiteral : IntConstant, ILiteralConstant |
|
{ |
|
public IntLiteral (BuiltinTypes types, int l, Location loc) |
|
: base (types, l, loc) |
|
{ |
|
} |
|
|
|
public override Constant ConvertImplicitly (TypeSpec type) |
|
{ |
|
// |
|
// The 0 literal can be converted to an enum value |
|
// |
|
if (Value == 0 && type.IsEnum) { |
|
Constant c = ConvertImplicitly (EnumSpec.GetUnderlyingType (type)); |
|
if (c == null) |
|
return null; |
|
|
|
return new EnumConstant (c, type); |
|
} |
|
|
|
return base.ConvertImplicitly (type); |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
#if FULL_AST |
|
public char[] ParsedValue { get; set; } |
|
#endif |
|
|
|
public override object Accept (StructuralVisitor visitor) |
|
{ |
|
return visitor.Visit (this); |
|
} |
|
} |
|
|
|
public class UIntLiteral : UIntConstant, ILiteralConstant |
|
{ |
|
public UIntLiteral (BuiltinTypes types, uint l, Location loc) |
|
: base (types, l, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
#if FULL_AST |
|
public char[] ParsedValue { get; set; } |
|
#endif |
|
|
|
public override object Accept (StructuralVisitor visitor) |
|
{ |
|
return visitor.Visit (this); |
|
} |
|
} |
|
|
|
public class LongLiteral : LongConstant, ILiteralConstant |
|
{ |
|
public LongLiteral (BuiltinTypes types, long l, Location loc) |
|
: base (types, l, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
#if FULL_AST |
|
public char[] ParsedValue { get; set; } |
|
#endif |
|
|
|
public override object Accept (StructuralVisitor visitor) |
|
{ |
|
return visitor.Visit (this); |
|
} |
|
} |
|
|
|
public class ULongLiteral : ULongConstant, ILiteralConstant |
|
{ |
|
public ULongLiteral (BuiltinTypes types, ulong l, Location loc) |
|
: base (types, l, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
#if FULL_AST |
|
public char[] ParsedValue { get; set; } |
|
#endif |
|
|
|
public override object Accept (StructuralVisitor visitor) |
|
{ |
|
return visitor.Visit (this); |
|
} |
|
} |
|
|
|
public class FloatLiteral : FloatConstant, ILiteralConstant |
|
{ |
|
public FloatLiteral (BuiltinTypes types, float f, Location loc) |
|
: base (types, f, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
#if FULL_AST |
|
public char[] ParsedValue { get; set; } |
|
#endif |
|
|
|
public override object Accept (StructuralVisitor visitor) |
|
{ |
|
return visitor.Visit (this); |
|
} |
|
} |
|
|
|
public class DoubleLiteral : DoubleConstant, ILiteralConstant |
|
{ |
|
public DoubleLiteral (BuiltinTypes types, double d, Location loc) |
|
: base (types, d, loc) |
|
{ |
|
} |
|
|
|
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl) |
|
{ |
|
if (target.BuiltinType == BuiltinTypeSpec.Type.Float) { |
|
Error_664 (ec, loc, "float", "f"); |
|
return; |
|
} |
|
|
|
if (target.BuiltinType == BuiltinTypeSpec.Type.Decimal) { |
|
Error_664 (ec, loc, "decimal", "m"); |
|
return; |
|
} |
|
|
|
base.Error_ValueCannotBeConverted (ec, target, expl); |
|
} |
|
|
|
static void Error_664 (ResolveContext ec, Location loc, string type, string suffix) |
|
{ |
|
ec.Report.Error (664, loc, |
|
"Literal of type double cannot be implicitly converted to type `{0}'. Add suffix `{1}' to create a literal of this type", |
|
type, suffix); |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
#if FULL_AST |
|
public char[] ParsedValue { get; set; } |
|
#endif |
|
|
|
public override object Accept (StructuralVisitor visitor) |
|
{ |
|
return visitor.Visit (this); |
|
} |
|
} |
|
|
|
public class DecimalLiteral : DecimalConstant, ILiteralConstant |
|
{ |
|
public DecimalLiteral (BuiltinTypes types, decimal d, Location loc) |
|
: base (types, d, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
#if FULL_AST |
|
public char[] ParsedValue { get; set; } |
|
#endif |
|
|
|
public override object Accept (StructuralVisitor visitor) |
|
{ |
|
return visitor.Visit (this); |
|
} |
|
} |
|
|
|
public class StringLiteral : StringConstant, ILiteralConstant |
|
{ |
|
public StringLiteral (BuiltinTypes types, string s, Location loc) |
|
: base (types, s, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
#if FULL_AST |
|
public char[] ParsedValue { get; set; } |
|
#endif |
|
|
|
public override object Accept (StructuralVisitor visitor) |
|
{ |
|
return visitor.Visit (this); |
|
} |
|
} |
|
}
|
|
|