X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fcs-parser.jay;h=005def9fa45a8608bce2ffa6a55904997d37358b;hb=bb70a0084a34cabdffa0164caa961383b6ca0722;hp=5772218b8e01d1a3b5ef55d91e6e1ed4bf07fa8f;hpb=81cd691acb26506bcdc24f6c4b144eef8dde11f5;p=mono.git diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay index 5772218b8e0..005def9fa45 100755 --- a/mcs/mcs/cs-parser.jay +++ b/mcs/mcs/cs-parser.jay @@ -1,35 +1,25 @@ %{ // -// 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 +// Possible optimization: +// Run memory profiler with parsing only, and consider dropping +// arraylists where not needed. Some pieces can use linked lists. // using System.Text; +using System.IO; using System; namespace Mono.CSharp @@ -44,6 +34,8 @@ namespace Mono.CSharp Namespace current_namespace; TypeContainer current_container; + IIteratorContainer iterator_container; + // // Current block is used to add statements as we find // them. @@ -69,7 +61,7 @@ namespace Mono.CSharp // value parameter that is passed to the "set" and "get"accesor // methods (properties and indexers). // - string implicit_value_parameter_type; + Expression implicit_value_parameter_type; Parameters indexer_parameters; // @@ -82,6 +74,16 @@ namespace Mono.CSharp // An out-of-band stack. // Stack oob_stack; + + // + // Switch stack. + // + Stack switch_stack; + + // + // The current file. + // + SourceFile file; %} %token EOF @@ -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" @@ -263,6 +268,7 @@ compilation_unit : outer_declarations opt_EOF | outer_declarations attribute_sections opt_EOF | attribute_sections opt_EOF + | opt_EOF /* allow empty files */ ; opt_EOF @@ -301,7 +307,7 @@ using_alias_directive using_namespace_directive : USING namespace_name SEMICOLON { - current_namespace.Using ((string) $2); + current_namespace.Using ((string) $2, lexer.Location); } ; @@ -318,11 +324,14 @@ namespace_declaration if (attrs != null) { foreach (AttributeSection asec in attrs.AttributeSections) if (asec.Target == "assembly") - RootContext.AddGlobalAttribute ( - current_container, asec, lexer.Location); + RootContext.AddGlobalAttributeSection (current_container, asec); + else + Report.Error(1518, Lexer.Location, + "Attributes cannot be applied to namespaces." + + " Expected class, delegate, enum, interface, or struct"); } - current_namespace = RootContext.Tree.RecordNamespace (current_namespace, name, (string) $3); + current_namespace = RootContext.Tree.RecordNamespace (current_namespace, file, (string) $3); } namespace_body opt_semicolon { @@ -398,8 +407,11 @@ namespace_member_declaration "Namespace elements cant be explicitly " + "declared private or protected in `" + name + "'"); } + current_namespace.DeclarationFound = true; + } + | namespace_declaration { + current_namespace.DeclarationFound = true; } - | namespace_declaration ; type_declaration @@ -430,10 +442,11 @@ attribute_sections { AttributeSection sect = (AttributeSection) $1; - if (sect.Target == "assembly") - RootContext.AddGlobalAttribute (current_container, sect, lexer.Location); - - $$ = new Attributes ((AttributeSection) $1, lexer.Location); + if (sect.Target == "assembly") + RootContext.AddGlobalAttributeSection (current_container, sect); + + + $$ = new Attributes ((AttributeSection) $1); } | attribute_sections attribute_section { @@ -441,11 +454,11 @@ attribute_sections AttributeSection sect = (AttributeSection) $2; if (sect.Target == "assembly") - RootContext.AddGlobalAttribute (current_container, sect, lexer.Location); + RootContext.AddGlobalAttributeSection (current_container, sect); if ($1 != null) { attrs = (Attributes) $1; - attrs.AddAttribute (sect); + attrs.AddAttributeSection (sect); } $$ = attrs; @@ -453,7 +466,7 @@ attribute_sections ; attribute_section - : OPEN_BRACKET attribute_target_specifier attribute_list CLOSE_BRACKET + : OPEN_BRACKET attribute_target_specifier attribute_list opt_comma CLOSE_BRACKET { string target = null; @@ -462,7 +475,7 @@ attribute_section $$ = new AttributeSection (target, (ArrayList) $3); } - | OPEN_BRACKET attribute_list CLOSE_BRACKET + | OPEN_BRACKET attribute_list opt_comma CLOSE_BRACKET { $$ = new AttributeSection (null, (ArrayList) $2); } @@ -708,7 +721,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 +759,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,16 +811,18 @@ 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); } ; 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){ @@ -824,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; } ; @@ -857,7 +873,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 +886,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 +900,7 @@ method_body ; opt_formal_parameter_list - : /* empty */ { $$ = Parameters.GetEmptyReadOnlyParameters (); } + : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; } | formal_parameter_list ; @@ -936,7 +952,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 +962,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 +984,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 +1002,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 +1202,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 +1227,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 +1245,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 +1264,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 +1303,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 +1320,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 +1365,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 @@ -1382,29 +1401,39 @@ constructor_declaration { Constructor c = (Constructor) $3; c.Block = (Block) $4; - c.ModFlags = (int) $2; c.OptAttributes = (Attributes) $1; - - if ((c.ModFlags & Modifiers.STATIC) != 0){ - if ((c.ModFlags & Modifiers.Accessibility) != 0) { - Report.Error ( - 515, c.Location, - "Access modifiers are not allowed on static constructors"); - } - - if (c.Initializer != null){ - Report.Error ( - 514, c.Location, - "Static constructors can not have an explicit this or base " + - "constructor invocations"); + c.ModFlags = (int) $2; + + if (c.Name == current_container.Basename){ + if ((c.ModFlags & Modifiers.STATIC) != 0){ + if ((c.ModFlags & Modifiers.Accessibility) != 0){ + Report.Error ( + 515, c.Location, String.Format ( + "`{0}.{1}': static constructor can not have access modifiers", + c.Name, current_container.Name)); + } + + c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location); + + if (c.Initializer != null){ + Report.Error ( + 514, c.Location, + "Static constructors can not have an explicit this or base " + + "constructor invocations"); + } + + if (!c.Parameters.Empty){ + Report.Error ( + 132, c.Location, "Static constructors should not have parameters"); + } + } else { + c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location); } + } else { + // We let another layer check the validity of the constructor. + Console.WriteLine ("{0} and {1}", c.Name, current_container.Basename); + } - if (!c.Parameters.Empty){ - Report.Error ( - 132, c.Location, "Static constructors should not have parameters"); - } - } - CheckDef (current_container.AddConstructor (c), c.Name, c.Location); current_local_parameters = null; @@ -1439,11 +1468,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 +1493,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 +1509,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 +1522,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 +1543,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); @@ -1551,6 +1580,10 @@ add_accessor_declaration $$ = new Accessor ((Block) $4, (Attributes) $1); lexer.EventParsing = true; } + | opt_attributes ADD error { + Report.Error (73, lexer.Location, "Add or remove accessor must have a body"); + $$ = null; + } ; remove_accessor_declaration @@ -1571,6 +1604,10 @@ remove_accessor_declaration $$ = new Accessor ((Block) $4, (Attributes) $1); lexer.EventParsing = true; } + | opt_attributes REMOVE error { + Report.Error (73, lexer.Location, "Add or remove accessor must have a body"); + $$ = null; + } ; indexer_declaration @@ -1626,7 +1663,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 +1672,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,16 +1687,15 @@ 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, - (Attributes) $1, enum_location); - - foreach (VariableDeclaration ev in (ArrayList) $6){ + Enum e = new Enum (current_container, (Expression) $5, (int) $2, full_name, + (Attributes) $1, enum_location); + + foreach (VariableDeclaration ev in (ArrayList) $6) { Location loc = (Location) ev.Location; CheckDef (e.AddEnumMember (ev.identifier, (Expression) ev.expression_or_array_initializer, - loc), + loc, ev.OptAttributes), ev.identifier, loc); } @@ -1672,7 +1708,7 @@ enum_declaration ; opt_enum_base - : /* empty */ { $$ = "System.Int32"; } + : /* empty */ { $$ = TypeManager.system_int32_expr; } | COLON type { $$ = $2; } ; @@ -1709,7 +1745,7 @@ enum_member_declarations enum_member_declaration : opt_attributes IDENTIFIER { - $$ = new VariableDeclaration ((string) $2, null, lexer.Location); + $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1); } | opt_attributes IDENTIFIER { @@ -1717,7 +1753,7 @@ enum_member_declaration } ASSIGN expression { - $$ = new VariableDeclaration ((string) $2, $5, lexer.Location); + $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1); } ; @@ -1731,7 +1767,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); @@ -1749,8 +1785,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); @@ -1777,7 +1813,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 @@ -1793,19 +1829,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); @@ -1822,6 +1855,15 @@ non_expression_type { $$ = new ComposedCast ((Expression) $1, "*", lexer.Location); } + + // + // We need this because the parser will happily go and reduce IDENTIFIER STAR + // through this different path + // + | multiplicative_expression STAR + { + $$ = new ComposedCast ((Expression) $1, "*", lexer.Location); + } ; type_list @@ -1846,26 +1888,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 @@ -1875,7 +1917,7 @@ interface_type array_type : type rank_specifiers { - $$ = (string) $1 + (string) $2; + $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location); } ; @@ -1909,8 +1951,6 @@ primary_expression | checked_expression | unchecked_expression | pointer_member_access - // TODO: pointer_element_access - // TODO: sizeof-expression ; literal @@ -1932,10 +1972,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) @@ -1966,7 +2002,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); } ; @@ -1979,7 +2015,7 @@ invocation_expression { if ($1 == null) { Location l = lexer.Location; - Report.Error (1, l, "THIS IS CRAZY"); + Report.Error (1, l, "Parse error"); } $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location); } @@ -2039,17 +2075,18 @@ element_access // Blah i; Expression expr = (Expression) $1; - if (!(expr is SimpleName || expr is MemberAccess)) { - Location l = lexer.Location; - Report.Error (-1, l, "Invalid Type definition"); - $$ = "System.Object"; + if (expr is ComposedCast){ + $$ = new ComposedCast (expr, (string) $2, lexer.Location); + } else if (!(expr is SimpleName || expr is MemberAccess)){ + Error_ExpectingTypeName (lexer.Location, expr); + $$ = TypeManager.system_object_expr; + } else { + // + // So we extract the string corresponding to the SimpleName + // or MemberAccess + // + $$ = new ComposedCast (expr, (string) $2, lexer.Location); } - - // - // So we extract the string corresponding to the SimpleName - // or MemberAccess - // - $$ = new SimpleName (GetQualifiedIdentifier (expr) + (string) $2, lexer.Location); } ; @@ -2071,7 +2108,7 @@ expression_list this_access : THIS { - $$ = new This (lexer.Location); + $$ = new This (current_block, lexer.Location); } ; @@ -2110,7 +2147,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); } ; @@ -2119,12 +2156,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 { @@ -2144,14 +2180,10 @@ opt_rank_specifier ; rank_specifiers - : rank_specifier - { - $$ = $1; - } - | rank_specifiers rank_specifier + : rank_specifier opt_rank_specifier { $$ = (string) $2 + (string) $1; - } + } ; rank_specifier @@ -2224,30 +2256,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); } ; @@ -2270,7 +2299,11 @@ unary_expression { $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, lexer.Location); } - | OPEN_PARENS expression CLOSE_PARENS unary_expression + | cast_expression + ; + +cast_expression + : OPEN_PARENS expression CLOSE_PARENS unary_expression { $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location); } @@ -2401,11 +2434,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); } ; @@ -2663,7 +2696,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 { @@ -2688,7 +2722,7 @@ statement_list statement : declaration_statement { - if ((Block) $1 != current_block){ + if ($1 != null && (Block) $1 != current_block){ current_block.AddStatement ((Statement) $1); current_block = (Block) $1; } @@ -2729,7 +2763,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,16 +2777,20 @@ labeled_statement declaration_statement : local_variable_declaration SEMICOLON { - DictionaryEntry de = (DictionaryEntry) $1; + if ($1 != null){ + 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; + if ($1 != null){ + DictionaryEntry de = (DictionaryEntry) $1; - $$ = declare_local_constant ((string) de.Key, (VariableDeclaration) de.Value); + $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value); + } } ; @@ -2782,21 +2820,27 @@ local_variable_type // Blah i; Expression expr = (Expression) $1; - if (!(expr is SimpleName || expr is MemberAccess)) { - Location l = lexer.Location; - Report.Error (-1, l, "Invalid Type definition"); - $$ = "System.Object"; + if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast)) { + Error_ExpectingTypeName (lexer.Location, expr); + $$ = null; + } else { + // + // So we extract the string corresponding to the SimpleName + // or MemberAccess + // + + if ((string) $2 == "") + $$ = $1; + else + $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location); } - - // - // So we extract the string corresponding to the SimpleName - // or MemberAccess - // - $$ = GetQualifiedIdentifier (expr) + (string) $2; } | builtin_types opt_rank_specifier { - $$ = (string) $1 + (string) $2; + if ((string) $2 == "") + $$ = $1; + else + $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location); } ; @@ -2804,43 +2848,59 @@ local_variable_pointer_type : primary_expression STAR { Expression expr = (Expression) $1; - if (!(expr is SimpleName || expr is MemberAccess)) { - Location l = lexer.Location; - Report.Error (-1, l, "Invalid Type definition"); - $$ = "System.Object"; - } - - $$ = GetQualifiedIdentifier (expr) + "*"; + Location l = lexer.Location; + + if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast)) { + Error_ExpectingTypeName (l, expr); + + $$ = null; + } else + $$ = new ComposedCast ((Expression) $1, "*", l); } | 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); } ; local_variable_declaration : local_variable_type variable_declarators { - $$ = new DictionaryEntry ($1, $2); + if ($1 != null) + $$ = new DictionaryEntry ($1, $2); + else + $$ = null; } | local_variable_pointer_type opt_rank_specifier variable_declarators { - $$ = new DictionaryEntry ((string) $1 + (string) $2, $3); + if ($1 != null){ + Expression t; + + if ((string) $2 == "") + t = (Expression) $1; + else + t = new ComposedCast ((Expression) $1, (string) $2, lexer.Location); + $$ = new DictionaryEntry (t, $3); + } else + $$ = null; } ; local_constant_declaration : CONST local_variable_type constant_declarator { - $$ = new DictionaryEntry ($2, $3); + if ($2 != null) + $$ = new DictionaryEntry ($2, $3); + else + $$ = null; } ; @@ -2919,11 +2979,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 (); } ; @@ -2964,14 +3026,15 @@ switch_sections switch_section : switch_labels { - current_block = new Block (current_block); + current_block = new Block (current_block, lexer.Location, lexer.Location); } statement_list { - while (current_block.Implicit) - current_block = current_block.Parent; - $$ = new SwitchSection ((ArrayList) $1, current_block); - current_block = current_block.Parent; + Block topmost = current_block; + + while (topmost.Implicit) + topmost = topmost.Parent; + $$ = new SwitchSection ((ArrayList) $1, topmost); } ; @@ -3028,9 +3091,14 @@ while_statement do_statement : DO embedded_statement - WHILE OPEN_PARENS boolean_expression CLOSE_PARENS SEMICOLON + WHILE OPEN_PARENS { + oob_stack.Push (lexer.Location); + } + boolean_expression CLOSE_PARENS SEMICOLON { - $$ = new Do ((Statement) $2, (Expression) $5, lexer.Location); + Location l = (Location) oob_stack.Pop (); + + $$ = new Do ((Statement) $2, (Expression) $6, l); } ; @@ -3044,7 +3112,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){ @@ -3053,30 +3121,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 if (decl.expression_or_array_initializer == null) { + expr = null; } 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); - } - - LocalVariableReference var; - var = new LocalVariableReference ( - assign_block, decl.identifier, l); + 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); + + if (expr != null) { Assign a = new Assign (var, expr, decl.Location); assign_block.AddStatement (new StatementExpression (a, lexer.Location)); @@ -3136,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; @@ -3159,20 +3221,18 @@ foreach_statement { oob_stack.Push (current_block); - Block foreach_block = new Block (current_block, true); - LocalVariableReference v; + Block foreach_block = new Block (current_block, Block.Flags.Implicit); + 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); @@ -3187,8 +3247,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; } @@ -3200,6 +3262,7 @@ jump_statement | goto_statement | return_statement | throw_statement + | yield_statement ; break_statement @@ -3245,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 @@ -3257,7 +3343,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); @@ -3266,7 +3352,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 { @@ -3276,14 +3362,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 { @@ -3321,11 +3407,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){ @@ -3338,19 +3425,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; } @@ -3401,12 +3490,12 @@ unsafe_statement fixed_statement : FIXED OPEN_PARENS - pointer_type fixed_pointer_declarators + 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; - string type = (string) $3; + Expression type = (Expression) $3; Location l = lexer.Location; int top = list.Count; @@ -3415,11 +3504,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; @@ -3437,7 +3523,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); } ; @@ -3485,43 +3571,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; @@ -3559,11 +3635,18 @@ public class VariableDeclaration { public string identifier; public object expression_or_array_initializer; public Location Location; + public Attributes OptAttributes; - public VariableDeclaration (string id, object eoai, Location l){ + public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) + { this.identifier = id; this.expression_or_array_initializer = eoai; this.Location = l; + this.OptAttributes = opt_attrs; + } + + public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null) + { } } @@ -3572,11 +3655,11 @@ public class VariableDeclaration { // 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; @@ -3590,15 +3673,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; @@ -3611,6 +3692,15 @@ public class OperatorDeclaration { } +void Error_ExpectingTypeName (Location l, Expression expr) +{ + if (expr is Invocation){ + Report.Error (1002, l, "; expected"); + } else { + Report.Error (-1, l, "Invalid Type definition"); + } +} + // // Given the @class_name name, it creates a fully qualified name // based on the containing declaration space @@ -3677,45 +3767,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); } } @@ -3726,6 +3790,7 @@ Expression DecomposeQI (string name, Location loc) // This is necessary because local_variable_type admits primary_expression // as the type of the variable. So we do some extra checking // +#if false string GetQualifiedIdentifier (Expression expr) { if (expr is SimpleName) @@ -3736,8 +3801,9 @@ string GetQualifiedIdentifier (Expression expr) throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")"); } +#endif -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; @@ -3757,9 +3823,10 @@ Block declare_local_variables (string type, ArrayList variable_declarators, Loca // // int j = 1; int k = j + 1; // - if (current_block.Used) - implicit_block = new Block (current_block, true, loc, Location.Null); - else + if (current_block.Used) { + implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null); + implicit_block.AddChildVariableNames (current_block); + } else implicit_block = current_block; foreach (VariableDeclaration decl in variable_declarators){ @@ -3770,9 +3837,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"); } } @@ -3789,11 +3853,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; @@ -3807,19 +3867,17 @@ 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; 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; 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; @@ -3916,40 +3974,35 @@ public Tokenizer Lexer { } } -public CSharpParser (string name, System.IO.Stream input, ArrayList defines) +public CSharpParser (StreamReader reader, SourceFile file, ArrayList defines) { - current_namespace = new Namespace (null, ""); - this.name = name; - this.input = input; + current_namespace = new Namespace (null, file, ""); + this.name = file.Name; + this.file = file; current_container = RootContext.Tree.Types; current_container.Namespace = current_namespace; oob_stack = new Stack (); + switch_stack = new Stack (); - lexer = new Tokenizer (input, name, defines); + lexer = new Tokenizer (reader, file, 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); + Tokenizer tokenizer = lexer as Tokenizer; + tokenizer.cleanup (); } 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 "); + Report.Error (-25, lexer.Location, ": Parsing error "); Console.WriteLine (e); - global_errors++; } - - return global_errors; } /* end end end */