X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmbas%2Fmb-parser.jay;h=2d7d5fd0c715bddc8e27a1dc59a3f68706cf575d;hb=98b7597517475eb0b3096b6ac5f6f36fe5ee6e94;hp=8463b685797863637342a9f23ce8bf603fd2871b;hpb=932f0579e6c601b589b7832ab2bd538d03113d89;p=mono.git diff --git a/mcs/mbas/mb-parser.jay b/mcs/mbas/mb-parser.jay index 8463b685797..2d7d5fd0c71 100644 --- a/mcs/mbas/mb-parser.jay +++ b/mcs/mbas/mb-parser.jay @@ -2,12 +2,14 @@ // // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler // -// Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com) -// Anirban Bhattacharjee (banirban@novell.com) +// Authors: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com) +// Anirban Bhattacharjee (banirban@novell.com) +// Jambunathan K (kjambunathan@novell.com) // // Licensed under the terms of the GNU GPL // -// Copyright (C) 2001 A Rafael D Teixeira +// Copyright (C) 2001, 2002, 2003, 2004 A Rafael D Teixeira +// Copyright (C) 2003, 2004 Novell // // @@ -40,6 +42,7 @@ namespace Mono.MonoBASIC { + /// /// Current block is used to add statements as we find /// them. @@ -258,7 +261,7 @@ namespace Mono.MonoBASIC // are not broken. public void HandleToken(IfElseStateMachine.Token tok) - { + { err = (int) errTable[(int)state, (int)tok]; if(err != 0) @@ -364,6 +367,13 @@ namespace Mono.MonoBASIC } } } + + bool allow_global_attribs = true; + + bool expecting_global_attribs = false; + bool expecting_local_attribs = false; + + bool local_attrib_section_added = false; %} %token EOF @@ -565,13 +575,6 @@ namespace Mono.MonoBASIC %token OP_NE "<>" %token OP_XOR "xor" //%token OP_MODULUS //"mod" -%token OP_MULT_ASSIGN "*=" -%token OP_DIV_ASSIGN "/=" -%token OP_IDIV_ASSIGN "\\=" -%token OP_ADD_ASSIGN "+=" -%token OP_SUB_ASSIGN "-=" -%token OP_CONCAT_ASSIGN "&=" -%token OP_EXP_ASSIGN "^=" /* VB.NET 2003 new bit-shift operators */ %token OP_SHIFT_LEFT "<<" @@ -623,15 +626,21 @@ logical_end_of_line compilation_unit : logical_end_of_line + opt_option_directives + opt_imports_directives + declarations + EOF + { + $$=$4; + } + |logical_end_of_line opt_option_directives opt_imports_directives opt_attributes - opt_declarations EOF { - $$=$5; + /* ????? */ ; } - ; opt_option_directives @@ -711,7 +720,7 @@ option_compare_directive opt_declarations : /* empty */ | declarations - ; + ; declarations : declaration @@ -719,14 +728,25 @@ declarations ; declaration - : namespace_declaration - | type_declaration + : declaration_qualifiers + { + // FIXME: Need to check declaration qualifiers for multi-file compilation + // FIXME: Qualifiers cannot be applied to namespaces + allow_global_attribs = false; + } + namespace_declaration + |declaration_qualifiers + { + // FIXME: Need to check declaration qualifiers for multi-file compilation + allow_global_attribs = false; + } + type_spec_declaration { string name = ""; int mod_flags; - if ($1 is Class || $1 is Struct || $1 is Module ){ - TypeContainer c = (TypeContainer) $1; + if ($3 is Class || $3 is Struct || $3 is Module ){ + TypeContainer c = (TypeContainer) $3; mod_flags = c.ModFlags; name = c.Name; } else @@ -809,77 +829,183 @@ opt_params | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { $$ = $2; } ; -global_attribute_list - : global_attribute - | global_attribute_list COMMA global_attribute - ; +opt_attributes + : /* empty */ + | attribute_sections + { + $$ = $1; + local_attrib_section_added = false; + } + ; -global_attribute - : attribute_modifier COLON attribute +attribute_sections + : attribute_section + { + $$ = $1; + if ($1 == null) { + expecting_local_attribs = false; + expecting_global_attribs = false; + break; + } + + if (expecting_local_attribs) { + local_attrib_section_added = true; + allow_global_attribs = false; -attribute_modifier - : ASSEMBLY - | MODULE - | identifier - { - Report.Error (658, lexer.Location, "`" + (string)$1 + "' is an invalid attribute target"); + $$ = new Attributes ((ArrayList) $1); + } + + if (expecting_global_attribs) { + $$ = null; + CodeGen.AddGlobalAttributes ((ArrayList) $1); + } + + expecting_local_attribs = false; + expecting_global_attribs = false; + } + | attribute_sections + { + $$ = lexer.Location; } - ; + attribute_section + { + $$ = $1; + if ($3 != null) { + ArrayList attrs = (ArrayList) $3; + + if (expecting_local_attribs) { + if (local_attrib_section_added) { + expecting_local_attribs = false; + expecting_global_attribs = false; + Report.Error (30205, (Location) $2, "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section"); + break; + } -opt_attributes - : /* empty */ - | attributes { $$ = $1; } - ; + if ($1 == null) + $$ = new Attributes (attrs); + else + ((Attributes) $1).Add (attrs); -attr_begin - : OP_LT - ; + local_attrib_section_added = true; + allow_global_attribs = false; + } -attr_end - : OP_GT + if (expecting_global_attribs) { + $$ = null; + CodeGen.AddGlobalAttributes ((ArrayList) $3); + } + } + + expecting_local_attribs = false; + expecting_global_attribs = false; + } ; -attributes - : attr_begin attribute_list attr_end +attribute_section + : OP_LT attribute_list OP_GT opt_end_of_stmt { - AttributeSection sect = new AttributeSection (null, (ArrayList) $2); - $$ = new Attributes (sect, lexer.Location); + $$ = null; + if ($2 != null) { + if (expecting_global_attribs && !(bool) $4) { + Report.Error (30205, lexer.Location, "End of statement expected"); + break; + } + + if (expecting_local_attribs) { + if ((bool) $4) { + Report.Error (32035, lexer.Location, "Use a line continuation after the attribute specifier to apply it to the following statement."); + break; + } + } + + $$ = $2; + } } - | attr_begin global_attribute_list attr_end logical_end_of_line ; +opt_end_of_stmt + : /* empty */ { $$ = false; } + | end_of_stmt { $$ = true; } + ; + attribute_list : attribute { - ArrayList attrs = new ArrayList (); - attrs.Add ($1); - + ArrayList attrs = null; + if ($1 != null) { + attrs = new ArrayList (); + attrs.Add ($1); + } $$ = attrs; - } | attribute_list COMMA attribute { - ArrayList attrs = (ArrayList) $1; - attrs.Add ($3); + ArrayList attrs = null; + + if ($3 != null) { + attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1; + attrs.Add ($3); + } $$ = attrs; } ; attribute - : attribute_name - { + : namespace_or_type_name + { $$ = lexer.Location; - } - opt_attribute_arguments - { - $$ = new Mono.MonoBASIC.Attribute ((string) $1, (ArrayList) $3, (Location) $2); - } + } + opt_attribute_arguments + { + $$ = null; + + if (expecting_global_attribs) + Report.Error (32015, (Location) $2, "Expecting Assembly or Module attribute specifiers"); + else { + expecting_local_attribs = true; + $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2); + } + } + | attribute_target_specifier + { + $$ = lexer.Location; + } + COLON + namespace_or_type_name + { + $$ = lexer.Location; + } + opt_attribute_arguments + { + $$ = null; + + string attribute_target = (string) $1; + if (attribute_target != "assembly" && attribute_target != "module") { + Report.Error (29999, lexer.Location, "`" + (string)$1 + "' is an invalid attribute modifier"); + break; + } + if (!allow_global_attribs) { + Report.Error (30637, (Location) $2, "Global attribute statements must precede any declarations in a file"); + break; + } + + if (expecting_local_attribs) { + Report.Error (30183, (Location) $2, "Global attributes cannot be combined with local attributes"); + break; + } + + expecting_global_attribs = true; + $$ = new Attribute (attribute_target, (string) $4, (ArrayList) $6, (Location) $5); + } ; -attribute_name - : namespace_or_type_name +attribute_target_specifier + : ASSEMBLY { $$ = "assembly"; } + | MODULE { $$ = "module"; } + | namespace_or_type_name ; + opt_attribute_arguments : /* empty */ { $$ = null; } @@ -975,14 +1101,13 @@ namespace_declaration } ; -type_declaration +declaration_qualifiers : opt_attributes opt_modifiers { current_attributes = (Attributes) $1; current_modifiers = (int) $2; } - type_spec_declaration ; type_spec_declaration @@ -1239,7 +1364,7 @@ must_override_declaration ; must_override_sub_declaration - : MUSTOVERRIDE SUB identifier opt_params logical_end_of_line + : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause logical_end_of_line { if (current_container is Module) Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'."); @@ -1250,7 +1375,7 @@ must_override_sub_declaration current_modifiers |= Modifiers.ABSTRACT; Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3, - (Parameters) $4, null, null, lexer.Location); + (Parameters) $4, null, (ArrayList) $5, lexer.Location); if (!(current_container is Class)) Report.Error (9999, "THIS SHOULD NEVER HAPPEN!"); @@ -1261,7 +1386,7 @@ must_override_sub_declaration must_override_func_declaration - : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line + : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line { Expression ftype = ($6 == null) ? (($4 == null) ? TypeManager. system_object_expr : (Expression) $4 ) : (Expression) $6; @@ -1275,7 +1400,7 @@ must_override_func_declaration current_modifiers |= Modifiers.ABSTRACT; Method method = new Method ((Expression) ftype, (int) current_modifiers, - (string) $3,(Parameters) $5, null, null, + (string) $3,(Parameters) $5, null, (ArrayList) $7, lexer.Location); if (!(current_container is Class)) @@ -1310,7 +1435,11 @@ sub_declaration if ($4 != null) { // we have an event handler to take care of - string evt_def = ((MemberAccess)$6).ToString(); + Expression handles_exp = (Expression) $4; + Location loc = lexer.Location; + + if (handles_exp is MemberAccess) { + string evt_def = ((MemberAccess)$4).ToString(); int pos = evt_def.LastIndexOf ("."); string evt_target = evt_def.Substring (0, pos); bool found = false; @@ -1318,11 +1447,11 @@ sub_declaration if (current_container.Properties != null) { foreach (Property p in current_container.Properties) { if (p.Name == evt_target) { - Location loc = lexer.Location; + Statement addhnd = (Statement) new AddHandler ((Expression) $4, DecomposeQI((string) $2, loc), - DecomposeQI(evt_target, loc), loc); + loc); current_container.AddEventHandler (addhnd); found = true; @@ -1330,11 +1459,20 @@ sub_declaration } } } - + if (!found){ Report.Error(30506, lexer.Location, evt_target + " is not declared with WithEvents"); } + } else if (handles_exp is BaseAccess) { + string evt_id = ((BaseAccess) $4).member; + Statement addhnd = (Statement) new AddHandler ((Expression) $4, + DecomposeQI((string) $2, loc), + loc); + + current_container.AddEventHandler (addhnd); + } + } } ; @@ -1446,7 +1584,7 @@ event_declaration VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location); Event e = new Event ((Expression) $4, var.identifier, - null, current_modifiers, null, null, + null, current_modifiers, current_attributes, (ArrayList) $5, lexer.Location); @@ -1483,7 +1621,7 @@ event_declaration Event e = new Event (DecomposeQI (delName, lexer.Location), (string) $2, - null, current_modifiers, null, null, + null, current_modifiers, current_attributes, (ArrayList) $4, lexer.Location); @@ -1493,13 +1631,17 @@ event_declaration enum_declaration : ENUM identifier opt_type_spec logical_end_of_line - opt_enum_member_declarations // FIXME: BC30280: Enum must contain atleast one member + opt_enum_member_declarations { Location enum_location = lexer.Location; string full_name = MakeName ((string) $2); Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3; ArrayList enum_members = (ArrayList) $5; + if (enum_members.Count == 0) + Report.Error (30280, enum_location, + "Enum can not have empty member list"); + // Module members are static by default, but enums *can't* be declared static // so we must fix it if mbas was the one actually responsible for this // instead of triggering an error. @@ -1599,29 +1741,23 @@ interface_declaration opt_interface_base : /* empty */ { $$ = null; } - | interface_base - ; - -interface_base - : INHERITS interface_type_list { $$ = $2; } + | interface_bases ; -interface_type_list - : interface_type +interface_bases + : interface_base + | interface_bases interface_base { - ArrayList interfaces = new ArrayList (); - - interfaces.Add ($1); - $$ = interfaces; - } - | interface_type_list COMMA interface_type - { - ArrayList interfaces = (ArrayList) $1; - interfaces.Add ($3); - $$ = interfaces; + ArrayList bases = (ArrayList) $1; + bases.AddRange ((ArrayList) $2); + $$ = bases; } ; +interface_base + : INHERITS type_list logical_end_of_line { $$ = $2; } + ; + interface_body : opt_interface_member_declarations ; @@ -1681,7 +1817,7 @@ interface_method_declaration ; interface_property_declaration - : PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec logical_end_of_line + : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line { Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5; @@ -1731,7 +1867,7 @@ interface_event_declaration VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location); Event e = new Event ((Expression) $4, var.identifier, - null, current_modifiers, null, null, + null, current_modifiers, current_attributes, lexer.Location); CheckDef (current_interface.AddEvent (e), e.Name, e.Location); @@ -1752,7 +1888,7 @@ interface_event_declaration Event e = new Event (DecomposeQI (delName, lexer.Location), (string) $2, - null, current_modifiers, null, null, + null, current_modifiers, current_attributes, lexer.Location); CheckDef (current_interface.AddEvent (e), e.Name, e.Location); @@ -1765,7 +1901,7 @@ property_declaration ; abstract_propery_declaration - : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec logical_end_of_line + : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line { Expression ftype = ($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6; @@ -1822,8 +1958,18 @@ abstract_propery_declaration non_abstract_propery_declaration - : PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec opt_implement_clause logical_end_of_line - { + : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks opt_implement_clause logical_end_of_line + { + if ((current_modifiers & Modifiers.DEFAULT) > 0) { + if (current_container.DefaultPropName != null) + Report.Error (30359, + lexer.Location, + "Type '" + current_container.Name + + "' cannot have more than one 'Default Property' "); + + current_container.DefaultPropName = (string) $2; + } + get_implicit_value_parameter_type = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5; @@ -2004,7 +2150,7 @@ opt_set_parameter set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; set_implicit_value_parameter_name = "Value"; } - | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_spec CLOSE_PARENS + | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS { Parameter.Modifier pm = (Parameter.Modifier)$2; if ((pm | Parameter.Modifier.VAL) != 0) @@ -2014,11 +2160,11 @@ opt_set_parameter set_implicit_value_parameter_type = (Expression) $4; - if (set_implicit_value_parameter_type != get_implicit_value_parameter_type) + if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ()) Report.Error (31064, lexer.Location, "Set value parameter type can not be different from property type"); - + if ($2 != null) set_implicit_value_parameter_name = (string) $3; else @@ -2125,7 +2271,7 @@ delegate_declaration | DELEGATE FUNCTION identifier OPEN_PARENS opt_formal_parameter_list - CLOSE_PARENS opt_type_spec logical_end_of_line + CLOSE_PARENS opt_type_with_ranks logical_end_of_line { Location l = lexer.Location; @@ -2148,18 +2294,29 @@ delegate_declaration ; opt_evt_handler - : /* empty */ - { $$ = null; } - | HANDLES qualified_identifier + : /* empty */ { $$ = null; } + | HANDLES evt_handler { $$ = $2; } + ; + +evt_handler + : qualified_identifier + { + $$ = (Expression) DecomposeQI ((string)$1, lexer.Location); + } + | base_access + { + $$ = $1; + } + | ME DOT qualified_identifier { - $$ = (Expression) DecomposeQI ((string)$2, lexer.Location); + $$ = (Expression) DecomposeQI ((string)$3, lexer.Location); } - | HANDLES MYBASE DOT qualified_identifier + /*| MYBASE DOT qualified_identifier { // FIXME: this is blatantly wrong and crash-prone $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location); - } - ; + }*/ + ; constructor_declaration : SUB NEW opt_params logical_end_of_line @@ -2200,38 +2357,40 @@ opt_formal_parameter_list ; formal_parameter_list - : fixed_parameters + : parameters { ArrayList pars_list = (ArrayList) $1; - - Parameter [] pars = new Parameter [pars_list.Count]; - pars_list.CopyTo (pars); - $$ = new Parameters (pars, null, lexer.Location); + Parameter [] pars = null; + Parameter array_parameter = null; + int non_array_count = pars_list.Count; + if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) { + array_parameter = (Parameter) pars_list [pars_list.Count - 1]; + non_array_count = pars_list.Count - 1; + } + foreach (Parameter par in pars_list) + if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) { + Report.Error (30192, lexer.Location, "ParamArray parameters must be last"); + non_array_count = 0; + array_parameter = null; + break; + } + if (non_array_count > 0) { + pars = new Parameter [non_array_count]; + pars_list.CopyTo (0, pars, 0, non_array_count); + } + $$ = new Parameters (pars, array_parameter, lexer.Location); } - | fixed_parameters COMMA parameter_array - { - ArrayList pars_list = (ArrayList) $1; - - Parameter [] pars = new Parameter [pars_list.Count]; - pars_list.CopyTo (pars); - - $$ = new Parameters (pars, (Parameter) $3, lexer.Location); - } - | parameter_array - { - $$ = new Parameters (null, (Parameter) $1, lexer.Location); - } ; -fixed_parameters - : fixed_parameter +parameters + : parameter { ArrayList pars = new ArrayList (); pars.Add ($1); $$ = pars; } - | fixed_parameters COMMA fixed_parameter + | parameters COMMA parameter { ArrayList pars = (ArrayList) $1; @@ -2240,58 +2399,47 @@ fixed_parameters } ; -fixed_parameter +parameter : opt_attributes opt_parameter_modifier - identifier opt_type_character opt_rank_specifiers opt_type_spec opt_variable_initializer + identifier opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer { Parameter.Modifier pm = (Parameter.Modifier)$2; bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0); Expression ptype; if (opt_parm && ($7 == null)) - Report.Error (30812, "Optional parameters must have a default value"); + Report.Error (30812, lexer.Location, "Optional parameters must have a default value"); + + if (!opt_parm && ($7 != null)) + Report.Error (32024, lexer.Location, "Non-Optional parameters should not have a default value"); + + if ((pm & Parameter.Modifier.PARAMS) != 0) { + if ((pm & ~Parameter.Modifier.PARAMS) != 0) + Report.Error (30667, lexer.Location, "ParamArray parameters must be ByVal"); + } - if (opt_parm) { - if ((pm & Parameter.Modifier.REF) !=0) - pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; - else - pm = Parameter.Modifier.NONE; //FIXME: should take into account BYREF - } + if ((pm & Parameter.Modifier.REF) !=0) + pm |= Parameter.Modifier.ISBYREF; if ($4 != null && $6 != null && $4 != $6) - Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text + Report.Error (30302, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6); if ($5 != null) { - string t = ptype.ToString() + VariableDeclaration.BuildRank ((ArrayList) $5); - ptype = DecomposeQI (t, lexer.Location); - } + string t = ptype.ToString (); + if (t.IndexOf('[') >= 0) + Report.Error (31087, lexer.Location, "Array types specified in too many places"); + else + ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $5, true, lexer.Location), lexer.Location); + } + if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0) + Report.Error (30050, lexer.Location, "ParamArray parameters must be an array type"); $$ = new Parameter (ptype, (string) $3, pm, (Attributes) $1, (Expression) $7, opt_parm); } ; -parameter_array - : PARAM_ARRAY identifier opt_parens AS type - { - string s_patype = ((Expression) $5).ToString(); - if ((bool) $3) - s_patype += "[]"; - - Expression patype = DecomposeQI (s_patype, Location.Null); - $$ = new Parameter (patype, (string) $2, Parameter.Modifier.PARAMS, null); - // note ("type must be a single-dimension array type"); - } - ; - -opt_parens - : /* empty */ - { $$ = false; } - | OPEN_PARENS CLOSE_PARENS - { $$ = true; } - ; - opt_parameter_modifier : /* empty */ { $$ = Parameter.Modifier.VAL; } | parameter_modifiers { $$ = $1; } @@ -2306,6 +2454,7 @@ parameter_modifier : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; } | BYVAL { $$ = Parameter.Modifier.VAL; } | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; } + | PARAM_ARRAY { $$ = Parameter.Modifier.PARAMS; } ; opt_statement_list @@ -2318,8 +2467,8 @@ statement_list | statement_list end_of_stmt statement ; -statement : - declaration_statement +statement + : declaration_statement { if ($1 != null && (Block) $1 != current_block){ current_block.AddStatement ((Statement) $1); @@ -2333,13 +2482,13 @@ statement : current_block.AddStatement ((Statement) $1); } | labeled_statement - | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier + | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler { - AddHandler ((Expression) $2, (string) $5); + AddHandler ((Expression) $2, (Expression) $5); } - | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier + | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler { - RemoveHandler ((Expression) $2, (string) $5); + RemoveHandler ((Expression) $2, (Expression) $5); } | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS { @@ -2566,43 +2715,77 @@ iteration_statement ; foreach_statement - : FOR EACH identifier IN + : FOR EACH identifier opt_type_spec IN { oob_stack.Push (lexer.Location); } expression end_of_stmt { - - start_block(); - Block foreach_block = current_block; Location l = lexer.Location; LocalVariableReference v = null; VariableInfo vi; - vi = foreach_block.GetVariableInfo ((string) $3); - if (vi != null) { - // Get a reference to this variable. - v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false); + if ($4 != null) + { + start_block(); + VariableDeclaration decl = new VariableDeclaration ((string) $3, + (Expression) $4, null, lexer.Location, null); + + vi = current_block.AddVariable ( + (Expression) $4, decl.identifier, current_local_parameters, decl.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 + { + ArrayList init = (ArrayList) decl.expression_or_array_initializer; + expr = new ArrayCreation ((Expression) $4, "", init, decl.Location); + } + + v = new LocalVariableReference (current_block, decl.identifier, l); + + if (expr != null) + { + Assign a = new Assign (v, expr, decl.Location); + current_block.AddStatement (new StatementExpression (a, lexer.Location)); + } } else - Report.Error (451, "Name '" + (string) $3 + "' is not declared."); - + { + vi = current_block.GetVariableInfo ((string) $3); + + if (vi != null) { + // Get a reference to this variable. + v = new LocalVariableReference (current_block, (string) $3, l, vi, false); + } + else + Report.Error (451, "Name '" + (string) $3 + "' is not declared."); + } + oob_stack.Push (v); + start_block(); } opt_statement_list NEXT opt_identifier { - Block foreach_block = current_block; LocalVariableReference v = (LocalVariableReference) oob_stack.Pop (); - Block prev_block = end_block(); + Block foreach_block = end_block(); Location l = (Location) oob_stack.Pop (); Foreach f = null; - if (v != null) { - f = new Foreach (null, v, (Expression) $6, (Statement) $9, l); - } + if (v != null) + f = new Foreach (null, v, (Expression) $7, foreach_block, l); - $$ = f; + if ($4 != null) + { + current_block.AddStatement (f); + $$ = end_block (); + } + else + $$ = f; } ; @@ -2749,8 +2932,13 @@ opt_identifier | identifier ; +opt_when + : /* empty */ { $$ = null; } + | WHEN boolean_expression { $$ = $2; } + ; + catch_clause - : CATCH opt_catch_args end_of_stmt + : CATCH opt_catch_args opt_when end_of_stmt { Expression type = null; string id = null; @@ -2766,14 +2954,12 @@ catch_clause one.Add (new VariableDeclaration (id, type, loc)); - $1 = current_block; current_block = new Block (current_block); Block b = declare_local_variables (type, one, loc); current_block = b; } } - } opt_statement_list { Expression type = null; @@ -2793,10 +2979,9 @@ catch_clause current_block = current_block.Parent; } } - - $$ = new Catch (type, id , (Block)b_catch, lexer.Location); + $$ = new Catch (type, id , (Block) b_catch, (Expression) $3, lexer.Location); } - ; + ; opt_catch_args : /* empty */ { $$ = null; } @@ -2873,29 +3058,48 @@ while_statement } ; - for_statement - : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt + : FOR identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt { - start_block(); + if ($3 != null) + { + start_block(); + ArrayList VarDeclaration = new ArrayList (); + VarDeclaration.Add (new VariableDeclaration ((string) $2, + (Expression) $3, null, lexer.Location, null)); + + DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), VarDeclaration); + Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location); + current_block = b; + } + oob_stack.Push (lexer.Location); + start_block(); } opt_statement_list NEXT opt_identifier { - Block statement = end_block(); - Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);; - - Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location); - Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual, - for_var, (Expression) $6, lexer.Location); - Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition, - for_var, (Expression) $7, lexer.Location), lexer.Location); - - Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location); - Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location); - - $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location); - } + Block inner_statement = end_block(); + Location l = (Location) oob_stack.Pop (); + Expression for_var = (Expression) DecomposeQI ((string)$2, l); + + Expression assign_expr = new Assign (for_var, (Expression) $5, l); + Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual, + for_var, (Expression) $7, l); + Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition, + for_var, (Expression) $8, l), l); + + Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, l); + Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, l); + + For f = new For (assign_stmt, test_expr, step_stmt, inner_statement, l); + if ($3 != null) + { + current_block.AddStatement (f); + $$ = end_block(); + } + else + $$ = f; + } ; opt_step @@ -2913,11 +3117,28 @@ if_statement { $$ = $3; } - | if_statement_open THEN pre_embedded_statement + | if_statement_open THEN pre_embedded_statement opt_else_pre_embedded_statement { - Location l = (Location) oob_stack.Pop (); - tmp_expr = (Expression)expr_stack.Pop(); - $$ = new If ((Expression) tmp_expr, end_block(), l); + if ($4 == null) + { + Location l = (Location) oob_stack.Pop (); + tmp_expr = (Expression)expr_stack.Pop(); + $$ = new If ((Expression) tmp_expr, end_block(), l); + } + else + { + Location l = (Location) oob_stack.Pop (); + tmp_expr = (Expression)expr_stack.Pop(); + tmp_block = (Block) tmp_blocks.Pop (); + $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l); + } + } + | if_statement_open THEN else_pre_embedded_statement + { + Location l = (Location) oob_stack.Pop (); + tmp_expr = (Expression)expr_stack.Pop(); + tmp_block = (Block) tmp_blocks.Pop (); + $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l); } ; @@ -2929,6 +3150,30 @@ pre_embedded_statement current_block.AddStatement ((Statement) $1); } ; + +opt_else_pre_embedded_statement + : /* empty */ + | else_pre_embedded_statement + ; + +else_pre_embedded_statement + : ELSE + { + Block bl = end_block(); + tmp_blocks.Push(bl); + + start_block(); + } + | ELSE embedded_statement + { + Block bl = end_block(); + tmp_blocks.Push(bl); + + start_block(); + Statement s = (Statement) $2; + current_block.AddStatement ((Statement) $2); + } + ; if_statement_open : IF boolean_expression @@ -2951,7 +3196,7 @@ if_statement_rest END IF { Location l = (Location) oob_stack.Pop (); - Expression expr = (Expression)expr_stack.Pop(); + Expression expr = (Expression)expr_stack.Pop(); $$ = new If ((Expression) expr, (Statement) end_block(), l); } | end_of_stmt @@ -2959,7 +3204,7 @@ if_statement_rest ELSE end_of_stmt { Block bl = end_block(); - tmp_blocks.Push(bl); + tmp_blocks.Push(bl); start_block(); } opt_statement_list @@ -3100,7 +3345,7 @@ case_section topmost.statements.Add (new Break (lexer.Location)); $$ = new SwitchSection ((ArrayList) $2, topmost); } - | CASE ELSE ends + | CASE ELSE ends /* FIXME: we should somehow flag an error (BC30321 'Case' cannot follow a 'Case Else' in the same 'Select' statement.) @@ -3195,7 +3440,7 @@ object_creation_expression ; array_creation_expression - : object_creation_expression array_initializer + : object_creation_expression opt_rank_specifiers array_initializer { New n = (New) $1; ArrayList dims = new ArrayList(); @@ -3208,7 +3453,10 @@ array_creation_expression Expression atype = n.RequestedType; - ArrayList init = (ArrayList) $2; + if ($2 != null) + atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, lexer.Location), lexer.Location); + + ArrayList init = (ArrayList) $3; if (init.Count == 0) init = null; @@ -3219,7 +3467,7 @@ array_creation_expression else { string rank = VariableDeclaration.BuildRank (dims); - $$ = new ArrayCreation (atype, rank, (ArrayList) $2, lexer.Location); + $$ = new ArrayCreation (atype, rank, (ArrayList) $3, lexer.Location); } //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'"); } @@ -3377,16 +3625,7 @@ variable_declarator Report.Error (30638, "Array bounds cannot appear in type specifiers."); current_rank_specifiers = new ArrayList (); - current_rank_specifiers.Add (args); - - /*string s_vartype = vartype.ToString(); - s_vartype += "["; - if (args != null) - for (int x = 0; x < args.Count; x++) - s_vartype += ","; - - s_vartype += "]"; - vartype = DecomposeQI(s_vartype, Location.Null); */ + current_rank_specifiers.Add (args); } else vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2; @@ -3426,7 +3665,7 @@ variable_declarator VariableDeclaration.VBFixIndexLists (ref a_dims); varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location); } - vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (this), lexer.Location); + vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, lexer.Location), lexer.Location); } if (vartype is New) { @@ -3483,19 +3722,15 @@ opt_type_with_ranks : opt_type_spec | AS type rank_specifiers { - $$ = TypeManager.system_object_expr; + $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$3, true, lexer.Location), lexer.Location); } ; opt_type_decl - : opt_type_spec + : opt_type_with_ranks { $$ = $1; } - | AS type OPEN_PARENS /*opt_argument_list*/ opt_dim_separators CLOSE_PARENS - { - $$ = new Pair ($2, $4); - } | AS NEW type { New n = new New ((Expression)$3, null, lexer.Location); @@ -3598,59 +3833,37 @@ rank_specifiers ; rank_specifier - : OPEN_PARENS opt_dim_separators CLOSE_PARENS + : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS { $$ = $2; } ; -opt_dim_separators +opt_dim_specifiers : /* empty */ - { - ArrayList ds = new ArrayList(); - ds.Add (new EmptyExpression()); - $$ = ds; - } - | dim_separators - { - ArrayList ds = (ArrayList) $1; - ds.Add (new EmptyExpression()); - $$ = ds; - } - | dim_specifiers - { - $$ = $1; - } - ; - -dim_separators - : COMMA { ArrayList ds = new ArrayList(); ds.Add (new EmptyExpression()); $$ = ds; - } - | dim_separators COMMA - { - ArrayList ds = (ArrayList) $1; - ds.Add (new EmptyExpression()); - $$ = ds; - } - ; - -dim_specifiers - : expression + } + | expression { ArrayList ds = new ArrayList(); ds.Add ((Expression) $1); $$ = ds; } - | dim_specifiers COMMA expression + | opt_dim_specifiers COMMA expression { ArrayList ds = (ArrayList) $1; ds.Add ((Expression) $3); $$ = ds; } + | opt_dim_specifiers COMMA + { + ArrayList ds = (ArrayList) $1; + ds.Add (new EmptyExpression()); + $$ = ds; + } ; primary_expression @@ -3666,11 +3879,7 @@ primary_expression string name = (string) $1; $$ = DecomposeQI (name, lexer.Location); } - //FIXME: address_of_expression is apparently missing here | get_type_expression - { - // TODO - } | member_access | invocation_expression //| element_access @@ -3762,7 +3971,7 @@ member_access } } ; - + predefined_type : builtin_types ; @@ -3776,7 +3985,16 @@ invocation_expression } $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location); // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0); - } + } + | CALL primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS + { + if ($2 == null) { + Location l = lexer.Location; + Report.Error (1, l, "THIS IS CRAZY"); + } + $$ = new Invocation ((Expression) $2, (ArrayList) $3, lexer.Location); +// Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0); + } ; base_access @@ -3908,7 +4126,7 @@ cast_operator get_type_expression : GETTYPE OPEN_PARENS type CLOSE_PARENS { - //TODO + $$ = new TypeOf ((Expression) $3, lexer.Location); } ; @@ -4038,11 +4256,14 @@ relational_expression } | relational_expression IS shift_expression { - //FIXME: Is this rule correctly defined ? + //FIXME: Should be a different op for reference equality but allows tests to use Is + $$ = new Binary (Binary.Operator.Equality, + (Expression) $1, (Expression) $3, lexer.Location); } - | TYPEOF shift_expression IS namespace_or_type_name + | TYPEOF shift_expression IS type { - //FIXME: Is this rule correctly defined ? + //FIXME: Is this rule correctly defined ? + $$ = new Is ((Expression) $2, (Expression) $4, lexer.Location); } ; @@ -4097,6 +4318,63 @@ assignment_expression { $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location); } + | prefixed_unary_expression STAR ASSIGN expression + { + Location l = lexer.Location; + + $$ = new CompoundAssign ( + Binary.Operator.Multiply, (Expression) $1, (Expression) $4, l); + } + | prefixed_unary_expression DIV ASSIGN expression + { + Location l = lexer.Location; + + $$ = new CompoundAssign ( + Binary.Operator.Division, (Expression) $1, (Expression) $4, l); + } + | prefixed_unary_expression PLUS ASSIGN expression + { + Location l = lexer.Location; + + $$ = new CompoundAssign ( + Binary.Operator.Addition, (Expression) $1, (Expression) $4, l); + } + | prefixed_unary_expression MINUS ASSIGN expression + { + Location l = lexer.Location; + + $$ = new CompoundAssign ( + Binary.Operator.Subtraction, (Expression) $1, (Expression) $4, l); + } + | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN expression + { + Location l = lexer.Location; + + $$ = new CompoundAssign ( + Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, l); + } + | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN expression + { + Location l = lexer.Location; + + $$ = new CompoundAssign ( + Binary.Operator.RightShift, (Expression) $1, (Expression) $4, l); + } + | prefixed_unary_expression OP_CONCAT ASSIGN expression + { + Location l = lexer.Location; + + // FIXME should be strings only + $$ = new CompoundAssign ( + Binary.Operator.Addition, (Expression) $1, (Expression) $4, l); + } + | prefixed_unary_expression OP_EXP ASSIGN expression + { + Location l = lexer.Location; + + /* TODO: $$ = new CompoundAssign ( + Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $4, l); */ + } | prefixed_unary_expression ASSIGN ADDRESSOF expression { ArrayList args = new ArrayList(); @@ -4180,10 +4458,6 @@ floating_point_type | DOUBLE { $$ = TypeManager.system_double_expr; } ; -interface_type - : namespace_or_type_name - ; - pp_directive : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL { @@ -4562,23 +4836,43 @@ public class VariableDeclaration { } public static string BuildRank (ArrayList rank) + { + bool allEmpty; + return BuildRank(rank, out allEmpty); + } + + public static string BuildRank (ArrayList rank, out bool allEmpty) { string res = ""; res += "["; - for (int x = 0; x < (rank.Count -1 ); x++) - res += ","; + allEmpty = true; + bool first = true; + foreach (object e in rank) { + if (!(e is EmptyExpression)) + allEmpty = false; + if (!first) + res += ","; + first = false; + } res += "]"; return res; } - public static string BuildRanks (Parser t) + public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc) { string res = ""; - foreach (ArrayList rank in t.current_rank_specifiers) - res += BuildRank (rank); + bool allEmpty = true; + foreach (ArrayList rank in rank_specifiers) { + bool tmp; + res = BuildRank (rank, out tmp) + res; + if (!tmp) + allEmpty = false; + } + if (!allEmpty && mustBeEmpty) + Report.Error (30638, loc, "Array bounds cannot appear in type specifiers."); return res; } @@ -4684,9 +4978,9 @@ Block end_block () return (res); } -private void AddHandler (Expression evt_definition, string handler_name) +private void AddHandler (Expression evt_definition, Expression handler_exp) { - AddHandler (current_block, evt_definition, handler_name); + AddHandler (current_block, evt_definition, handler_exp); } void CheckAttributeTarget (string a) @@ -4703,13 +4997,16 @@ void CheckAttributeTarget (string a) } } -private void AddHandler (Block b, Expression evt_id, string handler_name) +private void AddHandler (Block b, Expression evt_id, Expression handles_exp) { - Location loc = lexer.Location; - string evt_target = evt_id.ToString(); - evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.')); - Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc); - b.AddStatement (s); + Expression evt_target; + Location loc = lexer.Location; + + Statement addhnd = (Statement) new AddHandler (evt_id, + handles_exp, + loc); + + b.AddStatement (addhnd); } private void RaiseEvent (string evt_name, ArrayList args) @@ -4721,13 +5018,15 @@ private void RaiseEvent (string evt_name, ArrayList args) current_block.AddStatement (s); } -private void RemoveHandler (Block b, Expression evt_definition, string handler_name) +private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp) { + Expression evt_target; Location loc = lexer.Location; - string evt_target = evt_definition.ToString(); - evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.')); - Statement s = (Statement) new RemoveHandler (evt_definition, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc); - b.AddStatement (s); + + Statement rmhnd = (Statement) new RemoveHandler (evt_definition, + handler_exp, + loc); + b.AddStatement (rmhnd); } // @@ -4747,9 +5046,9 @@ string GetQualifiedIdentifier (Expression expr) } -private void RemoveHandler (Expression evt_definition, string handler_name) +private void RemoveHandler (Expression evt_definition, Expression handler_exp) { - RemoveHandler (current_block, evt_definition, handler_name); + RemoveHandler (current_block, evt_definition, handler_exp); } private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s) @@ -4807,6 +5106,11 @@ protected override int parse () with_stack = new Stack(); statement_stack = new Stack(); + allow_global_attribs = true; + expecting_global_attribs = false; + expecting_local_attribs = false; + local_attrib_section_added = false; + UseExtendedSyntax = name.EndsWith(".mbs"); OptionExplicit = InitialOptionExplicit || UseExtendedSyntax; OptionStrict = InitialOptionStrict || UseExtendedSyntax; @@ -4819,7 +5123,7 @@ protected override int parse () StringBuilder value = new StringBuilder (); try { - if (yacc_verbose_flag) + if (yacc_verbose_flag > 0) yyparse (lexer, new yydebug.yyDebugSimple ()); else { yyparse (lexer); @@ -4830,7 +5134,9 @@ protected override int parse () Report.Error(e.code, e.loc, e.Message); } catch (Exception e) { - Report.Error (29999, lexer.Location, lexer.location + "\nParsing error in " + lexer.EffectiveSource + "\n" + e.ToString()); + if (Report.Stacktrace) + Console.WriteLine(e); + Report.Error (29999, lexer.Location, "Parsing error"); } RootContext.VerifyImports();