/// Base class for constants and literals.
/// </summary>
public abstract class Constant : Expression {
-
- protected Constant ()
- {
- eclass = ExprClass.Value;
- }
-
/// <remarks>
/// This is different from ToString in that ToString
/// is supposed to be there for debugging purposes,
DoubleConstant c = ConvertToDouble ();
if (c == null)
- Error_CannotConvertImplicit (loc, Type, TypeManager.double_type);
+ Convert.Error_CannotImplicitConversion (loc, Type, TypeManager.double_type);
return c;
}
FloatConstant c = ConvertToFloat ();
if (c == null)
- Error_CannotConvertImplicit (loc, Type, TypeManager.float_type);
+ Convert.Error_CannotImplicitConversion (loc, Type, TypeManager.float_type);
return c;
}
ULongConstant c = ConvertToULong ();
if (c == null)
- Error_CannotConvertImplicit (loc, Type, TypeManager.uint64_type);
+ Convert.Error_CannotImplicitConversion (loc, Type, TypeManager.uint64_type);
return c;
}
LongConstant c = ConvertToLong ();
if (c == null)
- Error_CannotConvertImplicit (loc, Type, TypeManager.int64_type);
+ Convert.Error_CannotImplicitConversion (loc, Type, TypeManager.int64_type);
return c;
}
UIntConstant c = ConvertToUInt ();
if (c == null)
- Error_CannotConvertImplicit (loc, Type, TypeManager.uint32_type);
+ Convert.Error_CannotImplicitConversion (loc, Type, TypeManager.uint32_type);
return c;
}
IntConstant c = ConvertToInt ();
if (c == null)
- Error_CannotConvertImplicit (loc, Type, TypeManager.int32_type);
+ Convert.Error_CannotImplicitConversion (loc, Type, TypeManager.int32_type);
+
+ return c;
+ }
+
+ public DecimalConstant ToDecimal (Location loc)
+ {
+ DecimalConstant c = ConvertToDecimal ();
+
+ if (c == null)
+ Convert.Error_CannotConvertType (loc, Type, TypeManager.decimal_type);
return c;
}
+
+ public virtual DecimalConstant ConvertToDecimal ()
+ {
+ return null;
+ }
public virtual DoubleConstant ConvertToDouble ()
{
{
return null;
}
+
+ public abstract bool IsDefaultValue {
+ get;
+ }
+
+ public abstract bool IsNegative {
+ get;
+ }
+
+ //
+ // Returns true iff 1) the stack type of this is one of Object,
+ // int32, int64 and 2) this == 0 or this == null.
+ //
+ public virtual bool IsZeroInteger {
+ get { return false; }
+ }
}
public class BoolConstant : Constant {
public BoolConstant (bool val)
{
type = TypeManager.bool_type;
+ eclass = ExprClass.Value;
Value = val;
}
else
ec.ig.Emit (OpCodes.Ldc_I4_0);
}
+
+ public override bool IsDefaultValue {
+ get {
+ return !Value;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return false;
+ }
+ }
+
+ public override bool IsZeroInteger {
+ get { return Value == false; }
+ }
}
public class ByteConstant : Constant {
public ByteConstant (byte v)
{
type = TypeManager.byte_type;
+ eclass = ExprClass.Value;
Value = v;
}
{
return new IntConstant (Value);
}
+
+ public override bool IsDefaultValue {
+ get {
+ return Value == 0;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return false;
+ }
+ }
+
+ public override bool IsZeroInteger {
+ get { return Value == 0; }
+ }
}
public class CharConstant : Constant {
public CharConstant (char v)
{
type = TypeManager.char_type;
+ eclass = ExprClass.Value;
Value = v;
}
{
return new IntConstant (Value);
}
+
+ public override bool IsDefaultValue {
+ get {
+ return Value == 0;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return false;
+ }
+ }
+
+ public override bool IsZeroInteger {
+ get { return Value == '\0'; }
+ }
}
public class SByteConstant : Constant {
public SByteConstant (sbyte v)
{
type = TypeManager.sbyte_type;
+ eclass = ExprClass.Value;
Value = v;
}
{
return new IntConstant (Value);
}
+
+ public override bool IsDefaultValue {
+ get {
+ return Value == 0;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return Value < 0;
+ }
+ }
+
+ public override bool IsZeroInteger {
+ get { return Value == 0; }
+ }
}
public class ShortConstant : Constant {
public ShortConstant (short v)
{
type = TypeManager.short_type;
+ eclass = ExprClass.Value;
Value = v;
}
{
return new IntConstant (Value);
}
+
+ public override bool IsDefaultValue {
+ get {
+ return Value == 0;
+ }
+ }
+
+ public override bool IsZeroInteger {
+ get { return Value == 0; }
+ }
+
+ public override bool IsNegative {
+ get {
+ return Value < 0;
+ }
+ }
}
public class UShortConstant : Constant {
public UShortConstant (ushort v)
{
type = TypeManager.ushort_type;
+ eclass = ExprClass.Value;
Value = v;
}
{
return new IntConstant (Value);
}
+
+ public override bool IsDefaultValue {
+ get {
+ return Value == 0;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return false;
+ }
+ }
+
+ public override bool IsZeroInteger {
+ get { return Value == 0; }
+ }
}
public class IntConstant : Constant {
public IntConstant (int v)
{
type = TypeManager.int32_type;
+ eclass = ExprClass.Value;
Value = v;
}
return Value;
}
+ public override DecimalConstant ConvertToDecimal()
+ {
+ return new DecimalConstant (Value);
+ }
+
public override DoubleConstant ConvertToDouble ()
{
return new DoubleConstant (Value);
{
return this;
}
+
+ public override bool IsDefaultValue {
+ get {
+ return Value == 0;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return Value < 0;
+ }
+ }
+
+ public override bool IsZeroInteger {
+ get { return Value == 0; }
+ }
}
public class UIntConstant : Constant {
public UIntConstant (uint v)
{
type = TypeManager.uint32_type;
+ eclass = ExprClass.Value;
Value = v;
}
{
return null;
}
+
+ public override bool IsDefaultValue {
+ get {
+ return Value == 0;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return false;
+ }
+ }
+
+ public override bool IsZeroInteger {
+ get { return Value == 0; }
+ }
}
public class LongConstant : Constant {
public LongConstant (long v)
{
type = TypeManager.int64_type;
+ eclass = ExprClass.Value;
Value = v;
}
static public void EmitLong (ILGenerator ig, long l)
{
- ig.Emit (OpCodes.Ldc_I8, l);
+ if ((l >> 32) == 0){
+ IntLiteral.EmitInt (ig, unchecked ((int) l));
+ ig.Emit (OpCodes.Conv_U8);
+ } else {
+ ig.Emit (OpCodes.Ldc_I8, l);
+ }
}
public override string AsString ()
{
return null;
}
+
+ public override bool IsDefaultValue {
+ get {
+ return Value == 0;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return Value < 0;
+ }
+ }
+
+ public override bool IsZeroInteger {
+ get { return Value == 0; }
+ }
}
public class ULongConstant : Constant {
public ULongConstant (ulong v)
{
type = TypeManager.uint64_type;
+ eclass = ExprClass.Value;
Value = v;
}
{
return null;
}
+
+ public override bool IsDefaultValue {
+ get {
+ return Value == 0;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return false;
+ }
+ }
+
+ public override bool IsZeroInteger {
+ get { return Value == 0; }
+ }
}
public class FloatConstant : Constant {
public FloatConstant (float v)
{
type = TypeManager.float_type;
+ eclass = ExprClass.Value;
Value = v;
}
{
return null;
}
+
+ public override bool IsDefaultValue {
+ get {
+ return Value == 0;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return Value < 0;
+ }
+ }
}
public class DoubleConstant : Constant {
public DoubleConstant (double v)
{
type = TypeManager.double_type;
+ eclass = ExprClass.Value;
Value = v;
}
{
return null;
}
+
+ public override bool IsDefaultValue {
+ get {
+ return Value == 0;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return Value < 0;
+ }
+ }
}
public class DecimalConstant : Constant {
public DecimalConstant (decimal d)
{
type = TypeManager.decimal_type;
+ eclass = ExprClass.Value;
Value = d;
}
public override void Emit (EmitContext ec)
{
- throw new Exception ("Implement me");
+ ILGenerator ig = ec.ig;
+
+ int [] words = Decimal.GetBits (Value);
+ int power = (words [3] >> 16) & 0xff;
+
+ if (power == 0 && Value <= int.MaxValue && Value >= int.MinValue)
+ {
+ IntConstant.EmitInt (ig, (int)Value);
+ ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_int_arg);
+ return;
+ }
+
+
+ //
+ // FIXME: we could optimize this, and call a better
+ // constructor
+ //
+
+ IntConstant.EmitInt (ig, words [0]);
+ IntConstant.EmitInt (ig, words [1]);
+ IntConstant.EmitInt (ig, words [2]);
+
+ // sign
+ IntConstant.EmitInt (ig, words [3] >> 31);
+
+ // power
+ IntConstant.EmitInt (ig, power);
+
+ ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
+ }
+
+ public override bool IsDefaultValue {
+ get {
+ return Value == 0;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return Value < 0;
+ }
}
}
public StringConstant (string s)
{
type = TypeManager.string_type;
+ eclass = ExprClass.Value;
Value = s;
}
public override void Emit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldstr, Value);
+ if (Value == null)
+ ec.ig.Emit (OpCodes.Ldnull);
+ else
+ ec.ig.Emit (OpCodes.Ldstr, Value);
+ }
+
+ public override bool IsDefaultValue {
+ get {
+ return Value == null;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return false;
+ }
}
}