2003-04-28 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / cs-parser.jay
index 839c2dba89147d519c883e729358e0cff30f7d7e..005def9fa45a8608bce2ffa6a55904997d37358b 100755 (executable)
@@ -34,6 +34,8 @@ namespace Mono.CSharp
                Namespace     current_namespace;
                TypeContainer current_container;
        
+               IIteratorContainer iterator_container;
+
                // <summary>
                //   Current block is used to add statements as we find
                //   them.  
@@ -173,6 +175,9 @@ namespace Mono.CSharp
 %token VOLATILE
 %token WHILE   
 
+/* v2 tokens */
+%token YIELD
+
 /* C# keywords which are not really keywords */
 %token GET           "get"
 %token SET           "set"
@@ -404,7 +409,9 @@ namespace_member_declaration
                }
                current_namespace.DeclarationFound = true;
          }
-       | namespace_declaration
+       | namespace_declaration {
+               current_namespace.DeclarationFound = true;
+         }
        ;
 
 type_declaration
@@ -809,11 +816,13 @@ variable_initializer
        ;
 
 method_declaration
-       : method_header
+       : method_header {
+               iterator_container = (IIteratorContainer) $1;
+         }
          method_body
          {
                Method method = (Method) $1;
-               Block b = (Block) $2;
+               Block b = (Block) $3;
                const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
 
                if (b == null){
@@ -830,10 +839,11 @@ method_declaration
                        }
                }
 
-               method.Block = (Block) $2;
+               method.Block = (Block) $3;
                CheckDef (current_container.AddMethod (method), method.Name, method.Location);
 
                current_local_parameters = null;
+               iterator_container = null;
          }
        ;
 
@@ -3188,7 +3198,7 @@ statement_expression_list
        : statement_expression  
          {
                // CHANGE: was `null'
-               Block b = new Block (current_block, true);   
+               Block b = new Block (current_block, Block.Flags.Implicit);   
 
                b.AddStatement ((Statement) $1);
                $$ = b;
@@ -3211,7 +3221,7 @@ foreach_statement
          {
                oob_stack.Push (current_block);
 
-               Block foreach_block = new Block (current_block, true);
+               Block foreach_block = new Block (current_block, Block.Flags.Implicit);
                LocalVariableReference v = null;
                Location l = lexer.Location;
                VariableInfo vi;
@@ -3252,6 +3262,7 @@ jump_statement
        | goto_statement
        | return_statement
        | throw_statement
+       | yield_statement
        ;
 
 break_statement
@@ -3297,6 +3308,29 @@ throw_statement
          }
        ;
 
+yield_statement 
+       : YIELD expression SEMICOLON
+         {
+               if (iterator_container == null){
+                       Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+                       $$ = null;
+               } else {
+                       iterator_container.SetYields ();
+                       $$ = new Yield ((Expression) $2, lexer.Location);
+               }
+         }
+       | YIELD BREAK SEMICOLON
+         {
+               if (iterator_container == null){
+                       Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+                       $$ = null;
+               } else {
+                       iterator_container.SetYields ();
+                       $$ = new YieldBreak (lexer.Location);
+               }
+         }
+       ;
+
 opt_expression
        : /* empty */
        | expression
@@ -3459,7 +3493,7 @@ fixed_statement
          type fixed_pointer_declarators 
          CLOSE_PARENS 
          {
-               Block assign_block = new Block (current_block, true);
+               Block assign_block = new Block (current_block, Block.Flags.Implicit);
                ArrayList list = (ArrayList) $4;
                Expression type = (Expression) $3;
                Location l = lexer.Location;
@@ -3790,7 +3824,7 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators,
        // int j = 1;  int k = j + 1;
        //
        if (current_block.Used) {
-               implicit_block = new Block (current_block, true, loc, Location.Null);
+               implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null);
                implicit_block.AddChildVariableNames (current_block);
        } else
                implicit_block = current_block;
@@ -3838,7 +3872,7 @@ Block declare_local_constant (Expression type, VariableDeclaration decl)
        Block implicit_block;
 
        if (current_block.Used)
-               implicit_block = new Block (current_block, true);
+               implicit_block = new Block (current_block, Block.Flags.Implicit);
        else
                implicit_block = current_block;