Support for 'LateSet', 'LateIndexGet', 'LateIndexSet'
authorSatya Sudha K <sudha@mono-cvs.ximian.com>
Fri, 29 Apr 2005 11:58:58 +0000 (11:58 -0000)
committerSatya Sudha K <sudha@mono-cvs.ximian.com>
Fri, 29 Apr 2005 11:58:58 +0000 (11:58 -0000)
svn path=/trunk/mcs/; revision=43784

mcs/mbas/ChangeLog
mcs/mbas/argument.cs
mcs/mbas/assign.cs
mcs/mbas/ecore.cs
mcs/mbas/expression.cs
mcs/mbas/mb-parser.jay
mcs/mbas/statement.cs

index d924c2d3c6baca5caf54108b88181541f1f8130d..b6b56589aa9d8cddccf332cf684a947e34594b1e 100644 (file)
@@ -1,6 +1,18 @@
+2005-04-29 Satya Sudha K <ksathyasudha@novell.com>
+       * argument.cs
+       * statement.cs
+       * expression.cs
+       * assign.cs
+       * mb-parser.jay:
+               Support for 'LateSet', 'LateIndexGet', 'LateIndexSet'
+
+       * ecore.cs :
+               Minor fixes in conversions
+
 2005-04-26 Manjula GHM <mmanjula@novell.com>
        *statement.cs
                "out" is not supported as Parameter Modifier in VB.NET
+
 2005-04-26 Manjula GHM <mmanjula@novell.com>
        *support.cs
        *parameter.cs
index 1a3144dc0b2226f61687a6fb507847a6a5beba08..db3d884e4e7a7d509805ce8a7db1e2de2173ae55 100644 (file)
@@ -33,6 +33,7 @@ namespace Mono.MonoBASIC {
                
                public Argument (Expression expr, AType type)
                {
+                       expr = Parser.SetValueRequiredFlag (expr);
                        this.Expr = expr;
                        this.ArgType = type;
                }
index 98285325d362fc7642854a252b8100679948e8b3..e9733e264989e3b99b51629d2f19a8eaea6d67cc 100644 (file)
@@ -132,6 +132,10 @@ namespace Mono.MonoBASIC {
 
                public Assign (Expression target, Expression source, Location l)
                {
+                       source = Parser.SetValueRequiredFlag (source);
+                       target = Parser.SetLeftHandFlag (target);
+                       if (target is MemberAccess)
+                               ((MemberAccess) target).IsLeftHand = true;
                        this.target = target;
                        this.source = this.real_source = source;
                        this.loc = l;
@@ -258,12 +262,48 @@ namespace Mono.MonoBASIC {
                                                return e;
                                        }
                                }
-       
                        }
-                       target = target.ResolveLValue (ec, source);
 
-                       if (target == null)
+                       Expression tmpTarget = target.ResolveLValue (ec, source);
+                       if (tmpTarget == null) {
+                               // Case of LateBinding.
+                               // Get the appropriate arguments, add the source as the last argument
+                               Expression lateBindingExpr = null;
+                               ArrayList arguments = null;
+                               if (target is Invocation) {
+                                       lateBindingExpr = ((Invocation) target).Expr;
+                                       arguments = ((Invocation) target).Arguments;
+                               }
+                               if (target is MemberAccess) {
+                                       lateBindingExpr = target;
+                               }
+                               if (arguments == null)
+                                       arguments = new ArrayList ();
+
+                               arguments.Add (new Argument (source, Argument.AType.Expression));
+
+                               Expression etmp = lateBindingExpr;
+                               Type exprType = lateBindingExpr.Type;
+                               // Get the target of the invocation/memberAccess
+                               if (exprType == null) {
+                                       if (etmp is Invocation)
+                                               etmp = ((Invocation) etmp).Expr;
+                                       if (etmp is MemberAccess)
+                                               etmp = ((MemberAccess) etmp).Expr;
+                                       exprType = etmp.Type;
+                               }
+
+                               if (exprType == TypeManager.object_type) {
+                                       StatementSequence tmp = new StatementSequence (ec.CurrentBlock, loc, lateBindingExpr, 
+                                                                               arguments, false, true);
+                                       tmp.GenerateLateBindingStatements ();
+                                       return tmp.Resolve (ec);
+                               }
+
                                return null;
+                       }
+
+                       target = tmpTarget;
 
                        Type target_type = target.Type;
                        Type source_type = real_source.Type;
index 973e670302008b341d09bea74d5c4e6194635812..c8f6624453439b18cac1f1fb0cdb0192bf05aa52 100644 (file)
@@ -834,7 +834,8 @@ namespace Mono.MonoBASIC {
                                }
 
                                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);
                        }
 
@@ -4159,7 +4160,6 @@ namespace Mono.MonoBASIC {
 
        public class BoolToNumericCast : EmptyCast 
        {
-               Expression src;
                Type target_type;
                OpCode conv;
                
index 8e416e03131c47eac9ce692cd9e3cdbd4d37c983..96b92d7201c72613e21e05cd45f22a0fe201e8e8 100644 (file)
@@ -361,6 +361,14 @@ namespace Mono.MonoBASIC {
                                        return this;
                                }
 
+                               if (expr_type == TypeManager.object_type) {
+                                       Expression etmp = Parser.DecomposeQI ("Microsoft.VisualBasic.CompilerServices.ObjectType.NotObj", Location.Null);
+                                       ArrayList arguments = new ArrayList ();
+                                       arguments.Add (new Argument (Expr, Argument.AType.Expression));
+                                       Expression e = new Invocation (etmp, arguments, loc);
+                                       return e.Resolve (ec);
+                               }
+
                                break;
                        case Operator.AddressOf:
                                // Not required in VB ??
@@ -1698,6 +1706,8 @@ namespace Mono.MonoBASIC {
 
                public Binary (Operator oper, Expression left, Expression right, Location loc)
                {
+                       left = Parser.SetValueRequiredFlag (left);
+                       right = Parser.SetValueRequiredFlag (right);
                        this.oper = oper;
                        this.left = left;
                        this.right = right;
@@ -2092,9 +2102,11 @@ namespace Mono.MonoBASIC {
                                 // one from the other, then we catch the error there.
 
                                // If other type is a value type, convert it to object
-                               if (l.IsValueType && r == TypeManager.object_type)
+                               if (r == TypeManager.object_type &&
+                                   (l.IsValueType || l == TypeManager.string_type))
                                        left = ConvertImplicit (ec, left, TypeManager.object_type, loc);
-                               if (r.IsValueType && l == TypeManager.object_type)
+                               if (l == TypeManager.object_type &&
+                                   (r.IsValueType || r == TypeManager.string_type))
                                        right = ConvertImplicit (ec, right, TypeManager.object_type, loc);
                                if (left == null || right == null) {
                                        Error_OperatorCannotBeApplied (loc, OperName (oper), l, r);
@@ -2615,13 +2627,6 @@ namespace Mono.MonoBASIC {
                        left = left.Resolve (ec);
                        right = right.Resolve (ec);
 
-                       if (left is Invocation) {
-                               ((Invocation) left).IsRetvalRequired = true;
-                       }
-                       if (right is Invocation) {
-                               ((Invocation) right).IsRetvalRequired = true;
-                       }
-
                        if (left == null || right == null)
                                return null;
 
@@ -3585,6 +3590,9 @@ namespace Mono.MonoBASIC {
                public Invocation (Expression expr, ArrayList arguments, Location l)
                {
                        this.expr = expr;
+                       if (this.expr is MemberAccess) {
+                               ((MemberAccess) this.expr).IsInvocation = true;
+                       }
                        this.is_retval_required = false;
                        this.is_left_hand = false;
                        Arguments = arguments;
@@ -3598,6 +3606,15 @@ namespace Mono.MonoBASIC {
                        }
                }
 
+               public bool IsLeftHand {
+                       get {
+                               return is_left_hand;
+                       }
+                       set {
+                               is_left_hand = value;
+                       }
+               }
+
                public bool IsRetvalRequired {
                        get {
                                return is_retval_required;
@@ -4438,6 +4455,8 @@ namespace Mono.MonoBASIC {
                        }       
 
                        if (temp == null) {
+                               if (is_left_hand)
+                                       return null;
                                if (expr is MemberAccess) {
                                        MemberAccess m = expr as MemberAccess;
                                        if (m.Expr.Type == TypeManager.object_type) {
@@ -4597,42 +4616,25 @@ namespace Mono.MonoBASIC {
                                        // We can't resolve now, but we
                                        // have to try to access the array with a call
                                        // to LateIndexGet/Set in the runtime
-                                       Expression lig_call_expr;
-
-                                       if (!is_left_hand)
-                                               lig_call_expr = Mono.MonoBASIC.Parser.DecomposeQI("Microsoft.VisualBasic.CompilerServices.LateBinding.LateIndexGet", Location.Null);
-                                       else
-                                               lig_call_expr = Mono.MonoBASIC.Parser.DecomposeQI("Microsoft.VisualBasic.CompilerServices.LateBinding.LateIndexSet", Location.Null);
-                                       Expression obj_type = Mono.MonoBASIC.Parser.DecomposeQI("System.Object", Location.Null);
-                                       ArrayList adims = new ArrayList();
-
-                                       ArrayList ainit = new ArrayList();
-                                       foreach (Argument a in Arguments)
-                                               ainit.Add ((Expression) a.Expr);
-
-                                       adims.Add ((Expression) new IntLiteral (Arguments.Count));
-
-                                       Expression oace = new ArrayCreation (obj_type, adims, "", ainit, Location.Null);
-
-                                       ArrayList args = new ArrayList();
-                                       args.Add (new Argument(expr, Argument.AType.Expression));
-                                       args.Add (new Argument(oace, Argument.AType.Expression));
-                                       args.Add (new Argument(NullLiteral.Null, Argument.AType.Expression));
-
-                                       Expression lig_call = new Invocation (lig_call_expr, args, Location.Null);
-                                       expr_to_return = lig_call.Resolve(ec);
-                                       expr_to_return.eclass = ExprClass.Variable;
+                                       if (! is_left_hand) {
+                                               StatementSequence etmp = new StatementSequence (ec.CurrentBlock, 
+                                                                       loc, ia, Arguments, 
+                                                                       true, false);
+                                               etmp.GenerateLateBindingStatements();
+                                               return etmp.Resolve (ec);
+                                       }
+                                       return null;
                                }
                        }
 
                        return expr_to_return;
                }
 
-        static void Error_WrongNumArguments (Location loc, String name, int arg_count)
-        {
-            Report.Error (1501, loc, "No overload for method `" + name + "' takes `" +
+               static void Error_WrongNumArguments (Location loc, String name, int arg_count)
+               {
+                       Report.Error (1501, loc, "No overload for method `" + name + "' takes `" +
                                       arg_count + "' arguments");
-        }
+               }
 
                // <summary>
                //   Emits the list of arguments as an array
@@ -6096,6 +6098,8 @@ namespace Mono.MonoBASIC {
                public readonly string Identifier;
                Expression expr;
                Expression member_lookup;
+               bool is_invocation;
+               bool is_left_hand;
                
                public MemberAccess (Expression expr, string id, Location l)
                {
@@ -6104,6 +6108,32 @@ namespace Mono.MonoBASIC {
                        loc = l;
                }
 
+               public MemberAccess (Expression expr, string id, Location l, bool isInvocation)
+               {
+                       this.expr = expr;
+                       Identifier = id;
+                       loc = l;
+                       is_invocation = isInvocation;
+               }
+
+               public bool IsInvocation {
+                       get {
+                               return is_invocation;
+                       }
+                       set {
+                               is_invocation = value;
+                       }
+               }
+
+               public bool IsLeftHand {
+                       get {
+                               return is_left_hand;
+                       }
+                       set {
+                               is_left_hand = value;
+                       }
+               }
+
                public Expression Expr {
                        get {
                                return expr;
@@ -6367,6 +6397,23 @@ namespace Mono.MonoBASIC {
                                if (lookup == null) {
                                        if (expr_type != TypeManager.object_type)
                                                Error (30456, "'" + expr_type + "' does not contain a definition for '" + Identifier + "'");
+                                       // If this came as a part of Invocation, 
+                                       // Since argumets are not known, return null, 
+                                       // let Invocation's Resolve take care
+                                       if (is_invocation)
+                                               return null;
+
+                                       else if (! is_left_hand) {
+                                               StatementSequence etmp = new StatementSequence (ec.CurrentBlock, 
+                                                                               loc, this, null, 
+                                                                               true, is_left_hand);
+                                               etmp.GenerateLateBindingStatements();
+                                               return etmp.Resolve (ec);
+                                       } 
+
+                                       // if the expression is a left hand side of an assignment,
+                                       // return null, as we dont know the RHS
+                                       // Let assign take care of Late Binding
                                        return null;
                                }
                                else
@@ -7096,9 +7143,10 @@ namespace Mono.MonoBASIC {
                                }
                        }
 
-                       Report.Error (21, loc,
-                                     "Type '" + TypeManager.MonoBASIC_Name (lookup_type) +
-                                     "' does not have any indexers defined");
+                       if (lookup_type != TypeManager.object_type)
+                               Report.Error (21, loc,
+                                             "Type '" + TypeManager.MonoBASIC_Name (lookup_type) +
+                                             "' does not have any indexers defined");
                        return null;
                }
        }
@@ -7135,6 +7183,18 @@ namespace Mono.MonoBASIC {
                        this.loc = loc;
                }
 
+               public Expression Instance {
+                       get {
+                               return instance_expr;
+                       }
+               }
+
+               public ArrayList Arguments {
+                       get {
+                               return arguments;
+                       }
+               }
+
                protected virtual bool CommonResolve (EmitContext ec)
                {
                        indexer_type = instance_expr.Type;
@@ -7166,8 +7226,9 @@ namespace Mono.MonoBASIC {
                                        ec, new MethodGroupExpr (ilist.getters, loc), arguments, loc);
 
                        if (get == null){
-                               Error (30524, "indexer can not be used in this context, because " +
-                                      "it lacks a 'get' accessor");
+                               if (instance_expr.Type != TypeManager.object_type)
+                                       Error (30524, "indexer can not be used in this context, because " +
+                                               "it lacks a 'get' accessor");
                                return null;
                        }
 
index 50cb828d1feb68c3e8b2bad8bdbad983d535ed94..a88c5eff32534bf2a46eaba73d4d94bfda488bd5 100644 (file)
@@ -4061,7 +4061,9 @@ opt_variable_initializer
 variable_initializer
        : expression
          {
-               $$ = $1;
+               Expression etmp = (Expression) $1;
+               etmp = SetValueRequiredFlag (etmp);
+               $$ = etmp;
          }
        | array_initializer
          {
@@ -4362,15 +4364,11 @@ argument_list
 argument
        : expression
          {
-               Expression expr = (Expression) $1;
-               expr = SetValueRequiredFlag (expr);
-               $$ = new Argument (expr, Argument.AType.Expression);
+               $$ = new Argument ((Expression) $1, Argument.AType.Expression);
          }
        | BYREF variable_reference
          {
-               Expression expr = (Expression) $2;
-               expr = SetValueRequiredFlag (expr);
-               $$ = new Argument (expr, Argument.AType.Ref);
+               $$ = new Argument ((Expression) $2, Argument.AType.Ref);
          }
        | /* empty */
          {
@@ -4378,9 +4376,7 @@ argument
          }
        | ADDRESSOF expression
          {
-               Expression expr = (Expression) $2;
-               expr = SetValueRequiredFlag (expr);
-               $$ = new Argument (expr, Argument.AType.AddressOf);
+               $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
          }
        ;
 
@@ -4639,72 +4635,57 @@ conditional_xor_expression
 assignment_expression
        : prefixed_unary_expression ASSIGN _mark_ expression
          { 
-               Expression expr = SetValueRequiredFlag ((Expression) $4);
-               $$ = new Assign ((Expression) $1, expr, (Location)$3);
+               $$ = new Assign ((Expression) $1, (Expression) $4, (Location)$3);
          }
        | prefixed_unary_expression OP_EXP ASSIGN _mark_ expression
          {
                Location l = (Location)$4;
-               Expression expr = SetValueRequiredFlag ((Expression) $5);
-
                $$ = new CompoundAssign (
-                       Binary.Operator.Exponentiation, (Expression) $1, expr, l);
+                       Binary.Operator.Exponentiation, (Expression) $1, (Expression) $5, l);
          }
        | prefixed_unary_expression STAR ASSIGN _mark_ expression
          {
                Location l = (Location)$4;
-               Expression expr = SetValueRequiredFlag ((Expression) $5);
                $$ = new CompoundAssign (
-                       Binary.Operator.Multiply, (Expression) $1, expr, l);
+                       Binary.Operator.Multiply, (Expression) $1, (Expression) $5, l);
          }
        | prefixed_unary_expression DIV ASSIGN _mark_ expression
          {
                Location l = (Location)$4;
-
-               Expression expr = SetValueRequiredFlag ((Expression) $5);
                $$ = new CompoundAssign (
-                       Binary.Operator.Division, (Expression) $1, expr, l);
+                       Binary.Operator.Division, (Expression) $1, (Expression) $5, l);
          }
        | prefixed_unary_expression PLUS ASSIGN _mark_ expression
          {
                Location l = (Location)$4;
-               Expression expr = SetValueRequiredFlag ((Expression) $5);
-
                $$ = new CompoundAssign (
-                       Binary.Operator.Addition, (Expression) $1, expr, l);
+                       Binary.Operator.Addition, (Expression) $1, (Expression) $5, l);
          }
        | prefixed_unary_expression MINUS ASSIGN _mark_ expression
          {
                Location l = (Location)$4;
-
-               Expression expr = SetValueRequiredFlag ((Expression) $5);
                $$ = new CompoundAssign (
-                       Binary.Operator.Subtraction, (Expression) $1, expr, l);
+                       Binary.Operator.Subtraction, (Expression) $1, (Expression) $5, l);
          }
        | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN _mark_ expression
          {
                Location l = (Location)$4;
-
-               Expression expr = SetValueRequiredFlag ((Expression) $5);
                $$ = new CompoundAssign (
-                       Binary.Operator.LeftShift, (Expression) $1, expr, l);
+                       Binary.Operator.LeftShift, (Expression) $1, (Expression) $5, l);
          }
        | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN _mark_ expression
          {
                Location l = (Location)$4;
-
-               Expression expr = SetValueRequiredFlag ((Expression) $5);
                $$ = new CompoundAssign (
-                       Binary.Operator.RightShift, (Expression) $1, expr, l);
+                       Binary.Operator.RightShift, (Expression) $1, (Expression) $5, l);
          }
        | prefixed_unary_expression OP_CONCAT ASSIGN _mark_ expression
          {
                Location l = (Location)$4;
 
                // FIXME should be strings only
-               Expression expr = SetValueRequiredFlag ((Expression) $5);
                $$ = new CompoundAssign (
-                       Binary.Operator.Addition, (Expression) $1, expr, l);
+                       Binary.Operator.Addition, (Expression) $1, (Expression) $5, l);
          }
        | prefixed_unary_expression ASSIGN ADDRESSOF _mark_ expression
          { 
@@ -5588,11 +5569,37 @@ void Error_ExpectingTypeName (Location l, Expression expr)
        }
 }
 
-static Expression SetValueRequiredFlag (Expression expr) {
+public static Expression SetLeftHandFlag (Expression expr) {
+       if (expr is Invocation) {
+               Invocation e = (Invocation) expr;
+               e.IsLeftHand = true;
+               return e;
+       } else if (expr is MemberAccess) {
+               MemberAccess e = (MemberAccess) expr;
+               e.IsLeftHand = true;
+               return e;
+       }
+
+       return expr;
+}
+
+public static Expression SetValueRequiredFlag (Expression expr) {
        if (expr is Invocation) {
                Invocation e = (Invocation) expr;
                e.IsRetvalRequired = true;
                expr = e;
+               return expr;
+       }
+       if (expr is Binary) {
+               Binary binary = (Binary) expr;
+               binary.Left  = SetValueRequiredFlag (binary.Left);
+               binary.Right  = SetValueRequiredFlag (binary.Right);
+               return binary;  
+       }
+       if (expr is Unary) {
+               Unary unary = (Unary) expr;
+               unary.Expr = SetValueRequiredFlag (unary.Expr);
+               return unary;
        }
        return expr;
 }
index bd74c45a13e655d36c6b2402eac1070e80b0c5bd..a45742352bedcccb5f85a3878e7a4ef7fe664f42 100644 (file)
@@ -3303,6 +3303,21 @@ namespace Mono.MonoBASIC {
                        this.isRetValRequired = this.isLeftHandSide = false;
                }
 
+               public ArrayList Arguments {
+                       get {
+                               return args;
+                       }
+                       set {
+                               args = value;
+                       }
+               }
+
+               public bool IsLeftHandSide {
+                       set {
+                               isLeftHandSide = value;
+                       }
+               }
+
                public Block StmtBlock {
                        get {
                                return stmtBlock;
@@ -3321,12 +3336,6 @@ namespace Mono.MonoBASIC {
                public void GenerateLateBindingStatements ()
                {
                        int argCount = 0;
-                       // Arguments for call Microsoft.VisualBasic.CompilerServices.LateBinding.LateCall
-                       ArrayList invocationArgs = new ArrayList ();
-                       invocationArgs.Add (new Argument (((MemberAccess)expr).Expr, Argument.AType.Expression));
-                       invocationArgs.Add (new Argument (NullLiteral.Null, Argument.AType.Expression));
-                       invocationArgs.Add (new Argument (new StringLiteral (((MemberAccess)expr).Identifier), Argument.AType.Expression));
-                       // __LateBindingArgs = new Object () {arg1, arg2 ...}
                        ArrayList arrayInitializers = new ArrayList ();
                        ArrayList originalArgs = new ArrayList ();
                        if (args != null) {
@@ -3338,19 +3347,47 @@ namespace Mono.MonoBASIC {
                                }
                        }
 
+                       // __LateBindingArgs = new Object () {arg1, arg2 ...}
                        ArrayCreation new_expr = new ArrayCreation (Parser.DecomposeQI ("System.Object",  loc), "[]", arrayInitializers, loc);
                        Assign assign_stmt = null;
 
                        LocalVariableReference v1 = new LocalVariableReference (stmtBlock, Block.lateBindingArgs, loc);
                        assign_stmt = new Assign (v1, new_expr, loc);
                        stmtBlock.AddStatement (new StatementExpression ((ExpressionStatement) assign_stmt, loc));
-                       invocationArgs.Add (new Argument (v1, Argument.AType.Expression));
-
                        // __LateBindingArgNames = nothing
                        //LocalVariableReference v2 = new LocalVariableReference (stmtBlock, Block.lateBindingArgNames, loc);
                        //assign_stmt = new Assign (v2, NullLiteral.Null, loc);
                        //stmtBlock.AddStatement (new StatementExpression ((ExpressionStatement) assign_stmt, loc));
-
+                       // Arguments for call Microsoft.VisualBasic.CompilerServices.LateBinding.LateCall
+                       Expression tempExpr = expr;
+                       string memName = "";
+                       bool isIndexerAccess = true;
+                       if (expr is MemberAccess) {
+                               tempExpr = ((MemberAccess)expr).Expr;
+                               memName = ((MemberAccess)expr).Identifier;
+                               isIndexerAccess = false;
+                       } else if (expr is IndexerAccess) {
+                               tempExpr = ((IndexerAccess) expr).Instance;
+                       }
+                       ArrayList invocationArgs = new ArrayList ();
+                       if (isIndexerAccess) {
+                               invocationArgs.Add (new Argument (tempExpr, Argument.AType.Expression));
+                               invocationArgs.Add (new Argument (v1, Argument.AType.Expression));
+                               invocationArgs.Add (new Argument (NullLiteral.Null, Argument.AType.Expression));
+                               Expression tmp = null;
+                               if (!isLeftHandSide)
+                                       tmp = Parser.DecomposeQI ("Microsoft.VisualBasic.CompilerServices.LateBinding.LateIndexGet", loc);
+                               else
+                                       tmp = Parser.DecomposeQI ("Microsoft.VisualBasic.CompilerServices.LateBinding.LateIndexSet", loc);
+                               Invocation invStmt = new Invocation (tmp, invocationArgs, Location.Null);
+                               invStmt.IsLateBinding = true;
+                               stmtBlock.AddStatement (new StatementExpression ((ExpressionStatement) invStmt, loc));
+                               return;
+                       }
+                       invocationArgs.Add (new Argument (tempExpr, Argument.AType.Expression));
+                       invocationArgs.Add (new Argument (NullLiteral.Null, Argument.AType.Expression));
+                       invocationArgs.Add (new Argument (new StringLiteral (memName), Argument.AType.Expression));
+                       invocationArgs.Add (new Argument (v1, Argument.AType.Expression));
                        invocationArgs.Add (new Argument (NullLiteral.Null, Argument.AType.Expression));
 
                        // __LateBindingCopyBack = new Boolean (no_of_args) {}
@@ -3383,6 +3420,7 @@ namespace Mono.MonoBASIC {
                        Expression etmp = null;
                        if (isLeftHandSide) {
                                // LateSet
+                               etmp = Parser.DecomposeQI ("Microsoft.VisualBasic.CompilerServices.LateBinding.LateSet", loc);
                        } else if (isRetValRequired) {
                                // Late Get
                                etmp = Parser.DecomposeQI ("Microsoft.VisualBasic.CompilerServices.LateBinding.LateGet", loc);