X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fbmcs%2Fecore.cs;h=51ca97ab8f19dc831396befd7e65866feed728a4;hb=448c3ad93f9a0f4125ad3a924c192c12fe4504bd;hp=41987d0d1d60b525932f8b71314ac441b68de02f;hpb=b4b657acad8f88aed65d9eccc797f7f8295b4845;p=mono.git
diff --git a/mcs/bmcs/ecore.cs b/mcs/bmcs/ecore.cs
index 41987d0d1d6..51ca97ab8f1 100644
--- a/mcs/bmcs/ecore.cs
+++ b/mcs/bmcs/ecore.cs
@@ -815,7 +815,7 @@ namespace Mono.CSharp {
/// Returns an expression that can be used to invoke operator true
/// on the expression if it exists.
///
- static public StaticCallExpr GetOperatorTrue (EmitContext ec, Expression e, Location loc)
+ static public Expression GetOperatorTrue (EmitContext ec, Expression e, Location loc)
{
return GetOperatorTrueOrFalse (ec, e, true, loc);
}
@@ -824,16 +824,19 @@ namespace Mono.CSharp {
/// Returns an expression that can be used to invoke operator false
/// on the expression if it exists.
///
- static public StaticCallExpr GetOperatorFalse (EmitContext ec, Expression e, Location loc)
+ static public Expression GetOperatorFalse (EmitContext ec, Expression e, Location loc)
{
return GetOperatorTrueOrFalse (ec, e, false, loc);
}
- static StaticCallExpr GetOperatorTrueOrFalse (EmitContext ec, Expression e, bool is_true, Location loc)
+ static Expression GetOperatorTrueOrFalse (EmitContext ec, Expression e, bool is_true, Location loc)
{
MethodBase method;
Expression operator_group;
+ if (TypeManager.IsNullableType (e.Type))
+ return new Nullable.OperatorTrueOrFalse (e, is_true, loc).Resolve (ec);
+
operator_group = MethodLookup (ec, e.Type, is_true ? "op_True" : "op_False", loc);
if (operator_group == null)
return null;
@@ -941,7 +944,7 @@ namespace Mono.CSharp {
sb.Append (valid [i]);
}
- Error (119, "Expression denotes a `" + ExprClassName () + "' where " +
+ Report.Error (119, loc, "Expression denotes a `" + ExprClassName () + "' where " +
"a `" + sb.ToString () + "' was expected");
}
@@ -1335,6 +1338,42 @@ namespace Mono.CSharp {
{
Report.Error (248, loc, "Cannot create an array with a negative size");
}
+
+
+ ///
+ /// Converts a String to an equivalent SimpleName or a
+ /// MemberAccess expression
+ ///
+
+ public static Expression StringToExpression (string name, Location loc)
+ {
+ int pos;
+ string left;
+ string right;
+
+ Expression expr = null;
+
+ pos = name.IndexOf('.');
+ while (pos != -1)
+ {
+ left = name.Substring (0, pos);
+ right = name.Substring (pos + 1);
+
+ if (expr == null)
+ expr = new SimpleName (left, loc);
+ else
+ expr = new MemberAccess (expr, left, loc);
+
+ name = right;
+ pos = name.IndexOf('.');
+ }
+
+ if (expr == null)
+ return new SimpleName (name, loc);
+ else
+ return new MemberAccess (expr, name, loc);
+
+ }
//
// Converts `source' to an int, uint, long or ulong.
@@ -1459,6 +1498,78 @@ namespace Mono.CSharp {
}
}
+
+ ///
+ /// HelperMethodInvocation of methods or delegates. Used by the
+ /// VB.NET compiler specifically to emit calls to the
+ /// Microsoft.VisualBasic.CompilerServices helper routines
+ ///
+
+ public class HelperMethodInvocation : Expression
+ {
+ ArrayList args;
+ MethodInfo method;
+
+ public HelperMethodInvocation (EmitContext ec, Location l, Type return_type, MethodInfo method, params Expression [] exprs)
+ {
+ args = new ArrayList ();
+ foreach (Expression expr in exprs)
+ args.Add (new Argument (expr, Argument.AType.Expression));
+
+
+ this.loc = l;
+ this.method = method;
+ type = return_type;
+ eclass = ExprClass.Value;
+ }
+
+ public override Expression DoResolve (EmitContext ec)
+ {
+ return this;
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ Invocation.EmitArguments (ec, method, args, false, null);
+ ec.ig.Emit (OpCodes.Call, method);
+ }
+ }
+
+ ///
+ /// Implicit Creation of types. Used by the VB.NET compiler
+ /// (in the context of Type Conversions) to emit calls to the
+ /// appropriate constructors available in the core libraries.
+ ///
+
+ public class ImplicitNew : Expression
+ {
+ Expression child;
+
+ public ImplicitNew (EmitContext ec, string ns, string name, Location l, params Expression [] exprs)
+ {
+ name = ns + "." + name;
+ ArrayList args = new ArrayList ();
+
+ foreach (Expression expr in exprs)
+ args.Add (new Argument (expr, Argument.AType.Expression));
+
+ child = new New (StringToExpression (name, l), args, l).Resolve (ec);
+ }
+
+ public override Expression DoResolve (EmitContext ec)
+ {
+ // This should never be invoked, we are born in fully
+ // initialized state.
+
+ return this;
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ child.Emit (ec);
+ }
+ }
+
//
// We need to special case this since an empty cast of
// a NullLiteral is still a Constant
@@ -1493,7 +1604,19 @@ namespace Mono.CSharp {
public override void Emit (EmitContext ec)
{
- child.Emit (ec);
+ if (!type.IsValueType)
+ child.Emit (ec);
+ else {
+ // VB.NET allows Nothing to be converted to any value type
+
+ ILGenerator ig = ec.ig;
+
+ ig.Emit (OpCodes.Ldtoken, type);
+ ig.Emit (OpCodes.Call, TypeManager.system_type_get_type_from_handle);
+ ig.Emit (OpCodes.Call, TypeManager.activator_create_instance);
+ ig.Emit (OpCodes.Unbox, type);
+ ig.Emit (OpCodes.Ldobj, type);
+ }
}
public override bool IsNegative {
@@ -1998,6 +2121,102 @@ namespace Mono.CSharp {
ec.ig.Emit (OpCodes.Castclass, type);
}
}
+
+ //
+ // VB.NET specific
+ //
+ public class BooleanToNumericCast : EmptyCast {
+ OpCode op, op2;
+
+ public BooleanToNumericCast (Expression child, Type return_type, OpCode op)
+ : base (child, return_type)
+
+ {
+ this.op = op;
+ }
+
+ public override Expression DoResolve (EmitContext ec)
+ {
+ // This should never be invoked, we are born in fully
+ // initialized state.
+
+ return this;
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ base.Emit (ec);
+ ec.ig.Emit (OpCodes.Ldc_I4_0);
+ ec.ig.Emit (OpCodes.Cgt_Un);
+ ec.ig.Emit (OpCodes.Neg);
+ ec.ig.Emit (op);
+ }
+ }
+
+ //
+ // VB.NET specific
+ //
+ public class NumericToBooleanCast : EmptyCast {
+
+ Type expr_type;
+
+ public NumericToBooleanCast (Expression child, Type src_type)
+ : base (child, TypeManager.bool_type)
+
+ {
+ expr_type = src_type;
+ }
+
+ public override Expression DoResolve (EmitContext ec)
+ {
+ // This should never be invoked, we are born in fully
+ // initialized state.
+
+ return this;
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ base.Emit (ec);
+
+ if (expr_type == TypeManager.byte_type ||
+ expr_type == TypeManager.short_type ||
+ expr_type == TypeManager.int32_type) {
+ ec.ig.Emit (OpCodes.Ldc_I4_0);
+ ec.ig.Emit (OpCodes.Cgt_Un);
+ return;
+ }
+
+ if (expr_type == TypeManager.int64_type) {
+ ec.ig.Emit (OpCodes.Ldc_I8, (long) 0);
+ ec.ig.Emit (OpCodes.Cgt_Un);
+ return;
+ }
+
+ if (expr_type == TypeManager.float_type)
+ ec.ig.Emit (OpCodes.Ldc_R4, (float) 0);
+ else if (expr_type == TypeManager.double_type)
+ ec.ig.Emit (OpCodes.Ldc_R8, (double) 0);
+
+ ec.ig.Emit (OpCodes.Ceq);
+ ec.ig.Emit (OpCodes.Ldc_I4_0);
+ ec.ig.Emit (OpCodes.Ceq);
+ }
+ }
+
+ //
+ // VB.NET specific
+ //
+ public class FloatingToFixedCast : ConvCast {
+ public FloatingToFixedCast (EmitContext ec, Expression child, Type return_type, Mode mode)
+ : base (ec, new HelperMethodInvocation (ec, child.Location, TypeManager.double_type, TypeManager.math_round_double,
+ (child.Type == TypeManager.float_type) ?
+ new OpcodeCast (child, TypeManager.double_type, OpCodes.Conv_R8) : child),
+ return_type, mode)
+ {
+ }
+ }
+
///
/// SimpleName expressions are formed of a single word and only happen at the beginning
@@ -2275,6 +2494,11 @@ namespace Mono.CSharp {
/// section 10.8.1 (Fully Qualified Names).
///
public abstract class FullNamedExpression : Expression {
+ public override FullNamedExpression ResolveAsTypeStep (EmitContext ec)
+ {
+ return this;
+ }
+
public abstract string FullName {
get;
}