2002-08-19 Martin Baulig <martin@gnome.org>
[mono.git] / mcs / mcs / cs-parser.jay
index b151ed910416d75a81a3834eaf293849817dee89..49b08716d9edced03471596cda0b062a7d981d52 100755 (executable)
@@ -1,33 +1,19 @@
 %{
 //
-// OPTIMIZATION:
-//   This loop is pointless:
-//    while (current_block != prev_block)
-//       current_block = current_block.Parent;
-//
 // cs-parser.jay: The Parser for the C# compiler
 //
-// Author: Miguel de Icaza (miguel@gnu.org)
-//         Ravi Pratap     (ravi@ximian.com)
+// Authors: Miguel de Icaza (miguel@gnu.org)
+//          Ravi Pratap     (ravi@ximian.com)
 //
 // Licensed under the terms of the GNU GPL
 //
 // (C) 2001 Ximian, Inc (http://www.ximian.com)
 //
 // TODO:
-//   (1) Get rid of the *Collections.cs, that is an idea I took from System.CodeDOM
-//       And come to think of it, it is not that great, it duplicates a lot of code
-//       for something which is not really needed.  We still have piles of typecasts
-//       anwyays (due to the nature of the stack being a collection of Objects).
-//
-//   (2) Figure out why error productions dont work.  `type-declaration' is a
+//   (1) Figure out why error productions dont work.  `type-declaration' is a
 //       great spot to put an `error' because you can reproduce it with this input:
 //      "public X { }"
 //
-//   (3) Move Modifier checking from each object into the parser itself, that will
-//       get rid of the global "error" symbol that we use now to report errors. 
-//       We still need to pass a pointer to the tree.ErrorHandler, but that is a 
-//      separate problem
 //
 using System.Text;
 using System;
@@ -69,7 +55,7 @@ namespace Mono.CSharp
                //   value parameter that is passed to the "set" and "get"accesor
                //   methods (properties and indexers).
                // </summary>
-               string     implicit_value_parameter_type;
+               Expression implicit_value_parameter_type;
                Parameters indexer_parameters;
 
                // <summary>
@@ -82,6 +68,11 @@ namespace Mono.CSharp
                // An out-of-band stack.
                //
                Stack oob_stack;
+
+               //
+               // Switch stack.
+               //
+               Stack switch_stack;
 %}
 
 %token EOF
@@ -301,7 +292,7 @@ using_alias_directive
 using_namespace_directive
        : USING namespace_name SEMICOLON 
          {
-               current_namespace.Using ((string) $2);
+               current_namespace.Using ((string) $2, lexer.Location);
           }
        ;
 
@@ -398,6 +389,7 @@ namespace_member_declaration
                                "Namespace elements cant be explicitly " +
                                "declared private or protected in `" + name + "'");
                }
+               current_namespace.DeclarationFound = true;
          }
        | namespace_declaration
        ;
@@ -708,7 +700,7 @@ constant_declaration
                        Location l = constant.Location;
 
                        Const c = new Const (
-                               (string) $4, (string) constant.identifier, 
+                               (Expression) $4, (string) constant.identifier, 
                                (Expression) constant.expression_or_array_initializer, (int) $2, 
                                (Attributes) $1, l);
 
@@ -746,7 +738,7 @@ field_declaration
          variable_declarators
          SEMICOLON
          { 
-               string type = (string) $3;
+               Expression type = (Expression) $3;
                int mod = (int) $2;
 
                foreach (VariableDeclaration var in (ArrayList) $4){
@@ -798,7 +790,7 @@ variable_initializer
          }
        | STACKALLOC type OPEN_BRACKET expression CLOSE_BRACKET
          {
-               $$ = new StackAlloc ((string) $2, (Expression) $4, lexer.Location);
+               $$ = new StackAlloc ((Expression) $2, (Expression) $4, lexer.Location);
          }
        ;
 
@@ -857,7 +849,7 @@ method_header
          member_name
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
          {
-               Method method = new Method ((string) $3, (int) $2, (string) $4, 
+               Method method = new Method ((Expression) $3, (int) $2, (string) $4, 
                                            (Parameters) $6, (Attributes) $1, lexer.Location);
 
                current_local_parameters = (Parameters) $6;
@@ -870,7 +862,7 @@ method_header
          member_name
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
          {
-               Method method = new Method ("System.Void", (int) $2, (string) $4, 
+               Method method = new Method (TypeManager.system_void_expr, (int) $2, (string) $4, 
                                            (Parameters) $6, (Attributes) $1, lexer.Location);
 
                current_local_parameters = (Parameters) $6;
@@ -884,7 +876,7 @@ method_body
        ;
 
 opt_formal_parameter_list
-       : /* empty */                   { $$ = Parameters.GetEmptyReadOnlyParameters (); }
+       : /* empty */                   { $$ = Parameters.EmptyReadOnlyParameters; }
        | formal_parameter_list
        ;
 
@@ -936,7 +928,7 @@ fixed_parameter
          type
          IDENTIFIER
          {
-               $$ = new Parameter ((string) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1);
+               $$ = new Parameter ((Expression) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1);
          }
        ;
 
@@ -946,14 +938,14 @@ opt_parameter_modifier
        ;
 
 parameter_modifier
-       : REF                   { $$ = Parameter.Modifier.REF; }
-       | OUT                   { $$ = Parameter.Modifier.OUT; }
+       : REF                   { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
+       | OUT                   { $$ = Parameter.Modifier.OUT | Parameter.Modifier.ISBYREF; }
        ;
 
 parameter_array
        : opt_attributes PARAMS type IDENTIFIER
          { 
-               $$ = new Parameter ((string) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1);
+               $$ = new Parameter ((Expression) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1);
                note ("type must be a single-dimension array type"); 
          }
        ;
@@ -968,7 +960,7 @@ property_declaration
          type member_name
          OPEN_BRACE 
          {
-               implicit_value_parameter_type = (string) $3;
+               implicit_value_parameter_type = (Expression) $3;
 
                lexer.PropertyParsing = true;
 
@@ -986,7 +978,7 @@ property_declaration
                Accessor set_block = (Accessor) pair.Second;
 
                Location loc = (Location) $6;
-               prop = new Property ((string) $3, (string) $4, (int) $2, get_block, set_block,
+               prop = new Property ((Expression) $3, (string) $4, (int) $2, get_block, set_block,
                                     (Attributes) $1, loc);
                
                CheckDef (current_container.AddProperty (prop), prop.Name, loc);
@@ -1186,14 +1178,15 @@ interface_method_declaration
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
          SEMICOLON
          {
-               $$ = new InterfaceMethod ((string) $3, (string) $4, (bool) $2, 
+               $$ = new InterfaceMethod ((Expression) $3, (string) $4, (bool) $2, 
                                          (Parameters) $6, (Attributes) $1, lexer.Location);
          }
        | opt_attributes opt_new VOID IDENTIFIER 
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
          SEMICOLON
          {
-               $$ = new InterfaceMethod ("System.Void", (string) $4, (bool) $2, (Parameters) $6, 
+               $$ = new InterfaceMethod (
+                       TypeManager.system_void_expr, (string) $4, (bool) $2, (Parameters) $6, 
                                          (Attributes) $1, lexer.Location);
          }
        ;
@@ -1210,7 +1203,7 @@ interface_property_declaration
          {
                int gs = (int) $7;
 
-               $$ = new InterfaceProperty ((string) $3, (string) $4, (bool) $2, 
+               $$ = new InterfaceProperty ((Expression) $3, (string) $4, (bool) $2, 
                                            (gs & 1) == 1, (gs & 2) == 2, (Attributes) $1,
                                            lexer.Location);
          }
@@ -1228,7 +1221,8 @@ interface_accesors
 interface_event_declaration
        : opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON
          {
-               $$ = new InterfaceEvent ((string) $4, (string) $5, (bool) $2, (Attributes) $1);
+               $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
+                                        lexer.Location);
          }
        ;
 
@@ -1246,7 +1240,7 @@ interface_indexer_declaration
                bool do_get = (a_flags & 1) == 1;
                bool do_set = (a_flags & 2) == 2;
 
-               $$ = new InterfaceIndexer ((string) $3, (Parameters) $6, do_get, do_set,
+               $$ = new InterfaceIndexer ((Expression) $3, (Parameters) $6, do_get, do_set,
                                           (bool) $2, (Attributes) $1, lexer.Location);
          }
        ;
@@ -1285,11 +1279,11 @@ operator_declarator
 
                Parameter [] pars = new Parameter [1];
 
-               pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
+               pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
 
                current_local_parameters = new Parameters (pars, null, lexer.Location);
 
-               $$ = new OperatorDeclaration (op, (string) $1, (string) $5, (string) $6,
+               $$ = new OperatorDeclaration (op, (Expression) $1, (Expression) $5, (string) $6,
                                              null, null, lexer.Location);
        }
        | type OPERATOR overloadable_operator
@@ -1302,13 +1296,14 @@ operator_declarator
 
               Parameter [] pars = new Parameter [2];
 
-              pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
-              pars [1] = new Parameter ((string) $8, (string) $9, Parameter.Modifier.NONE, null);
+              pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
+              pars [1] = new Parameter ((Expression) $8, (string) $9, Parameter.Modifier.NONE, null);
 
               current_local_parameters = new Parameters (pars, null, lexer.Location);
               
-              $$ = new OperatorDeclaration ((Operator.OpType) $3, (string) $1, (string) $5, (string) $6,
-                                            (string) $8, (string) $9, lexer.Location);
+              $$ = new OperatorDeclaration ((Operator.OpType) $3, (Expression) $1, 
+                                            (Expression) $5, (string) $6,
+                                            (Expression) $8, (string) $9, lexer.Location);
         }
        | conversion_operator_declarator
        ;
@@ -1346,22 +1341,22 @@ conversion_operator_declarator
          {
                Parameter [] pars = new Parameter [1];
 
-               pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
+               pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
 
                current_local_parameters = new Parameters (pars, null, lexer.Location);  
                  
-               $$ = new OperatorDeclaration (Operator.OpType.Implicit, (string) $3, (string) $5, (string) $6,
+               $$ = new OperatorDeclaration (Operator.OpType.Implicit, (Expression) $3, (Expression) $5, (string) $6,
                                              null, null, lexer.Location);
          }
        | EXPLICIT OPERATOR type OPEN_PARENS type IDENTIFIER CLOSE_PARENS
          {
                Parameter [] pars = new Parameter [1];
 
-               pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
+               pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
 
                current_local_parameters = new Parameters (pars, null, lexer.Location);  
                  
-               $$ = new OperatorDeclaration (Operator.OpType.Explicit, (string) $3, (string) $5, (string) $6,
+               $$ = new OperatorDeclaration (Operator.OpType.Explicit, (Expression) $3, (Expression) $5, (string) $6,
                                              null, null, lexer.Location);
          }
        | IMPLICIT error 
@@ -1439,11 +1434,11 @@ opt_constructor_initializer
 constructor_initializer
        : COLON BASE OPEN_PARENS opt_argument_list CLOSE_PARENS
          {
-               $$ = new ConstructorBaseInitializer ((ArrayList) $4, lexer.Location);
+               $$ = new ConstructorBaseInitializer ((ArrayList) $4, current_local_parameters, lexer.Location);
          }
        | COLON THIS OPEN_PARENS opt_argument_list CLOSE_PARENS
          {
-               $$ = new ConstructorThisInitializer ((ArrayList) $4, lexer.Location);
+               $$ = new ConstructorThisInitializer ((ArrayList) $4, current_local_parameters, lexer.Location);
          }
        ;
 
@@ -1464,7 +1459,7 @@ destructor_declaration
                                m = Modifiers.PROTECTED | Modifiers.OVERRIDE;
 
                        Method d = new Method (
-                               "System.Void", m, "Finalize", 
+                               TypeManager.system_void_expr, m, "Finalize", 
                                new Parameters (null, null, l), (Attributes) $1, l);
                  
                        d.Block = (Block) $6;
@@ -1480,7 +1475,7 @@ event_declaration
          {
                foreach (VariableDeclaration var in (ArrayList) $5) {
 
-                       Event e = new Event ((string) $4, var.identifier, 
+                       Event e = new Event ((Expression) $4, var.identifier, 
                                             var.expression_or_array_initializer,
                                             (int) $2, null, null, (Attributes) $1, lexer.Location);
 
@@ -1493,7 +1488,7 @@ event_declaration
          EVENT type member_name
          OPEN_BRACE
          {
-               implicit_value_parameter_type = (string) $4;  
+               implicit_value_parameter_type = (Expression) $4;  
                lexer.EventParsing = true;
                oob_stack.Push (lexer.Location);
          }
@@ -1514,7 +1509,7 @@ event_declaration
                if (pair.Second != null)
                        rem_accessor = (Accessor) pair.Second;
                
-               Event e = new Event ((string) $4, (string) $5, null, (int) $2, add_accessor, rem_accessor,
+               Event e = new Event ((Expression) $4, (string) $5, null, (int) $2, add_accessor, rem_accessor,
                                     (Attributes) $1, loc);
                
                CheckDef (current_container.AddEvent (e), e.Name, loc);
@@ -1626,7 +1621,7 @@ indexer_declarator
                        Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
                }
 
-               $$ = new IndexerDeclaration ((string) $1, null, pars);
+               $$ = new IndexerDeclaration ((Expression) $1, null, pars);
          }
        | type qualified_identifier DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
          {
@@ -1635,7 +1630,7 @@ indexer_declarator
                if (pars.FixedParameters == null && pars.ArrayParameter == null){
                        Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
                }
-               $$ = new IndexerDeclaration ((string) $1, (string) $2, pars);
+               $$ = new IndexerDeclaration ((Expression) $1, (string) $2, pars);
          }
        ;
 
@@ -1650,7 +1645,7 @@ enum_declaration
                Location enum_location = lexer.Location;
 
                string full_name = MakeName ((string) $4);
-               Enum e = new Enum (current_container, (string) $5, (int) $2, full_name, 
+               Enum e = new Enum (current_container, (Expression) $5, (int) $2, full_name, 
                                   (Attributes) $1, enum_location);
                
                foreach (VariableDeclaration ev in (ArrayList) $6) {
@@ -1671,7 +1666,7 @@ enum_declaration
        ;
 
 opt_enum_base
-       : /* empty */           { $$ = "System.Int32"; }
+       : /* empty */           { $$ = TypeManager.system_int32_expr; }
        | COLON type            { $$ = $2;   }
        ;
 
@@ -1730,7 +1725,7 @@ delegate_declaration
          SEMICOLON
          {
                Location l = lexer.Location;
-               Delegate del = new Delegate (current_container, (string) $4, (int) $2, 
+               Delegate del = new Delegate (current_container, (Expression) $4, (int) $2, 
                                             MakeName ((string) $5), (Parameters) $7, 
                                             (Attributes) $1, l);
                  
@@ -1748,8 +1743,8 @@ delegate_declaration
                Location l = lexer.Location;
                Delegate del = new Delegate (
                        current_container,
-                       "System.Void", (int) $2, MakeName ((string) $5), (Parameters) $7
-                       (Attributes) $1, l);
+                       TypeManager.system_void_expr, (int) $2, MakeName ((string) $5)
+                       (Parameters) $7, (Attributes) $1, l);
 
                del.Namespace = current_namespace;
                CheckDef (current_container.AddDelegate (del), del.Name, l);
@@ -1776,7 +1771,7 @@ type
                   This does interfaces, delegates, struct_types, class_types, 
                   parent classes, and more! 4.2 
                 */
-               $$ = $1; 
+               $$ = DecomposeQI ((string) $1, lexer.Location);
          }
        | builtin_types
        | array_type
@@ -1792,19 +1787,16 @@ pointer_type
                // can't perform checks during this phase - we do it during
                // semantic analysis.
                //
-               $$ = (string) $1 + "*";
+               $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
          }
        | VOID STAR
          {
-               $$ = "System.Void*";
+               $$ = new ComposedCast (TypeManager.system_void_expr, "*", lexer.Location);
          }
        ;
 
 non_expression_type
        : builtin_types 
-         {
-               $$ = new SimpleName ((string) $1, lexer.Location);
-         }
        | non_expression_type rank_specifier
          {
                $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
@@ -1845,26 +1837,26 @@ type_list
  * simple types, but we need this to reuse it easily in local_variable_type
  */
 builtin_types
-       : OBJECT        { $$ = "System.Object"; }
-       | STRING        { $$ = "System.String"; }
-       | BOOL          { $$ = "System.Boolean"; }
-       | DECIMAL       { $$ = "System.Decimal"; }
-       | FLOAT         { $$ = "System.Single"; }
-       | DOUBLE        { $$ = "System.Double"; }
+       : OBJECT        { $$ = TypeManager.system_object_expr; }
+       | STRING        { $$ = TypeManager.system_string_expr; }
+       | BOOL          { $$ = TypeManager.system_boolean_expr; }
+       | DECIMAL       { $$ = TypeManager.system_decimal_expr; }
+       | FLOAT         { $$ = TypeManager.system_single_expr; }
+       | DOUBLE        { $$ = TypeManager.system_double_expr; }
        | integral_type
        ;
 
 integral_type
-       : SBYTE         { $$ = "System.SByte"; }
-       | BYTE          { $$ = "System.Byte"; }
-       | SHORT         { $$ = "System.Int16"; }
-       | USHORT        { $$ = "System.UInt16"; }
-       | INT           { $$ = "System.Int32"; }
-       | UINT          { $$ = "System.UInt32"; }
-       | LONG          { $$ = "System.Int64"; }
-       | ULONG         { $$ = "System.UInt64"; }
-       | CHAR          { $$ = "System.Char"; }
-       | VOID          { $$ = "System.Void"; }
+       : SBYTE         { $$ = TypeManager.system_sbyte_expr; }
+       | BYTE          { $$ = TypeManager.system_byte_expr; }
+       | SHORT         { $$ = TypeManager.system_int16_expr; }
+       | USHORT        { $$ = TypeManager.system_uint16_expr; }
+       | INT           { $$ = TypeManager.system_int32_expr; }
+       | UINT          { $$ = TypeManager.system_uint32_expr; }
+       | LONG          { $$ = TypeManager.system_int64_expr; }
+       | ULONG         { $$ = TypeManager.system_uint64_expr; }
+       | CHAR          { $$ = TypeManager.system_char_expr; }
+       | VOID          { $$ = TypeManager.system_void_expr; }
        ;
 
 interface_type
@@ -1874,7 +1866,7 @@ interface_type
 array_type
        : type rank_specifiers
          {
-                 $$ = (string) $1 + (string) $2;
+               $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
          }
        ;
 
@@ -1908,8 +1900,6 @@ primary_expression
        | checked_expression
        | unchecked_expression
        | pointer_member_access
-       // TODO: pointer_element_access
-       // TODO: sizeof-expression
        ;
 
 literal
@@ -1931,10 +1921,6 @@ integer_literal
        : LITERAL_INTEGER       { 
                object v = lexer.Value;
 
-               // 
-               // FIXME: Possible optimization would be to 
-               // compute the *Literal objects directly in the scanner
-               //
                if (v is int)
                        $$ = new IntLiteral ((Int32) v); 
                else if (v is uint)
@@ -1965,7 +1951,7 @@ member_access
          }
        | predefined_type DOT IDENTIFIER
          {
-               $$ = new MemberAccess (new SimpleName ((string) $1, lexer.Location), (string) $3, lexer.Location);
+               $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
          }
        ;
 
@@ -2070,7 +2056,7 @@ expression_list
 this_access
        : THIS
          {
-               $$ = new This (lexer.Location);
+               $$ = new This (current_block, lexer.Location);
          }
        ;
 
@@ -2109,7 +2095,7 @@ new_expression
 object_or_delegate_creation_expression
        : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
          {
-               $$ = new New ((string) $2, (ArrayList) $4, lexer.Location);
+               $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
          }
        ;
 
@@ -2118,11 +2104,11 @@ array_creation_expression
          opt_rank_specifier
          opt_array_initializer
          {
-               $$ = new ArrayCreation ((string) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, lexer.Location);
+               $$ = new ArrayCreation ((Expression) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, lexer.Location);
          }
        | NEW type rank_specifiers array_initializer
          {
-               $$ = new ArrayCreation ((string) $2, (string) $3, (ArrayList) $4, lexer.Location);
+               $$ = new ArrayCreation ((Expression) $2, (string) $3, (ArrayList) $4, lexer.Location);
          }
        | NEW type error 
          {
@@ -2222,30 +2208,27 @@ variable_initializer_list
 typeof_expression
        : TYPEOF OPEN_PARENS type CLOSE_PARENS
          {
-               $$ = new TypeOf ((string) $3, lexer.Location);
+               $$ = new TypeOf ((Expression) $3, lexer.Location);
          }
        ;
 
 sizeof_expression
        : SIZEOF OPEN_PARENS type CLOSE_PARENS { 
-               $$ = new SizeOf ((string) $3, lexer.Location);
-
-               note ("Verify type is unmanaged"); 
-               note ("if (5.8) builtin, yield constant expression");
+               $$ = new SizeOf ((Expression) $3, lexer.Location);
          }
        ;
 
 checked_expression
        : CHECKED OPEN_PARENS expression CLOSE_PARENS
          {
-               $$ = new CheckedExpr ((Expression) $3);
+               $$ = new CheckedExpr ((Expression) $3, lexer.Location);
          }
        ;
 
 unchecked_expression
        : UNCHECKED OPEN_PARENS expression CLOSE_PARENS
          {
-               $$ = new UnCheckedExpr ((Expression) $3);
+               $$ = new UnCheckedExpr ((Expression) $3, lexer.Location);
          }
        ;
 
@@ -2399,11 +2382,11 @@ relational_expression
          }
        | relational_expression IS type
          {
-               $$ = new Is ((Expression) $1, (string) $3, lexer.Location);
+               $$ = new Is ((Expression) $1, (Expression) $3, lexer.Location);
          }
        | relational_expression AS type
          {
-               $$ = new As ((Expression) $1, (string) $3, lexer.Location);
+               $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
          }
        ;
 
@@ -2661,7 +2644,8 @@ class_base
 block
        : OPEN_BRACE 
          {
-               current_block = new Block (current_block, lexer.Location, Location.Null);
+               current_block = new Block (current_block, current_local_parameters,
+                                          lexer.Location, Location.Null);
          } 
          opt_statement_list CLOSE_BRACE 
          { 
@@ -2727,7 +2711,7 @@ empty_statement
 labeled_statement
        : IDENTIFIER COLON 
          {
-               LabeledStatement labeled = new LabeledStatement ((string) $1);
+               LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
 
                if (!current_block.AddLabel ((string) $1, labeled)){
                        Location l = lexer.Location;
@@ -2743,14 +2727,14 @@ declaration_statement
          {
                DictionaryEntry de = (DictionaryEntry) $1;
 
-               $$ = declare_local_variables ((string) de.Key, (ArrayList) de.Value, lexer.Location);
+               $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
          }
 
        | local_constant_declaration SEMICOLON
          {
                DictionaryEntry de = (DictionaryEntry) $1;
 
-               $$ = declare_local_constant ((string) de.Key, (VariableDeclaration) de.Value);
+               $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value);
          }
        ;
 
@@ -2783,18 +2767,24 @@ local_variable_type
                if (!(expr is SimpleName || expr is MemberAccess)) {
                        Location l = lexer.Location;
                        Report.Error (-1, l, "Invalid Type definition");
-                       $$ = "System.Object";
+                       $$ = TypeManager.system_object_expr;
                }
                
                //
                // So we extract the string corresponding to the SimpleName
                // or MemberAccess
                // 
-               $$ = GetQualifiedIdentifier (expr) + (string) $2;
+               if ((string) $2 == "")
+                       $$ = $1;
+               else
+                       $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
          }
        | builtin_types opt_rank_specifier
          {
-                 $$ = (string) $1 + (string) $2;
+               if ((string) $2 == "")
+                       $$ = $1;
+               else
+                       $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
          }
         ;
 
@@ -2808,19 +2798,19 @@ local_variable_pointer_type
                        $$ = "System.Object";
                }
                
-               $$ = GetQualifiedIdentifier (expr) + "*";
+               $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
          }
         | builtin_types STAR
          {
-               $$ = (string) $1 + "*";
+               $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);;
          }
         | VOID STAR
          {
-               $$ = "System.Void*";
+               $$ = new ComposedCast (TypeManager.system_void_expr, "*", lexer.Location);;
          }
        | local_variable_pointer_type STAR
           {
-               $$ = (string) $1 + "*";
+               $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
          }
         ;
 
@@ -2831,7 +2821,13 @@ local_variable_declaration
          }
         | local_variable_pointer_type opt_rank_specifier variable_declarators
        {
-               $$ = new DictionaryEntry ((string) $1 + (string) $2, $3);
+               Expression t;
+
+               if ((string) $2 == "")
+                       t = (Expression) $1;
+               else
+                       t = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
+               $$ = new DictionaryEntry (t, $3);
        }
        ;
 
@@ -2917,11 +2913,13 @@ switch_statement
        : SWITCH OPEN_PARENS 
          { 
                oob_stack.Push (lexer.Location);
+               switch_stack.Push (current_block);
          }
          expression CLOSE_PARENS 
          switch_block
          {
                $$ = new Switch ((Expression) $4, (ArrayList) $6, (Location) oob_stack.Pop ());
+               current_block = (Block) switch_stack.Pop ();
          }
        ;
 
@@ -2969,7 +2967,6 @@ switch_section
                while (current_block.Implicit)
                        current_block = current_block.Parent;
                $$ = new SwitchSection ((ArrayList) $1, current_block);
-               current_block = current_block.Parent;
          }
        ;
 
@@ -3042,7 +3039,7 @@ for_statement
                if ($3 is DictionaryEntry){
                        DictionaryEntry de = (DictionaryEntry) $3;
                        
-                       string type = (string) de.Key;
+                       Expression type = (Expression) de.Key;
                        ArrayList var_declarators = (ArrayList) de.Value;
 
                        foreach (VariableDeclaration decl in var_declarators){
@@ -3051,34 +3048,24 @@ for_statement
 
                                vi = current_block.AddVariable (
                                        type, decl.identifier, current_local_parameters, decl.Location);
-                               if (vi == null){
-                                       Report.Error (128, decl.Location, 
-                                                     "A local variable `" + decl.identifier + 
-                                                     "' is already defined in this scope");
+                               if (vi == null)
+                                       continue;
+
+                               Location l = lexer.Location;
+                               Expression expr;
+                               if (decl.expression_or_array_initializer is Expression){
+                                       expr = (Expression) decl.expression_or_array_initializer;
                                } else {
-                                       Location l = lexer.Location;
-                                       Expression expr;
-                                       if (decl.expression_or_array_initializer is Expression){
-                                               expr = (Expression) decl.expression_or_array_initializer;
-                                               
-                                       } else {
-                                               
-                                               ArrayList init = (ArrayList) decl.expression_or_array_initializer;
-                                               
-                                               string base_type = type.Substring (0, type.IndexOf ("["));
-                                               string rank = type.Substring (type.IndexOf ("["));
-                                               
-                                               expr = new ArrayCreation (base_type, rank, init, decl.Location);
-                                       }
+                                       ArrayList init = (ArrayList) decl.expression_or_array_initializer;
+                                       expr = new ArrayCreation (type, "", init, decl.Location);
+                               }
                                        
-                                       LocalVariableReference var;
-                                       var = new LocalVariableReference (
-                                                                         assign_block, decl.identifier, l);
+                               LocalVariableReference var;
+                               var = new LocalVariableReference (assign_block, decl.identifier, l);
                                        
-                                       Assign a = new Assign (var, expr, decl.Location);
+                               Assign a = new Assign (var, expr, decl.Location);
                                        
-                                       assign_block.AddStatement (new StatementExpression (a, lexer.Location));
-                               }
+                               assign_block.AddStatement (new StatementExpression (a, lexer.Location));
                        }
                        
                        $3 = null;
@@ -3158,19 +3145,17 @@ foreach_statement
                oob_stack.Push (current_block);
 
                Block foreach_block = new Block (current_block, true);
-               LocalVariableReference v;
+               LocalVariableReference v = null;
                Location l = lexer.Location;
                VariableInfo vi;
 
-               vi = foreach_block.AddVariable ((string) $3, (string) $4, current_local_parameters, l);
-               vi.ReadOnly = true;
-               if (vi == null){
-                       Report.Error (
-                               128, l, "A local variable `" + (string) $4 + "' is already "+
-                               "defined in this scope");
-               }
+               vi = foreach_block.AddVariable ((Expression) $3, (string) $4, current_local_parameters, l);
+               if (vi != null) {
+                       vi.ReadOnly = true;
 
-               v = new LocalVariableReference (foreach_block, (string) $4, l);
+                       // Get a writable reference to this read-only variable.
+                       v = new LocalVariableReference (foreach_block, (string) $4, l, vi, false);
+               }
                current_block = foreach_block;
 
                oob_stack.Push (v);
@@ -3185,8 +3170,10 @@ foreach_statement
 
                current_block = prev_block;
 
-               Foreach f = new Foreach ((string) $3, v, (Expression) $7, (Statement) $10, l);
-               foreach_block.AddStatement (f);
+               if (v != null) {
+                       Foreach f = new Foreach ((Expression) $3, v, (Expression) $7, (Statement) $10, l);
+                       foreach_block.AddStatement (f);
+               }
 
                $$ = foreach_block;
          }
@@ -3255,7 +3242,7 @@ try_statement
                ArrayList s = new ArrayList ();
                
                foreach (Catch cc in (ArrayList) $3) {
-                       if (cc.Type == null)
+                       if (cc.IsGeneral)
                                g = cc;
                        else
                                s.Add (cc);
@@ -3264,7 +3251,7 @@ try_statement
                // Now s contains the list of specific catch clauses
                // and g contains the general one.
                
-               $$ = new Try ((Block) $2, s, g, null);
+               $$ = new Try ((Block) $2, s, g, null, lexer.Location);
        }
        | TRY block opt_catch_clauses FINALLY block
          {
@@ -3274,14 +3261,14 @@ try_statement
 
                if (catch_list != null){
                        foreach (Catch cc in catch_list) {
-                               if (cc.Type == null)
+                               if (cc.IsGeneral)
                                        g = cc;
                                else
                                        s.Add (cc);
                        }
                }
 
-               $$ = new Try ((Block) $2, s, g, (Block) $5);
+               $$ = new Try ((Block) $2, s, g, (Block) $5, lexer.Location);
          }
        | TRY block error 
          {
@@ -3319,11 +3306,12 @@ opt_identifier
 catch_clause 
        : CATCH opt_catch_args 
        {
-               string type = null, id = null;
+               Expression type = null;
+               string id = null;
                
                if ($2 != null) {
                        DictionaryEntry cc = (DictionaryEntry) $2;
-                       type = (string) cc.Key;
+                       type = (Expression) cc.Key;
                        id   = (string) cc.Value;
 
                        if (id != null){
@@ -3336,19 +3324,21 @@ catch_clause
                                current_block = new Block (current_block);
                                Block b = declare_local_variables (type, one, loc);
                                current_block = b;
-
-                               
                        }
                }
        } block {
-               string type = null, id = null;
+               Expression type = null;
+               string id = null;
 
                if ($2 != null){
                        DictionaryEntry cc = (DictionaryEntry) $2;
-                       type = (string) cc.Key;
+                       type = (Expression) cc.Key;
                        id   = (string) cc.Value;
 
                        if ($1 != null){
+                               //
+                               // FIXME: I can change this for an assignment.
+                               //
                                while (current_block != (Block) $1)
                                        current_block = current_block.Parent;
                        }
@@ -3404,7 +3394,7 @@ fixed_statement
          {
                Block assign_block = new Block (current_block, true);
                ArrayList list = (ArrayList) $4;
-               string type = (string) $3;
+               Expression type = (Expression) $3;
                Location l = lexer.Location;
                int top = list.Count;
 
@@ -3413,11 +3403,8 @@ fixed_statement
                        VariableInfo v;
 
                        v = current_block.AddVariable (type, (string) p.First,current_local_parameters, l);
-                       if (v == null){
-                               Report.Error (
-                                       128, l, "A local variable `" + (string) p.First + "' is already "+
-                                       "defined in this scope");
-                       }
+                       if (v == null)
+                               continue;
                        v.ReadOnly = true;
                        p.First = v;
                        list [i] = p;
@@ -3435,7 +3422,7 @@ fixed_statement
                ArrayList list = (ArrayList) $4;
                int top = list.Count;
 
-               $$ = new Fixed ((string) $3, (ArrayList) $4, (Statement) $7, l);
+               $$ = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l);
          }
        ;
 
@@ -3483,43 +3470,33 @@ using_statement
                        DictionaryEntry de = (DictionaryEntry) $3;
                        Location l = lexer.Location;
 
-                       string type = (string) de.Key;
+                       Expression type = (Expression) de.Key;
                        ArrayList var_declarators = (ArrayList) de.Value;
 
-                       foreach (VariableDeclaration decl in var_declarators){
-                               if (current_block.AddVariable (
-                                       type, decl.identifier, 
-                                       current_local_parameters, decl.Location) == null){
-                                       Report.Error (128, decl.Location, 
-                                       "A local variable `" + decl.identifier + "' is already" +
-                                       "defined in this scope");
-                               }
-                       }
-
                        ArrayList vars = new ArrayList ();
 
                        foreach (VariableDeclaration decl in var_declarators){
 
+                               VariableInfo vi = current_block.AddVariable (
+                                       type, decl.identifier, 
+                                       current_local_parameters, decl.Location);
+                               if (vi == null)
+                                       continue;
+                               vi.ReadOnly = true;
+
                                Expression expr;
                                if (decl.expression_or_array_initializer is Expression){
                                        expr = (Expression) decl.expression_or_array_initializer;
-                                       
                                } else {
-
                                        ArrayList init = (ArrayList) decl.expression_or_array_initializer;
                                        
-                                       string base_type = type.Substring (0, type.IndexOf ("["));
-                                       string rank = type.Substring (type.IndexOf ("["));
-                                       
-                                       expr = new ArrayCreation (base_type, rank, init, decl.Location);
+                                       expr = new ArrayCreation (type, "", init, decl.Location);
                                }
 
                                LocalVariableReference var;
-                               VariableInfo vi;
 
-                               var = new LocalVariableReference (assign_block, decl.identifier, l);
-                               vi = var.VariableInfo;
-                               vi.ReadOnly = true;
+                               // Get a writable reference to this read-only variable.
+                               var = new LocalVariableReference (assign_block, decl.identifier, l, vi, false);
 
                                // This is so that it is not a warning on using variables
                                vi.Used = true;
@@ -3577,11 +3554,11 @@ public class VariableDeclaration {
 // </summary>
 
 public class IndexerDeclaration {
-       public string type;
+       public Expression type;
        public string interface_type;
        public Parameters param_list;
 
-       public IndexerDeclaration (string type, string interface_type, Parameters param_list)
+       public IndexerDeclaration (Expression type, string interface_type, Parameters param_list)
        {
                this.type = type;
                this.interface_type = interface_type;
@@ -3595,15 +3572,13 @@ public class IndexerDeclaration {
 
 public class OperatorDeclaration {
        public Operator.OpType optype;
-       public string ret_type;
-       public string arg1type;
-       public string arg1name;
-       public string arg2type;
-       public string arg2name;
+       public Expression ret_type, arg1type, arg2type;
+       public string arg1name, arg2name;
        public Location location;
 
-       public OperatorDeclaration (Operator.OpType op, string ret_type, string arg1type, string arg1name,
-                                   string arg2type, string arg2name, Location location)
+       public OperatorDeclaration (Operator.OpType op, Expression ret_type, 
+                                   Expression arg1type, string arg1name,
+                                   Expression arg2type, string arg2name, Location location)
        {
                optype = op;
                this.ret_type = ret_type;
@@ -3682,45 +3657,19 @@ CheckDef (bool result, string name, Location l)
        CheckDef (AdditionResult.NameExists, name, l);
 }
 
-//
-// This routine should be removed soon.  I am in the process of making
-// changes to never keep anything but SimpleNames during parsing, as
-// that breaks some kinds of code (documented in the ChangeLog).
-//
-Expression
-SimpleLookup (string name, Location loc)
-{
-       //
-       // we need to check against current_block not being null
-       // as `expression' is allowed in argument_lists, which 
-       // do not exist inside a block.  
-       //
-
-       if (current_local_parameters != null){
-               int idx;
-               Parameter par = current_local_parameters.GetParameterByName (name, out idx);
-               if (par != null)
-                       return new ParameterReference (current_local_parameters, idx, name);
-       }
-
-       return null;
-}
-
 Expression DecomposeQI (string name, Location loc)
 {
        Expression o;
 
        if (name.IndexOf ('.') == -1){
-               o = SimpleLookup (name, loc);
-               if (o == null)
-                       return new SimpleName (name, loc);
-               return o;
+               return new SimpleName (name, loc);
        } else {
                int pos = name.LastIndexOf (".");
                string left = name.Substring (0, pos);
                string right = name.Substring (pos + 1);
 
                o = DecomposeQI (left, loc);
+
                return new MemberAccess (o, right, loc);
        }
 }
@@ -3742,7 +3691,7 @@ string GetQualifiedIdentifier (Expression expr)
        
 }
 
-Block declare_local_variables (string type, ArrayList variable_declarators, Location loc)
+Block declare_local_variables (Expression type, ArrayList variable_declarators, Location loc)
 {
        Block implicit_block;
        ArrayList inits = null;
@@ -3775,9 +3724,6 @@ Block declare_local_variables (string type, ArrayList variable_declarators, Loca
                                        inits = new ArrayList ();
                                inits.Add (decl);
                        }
-               } else {
-                       Report.Error (128, decl.Location, "A local variable `" + decl.identifier +
-                                        "' is already defined in this scope");
                }
        }
 
@@ -3794,11 +3740,7 @@ Block declare_local_variables (string type, ArrayList variable_declarators, Loca
                } else {
                        ArrayList init = (ArrayList) decl.expression_or_array_initializer;
                        
-                       string base_type = type.Substring (0, type.IndexOf ("["));
-                       string rank = type.Substring (type.IndexOf ("["));
-
-                       expr = new ArrayCreation (base_type, rank, init, decl.Location);
-                       
+                       expr = new ArrayCreation (type, "", init, decl.Location);
                }
 
                LocalVariableReference var;
@@ -3812,7 +3754,7 @@ Block declare_local_variables (string type, ArrayList variable_declarators, Loca
        return implicit_block;
 }
 
-Block declare_local_constant (string type, VariableDeclaration decl)
+Block declare_local_constant (Expression type, VariableDeclaration decl)
 {
        Block implicit_block;
 
@@ -3823,8 +3765,6 @@ Block declare_local_constant (string type, VariableDeclaration decl)
 
        if (!(implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
                                          current_local_parameters, decl.Location))){
-               Report.Error (128, decl.Location, "A local variable `" + decl.identifier +
-                             "' is already defined in this scope");
        }
        
        return implicit_block;
@@ -3929,32 +3869,25 @@ public CSharpParser (string name, System.IO.Stream input, ArrayList defines)
        current_container = RootContext.Tree.Types;
        current_container.Namespace = current_namespace;
        oob_stack = new Stack ();
+       switch_stack = new Stack ();
 
        lexer = new Tokenizer (input, name, defines);
 }
 
-public override int parse ()
+public override void parse ()
 {
-       global_errors = 0;
        try {
                if (yacc_verbose_flag)
                        yyparse (lexer, new yydebug.yyDebugSimple ());
                else
                        yyparse (lexer);
        } catch (Exception e){
-               // Console.WriteLine ("Fatal error: " + name);
-               // Console.WriteLine (lexer.location);
-
-               // 
                // Please do not remove this, it is used during debugging
                // of the grammar
                //
                Console.WriteLine (lexer.location + "  : Parsing error ");
                Console.WriteLine (e);
-               global_errors++;
        }
-       
-       return global_errors;
 }
 
 /* end end end */