2003-07-22 Martin Baulig <martin@ximian.com>
authorMartin Baulig <martin@novell.com>
Tue, 22 Jul 2003 19:01:08 +0000 (19:01 -0000)
committerMartin Baulig <martin@novell.com>
Tue, 22 Jul 2003 19:01:08 +0000 (19:01 -0000)
* cs-parser.jay (invocation_expression): Moved
`OPEN_PARENS expression CLOSE_PARENS unary_expression' here from
`cast_expression', but create a InvocationOrCast which later
resolves to either an Invocation or a Cast.

* ecore.cs (ExpressionStatement.ResolveStatement): New virtual
method; call this before EmitStatement() to make sure that this
expression can be used as a statement.

* expression.cs (InvocationOrCast): New class; resolves to either
an Invocation or a Cast.

* statement.cs (StatementExpression): Call ResolveStatement() on
the ExpressionStatement before emitting it.

svn path=/trunk/mcs/; revision=16537

mcs/mcs/ChangeLog
mcs/mcs/class.cs
mcs/mcs/cs-parser.jay
mcs/mcs/ecore.cs
mcs/mcs/expression.cs
mcs/mcs/statement.cs

index 706c2209be671acfb9914f768aa34866dd3fc0bc..ed9262a950fca468ba21f774a6efc172a5a80059 100755 (executable)
@@ -1,3 +1,20 @@
+2003-07-22  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay (invocation_expression): Moved
+       `OPEN_PARENS expression CLOSE_PARENS unary_expression' here from
+       `cast_expression', but create a InvocationOrCast which later
+       resolves to either an Invocation or a Cast.
+
+       * ecore.cs (ExpressionStatement.ResolveStatement): New virtual
+       method; call this before EmitStatement() to make sure that this
+       expression can be used as a statement.
+
+       * expression.cs (InvocationOrCast): New class; resolves to either
+       an Invocation or a Cast.
+
+       * statement.cs (StatementExpression): Call ResolveStatement() on
+       the ExpressionStatement before emitting it.
+
 2003-07-21  Martin Baulig  <martin@ximian.com>
 
        * expression.cs (Invocation.VerifyArgumentsCompat): Check whether
index 5024864c14a4580158f52cfbe4d4802561336bbe..19ee88d1b099b03853ad3a3a7f7eabf468630b97 100755 (executable)
@@ -553,17 +553,13 @@ namespace Mono.CSharp {
                                Location l = f.Location;
                                FieldExpr fe = new FieldExpr (f.FieldBuilder, l);
                                fe.InstanceExpression = instance_expr;
-                               Expression a = new Assign (fe, e, l);
+                               ExpressionStatement a = new Assign (fe, e, l);
 
-                               a = a.Resolve (ec);
+                               a = a.ResolveStatement (ec);
                                if (a == null)
                                        return false;
 
-                               if (a is ExpressionStatement)
-                                       ((ExpressionStatement) a).EmitStatement (ec);
-                               else {
-                                       throw new Exception ("Assign.Resolve returned a non ExpressionStatement");
-                               }
+                               a.EmitStatement (ec);
                        }
 
                        return true;
index 0310a7c33054840fe96fbb1aeb1b910238d8833a..71a65608256402187e206ee45c6861e6ee1355b5 100755 (executable)
@@ -2046,7 +2046,11 @@ invocation_expression
                }
                $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
          }
-       ; 
+       | OPEN_PARENS expression CLOSE_PARENS unary_expression
+         {
+                 $$ = new InvocationOrCast ((Expression) $2, (Expression) $4, lexer.Location);
+         }
+       ;
 
 opt_argument_list
        : /* empty */           { $$ = null; }
@@ -2394,11 +2398,7 @@ unary_expression
        ;
 
 cast_expression
-        : OPEN_PARENS expression CLOSE_PARENS unary_expression
-         {
-                 $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
-         }
-        | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
+       : OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
          {
                  $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
          }
index a7dc5e4a01049cf8a7ff499d6ad33f61a00b0ef9..c10835bdae4c738392c628bae53838cfc0689c3d 100755 (executable)
@@ -1282,6 +1282,20 @@ namespace Mono.CSharp {
        /// </summary>
        public abstract class ExpressionStatement : Expression {
 
+               public virtual ExpressionStatement ResolveStatement (EmitContext ec)
+               {
+                       Expression e = Resolve (ec);
+                       if (e == null)
+                               return null;
+
+                       ExpressionStatement es = e as ExpressionStatement;
+                       if (es == null)
+                               Error (201, "Only assignment, call, increment, decrement and new object " +
+                                      "expressions can be used as a statement");
+
+                       return es;
+               }
+
                /// <summary>
                ///   Requests the expression to be emitted in a `statement'
                ///   context.  This means that no new value is left on the
index da4ef718e38d014b89ccbf4dad99fecd34b31092..966484c26a6040f25490e53c4188eca6d73b7f21 100755 (executable)
@@ -5013,6 +5013,111 @@ namespace Mono.CSharp {
                }
        }
 
+       public class InvocationOrCast : ExpressionStatement
+       {
+               Expression expr;
+               Expression argument;
+
+               public InvocationOrCast (Expression expr, Expression argument, Location loc)
+               {
+                       this.expr = expr;
+                       this.argument = argument;
+                       this.loc = loc;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       //
+                       // First try to resolve it as a cast.
+                       //
+                       type = ec.DeclSpace.ResolveType (expr, true, loc);
+                       if (type != null) {
+                               Cast cast = new Cast (new TypeExpr (type, loc), argument, loc);
+                               return cast.Resolve (ec);
+                       }
+
+                       //
+                       // This can either be a type or a delegate invocation.
+                       // Let's just resolve it and see what we'll get.
+                       //
+                       expr = expr.Resolve (ec, ResolveFlags.Type | ResolveFlags.VariableOrValue);
+                       if (expr == null)
+                               return null;
+
+                       //
+                       // Ok, so it's a Cast.
+                       //
+                       if (expr.eclass == ExprClass.Type) {
+                               Cast cast = new Cast (new TypeExpr (expr.Type, loc), argument, loc);
+                               return cast.Resolve (ec);
+                       }
+
+                       //
+                       // It's a delegate invocation.
+                       //
+                       if (!TypeManager.IsDelegateType (expr.Type)) {
+                               Error (149, "Method name expected");
+                               return null;
+                       }
+
+                       ArrayList args = new ArrayList ();
+                       args.Add (new Argument (argument, Argument.AType.Expression));
+                       DelegateInvocation invocation = new DelegateInvocation (expr, args, loc);
+                       return invocation.Resolve (ec);
+               }
+
+               void error201 ()
+               {
+                       Error (201, "Only assignment, call, increment, decrement and new object " +
+                              "expressions can be used as a statement");
+               }
+
+               public override ExpressionStatement ResolveStatement (EmitContext ec)
+               {
+                       //
+                       // First try to resolve it as a cast.
+                       //
+                       type = ec.DeclSpace.ResolveType (expr, true, loc);
+                       if (type != null) {
+                               error201 ();
+                               return null;
+                       }
+
+                       //
+                       // This can either be a type or a delegate invocation.
+                       // Let's just resolve it and see what we'll get.
+                       //
+                       expr = expr.Resolve (ec, ResolveFlags.Type | ResolveFlags.VariableOrValue);
+                       if ((expr == null) || (expr.eclass == ExprClass.Type)) {
+                               error201 ();
+                               return null;
+                       }
+
+                       //
+                       // It's a delegate invocation.
+                       //
+                       if (!TypeManager.IsDelegateType (expr.Type)) {
+                               Error (149, "Method name expected");
+                               return null;
+                       }
+
+                       ArrayList args = new ArrayList ();
+                       args.Add (new Argument (argument, Argument.AType.Expression));
+                       DelegateInvocation invocation = new DelegateInvocation (expr, args, loc);
+                       return invocation.ResolveStatement (ec);
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       throw new Exception ("Cannot happen");
+               }
+
+               public override void EmitStatement (EmitContext ec)
+               {
+                       throw new Exception ("Cannot happen");
+               }
+       }
+
        //
        // This class is used to "disable" the code generation for the
        // temporary variable when initializing value types.
index 376d82dc17a1b9dc9af8de800c352fe97514d951..e6f8eeee053977017ab2a8e99f2391c66ae261cc 100755 (executable)
@@ -544,7 +544,7 @@ namespace Mono.CSharp {
        }
        
        public class StatementExpression : Statement {
-               Expression expr;
+               ExpressionStatement expr;
                
                public StatementExpression (ExpressionStatement expr, Location l)
                {
@@ -554,7 +554,7 @@ namespace Mono.CSharp {
 
                public override bool Resolve (EmitContext ec)
                {
-                       expr = (Expression) expr.Resolve (ec);
+                       expr = expr.ResolveStatement (ec);
                        return expr != null;
                }
                
@@ -562,12 +562,7 @@ namespace Mono.CSharp {
                {
                        ILGenerator ig = ec.ig;
                        
-                       if (expr is ExpressionStatement)
-                               ((ExpressionStatement) expr).EmitStatement (ec);
-                       else {
-                               expr.Emit (ec);
-                               ig.Emit (OpCodes.Pop);
-                       }
+                       expr.EmitStatement (ec);
 
                        return false;
                }