//
// Author:
// Miguel de Icaza (miguel@ximian.com)
+// Manjula GHM (mmanjula@novell.com)
//
// (C) 2001 Ximian, Inc.
//
return new CharConstant ((char)v);
else if (t == TypeManager.bool_type)
return new BoolConstant ((bool) v);
+ else if (t == TypeManager.decimal_type)
+ return new DecimalConstant ((decimal)v);
else if (TypeManager.IsEnumType (t)){
- Constant e = Constantify (v, TypeManager.TypeToCoreType (v.GetType ()));
+ Constant e = Constantify (v, TypeManager.EnumToUnderlying (v.GetType ()));
return new EnumConstant (e, t);
} else
int count = mi.Length;
- if (count > 1)
- return new MethodGroupExpr (mi, loc);
-
if (mi [0] is MethodBase)
return new MethodGroupExpr (mi, loc);
+ if (mi [0] is PropertyInfo)
+ return new PropertyGroupExpr (mi, loc);
+
+ if (count > 1)
+ return null;
+
return ExprClassFromMemberInfo (ec, mi [0], loc);
}
//
// Attempt to do the implicit constant expression conversions
- if (expr is IntConstant){
+ if (expr is BoolConstant || expr is IntConstant || expr is LongConstant || expr is DoubleConstant || expr is FloatConstant){
Expression e;
- e = TryImplicitIntConversion (target_type, (IntConstant) expr);
+ e = TryImplicitNumericConversion (target_type, (Constant) expr);
if (e != null)
return e;
- } else if (expr is LongConstant && target_type == TypeManager.uint64_type){
+ if (target_type == TypeManager.byte_type ||
+ target_type == TypeManager.short_type ||
+ target_type == TypeManager.int32_type ||
+ target_type == TypeManager.int64_type ||
+ target_type == TypeManager.float_type) {
+
+ string val = null;
+ if (expr is IntConstant)
+ val = ((IntConstant) expr).Value.ToString();
+ if (expr is LongConstant)
+ val = ((LongConstant) expr).Value.ToString();
+ if (expr is FloatConstant)
+ val = ((FloatConstant) expr).Value.ToString();
+ if (expr is DoubleConstant)
+ val = ((DoubleConstant) expr).Value.ToString();
+ Error_ConstantValueCannotBeConverted(loc, val, target_type);
+ return null;
+ }
+ } else if (expr is LongConstant && target_type == TypeManager.uint64_type) {
//
// Try the implicit constant expression conversion
// from long to ulong, instead of a nice routine,
}
if ((expr_type != TypeManager.char_type) &&
- (expr_type != TypeManager.string_type))
+ (expr_type != TypeManager.string_type) &&
+ (expr_type != TypeManager.object_type))
return new NumericToBoolCast (expr, expr.Type);
}
if (real_target_type == TypeManager.float_type)
return new OpcodeCast (expr, target_type, OpCodes.Conv_R_Un,
OpCodes.Conv_R4);
- } else if (expr_type == TypeManager.char_type){
- //
- // From char to ushort, int, uint, long, ulong, float, double
- //
- if ((real_target_type == TypeManager.ushort_type) ||
- (real_target_type == TypeManager.int32_type) ||
- (real_target_type == TypeManager.uint32_type))
- return new EmptyCast (expr, target_type);
- if (real_target_type == TypeManager.uint64_type)
- return new OpcodeCast (expr, target_type, OpCodes.Conv_U8);
- if (real_target_type == TypeManager.int64_type)
- return new OpcodeCast (expr, target_type, OpCodes.Conv_I8);
- if (real_target_type == TypeManager.float_type)
- return new OpcodeCast (expr, target_type, OpCodes.Conv_R4);
- if (real_target_type == TypeManager.double_type)
- return new OpcodeCast (expr, target_type, OpCodes.Conv_R8);
} else if (expr_type == TypeManager.string_type){
if (real_target_type == TypeManager.bool_type)
return RTConversionExpression(ec, "System.Convert", ".ToSingle", expr, loc);
if (real_target_type == TypeManager.double_type)
return RTConversionExpression(ec, "System.Convert", ".ToDouble", expr, loc);
- if (real_target_type == TypeManager.char_type)
- return RTConversionExpression(ec, "System.Convert", ".ToChar", expr, loc);
}
return null;
(target_type == TypeManager.decimal_type))
return true;
- } else if (expr_type == TypeManager.char_type){
- //
- // From char to ushort, int, uint, long, ulong, float, double
- //
- if ((target_type == TypeManager.ushort_type) ||
- (target_type == TypeManager.int32_type) ||
- (target_type == TypeManager.uint32_type) ||
- (target_type == TypeManager.uint64_type) ||
- (target_type == TypeManager.int64_type) ||
- (target_type == TypeManager.float_type) ||
- (target_type == TypeManager.double_type) ||
- (target_type == TypeManager.string_type) ||
- (target_type == TypeManager.decimal_type))
+ } else if (expr_type == TypeManager.decimal_type) {
+ if (target_type == TypeManager.float_type ||
+ target_type == TypeManager.double_type)
return true;
-
} else if (expr_type == TypeManager.float_type){
//
// float to double, decimal
if (ImplicitReferenceConversionExists (expr, expr_type, target_type))
return true;
+/*
if (expr is IntConstant){
int value = ((IntConstant) expr).Value;
if (v > 0)
return true;
}
+*/
if (target_type.IsSubclassOf (TypeManager.enum_type) && expr is IntLiteral){
IntLiteral i = (IntLiteral) expr;
if (e != null)
return e;
-
+
e = NarrowingConversion (ec, expr, target_type, loc);
if (e != null)
return e;
static public bool NarrowingConversionExists (EmitContext ec, Expression expr, Type target_type)
{
Type expr_type = expr.Type;
+ if (expr_type.IsSubclassOf (TypeManager.enum_type))
+ expr_type = TypeManager.EnumToUnderlying (expr_type);
+
+ if (target_type.IsSubclassOf (TypeManager.enum_type))
+ target_type = TypeManager.EnumToUnderlying (target_type);
+
+
+ if (expr_type == target_type)
+ return true;
if (target_type == TypeManager.sbyte_type){
//
(expr_type == TypeManager.decimal_type))
return true;
- } else if (target_type == TypeManager.char_type){
- //
- // To char from ushort, int, uint, long, ulong, float, double, decimal,string
- //
- if ((expr_type == TypeManager.ushort_type) ||
- (expr_type == TypeManager.int32_type) ||
- (expr_type == TypeManager.uint32_type) ||
- (expr_type == TypeManager.uint64_type) ||
- (expr_type == TypeManager.int64_type) ||
- (expr_type == TypeManager.float_type) ||
- (expr_type == TypeManager.double_type) ||
- (expr_type == TypeManager.decimal_type) ||
- (expr_type == TypeManager.string_type))
-
+ } else if (target_type == TypeManager.decimal_type){
+ if (expr_type == TypeManager.float_type ||
+ expr_type == TypeManager.double_type)
return true;
-
} else if (target_type == TypeManager.float_type){
//
// To float from double
{
Type expr_type = expr.Type;
+ if (expr_type.IsSubclassOf (TypeManager.enum_type))
+ expr_type = TypeManager.EnumToUnderlying (expr_type);
+
+ if (target_type.IsSubclassOf (TypeManager.enum_type))
+ target_type = TypeManager.EnumToUnderlying (target_type);
+
+ if (expr_type == target_type)
+ return expr;
+
if (target_type == TypeManager.sbyte_type){
//
// To sbyte from short, int, long, float, double.
Expression rounded_expr = RTConversionExpression(ec, "System.Math", ".Round", expr, loc);
return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R8_I8);
}
-
- } else if (target_type == TypeManager.char_type){
- //
- // To char from ushort, int, uint, long, ulong, float, double
- //
- if (expr_type == TypeManager.ushort_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.U2_CH);
- if (expr_type == TypeManager.int32_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_CH);
- if (expr_type == TypeManager.uint32_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.U4_CH);
- if (expr_type == TypeManager.uint64_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_CH);
- if (expr_type == TypeManager.int64_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_CH);
-
- if (expr_type == TypeManager.float_type) {
- Expression rounded_expr = RTConversionExpression(ec, "System.Math", ".Round", expr, loc);
- return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R4_CH);
- }
- if (expr_type == TypeManager.double_type) {
- Expression rounded_expr = RTConversionExpression(ec, "System.Math", ".Round", expr, loc);
- return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R8_CH);
- }
} else if (target_type == TypeManager.float_type){
//
}
break;
+ case TypeCode.Double:
+ switch (src_type) {
+ case TypeCode.String:
+ e = RTConversionExpression(ec, "DoubleType.FromString", expr, loc);
+ break;
+ case TypeCode.Object:
+ e = RTConversionExpression(ec, "DoubleType.FromObject", expr, loc);
+ break;
+ }
+ break;
+
+ case TypeCode.Single:
+ switch (src_type) {
+ case TypeCode.String:
+ e = RTConversionExpression(ec, "SingleType.FromString", expr, loc);
+ break;
+ case TypeCode.Object:
+ e = RTConversionExpression(ec, "SingleType.FromObject", expr, loc);
+ break;
+ }
+ break;
+
+ case TypeCode.Decimal:
+ switch (src_type) {
+ case TypeCode.String:
+ e = RTConversionExpression(ec, "DecimalType.FromString", expr, loc);
+ break;
+ case TypeCode.Object:
+ e = RTConversionExpression(ec, "DecimalType.FromObject", expr, loc);
+ break;
+ }
+ break;
+
+ case TypeCode.Int64:
+ case TypeCode.UInt64:
+ switch (src_type) {
+ case TypeCode.String:
+ e = RTConversionExpression(ec, "LongType.FromString", expr, loc);
+ break;
+ case TypeCode.Object:
+ e = RTConversionExpression(ec, "LongType.FromObject", expr, loc);
+ break;
+ }
+ break;
case TypeCode.Int32:
case TypeCode.UInt32:
switch (src_type) {
}
break;
case TypeCode.Byte:
- // Ok, this *is* broken
- e = RTConversionExpression(ec, "ByteType.FromObject", expr, loc);
- break;
+
+ switch (src_type) {
+ case TypeCode.String:
+ e = RTConversionExpression(ec, "BooleanType.FromString", expr, loc);
+ break;
+ case TypeCode.Object:
+ e = RTConversionExpression(ec, "ByteType.FromObject", expr, loc);
+ break;
+ }
+ break;
+ case TypeCode.Boolean:
+ switch (src_type) {
+ case TypeCode.String:
+ e = RTConversionExpression(ec, "BooleanType.FromString", expr, loc);
+ break;
+ case TypeCode.Object:
+ e = RTConversionExpression(ec, "BooleanType.FromObject", expr, loc);
+ break;
+ }
+ break;
case TypeCode.DateTime:
switch (src_type) {
case TypeCode.String:
}
return null;
}
+
+ static public Expression ConvertNothingToDefaultValues (EmitContext ec, Expression expr,
+ Type target_type, Location loc)
+ {
+ switch (Type.GetTypeCode (target_type)) {
+ case TypeCode.Boolean :
+ return new BoolConstant (false);
+ case TypeCode.Byte :
+ return new ByteConstant (0);
+ case TypeCode.Char :
+ return new CharConstant ((char)0);
+ case TypeCode.SByte :
+ return new SByteConstant (0);
+ case TypeCode.Int16 :
+ return new ShortConstant (0);
+ case TypeCode.Int32 :
+ return new IntConstant (0);
+ case TypeCode.Int64 :
+ return new LongConstant (0);
+ case TypeCode.Decimal :
+ return new DecimalConstant (System.Decimal.Zero);
+ case TypeCode.Single :
+ return new FloatConstant (0.0F);
+ case TypeCode.Double :
+ return new DoubleConstant (0.0);
+ }
+
+ return null;
+ }
/// <summary>
/// Attempts to apply the 'Standard Implicit
Type target_type, Location loc)
{
Type expr_type = expr.Type;
+
+ if (expr_type.IsSubclassOf (TypeManager.enum_type))
+ expr_type = TypeManager.EnumToUnderlying (expr_type);
+
Expression e;
+ if (expr is NullLiteral) {
+ if (target_type == TypeManager.string_type)
+ return expr;
+ e = ConvertNothingToDefaultValues (ec, expr, target_type, loc);
+ if (e != null)
+ return e;
+ }
+
if (expr_type == target_type)
return expr;
if (e != null)
return e;
+ if (expr is StringConstant && target_type == TypeManager.char_type)
+ return new CharConstant (((StringConstant) expr).Value [0]);
+
+ if (expr is CharConstant && target_type == TypeManager.string_type)
+ return new StringConstant (((CharConstant) expr).Value.ToString ());
+
e = ImplicitReferenceConversion (expr, target_type);
if (e != null)
return e;
}
/// <summary>
- /// Attemps to perform an implict constant conversion of the IntConstant
+ /// Attemps to perform an implict constant conversion of the any Numeric Constant
/// into a different data type using casts (See Implicit Constant
/// Expression Conversions)
/// </summary>
- static protected Expression TryImplicitIntConversion (Type target_type, IntConstant ic)
- {
- int value = ic.Value;
+ static protected Expression TryImplicitNumericConversion (Type target_type, Constant ic)
+ {
+ double value = 0;
+ if (ic is BoolConstant) {
+ bool val = (bool) ((BoolConstant)ic).Value;
+ if (val) {
+ if (target_type == TypeManager.byte_type)
+ value = Byte.MaxValue;
+ else
+ value = -1;
+ }
+ }
+ if (ic is IntConstant)
+ value = (double)((IntConstant)ic).Value;
+
+ if (ic is LongConstant)
+ value = (double) ((LongConstant)ic).Value;
+
+ if (ic is FloatConstant) {
+ value = (double) ((FloatConstant)ic).Value;
+ }
+
+ if (ic is DoubleConstant) {
+ value = ((DoubleConstant)ic).Value;
+ }
//
// FIXME: This could return constants instead of EmptyCasts
//
- if (target_type == TypeManager.sbyte_type){
+ if (target_type == TypeManager.bool_type){
+ if (value != 0)
+ return new BoolConstant (true);
+ return new BoolConstant (false);
+ } else if (target_type == TypeManager.sbyte_type){
if (value >= SByte.MinValue && value <= SByte.MaxValue)
- return new SByteConstant ((sbyte) value);
+ return new SByteConstant ((sbyte) System.Math.Round (value));
} else if (target_type == TypeManager.byte_type){
- if (Byte.MinValue >= 0 && value <= Byte.MaxValue)
- return new ByteConstant ((byte) value);
+ if (value >= Byte.MinValue && value <= Byte.MaxValue)
+ return new ByteConstant ((byte) System.Math.Round (value));
} else if (target_type == TypeManager.short_type){
if (value >= Int16.MinValue && value <= Int16.MaxValue)
- return new ShortConstant ((short) value);
+ return new ShortConstant ((short) System.Math.Round (value));
} else if (target_type == TypeManager.ushort_type){
if (value >= UInt16.MinValue && value <= UInt16.MaxValue)
- return new UShortConstant ((ushort) value);
+ return new UShortConstant ((ushort) System.Math.Round (value));
+ } else if (target_type == TypeManager.int32_type){
+ if (value >= Int32.MinValue && value <= Int32.MaxValue)
+ return new IntConstant ((int) System.Math.Round (value));
} else if (target_type == TypeManager.uint32_type){
if (value >= 0)
- return new UIntConstant ((uint) value);
+ return new UIntConstant ((uint) System.Math.Round (value));
+ } else if (target_type == TypeManager.int64_type){
+ return new LongConstant ((long) System.Math.Round (value));
} else if (target_type == TypeManager.uint64_type){
//
// we can optimize this case: a positive int32
// to do it.
//
if (value >= 0)
- return new ULongConstant ((ulong) value);
+ return new ULongConstant ((ulong)System.Math.Round ( value));
+ } else if (target_type == TypeManager.float_type){
+ return new FloatConstant ((float) value);
+ } else if (target_type == TypeManager.double_type){
+ return new DoubleConstant ((double) value);
}
if (value == 0 && ic is IntLiteral && TypeManager.IsEnumType (target_type)){
throw new Exception (msg);
- Report.Error (30512, loc, msg);
+ // Report.Error (30512, loc, msg);
}
/// <summary>
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I1_U4);
if (real_target_type == TypeManager.uint64_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I1_U8);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.I1_CH);
} else if (expr_type == TypeManager.byte_type){
//
// From byte to sbyte and char
//
if (real_target_type == TypeManager.sbyte_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.U1_I1);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.U1_CH);
} else if (expr_type == TypeManager.short_type){
//
// From short to sbyte, byte, ushort, uint, ulong, char
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I2_U4);
if (real_target_type == TypeManager.uint64_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I2_U8);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.I2_CH);
} else if (expr_type == TypeManager.ushort_type){
//
// From ushort to sbyte, byte, short, char
return new ConvCast (ec, expr, target_type, ConvCast.Mode.U2_U1);
if (real_target_type == TypeManager.short_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.U2_I2);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.U2_CH);
} else if (expr_type == TypeManager.int32_type){
//
// From int to sbyte, byte, short, ushort, uint, ulong, char
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_U4);
if (real_target_type == TypeManager.uint64_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_U8);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_CH);
} else if (expr_type == TypeManager.uint32_type){
//
// From uint to sbyte, byte, short, ushort, int, char
return new ConvCast (ec, expr, target_type, ConvCast.Mode.U4_U2);
if (real_target_type == TypeManager.int32_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.U4_I4);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.U4_CH);
} else if (expr_type == TypeManager.int64_type){
//
// From long to sbyte, byte, short, ushort, int, uint, ulong, char
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_U4);
if (real_target_type == TypeManager.uint64_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_U8);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_CH);
} else if (expr_type == TypeManager.uint64_type){
//
// From ulong to sbyte, byte, short, ushort, int, uint, long, char
return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_U4);
if (real_target_type == TypeManager.int64_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_I8);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_CH);
- } else if (expr_type == TypeManager.char_type){
- //
- // From char to sbyte, byte, short
- //
- if (real_target_type == TypeManager.sbyte_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.CH_I1);
- if (real_target_type == TypeManager.byte_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.CH_U1);
- if (real_target_type == TypeManager.short_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.CH_I2);
} else if (expr_type == TypeManager.float_type){
//
// From float to sbyte, byte, short,
return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R4_I8);
if (real_target_type == TypeManager.uint64_type)
return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R4_U8);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R4_CH);
} else if (expr_type == TypeManager.double_type){
//
// From double to byte, byte, short,
return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R8_I8);
if (real_target_type == TypeManager.uint64_type)
return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R8_U8);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R8_CH);
if (real_target_type == TypeManager.float_type)
- return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R8_R4);
+ return new ConvCast (ec, expr, target_type, ConvCast.Mode.R8_R4);
}
// decimal is taken care of by the op_Explicit methods.
static void Error_ConstantValueCannotBeConverted (Location l, string val, Type t)
{
- Report.Error (31, l, "Constant value '" + val + "' cannot be converted to " +
+ Report.Error (30439, l, "Constant value '" + val + "' not representable in type " +
TypeManager.MonoBASIC_Name (t));
}
/// <summary>
/// Converts the IntConstant, UIntConstant, LongConstant or
- /// ULongConstant into the integral target_type. Notice
+ /// ULongConstant,Double into the integral target_type. Notice
/// that we do not return an 'Expression' we do return
/// a boxed integral type.
///
if (target_type == TypeManager.uint32_type){
if (v >= 0)
return (uint) v;
- } else if (target_type == TypeManager.char_type){
- if (v >= Char.MinValue && v <= Char.MaxValue)
- return (char) v;
} else if (target_type == TypeManager.byte_type){
if (v >= Byte.MinValue && v <= Byte.MaxValue)
return (byte) v;
if (target_type == TypeManager.int32_type){
if (v <= Int32.MaxValue)
return (int) v;
- } else if (target_type == TypeManager.char_type){
- if (v >= Char.MinValue && v <= Char.MaxValue)
- return (char) v;
} else if (target_type == TypeManager.byte_type){
if (v <= Byte.MaxValue)
return (byte) v;
} else if (target_type == TypeManager.uint32_type){
if (v >= 0 && v <= UInt32.MaxValue)
return (uint) v;
- } else if (target_type == TypeManager.char_type){
- if (v >= Char.MinValue && v <= Char.MaxValue)
- return (char) v;
} else if (target_type == TypeManager.byte_type){
if (v >= Byte.MinValue && v <= Byte.MaxValue)
return (byte) v;
} else if (target_type == TypeManager.uint32_type){
if (v <= UInt32.MaxValue)
return (uint) v;
- } else if (target_type == TypeManager.char_type){
- if (v >= Char.MinValue && v <= Char.MaxValue)
- return (char) v;
} else if (target_type == TypeManager.byte_type){
if (v >= Byte.MinValue && v <= Byte.MaxValue)
return (byte) v;
return (int) v;
else if (target_type == TypeManager.uint32_type)
return (uint) v;
- else if (target_type == TypeManager.char_type)
- return (char) v;
else if (target_type == TypeManager.sbyte_type){
if (v <= SByte.MaxValue)
return (sbyte) v;
else if (target_type == TypeManager.uint32_type){
if (v >= 0)
return (uint) v;
- } else if (target_type == TypeManager.char_type){
- if (v >= 0)
- return (char) v;
} else if (target_type == TypeManager.byte_type){
if (v >= 0)
return (byte) v;
} else if (target_type == TypeManager.uint32_type){
if (v >= 0)
return (uint) v;
- } else if (target_type == TypeManager.char_type){
- if (v >= 0)
- return (char) v;
} else if (target_type == TypeManager.byte_type){
if (v >= Byte.MinValue && v <= Byte.MaxValue)
return (byte) v;
return (int) v;
else if (target_type == TypeManager.uint32_type)
return (uint) v;
- else if (target_type == TypeManager.char_type){
- if (v >= Char.MinValue && v <= Char.MaxValue)
- return (char) v;
- } else if (target_type == TypeManager.byte_type){
+ else if (target_type == TypeManager.byte_type){
if (v >= Byte.MinValue && v <= Byte.MaxValue)
return (byte) v;
} else if (target_type == TypeManager.sbyte_type){
return (ulong) v;
s = v.ToString ();
+
+ } else if (c is DoubleConstant){
+ double v = ((DoubleConstant) c).Value;
+
+ if (target_type == TypeManager.sbyte_type){
+ if (v >= SByte.MinValue && v <= SByte.MaxValue)
+ return new SByteConstant ((sbyte) System.Math.Round (v));
+ } else if (target_type == TypeManager.byte_type){
+ if (v >= Byte.MinValue && v <= Byte.MaxValue)
+ return new ByteConstant ((byte) System.Math.Round (v));
+ } else if (target_type == TypeManager.short_type){
+ if (v >= Int16.MinValue && v <= Int16.MaxValue)
+ return new ShortConstant ((short) System.Math.Round (v));
+ } else if (target_type == TypeManager.ushort_type){
+ if (v >= UInt16.MinValue && v <= UInt16.MaxValue)
+ return new UShortConstant ((ushort) System.Math.Round (v));
+ } else if (target_type == TypeManager.int32_type){
+ if (v >= Int32.MinValue && v <= Int32.MaxValue)
+ return new IntConstant ((int) System.Math.Round (v));
+ } else if (target_type == TypeManager.uint32_type){
+ if (v >= 0 && v <= UInt32.MaxValue)
+ return new UIntConstant ((uint) System.Math.Round (v));
+ } else if (target_type == TypeManager.uint64_type){
+ if (v > 0)
+ return new ULongConstant ((ulong) System.Math.Round (v));
+ }
+ s = v.ToString ();
}
+
Error_ConstantValueCannotBeConverted (loc, s, target_type);
return null;
}
public class BoolToNumericCast : EmptyCast
{
- Expression src;
Type target_type;
OpCode conv;
/// </remarks>
public class SimpleName : Expression, ITypeExpression {
public readonly string Name;
+ bool is_invocation = false;
+ bool is_addressof = false;
+
+ public bool IsInvocation {
+ set {
+ is_invocation = value;
+ }
+ }
+
+ public bool IsAddressOf {
+ set {
+ is_addressof = value;
+ }
+ }
public SimpleName (string name, Location l)
{
if (ec.InvokingOwnOverload == false && current_block != null && current_block.IsVariableDefined (Name)){
LocalVariableReference var;
- var = new LocalVariableReference (ec.CurrentBlock, Name, loc);
+ var = new LocalVariableReference (current_block, Name, loc);
if (right_side != null)
return var.ResolveLValue (ec, right_side);
// #52067 - Start - Trying to solve
if (e == null) {
-
ArrayList lookups = new ArrayList();
ArrayList typelookups = new ArrayList();
// #52067 - End
- if (e == null)
- return DoResolveType (ec);
-
+ if (e == null) {
+
+ /* preparing to support automatic definition of variables on first usage with Option Explicit Off
+
+ Isn't good enough to enable just now (tries to define some internal links and breaks on emit)
+
+ if (Name.IndexOf ('.') == -1 && current_block != null && !Mono.MonoBASIC.Parser.OptionExplicit) {
+
+ // while looking for a real solution
+ if (Name != "anything")
+ return DoResolveType (ec);
+
+ Console.WriteLine("Implicitly adding a variable named '{0}'", Name);
+
+ // TODO: look at type-suffixes to correct name and type
+ Expression type = Mono.MonoBASIC.Parser.DecomposeQI("System.Object", loc);
+
+ current_block.AddVariable(ec, type, Name, loc);
+
+ LocalVariableReference var = new LocalVariableReference (current_block, Name, loc);
+ if (right_side != null)
+ return var.ResolveLValue (ec, right_side);
+ else
+ return var.Resolve (ec);
+ } else
+ */
+ return DoResolveType (ec);
+ }
+
if (e is TypeExpr)
return e;
if (e is IMemberExpr) {
+ if ((e is MethodGroupExpr) && !is_invocation && !is_addressof) {
+ Expression inv = new Invocation (this, new ArrayList (), loc);
+ return inv.Resolve (ec);
+ }
e = MemberAccess.ResolveMemberAccess (ec, e, null, loc, this);
if (e == null)
return null;
+ if (e is PropertyGroupExpr && is_invocation) // We dont know the arguments yet
+ return e;
+
IMemberExpr me = e as IMemberExpr;
if (me == null)
return e;
return null;
}
*/
+ bool isPropertyGroup = (e is PropertyGroupExpr);
if (right_side != null)
e = e.DoResolveLValue (ec, right_side);
else
e = e.DoResolve (ec);
+ if (e == null && isPropertyGroup && !is_invocation)
+ Error (30057, "Property '" + Name + "' cannot be invoked with given arguments");
+
return e;
}
- if (ec.IsStatic || ec.IsFieldInitializer){
+ if (ec.IsStatic || ec.IsFieldInitializer) {
if (allow_static)
return e;
return MemberStaticCheck (ec, e);
- } else
- return e;
+ }
+
+ return e;
}
public override void Emit (EmitContext ec)
return Name;
}
}
+
+ public class DecoratedIdentifier : Expression {
+ Expression id;
+ Type decoration;
+
+ public DecoratedIdentifier (Expression id, Type decoration)
+ {
+ this.id = id;
+ this.decoration = decoration;
+ }
+
+ override public Expression DoResolve (EmitContext ec)
+ {
+ if (id == null || decoration == null)
+ return null;
+
+ Expression ret = id.DoResolve (ec);
+ if (ret.Type != TypeManager.TypeToCoreType (decoration)) {
+ Report.Error (30277, id.Location, "Type character '" + decoration + "' does not match declared type '" + ret.Type + "'.");
+ return null;
+ }
+
+ return ret;
+ }
+
+ override public void Emit (EmitContext ec)
+ {
+ throw new InternalErrorException ("Should never be called");
+ }
+ }
/// <summary>
/// Fully resolved expression that evaluates to a type
}
}
+ /// <summary>
+ /// Property Group Expression.
+ ///
+ /// </summary>
+ public class PropertyGroupExpr : ExpressionStatement, IMemberExpr {
+ public PropertyInfo [] Properties;
+ Expression instance_expression = null;
+ bool is_explicit_impl = false;
+ MethodBase method = null;
+ bool indexer_access_req = false;
+ ArrayList arguments = null;
+
+ public PropertyGroupExpr (MemberInfo [] mi, Location l)
+ {
+ Properties = new PropertyInfo [mi.Length];
+ mi.CopyTo (Properties, 0);
+ eclass = ExprClass.PropertyAccess;
+ type = TypeManager.object_type;
+ loc = l;
+ }
+
+ public PropertyGroupExpr (MemberInfo [] mi, ArrayList args, Expression expr, Location l)
+ : this (mi, l)
+ {
+ arguments = args;
+ instance_expression = expr;
+ }
+
+ public PropertyGroupExpr (ArrayList list, Location l)
+ {
+ Properties = new PropertyInfo [list.Count];
+
+ try {
+ list.CopyTo (Properties, 0);
+ } catch {
+ foreach (MemberInfo m in list){
+ if (!(m is PropertyInfo)){
+ Console.WriteLine ("Name " + m.Name);
+ Console.WriteLine ("Found a: " + m.GetType ().FullName);
+ }
+ }
+ throw;
+ }
+ loc = l;
+ eclass = ExprClass.PropertyAccess;
+ type = TypeManager.object_type;
+ }
+
+ public ArrayList Arguments {
+ get {
+ return arguments;
+ }
+ set {
+ arguments = value;
+ }
+ }
+
+ public Type DeclaringType {
+ get {
+ return Properties [0].DeclaringType;
+ }
+ }
+
+ public bool IndexerAccessRequired {
+ get {
+ return indexer_access_req;
+ }
+ }
+
+ //
+ // 'A method group may have associated an instance expression'
+ //
+ public Expression InstanceExpression {
+ get {
+ return instance_expression;
+ }
+
+ set {
+ instance_expression = value;
+ }
+ }
+
+ public bool IsExplicitImpl {
+ get {
+ return is_explicit_impl;
+ }
+
+ set {
+ is_explicit_impl = value;
+ }
+ }
+
+ public string Name {
+ get {
+ return Properties [0].Name;
+ }
+ }
+
+ public bool IsInstance {
+ get {
+ foreach (PropertyInfo pi in Properties) {
+ MethodInfo mi = pi.GetGetMethod ();
+ if (mi != null && !mi.IsStatic)
+ return true;
+ mi = pi.GetSetMethod ();
+ if (mi != null && !mi.IsStatic)
+ return true;
+ }
+ return false;
+ }
+ }
+
+ public bool IsStatic {
+ get {
+ return (!IsInstance);
+ }
+ }
+
+ public ArrayList GetAccessors () {
+ ArrayList GetAccessors = new ArrayList ();
+ foreach (PropertyInfo pi in Properties) {
+ if (pi.GetGetMethod () != null)
+ GetAccessors.Add (pi.GetGetMethod ());
+/*
+ else if (pi.GetGetMethod (true) != null)
+ GetAccessors.Add (pi.GetGetMethod (true));
+*/
+
+ }
+ return GetAccessors;
+ }
+
+ public ArrayList SetAccessors () {
+ ArrayList SetAccessors = new ArrayList ();
+ foreach (PropertyInfo pi in Properties) {
+ if (pi.GetSetMethod () != null)
+ SetAccessors.Add (pi.GetSetMethod ());
+/*
+ else if (pi.GetSetMethod (true) != null)
+ SetAccessors.Add (pi.GetSetMethod (true));
+*/
+ }
+ return SetAccessors;
+ }
+
+ override public Expression DoResolve (EmitContext ec)
+ {
+ if (instance_expression != null) {
+ instance_expression = instance_expression.DoResolve (ec);
+ if (instance_expression == null)
+ return null;
+ }
+
+ ArrayList members = GetAccessors ();
+ if (members == null || members.Count == 0) {
+ Report.Error (30524, loc, "Property '" + Name + "' lacks a 'get' accesor");
+ return null;
+ }
+
+ MethodGroupExpr m_expr = new MethodGroupExpr (members, loc);
+ method = Invocation.OverloadResolve (ec, m_expr, ref arguments, loc);
+ if ((method as MethodInfo) != null) {
+ MethodInfo mi = method as MethodInfo;
+ type = TypeManager.TypeToCoreType (mi.ReturnType);
+ indexer_access_req = false;
+ eclass = ExprClass.Value;
+ return this;
+ } else {
+ // find a get method that doesnt take any arguments. Check the return type of
+ // that method to find out if indexer access is required. Leave the rest to
+ // 'Invocation's Resolve'
+ method = Invocation.OverloadResolve (ec, m_expr, null, loc);
+ if (method != null) {
+ MethodInfo mi = method as MethodInfo;
+ Type ret_type = mi.ReturnType;
+ if (ret_type.IsArray)
+ indexer_access_req = true;
+ else {
+ Indexers list = Indexers.GetIndexersForType (ec.ContainerType, ret_type, loc);
+ if (list != null && list.getters.Count > 0)
+ indexer_access_req = true;
+ else
+ return null;
+ }
+ Arguments = null;
+ type = mi.ReturnType;
+ return this;
+ }
+ }
+
+ return null;
+ }
+
+ override public Expression DoResolveLValue (EmitContext ec, Expression right_side) {
+ if (instance_expression != null) {
+ instance_expression = instance_expression.DoResolve (ec);
+ if (instance_expression == null)
+ return null;
+ }
+
+ ArrayList members = SetAccessors ();
+ if (members == null || members.Count == 0) {
+ Report.Error (30524, loc, "Property '" + Name + "' lacks a 'set' accesor");
+ return null;
+ }
+
+ MethodGroupExpr m_expr = new MethodGroupExpr (members, loc);
+ if (arguments == null)
+ arguments = new ArrayList ();
+ arguments.Add (new Argument (right_side, Argument.AType.Expression));
+ method = Invocation.OverloadResolve (ec, m_expr, ref arguments, loc);
+ if (method != null) {
+ //MethodInfo mi = method as MethodInfo;
+ type = TypeManager.void_type; //TypeManager.TypeToCoreType (mi.ReturnType);
+ eclass = ExprClass.Value;
+ indexer_access_req = false;
+ return this;
+ } else {
+ // Look for properties that do not take any arguments.
+ // Check if the return type has any indexers
+ arguments = null;
+ DoResolve (ec);
+ if (method != null) {
+ MethodInfo mi = method as MethodInfo;
+ Type ret_type = mi.ReturnType;
+ if (ret_type.IsArray)
+ indexer_access_req = true;
+ else {
+
+ Indexers list = Indexers.GetIndexersForType (ec.ContainerType,
+ ret_type, loc);
+ if (list != null && list.setters.Count > 0)
+ indexer_access_req = true;
+ else
+ return null;
+ }
+ type = mi.ReturnType;
+ return this;
+ }
+ }
+
+ return null;
+ }
+
+ override public void Emit (EmitContext ec)
+ {
+ if (Arguments == null)
+ Arguments = new ArrayList ();
+ Invocation.EmitCall (ec, false, IsStatic, instance_expression, method, null, Arguments, loc);
+ }
+
+ override public void EmitStatement (EmitContext ec)
+ {
+ Emit (ec);
+ }
+
+ }
+
/// <summary>
/// Fully resolved expression that evaluates to a Field
/// </summary>
{
PropertyInfo = pi;
eclass = ExprClass.PropertyAccess;
- PropertyArgs = new ArrayList();
+ PropertyArgs = null;
is_static = false;
loc = l;
return;
}
}
+ if (PropertyArgs == null)
+ PropertyArgs = new ArrayList ();
Invocation.EmitCall (ec, IsBase, IsStatic, instance_expr, getter, null, PropertyArgs, loc);
}