X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fcs-parser.jay;h=005def9fa45a8608bce2ffa6a55904997d37358b;hb=bb70a0084a34cabdffa0164caa961383b6ca0722;hp=238884fc822de187961c438d3e34e67cbe4416b6;hpb=6d73a098f2e3840d7db52d276f5d6b32835cb18b;p=mono.git diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay index 238884fc822..005def9fa45 100755 --- a/mcs/mcs/cs-parser.jay +++ b/mcs/mcs/cs-parser.jay @@ -2,28 +2,24 @@ // // cs-parser.jay: The Parser for the C# compiler // -// Author: Miguel de Icaza (miguel@gnu.org) +// 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 @@ -38,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. @@ -63,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; // @@ -76,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 @@ -146,6 +154,7 @@ namespace Mono.CSharp %token SEALED %token SHORT %token SIZEOF +%token STACKALLOC %token STATIC %token STRING %token STRUCT @@ -166,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" @@ -250,21 +262,30 @@ namespace Mono.CSharp %nonassoc HIGHPREC %start compilation_unit -/*%start namespace_declaration */ %% compilation_unit - : opt_using_directives opt_namespace_member_declarations opt_attributes opt_EOF - { - // Check that using comes only before namespace elements - } - ; - + : outer_declarations opt_EOF + | outer_declarations attribute_sections opt_EOF + | attribute_sections opt_EOF + | opt_EOF /* allow empty files */ + ; + opt_EOF : /* empty */ | EOF ; +outer_declarations + : outer_declaration + | outer_declarations outer_declaration + ; + +outer_declaration + : using_directive + | namespace_member_declaration + ; + using_directives : using_directive | using_directives using_directive @@ -286,19 +307,32 @@ using_alias_directive using_namespace_directive : USING namespace_name SEMICOLON { - current_namespace.Using ((string) $2); + current_namespace.Using ((string) $2, lexer.Location); } ; -// namespace_declarations -// : namespace_declaration -// | namespace_declarations namespace_declaration - +// +// Strictly speaking, namespaces don't have attributes but +// we parse global attributes along with namespace declarations and then +// detach them +// namespace_declaration - : NAMESPACE qualified_identifier - { - current_namespace = RootContext.Tree.RecordNamespace (current_namespace, name, (string) $2); - } + : opt_attributes NAMESPACE qualified_identifier + { + Attributes attrs = (Attributes) $1; + + if (attrs != null) { + foreach (AttributeSection asec in attrs.AttributeSections) + if (asec.Target == "assembly") + 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, file, (string) $3); + } namespace_body opt_semicolon { current_namespace = current_namespace.Parent; @@ -373,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 @@ -394,26 +431,34 @@ type_declaration // // Attributes 17.2 // + opt_attributes - : /* empty */ { $$ = null; } - | attribute_section opt_attributes + : /* empty */ + | attribute_sections { $$ = $1; } + ; + +attribute_sections + : attribute_section + { + AttributeSection sect = (AttributeSection) $1; + + if (sect.Target == "assembly") + RootContext.AddGlobalAttributeSection (current_container, sect); + + + $$ = new Attributes ((AttributeSection) $1); + } + | attribute_sections attribute_section { Attributes attrs = null; - AttributeSection sect = (AttributeSection) $1; + AttributeSection sect = (AttributeSection) $2; - if (sect.Target == "assembly"){ - RootContext.AddGlobalAttributes (sect, lexer.Location); - sect = null; - } + if (sect.Target == "assembly") + RootContext.AddGlobalAttributeSection (current_container, sect); - if ($2 != null) { - if (sect != null){ - attrs = (Attributes) $2; - attrs.AddAttribute (sect); - } - } else { - if (sect != null) - attrs = new Attributes (sect, lexer.Location); + if ($1 != null) { + attrs = (Attributes) $1; + attrs.AddAttributeSection (sect); } $$ = attrs; @@ -421,7 +466,7 @@ opt_attributes ; 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; @@ -430,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); } @@ -496,12 +541,16 @@ opt_attribute_arguments attribute_arguments - : positional_argument_list + : opt_positional_argument_list { - ArrayList args = new ArrayList (); - args.Add ($1); + if ($1 == null) + $$ = null; + else { + ArrayList args = new ArrayList (); + args.Add ($1); - $$ = args; + $$ = args; + } } | positional_argument_list COMMA named_argument_list { @@ -522,6 +571,11 @@ attribute_arguments ; +opt_positional_argument_list + : /* empty */ { $$ = null; } + | positional_argument_list + ; + positional_argument_list : expression { @@ -606,34 +660,23 @@ struct_declaration (Attributes) $1, lexer.Location); current_container = new_struct; current_container.Namespace = current_namespace; - RootContext.Tree.RecordStruct (full_struct_name, new_struct); + RootContext.Tree.RecordDecl (full_struct_name, new_struct); } - opt_struct_interfaces + opt_class_base struct_body opt_semicolon { Struct new_struct = (Struct) current_container; + if ($6 != null) + new_struct.Bases = (ArrayList) $6; + current_container = current_container.Parent; - CheckDef (current_container.AddStruct (new_struct), new_struct.Name); + CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location); $$ = new_struct; } ; -opt_struct_interfaces - : /* empty */ - | struct_interfaces - ; - -struct_interfaces - : struct_interface - | struct_interfaces struct_interface - ; - -struct_interface - : COLON type_list - ; - struct_body : OPEN_BRACE opt_struct_member_declarations CLOSE_BRACE ; @@ -675,12 +718,14 @@ constant_declaration SEMICOLON { foreach (VariableDeclaration constant in (ArrayList) $5){ + Location l = constant.Location; + Const c = new Const ( - (string) $4, (string) constant.identifier, - (Expression) constant.expression_or_array_initializer, (int) $2, (Attributes) $1, - constant.Location); + (Expression) $4, (string) constant.identifier, + (Expression) constant.expression_or_array_initializer, (int) $2, + (Attributes) $1, l); - CheckDef (current_container.AddConstant (c), c.Name); + CheckDef (current_container.AddConstant (c), c.Name, l); } } ; @@ -714,14 +759,17 @@ field_declaration variable_declarators SEMICOLON { - string type = (string) $3; + Expression type = (Expression) $3; int mod = (int) $2; foreach (VariableDeclaration var in (ArrayList) $4){ + Location l = var.Location; + Field field = new Field (type, mod, var.identifier, - var.expression_or_array_initializer, (Attributes) $1, var.Location); + var.expression_or_array_initializer, + (Attributes) $1, l); - CheckDef (current_container.AddField (field), field.Name); + CheckDef (current_container.AddField (field), field.Name, l); } } ; @@ -758,17 +806,23 @@ variable_initializer $$ = $1; } | array_initializer - { + { $$ = $1; - } + } + | STACKALLOC type OPEN_BRACKET expression CLOSE_BRACKET + { + $$ = 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){ @@ -785,10 +839,11 @@ method_declaration } } - method.Block = (Block) $2; - CheckDef (current_container.AddMethod (method), method.Name); + method.Block = (Block) $3; + CheckDef (current_container.AddMethod (method), method.Name, method.Location); current_local_parameters = null; + iterator_container = null; } ; @@ -818,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; @@ -831,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; @@ -845,7 +900,7 @@ method_body ; opt_formal_parameter_list - : /* empty */ { $$ = Parameters.GetEmptyReadOnlyParameters (); } + : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; } | formal_parameter_list ; @@ -897,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); } ; @@ -907,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"); } ; @@ -929,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; @@ -943,18 +998,14 @@ property_declaration { Property prop; Pair pair = (Pair) $7; - Block get_block = null; - Block set_block = null; - - if (pair.First != null) - get_block = (Block) pair.First; - if (pair.Second != null) - set_block = (Block) pair.Second; + Accessor get_block = (Accessor) pair.First; + Accessor set_block = (Accessor) pair.Second; - prop = new Property ((string) $3, (string) $4, (int) $2, get_block, set_block, - (Attributes) $1, (Location) $6); + Location loc = (Location) $6; + prop = new Property ((Expression) $3, (string) $4, (int) $2, get_block, set_block, + (Attributes) $1, loc); - CheckDef (current_container.AddProperty (prop), prop.Name); + CheckDef (current_container.AddProperty (prop), prop.Name, loc); implicit_value_parameter_type = null; } ; @@ -993,7 +1044,7 @@ get_accessor_declaration } accessor_body { - $$ = $4; + $$ = new Accessor ((Block) $4, (Attributes) $1); current_local_parameters = null; lexer.PropertyParsing = true; } @@ -1010,22 +1061,27 @@ set_accessor_declaration if (parsing_indexer == false) { args = new Parameter [1]; args [0] = implicit_value_parameter; + current_local_parameters = new Parameters (args, null, lexer.Location); } else { - Parameter [] fp = indexer_parameters.FixedParameters; - int count = fp.Length; - - args = new Parameter [count + 1]; - - fp.CopyTo (args, 0); - args [count] = implicit_value_parameter; + Parameter [] fpars = indexer_parameters.FixedParameters; + + if (fpars != null){ + int count = fpars.Length; + + args = new Parameter [count + 1]; + fpars.CopyTo (args, 0); + args [count] = implicit_value_parameter; + } else + args = null; + current_local_parameters = new Parameters ( + args, indexer_parameters.ArrayParameter, lexer.Location); } - current_local_parameters = new Parameters (args, null, lexer.Location); lexer.PropertyParsing = false; } accessor_body { - $$ = $4; + $$ = new Accessor ((Block) $4, (Attributes) $1); current_local_parameters = null; lexer.PropertyParsing = true; } @@ -1033,7 +1089,7 @@ set_accessor_declaration accessor_body : block - | SEMICOLON { $$ = new Block (null); } + | SEMICOLON { $$ = null; } ; interface_declaration @@ -1052,10 +1108,10 @@ interface_declaration } current_interface = new_interface; new_interface.Namespace = current_namespace; - RootContext.Tree.RecordInterface (full_interface_name, new_interface); + RootContext.Tree.RecordDecl (full_interface_name, new_interface); } opt_interface_base - interface_body + interface_body opt_semicolon { Interface new_interface = (Interface) current_interface; @@ -1063,7 +1119,8 @@ interface_declaration new_interface.Bases = (ArrayList) $6; current_interface = null; - CheckDef (current_container.AddInterface (new_interface), new_interface.Name); + CheckDef (current_container.AddInterface (new_interface), + new_interface.Name, new_interface.Location); } ; @@ -1113,25 +1170,25 @@ interface_member_declaration { InterfaceMethod m = (InterfaceMethod) $1; - CheckDef (current_interface.AddMethod (m), m.Name); + CheckDef (current_interface.AddMethod (m), m.Name, m.Location); } | interface_property_declaration { InterfaceProperty p = (InterfaceProperty) $1; - CheckDef (current_interface.AddProperty (p), p.Name); + CheckDef (current_interface.AddProperty (p), p.Name, p.Location); } | interface_event_declaration { InterfaceEvent e = (InterfaceEvent) $1; - CheckDef (current_interface.AddEvent (e), e.Name); + CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location); } | interface_indexer_declaration { InterfaceIndexer i = (InterfaceIndexer) $1; - CheckDef (current_interface.AddIndexer (i), "indexer"); + CheckDef (current_interface.AddIndexer (i), "indexer", i.Location); } ; @@ -1145,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); } ; @@ -1169,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); } @@ -1187,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); } ; @@ -1205,13 +1264,13 @@ 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); } ; operator_declaration - : opt_attributes opt_modifiers operator_declarator block + : opt_attributes opt_modifiers operator_declarator operator_body { OperatorDeclaration decl = (OperatorDeclaration) $3; @@ -1225,6 +1284,10 @@ operator_declaration } ; +operator_body + : block + | SEMICOLON { $$ = null; } + ; operator_declarator : type OPERATOR overloadable_operator OPEN_PARENS type IDENTIFIER CLOSE_PARENS @@ -1240,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 @@ -1257,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 ; @@ -1301,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 @@ -1333,31 +1397,44 @@ constructor_declaration : opt_attributes opt_modifiers constructor_declarator - block + constructor_body { 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) { - Location l = lexer.Location; - Report.Error (515, l, "Access modifiers are not allowed on static constructors"); - } - - if (c.Initializer != null){ - Location l = lexer.Location; - Report.Error (514, l, "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){ - Location l = lexer.Location; - Report.Error (132, l, "Static constructors should not have parameters"); - } - } - - CheckDef (current_container.AddConstructor (c), c.Name); + CheckDef (current_container.AddConstructor (c), c.Name, c.Location); current_local_parameters = null; } @@ -1378,6 +1455,11 @@ constructor_declarator } ; +constructor_body + : block + | SEMICOLON { $$ = null; } + ; + opt_constructor_initializer : /* empty */ { $$ = null; } | constructor_initializer @@ -1386,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); } ; @@ -1404,12 +1486,18 @@ destructor_declaration } else { Location l = lexer.Location; + int m; + if (!RootContext.StdLib && current_container.Name == "System.Object") + m = Modifiers.PROTECTED | Modifiers.VIRTUAL; + else + m = Modifiers.PROTECTED | Modifiers.OVERRIDE; + Method d = new Method ( - "System.Void", 0, "Finalize", + TypeManager.system_void_expr, m, "Finalize", new Parameters (null, null, l), (Attributes) $1, l); d.Block = (Block) $6; - CheckDef (current_container.AddMethod (d), d.Name); + CheckDef (current_container.AddMethod (d), d.Name, d.Location); } } ; @@ -1421,10 +1509,11 @@ event_declaration { foreach (VariableDeclaration var in (ArrayList) $5) { - Event e = new Event ((string) $4, var.identifier, var.expression_or_array_initializer, + Event e = new Event ((Expression) $4, var.identifier, + var.expression_or_array_initializer, (int) $2, null, null, (Attributes) $1, lexer.Location); - CheckDef (current_container.AddEvent (e), e.Name); + CheckDef (current_container.AddEvent (e), e.Name, e.Location); } } @@ -1433,8 +1522,9 @@ 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); } event_accessor_declarations { @@ -1442,19 +1532,21 @@ event_declaration } CLOSE_BRACE { + Location loc = (Location) oob_stack.Pop (); + Pair pair = (Pair) $8; - Block add_block = null; - Block rem_block = null; + Accessor add_accessor = null; + Accessor rem_accessor = null; if (pair.First != null) - add_block = (Block) pair.First; + add_accessor = (Accessor) pair.First; if (pair.Second != null) - rem_block = (Block) pair.Second; + rem_accessor = (Accessor) pair.Second; - Event e = new Event ((string) $4, (string) $5, null, (int) $2, add_block, rem_block, - (Attributes) $1, lexer.Location); + 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); + CheckDef (current_container.AddEvent (e), e.Name, loc); implicit_value_parameter_type = null; } ; @@ -1485,9 +1577,13 @@ add_accessor_declaration } block { - $$ = $4; + $$ = 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 @@ -1505,9 +1601,13 @@ remove_accessor_declaration } block { - $$ = $4; + $$ = 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 @@ -1522,7 +1622,7 @@ indexer_declaration parsing_indexer = true; indexer_parameters = decl.param_list; - $$ = lexer.Location; + oob_stack.Push (lexer.Location); } accessor_declarations { @@ -1533,20 +1633,15 @@ indexer_declaration { // The signature is computed from the signature of the indexer. Look // at section 3.6 on the spec - + Location loc = (Location) oob_stack.Pop (); Indexer indexer; IndexerDeclaration decl = (IndexerDeclaration) $3; Pair pair = (Pair) $6; - Block get_block = null; - Block set_block = null; - - if (pair.First != null) - get_block = (Block) pair.First; - if (pair.Second != null) - set_block = (Block) pair.Second; + Accessor get_block = (Accessor) pair.First; + Accessor set_block = (Accessor) pair.Second; indexer = new Indexer (decl.type, decl.interface_type, (int) $2, decl.param_list, - get_block, set_block, (Attributes) $1, (Location) $5); + get_block, set_block, (Attributes) $1, loc); // Note that there is no equivalent of CheckDef for this case // We shall handle this in semantic analysis @@ -1564,47 +1659,56 @@ indexer_declarator { Parameters pars = (Parameters) $4; - if (pars.FixedParameters == null){ + if (pars.FixedParameters == null && pars.ArrayParameter == null){ 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 { Parameters pars = (Parameters) $6; - if (pars.FixedParameters == null){ + 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); } ; enum_declaration : opt_attributes opt_modifiers - ENUM IDENTIFIER + ENUM IDENTIFIER opt_enum_base enum_body opt_semicolon { + 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, lexer.Location); + 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; - foreach (VariableDeclaration ev in (ArrayList) $6){ CheckDef (e.AddEnumMember (ev.identifier, (Expression) ev.expression_or_array_initializer, - (Location) ev.Location), - ev.identifier); + loc, ev.OptAttributes), + ev.identifier, loc); } - CheckDef (current_container.AddEnum (e), name); + e.Namespace = current_namespace; + + CheckDef (current_container.AddEnum (e), full_name, enum_location); + RootContext.Tree.RecordDecl (full_name, e); + } ; opt_enum_base - : /* empty */ { $$ = "System.Int32"; } + : /* empty */ { $$ = TypeManager.system_int32_expr; } | COLON type { $$ = $2; } ; @@ -1641,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 { @@ -1649,7 +1753,7 @@ enum_member_declaration } ASSIGN expression { - $$ = new VariableDeclaration ((string) $2, $5, lexer.Location); + $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1); } ; @@ -1662,11 +1766,13 @@ delegate_declaration CLOSE_PARENS SEMICOLON { - Delegate del = new Delegate ((string) $4, (int) $2, + Location l = lexer.Location; + Delegate del = new Delegate (current_container, (Expression) $4, (int) $2, MakeName ((string) $5), (Parameters) $7, - (Attributes) $1, lexer.Location); + (Attributes) $1, l); - CheckDef (current_container.AddDelegate (del), del.Name); + del.Namespace = current_namespace; + CheckDef (current_container.AddDelegate (del), del.Name, l); } | opt_attributes opt_modifiers @@ -1676,10 +1782,14 @@ delegate_declaration CLOSE_PARENS SEMICOLON { - Delegate del = new Delegate ("System.Void", (int) $2, (string) $5, (Parameters) $7, - (Attributes) $1, lexer.Location); + Location l = lexer.Location; + Delegate del = new Delegate ( + current_container, + TypeManager.system_void_expr, (int) $2, MakeName ((string) $5), + (Parameters) $7, (Attributes) $1, l); - CheckDef (current_container.AddDelegate (del), del.Name); + del.Namespace = current_namespace; + CheckDef (current_container.AddDelegate (del), del.Name, l); } ; @@ -1703,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 @@ -1719,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); @@ -1748,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 @@ -1772,25 +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"; } + : 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 @@ -1800,7 +1917,7 @@ interface_type array_type : type rank_specifiers { - $$ = (string) $1 + (string) $2; + $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location); } ; @@ -1834,8 +1951,6 @@ primary_expression | checked_expression | unchecked_expression | pointer_member_access - // TODO: pointer_element_access - // TODO: sizeof-expression ; literal @@ -1857,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) @@ -1891,7 +2002,7 @@ member_access } | predefined_type DOT IDENTIFIER { - $$ = new SimpleName ((string) $1 + "." + (string) $3, lexer.Location); + $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location); } ; @@ -1904,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); } @@ -1964,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); } ; @@ -1996,7 +2108,7 @@ expression_list this_access : THIS { - $$ = new This (lexer.Location); + $$ = new This (current_block, lexer.Location); } ; @@ -2035,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); } ; @@ -2044,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 { @@ -2069,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 @@ -2149,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); } ; @@ -2195,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); } @@ -2326,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); } ; @@ -2410,91 +2518,71 @@ assignment_expression { Location l = lexer.Location; - $$ = new Assign ((Expression) $1, - new Binary (Binary.Operator.Multiply, - (Expression) $1, - (Expression) $3, l), l); + $$ = new CompoundAssign ( + Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l); } | prefixed_unary_expression OP_DIV_ASSIGN expression { Location l = lexer.Location; - $$ = new Assign ((Expression) $1, - new Binary (Binary.Operator.Division, - (Expression) $1, - (Expression) $3, l), l); + $$ = new CompoundAssign ( + Binary.Operator.Division, (Expression) $1, (Expression) $3, l); } | prefixed_unary_expression OP_MOD_ASSIGN expression { Location l = lexer.Location; - $$ = new Assign ((Expression) $1, - new Binary (Binary.Operator.Modulus, - (Expression) $1, - (Expression) $3, l), l); + $$ = new CompoundAssign ( + Binary.Operator.Modulus, (Expression) $1, (Expression) $3, l); } | prefixed_unary_expression OP_ADD_ASSIGN expression { Location l = lexer.Location; - $$ = new Assign ((Expression) $1, - new Binary (Binary.Operator.Addition, - (Expression) $1, - (Expression) $3, l), l); + $$ = new CompoundAssign ( + Binary.Operator.Addition, (Expression) $1, (Expression) $3, l); } | prefixed_unary_expression OP_SUB_ASSIGN expression { Location l = lexer.Location; - $$ = new Assign ((Expression) $1, - new Binary (Binary.Operator.Subtraction, - (Expression) $1, - (Expression) $3, l), l); + $$ = new CompoundAssign ( + Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l); } | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression { Location l = lexer.Location; - $$ = new Assign ((Expression) $1, - new Binary (Binary.Operator.LeftShift, - (Expression) $1, - (Expression) $3, l), l); + $$ = new CompoundAssign ( + Binary.Operator.LeftShift, (Expression) $1, (Expression) $3, l); } | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression { Location l = lexer.Location; - $$ = new Assign ((Expression) $1, - new Binary (Binary.Operator.RightShift, - (Expression) $1, - (Expression) $3, l), l); + $$ = new CompoundAssign ( + Binary.Operator.RightShift, (Expression) $1, (Expression) $3, l); } | prefixed_unary_expression OP_AND_ASSIGN expression { Location l = lexer.Location; - $$ = new Assign ((Expression) $1, - new Binary (Binary.Operator.BitwiseAnd, - (Expression) $1, - (Expression) $3, l), l); + $$ = new CompoundAssign ( + Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3, l); } | prefixed_unary_expression OP_OR_ASSIGN expression { Location l = lexer.Location; - $$ = new Assign ((Expression) $1, - new Binary (Binary.Operator.BitwiseOr, - (Expression) $1, - (Expression) $3, l), l); + $$ = new CompoundAssign ( + Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3, l); } | prefixed_unary_expression OP_XOR_ASSIGN expression { Location l = lexer.Location; - $$ = new Assign ((Expression) $1, - new Binary (Binary.Operator.ExclusiveOr, - (Expression) $1, - (Expression) $3, l), l); + $$ = new CompoundAssign ( + Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3, l); } ; @@ -2528,7 +2616,7 @@ class_declaration (Attributes) $1, lexer.Location); current_container = new_class; current_container.Namespace = current_namespace; - RootContext.Tree.RecordClass (name, new_class); + RootContext.Tree.RecordDecl (name, new_class); } opt_class_base class_body @@ -2540,7 +2628,7 @@ class_declaration new_class.Bases = (ArrayList) $6; current_container = current_container.Parent; - CheckDef (current_container.AddClass (new_class), new_class.Name); + CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location); $$ = new_class; } @@ -2608,13 +2696,15 @@ class_base block : OPEN_BRACE { - current_block = new Block (current_block); + current_block = new Block (current_block, current_local_parameters, + lexer.Location, Location.Null); } opt_statement_list CLOSE_BRACE { while (current_block.Implicit) current_block = current_block.Parent; $$ = current_block; + current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; } ; @@ -2632,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; } @@ -2673,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; @@ -2687,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); + } } ; @@ -2726,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); } ; @@ -2748,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; } ; @@ -2800,13 +2916,13 @@ expression_statement // because statement_expression is used for example in for_statement // statement_expression - : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1); } - | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1); } - | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); } - | post_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); } - | post_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1); } - | pre_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); } - | pre_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1); } + : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); } + | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); } + | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); } + | post_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); } + | post_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); } + | pre_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); } + | pre_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); } | error { Report.Error (1002, lexer.Location, "Expecting `;'"); } @@ -2823,21 +2939,39 @@ selection_statement ; if_statement - : IF OPEN_PARENS boolean_expression CLOSE_PARENS + : if_statement_open if_statement_rest + { + $$ = $2; + } + ; + +if_statement_open + : IF OPEN_PARENS + { + oob_stack.Push (lexer.Location); + } + ; + +if_statement_rest + : boolean_expression CLOSE_PARENS embedded_statement { - $$ = new If ((Expression) $3, (Statement) $5); + Location l = (Location) oob_stack.Pop (); + + $$ = new If ((Expression) $1, (Statement) $3, l); if (RootContext.WarningLevel >= 3){ - if ($5 is EmptyStatement) + if ($3 is EmptyStatement) Report.Warning (642, lexer.Location, "Possibly mistaken empty statement"); } } - | IF OPEN_PARENS boolean_expression CLOSE_PARENS + | boolean_expression CLOSE_PARENS embedded_statement ELSE embedded_statement { - $$ = new If ((Expression) $3, (Statement) $5, (Statement) $7); + Location l = (Location) oob_stack.Pop (); + + $$ = new If ((Expression) $1, (Statement) $3, (Statement) $5, l); } ; @@ -2845,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 (); } ; @@ -2890,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); } ; @@ -2936,12 +3073,17 @@ iteration_statement ; while_statement - : WHILE OPEN_PARENS boolean_expression CLOSE_PARENS embedded_statement + : WHILE OPEN_PARENS + { + oob_stack.Push (lexer.Location); + } + boolean_expression CLOSE_PARENS embedded_statement { - $$ = new While ((Expression) $3, (Statement) $5); + Location l = (Location) oob_stack.Pop (); + $$ = new While ((Expression) $4, (Statement) $6, l); if (RootContext.WarningLevel >= 3){ - if ($5 is EmptyStatement) + if ($6 is EmptyStatement) Report.Warning (642, lexer.Location, "Possibly mistaken empty statement"); } } @@ -2949,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); + Location l = (Location) oob_stack.Pop (); + + $$ = new Do ((Statement) $2, (Expression) $6, l); } ; @@ -2965,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){ @@ -2974,44 +3121,41 @@ 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)); + assign_block.AddStatement (new StatementExpression (a, lexer.Location)); } } $3 = null; } + oob_stack.Push (lexer.Location); } opt_for_condition SEMICOLON opt_for_iterator CLOSE_PARENS embedded_statement { - For f = new For ((Statement) $3, (Expression) $6, (Statement) $8, (Statement) $10); + Location l = (Location) oob_stack.Pop (); + + For f = new For ((Statement) $3, (Expression) $6, (Statement) $8, (Statement) $10, l); if (RootContext.WarningLevel >= 3){ if ($10 is EmptyStatement) @@ -3053,7 +3197,8 @@ for_iterator statement_expression_list : statement_expression { - Block b = new Block (null, true); + // CHANGE: was `null' + Block b = new Block (current_block, Block.Flags.Implicit); b.AddStatement ((Statement) $1); $$ = b; @@ -3076,35 +3221,38 @@ 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); - if (vi == null){ - Report.Error ( - 128, l, "A local variable `" + (string) $4 + "' is already "+ - "defined in this scope"); - } - - v = new LocalVariableReference (foreach_block, (string) $4, l); + vi = foreach_block.AddVariable ((Expression) $3, (string) $4, current_local_parameters, l); + if (vi != null) { + vi.ReadOnly = true; - current_block.AddStatement (foreach_block); + // 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); + oob_stack.Push (current_block); } embedded_statement { + Block foreach_block = (Block) oob_stack.Pop (); LocalVariableReference v = (LocalVariableReference) oob_stack.Pop (); Block prev_block = (Block) oob_stack.Pop (); Location l = (Location) oob_stack.Pop (); - while (current_block != prev_block) - current_block = current_block.Parent; + current_block = prev_block; - $$ = new Foreach ((string) $3, v, (Expression) $7, (Statement) $10, l); + if (v != null) { + Foreach f = new Foreach ((Expression) $3, v, (Expression) $7, (Statement) $10, l); + foreach_block.AddStatement (f); + } + + $$ = foreach_block; } ; @@ -3114,6 +3262,7 @@ jump_statement | goto_statement | return_statement | throw_statement + | yield_statement ; break_statement @@ -3159,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 @@ -3171,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); @@ -3180,21 +3352,24 @@ 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 { Catch g = null; ArrayList s = new ArrayList (); - - foreach (Catch cc in (ArrayList) $3) { - if (cc.Type == null) - g = cc; - else - s.Add (cc); + ArrayList catch_list = (ArrayList) $3; + + if (catch_list != null){ + foreach (Catch cc in catch_list) { + 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 { @@ -3232,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){ @@ -3249,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; } @@ -3312,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; @@ -3326,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; @@ -3348,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); } ; @@ -3396,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; @@ -3440,7 +3605,7 @@ using_statement vars.Add (new DictionaryEntry (var, expr)); // Assign a = new Assign (var, expr, decl.Location); - // assign_block.AddStatement (new StatementExpression (a)); + // assign_block.AddStatement (new StatementExpression (a, lexer.Location)); } $3 = new DictionaryEntry (type, vars); } @@ -3470,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) + { } } @@ -3483,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; @@ -3501,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; @@ -3522,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 @@ -3546,16 +3725,14 @@ MakeName (string class_name) // in the current declaration space // void -CheckDef (AdditionResult result, string name) +CheckDef (AdditionResult result, string name, Location l) { if (result == AdditionResult.Success) return; - Location l = lexer.Location; - switch (result){ case AdditionResult.NameExists: - Report.Error (102, l, "The namespace `" + current_container.Name + + Report.Error (102, l, "The container `" + current_container.Name + "' already contains a definition for `"+ name + "'"); break; @@ -3583,34 +3760,11 @@ CheckDef (AdditionResult result, string name) } void -CheckDef (bool result, string name) +CheckDef (bool result, string name, Location l) { if (result) return; - CheckDef (AdditionResult.NameExists, name); -} - -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_block != null){ - if (current_block.IsVariableDefined (name)) - return new LocalVariableReference (current_block, name, loc); - } - - 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; + CheckDef (AdditionResult.NameExists, name, l); } Expression DecomposeQI (string name, Location loc) @@ -3618,16 +3772,14 @@ 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); } } @@ -3638,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) @@ -3648,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; @@ -3669,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); - 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){ @@ -3682,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"); } } @@ -3701,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; @@ -3713,25 +3861,23 @@ Block declare_local_variables (string type, ArrayList variable_declarators, Loca assign = new Assign (var, expr, decl.Location); - implicit_block.AddStatement (new StatementExpression (assign)); + implicit_block.AddStatement (new StatementExpression (assign, lexer.Location)); } 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; @@ -3828,42 +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 () { - StringBuilder value = new StringBuilder (); - - 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 */