2001-09-18 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / expression.cs
index eb2f6b2c7e4a3cce411b7778ab8a9e73daee8dad..45854d2aa2604c3583b75089947bbfca571b1d46 100755 (executable)
@@ -125,7 +125,7 @@ namespace CIR {
                        
                        if (mi.Length == 1 && !(mi [0] is MethodBase))
                                return Expression.ExprClassFromMemberInfo (mi [0]);
-
+                       
                        for (int i = 0; i < mi.Length; i++)
                                if (!(mi [i] is MethodBase)){
                                        rc.Report.Error (-5, "Do not know how to reproduce this case: " + 
@@ -159,7 +159,7 @@ namespace CIR {
                        BindingFlags.Instance;
 
                public static Expression MemberLookup (RootContext rc, Type t, string name,
-                                                         bool same_type)
+                                                      bool same_type)
                {
                        return MemberLookup (rc, t, name, same_type, AllMemberTypes, AllBindingsFlags);
                }
@@ -654,6 +654,7 @@ namespace CIR {
                Expression left, right;
                MethodBase method;
                ArrayList  Arguments;
+               
 
                public Binary (Operator oper, Expression left, Expression right)
                {
@@ -910,8 +911,7 @@ namespace CIR {
                        if (left_expr != null || right_expr != null) {
                                //
                                // Now we need to form the union of these two sets and
-                               // then call OverloadResolve
-                               // on that.
+                               // then call OverloadResolve on that.
                                //
                                MethodGroupExpr left_set = null, right_set = null;
                                int length1 = 0, length2 = 0;
@@ -925,7 +925,7 @@ namespace CIR {
                                        right_set = (MethodGroupExpr) right_expr;
                                        length2 = right_set.Methods.Length;
                                }
-                               
+
                                MemberInfo [] mi = new MemberInfo [length1 + length2];
                                if (left_set != null)
                                        left_set.Methods.CopyTo (mi, 0);
@@ -937,7 +937,7 @@ namespace CIR {
                                Arguments = new ArrayList ();
                                Arguments.Add (new Argument (left, Argument.AType.Expression));
                                Arguments.Add (new Argument (right, Argument.AType.Expression));
-                               
+
                                method = Invocation.OverloadResolve (union, Arguments);
                                if (method != null)
                                        return this;
@@ -1091,11 +1091,29 @@ namespace CIR {
                        OpCode opcode;
 
                        if (method != null) {
-                               if (method is MethodInfo) {
-                                       Invocation.EmitArguments (ec, Arguments);
-                                       ec.ig.Emit (OpCodes.Call, (MethodInfo) method);
-                                       return;
-                               }
+
+                               bool is_static = method.IsStatic;
+
+                               // FIXME : I am just not able to get this right !!
+                               // There's something wrong with this part which causes
+                               // an InvalidProgramException if this code is emitted
+                               
+                               //if (Arguments != null)
+                               //      Invocation.EmitArguments (ec, Arguments);
+                               
+                               //if (is_static){
+                               //      if (method is MethodInfo)
+                               //              ig.Emit (OpCodes.Call, (MethodInfo) method);
+                               //      else
+                               //              ig.Emit (OpCodes.Call, (ConstructorInfo) method);
+                               //} else {
+                               //      if (method is MethodInfo)
+                               //              ig.Emit (OpCodes.Callvirt, (MethodInfo) method);
+                               //      else
+                               //              ig.Emit (OpCodes.Callvirt, (ConstructorInfo) method);
+                               //}
+                               
+                               //return;
                        }
                        
                        left.Emit (ec);
@@ -1320,6 +1338,13 @@ namespace CIR {
                        if (e != null){
                                if (e is TypeExpr)
                                        return e;
+                               else if (e is FieldExpr){
+                                       FieldExpr fe = (FieldExpr) e;
+
+                                       if (!fe.FieldInfo.IsStatic)
+                                               fe.Instance = new This ();
+                               }
+                               
                                if ((tc.ModFlags & Modifiers.STATIC) != 0)
                                        return MemberStaticCheck (r, e);
                                else
@@ -1528,9 +1553,9 @@ namespace CIR {
                                throw new Exception ("Expression of type " + a.Expr + " does not resolve its type");
                        }
                        
-                       if (t == a.Expr.Type)
+                       if (t == a.Expr.Type) 
                                return 0;
-
+                       
                        // FIXME: Implement implicit conversions here.
                        // FIXME: Implement better conversion here.
                        
@@ -1714,7 +1739,7 @@ namespace CIR {
                        if (Arguments != null)
                                EmitArguments (ec, Arguments);
 
-                       if (method.IsStatic){
+                       if (is_static){
                                if (method is MethodInfo)
                                        ec.ig.Emit (OpCodes.Call, (MethodInfo) method);
                                else
@@ -1794,7 +1819,7 @@ namespace CIR {
 
                        method = Invocation.OverloadResolve ((MethodGroupExpr) ml, Arguments);
 
-                       if (method == null){
+                       if (method == null) {
                                tc.RootContext.Report.Error (-6,
                                "New invocation: Can not find a constructor for this argument list");
                                return null;
@@ -1810,15 +1835,21 @@ namespace CIR {
                }
        }
 
+       //
+       // Represents the `this' construct
+       //
        public class This : Expression {
                public override Expression Resolve (TypeContainer tc)
                {
-                       // FIXME: Implement;
+                       eclass = ExprClass.Variable;
+                       type = tc.TypeBuilder;
+                       
                        return this;
                }
 
                public override void Emit (EmitContext ec)
                {
+                       ec.ig.Emit (OpCodes.Ldarg_0);
                }
        }
 
@@ -1832,12 +1863,18 @@ namespace CIR {
 
                public override Expression Resolve (TypeContainer tc)
                {
-                       // FIXME: Implement;
+                       type = tc.LookupType (QueriedType, false);
+
+                       if (type == null)
+                               return null;
+                       
+                       eclass = ExprClass.Type;
                        return this;
                }
 
                public override void Emit (EmitContext ec)
                {
+                       // FIXME: Implement.
                }
        }
 
@@ -1897,11 +1934,18 @@ namespace CIR {
                                // FIXME: This is a horrible way of detecting if it is
                                // an instance expression.  Figure out how to fix this.
                                //
-                               Console.WriteLine ("FIXME: Horrible way of figuring if something is an isntance");
 
-                               if (expr is LocalVariableReference)
+                               if (expr is LocalVariableReference ||
+                                   expr is ParameterReference ||
+                                   expr is FieldExpr)
                                        mg.InstanceExpression = expr;
                                        
+                               return member_lookup;
+                       } else if (member_lookup is FieldExpr){
+                               FieldExpr fe = (FieldExpr) member_lookup;
+
+                               fe.Instance = expr;
+
                                return member_lookup;
                        } else
                                //
@@ -1909,7 +1953,7 @@ namespace CIR {
                                // ie, for a Property Access, it should like call it
                                // and stuff.
 
-                               return null;
+                               return member_lookup;
                }
 
                public override void Emit (EmitContext ec)
@@ -2032,7 +2076,8 @@ namespace CIR {
        // </summary>
        public class FieldExpr : Expression {
                public readonly FieldInfo FieldInfo;
-
+               public Expression Instance;
+                       
                public FieldExpr (FieldInfo fi)
                {
                        FieldInfo = fi;
@@ -2042,13 +2087,32 @@ namespace CIR {
 
                override public Expression Resolve (TypeContainer tc)
                {
-                       // We are born in resolved state. 
+                       if (!FieldInfo.IsStatic){
+                               if (Instance == null){
+                                       throw new Exception ("non-static FieldExpr without instance var\n" +
+                                                            "You have to assign the Instance variable\n" +
+                                                            "Of the FieldExpr to set this\n");
+                               }
+
+                               Instance = Instance.Resolve (tc);
+                               if (Instance == null)
+                                       return null;
+                               
+                       }
                        return this;
                }
 
                override public void Emit (EmitContext ec)
                {
-                       // FIXME: Assert that this should not be reached?
+                       ILGenerator ig = ec.ig;
+
+                       if (FieldInfo.IsStatic)
+                               ig.Emit (OpCodes.Ldsfld, FieldInfo);
+                       else {
+                               Instance.Emit (ec);
+                               
+                               ig.Emit (OpCodes.Ldfld, FieldInfo);
+                       }
                }
        }
        
@@ -2112,7 +2176,7 @@ namespace CIR {
        
        public class CheckedExpr : Expression {
 
-               public readonly Expression Expr;
+               public Expression Expr;
 
                public CheckedExpr (Expression e)
                {
@@ -2121,19 +2185,32 @@ namespace CIR {
 
                public override Expression Resolve (TypeContainer tc)
                {
-                       // FIXME : Implement !
+                       Expr = Expr.Resolve (tc);
+
+                       if (Expr == null)
+                               return null;
+
+                       eclass = Expr.ExprClass;
+                       type = Expr.Type;
                        return this;
                }
 
                public override void Emit (EmitContext ec)
                {
+                       bool last_check = ec.CheckState;
+
+                       ec.CheckState = true;
+                       
+                       Expr.Emit (ec);
+
+                       ec.CheckState = last_check;
                }
                
        }
 
        public class UnCheckedExpr : Expression {
 
-               public readonly Expression Expr;
+               public Expression Expr;
 
                public UnCheckedExpr (Expression e)
                {
@@ -2142,12 +2219,25 @@ namespace CIR {
 
                public override Expression Resolve (TypeContainer tc)
                {
-                       // FIXME : Implement !
+                       Expr = Expr.Resolve (tc);
+
+                       if (Expr == null)
+                               return null;
+
+                       eclass = Expr.ExprClass;
+                       type = Expr.Type;
                        return this;
                }
 
                public override void Emit (EmitContext ec)
                {
+                       bool last_check = ec.CheckState;
+
+                       ec.CheckState = false;
+                       
+                       Expr.Emit (ec);
+
+                       ec.CheckState = last_check;
                }
                
        }