X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mcs%2Fgmcs%2Fcs-parser.jay;h=68df7ca00741aa2f52426ed8bea440c58ac8df02;hb=4f18285002b709dba48164d1bfc195601d3d0337;hp=9f57f295f354a5fa8b35403119b721217ca0427d;hpb=821e657ebf86fed47ac2afde141dad01ca98fcef;p=mono.git diff --git a/mcs/gmcs/cs-parser.jay b/mcs/gmcs/cs-parser.jay index 9f57f295f35..68df7ca0074 100644 --- a/mcs/gmcs/cs-parser.jay +++ b/mcs/gmcs/cs-parser.jay @@ -4,6 +4,7 @@ // // Authors: Miguel de Icaza (miguel@gnu.org) // Ravi Pratap (ravi@ximian.com) +// Marek Safar (marek.safar@gmail.com) // // Licensed under the terms of the GNU GPL // @@ -41,7 +42,7 @@ namespace Mono.CSharp /// Current block is used to add statements as we find /// them. /// - Block current_block, top_current_block; + Block current_block; Delegate current_delegate; @@ -205,10 +206,25 @@ namespace Mono.CSharp %token ARGLIST %token PARTIAL %token ARROW +%token QUERY_FIRST_TOKEN +%token FROM +%token JOIN +%token ON +%token EQUALS +%token SELECT +%token GROUP +%token BY +%token LET +%token ORDERBY +%token ASCENDING +%token DESCENDING +%token INTO +%token QUERY_LAST_TOKEN /* C# keywords which are not really keywords */ %token GET "get" %token SET "set" +%token VAR %left LAST_KEYWORD @@ -264,6 +280,7 @@ namespace Mono.CSharp %token OP_XOR_ASSIGN "^=" %token OP_OR_ASSIGN "|=" %token OP_PTR "->" +%token OP_COALESCING "??" /* Numbers */ %token LITERAL_INTEGER "int literal" @@ -560,55 +577,63 @@ opt_attributes attribute_sections : attribute_section { - ArrayList sect = (ArrayList) $1; - - if (global_attrs_enabled) { - if (current_attr_target == "module") { - CodeGen.Module.AddAttributes (sect); - $$ = null; - } else if (current_attr_target != null && current_attr_target.Length > 0) { - CodeGen.Assembly.AddAttributes (sect); - $$ = null; + if (current_attr_target != String.Empty) { + ArrayList sect = (ArrayList) $1; + + if (global_attrs_enabled) { + if (current_attr_target == "module") { + CodeGen.Module.AddAttributes (sect); + $$ = null; + } else if (current_attr_target != null && current_attr_target.Length > 0) { + CodeGen.Assembly.AddAttributes (sect); + $$ = null; + } else { + $$ = new Attributes (sect); + } + if ($$ == null) { + if (RootContext.Documentation != null) { + Lexer.check_incorrect_doc_comment (); + Lexer.doc_state = + XmlCommentState.Allowed; + } + } } else { $$ = new Attributes (sect); - } - if ($$ == null) { - if (RootContext.Documentation != null) { - Lexer.check_incorrect_doc_comment (); - Lexer.doc_state = - XmlCommentState.Allowed; - } - } - } else { - $$ = new Attributes (sect); - } + } + } + else + $$ = null; current_attr_target = null; - } + } | attribute_sections attribute_section { - Attributes attrs = $1 as Attributes; - ArrayList sect = (ArrayList) $2; - - if (global_attrs_enabled) { - if (current_attr_target == "module") { - CodeGen.Module.AddAttributes (sect); - $$ = null; - } else if (current_attr_target == "assembly") { - CodeGen.Assembly.AddAttributes (sect); - $$ = null; + if (current_attr_target != String.Empty) { + Attributes attrs = $1 as Attributes; + ArrayList sect = (ArrayList) $2; + + if (global_attrs_enabled) { + if (current_attr_target == "module") { + CodeGen.Module.AddAttributes (sect); + $$ = null; + } else if (current_attr_target == "assembly") { + CodeGen.Assembly.AddAttributes (sect); + $$ = null; + } else { + if (attrs == null) + attrs = new Attributes (sect); + else + attrs.AddAttributes (sect); + } } else { if (attrs == null) attrs = new Attributes (sect); else - attrs.AddAttributes (sect); - } - } else { - if (attrs == null) - attrs = new Attributes (sect); - else - attrs.AddAttributes (sect); - } - $$ = attrs; + attrs.AddAttributes (sect); + } + $$ = attrs; + } + else + $$ = null; current_attr_target = null; } ; @@ -636,11 +661,15 @@ attribute_target : IDENTIFIER { LocatedToken lt = (LocatedToken) $1; - CheckAttributeTarget (lt.Value, lt.Location); - $$ = lt.Value; // Location won't be required anymore. + $$ = CheckAttributeTarget (lt.Value, lt.Location); } | EVENT { $$ = "event"; } | RETURN { $$ = "return"; } + | error + { + string name = yyNames [yyToken].ToLower (); + $$ = CheckAttributeTarget (name, GetLocation ($1)); + } ; attribute_list @@ -676,7 +705,9 @@ attribute Expression left_expr = left == null ? null : left.GetTypeExpression (); - if (current_attr_target == "assembly" || current_attr_target == "module") + if (current_attr_target == String.Empty) + $$ = null; + else if (current_attr_target == "assembly" || current_attr_target == "module") // FIXME: supply "nameEscaped" parameter here. $$ = new GlobalAttribute (current_namespace, current_attr_target, left_expr, identifier, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location)); @@ -814,7 +845,7 @@ struct_declaration MemberName name = MakeName ((MemberName) $6); push_current_class (new Struct ( current_namespace, current_class, name, (int) $2, - (Attributes) $1), false, $3); + (Attributes) $1), $3); } opt_class_base opt_type_parameter_constraints_clauses @@ -1097,6 +1128,7 @@ method_declaration anonymous_host = (IAnonymousHost) $1; if (RootContext.Documentation != null) Lexer.doc_state = XmlCommentState.NotAllowed; + Lexer.VarParsing = true; } method_body { @@ -1110,6 +1142,7 @@ method_declaration if (RootContext.Documentation != null) Lexer.doc_state = XmlCommentState.Allowed; + Lexer.VarParsing = false; } ; @@ -1325,8 +1358,12 @@ fixed_parameters | fixed_parameters COMMA fixed_parameter { ArrayList pars = (ArrayList) $1; - - pars.Add ($3); + Parameter p = (Parameter)$3; + if (p != null) { + if ((p.modFlags & Parameter.Modifier.This) != 0) + Report.Error (1100, p.Location, "The parameter modifier `this' can only be used on the first parameter"); + pars.Add (p); + } $$ = $1; } ; @@ -1388,14 +1425,31 @@ parameter_modifiers } | parameter_modifiers parameter_modifier { - Report.Error (1108, lexer.Location, "A parameter cannot have specified more than one modifier"); - $$ = $1; + Parameter.Modifier p2 = (Parameter.Modifier)$2; + Parameter.Modifier mod = (Parameter.Modifier)$1 | p2; + if (((Parameter.Modifier)$1 & p2) == p2) { + Error_DuplicateParameterModifier (lexer.Location, p2); + } else { + switch (mod & ~Parameter.Modifier.This) { + case Parameter.Modifier.REF: + Report.Error (1101, lexer.Location, "The parameter modifiers `this' and `ref' cannot be used altogether"); + break; + case Parameter.Modifier.OUT: + Report.Error (1102, lexer.Location, "The parameter modifiers `this' and `out' cannot be used altogether"); + break; + default: + Report.Error (1108, lexer.Location, "A parameter cannot have specified more than one modifier"); + break; + } + } + $$ = mod; } ; parameter_modifier : REF { $$ = Parameter.Modifier.REF; } | OUT { $$ = Parameter.Modifier.OUT; } + | THIS { $$ = Parameter.Modifier.This; } ; parameter_array @@ -1404,10 +1458,20 @@ parameter_array LocatedToken lt = (LocatedToken) $4; $$ = new ParamsParameter ((Expression) $3, lt.Value, (Attributes) $1, lt.Location); } + | opt_attributes PARAMS PARAMS type IDENTIFIER + { + Error_DuplicateParameterModifier (lexer.Location, Parameter.Modifier.PARAMS); + $$ = null; + } | opt_attributes PARAMS parameter_modifier type IDENTIFIER { - Report.Error (1611, (Location) $2, "The params parameter cannot be declared as ref or out"); - $$ = null; + Parameter.Modifier mod = (Parameter.Modifier)$3; + if ((mod & Parameter.Modifier.This) != 0) { + Report.Error (1104, lexer.Location, "The parameter modifiers `this' and `params' cannot be used altogether"); + } else { + Report.Error (1611, (Location) $2, "The params parameter cannot be declared as ref or out"); + } + $$ = null; } | opt_attributes PARAMS type error { CheckIdentifierToken (yyToken, GetLocation ($4)); @@ -1451,8 +1515,8 @@ property_declaration syntax_error (lexer.Location, "a property can't have type arguments"); prop = new Property (current_class, (Expression) $3, (int) $2, false, - name, (Attributes) $1, get_block, set_block, accessors.declared_in_reverse); - + name, (Attributes) $1, get_block, set_block, accessors.declared_in_reverse, current_block); + current_container.AddProperty (prop); implicit_value_parameter_type = null; @@ -1598,7 +1662,7 @@ interface_declaration push_current_class (new Interface ( current_namespace, current_class, name, (int) $2, - (Attributes) $1), true, $3); + (Attributes) $1), $3); } opt_class_base opt_type_parameter_constraints_clauses @@ -1760,7 +1824,7 @@ opt_new ; interface_method_declaration_body - : open_brace + : OPEN_BRACE { lexer.ConstraintsParsing = false; } @@ -2028,13 +2092,13 @@ operator_body ; operator_declarator : type OPERATOR overloadable_operator - open_parens opt_parameter_modifier type IDENTIFIER CLOSE_PARENS + open_parens opt_attributes opt_parameter_modifier type IDENTIFIER CLOSE_PARENS { // TODO: wrong location - if ((Parameter.Modifier)$5 != Parameter.Modifier.NONE) + if ((Parameter.Modifier)$6 != Parameter.Modifier.NONE) Error_ParameterModifierNotValid ((Location) $2); - LocatedToken lt = (LocatedToken) $7; + LocatedToken lt = (LocatedToken) $8; Operator.OpType op = (Operator.OpType) $3; CheckUnaryOperator (op, lt.Location); @@ -2045,9 +2109,9 @@ operator_declarator op = Operator.OpType.UnaryNegation; Parameter [] pars = new Parameter [1]; - Expression type = (Expression) $6; + Expression type = (Expression) $7; - pars [0] = new Parameter (type, lt.Value, Parameter.Modifier.NONE, null, lt.Location); + pars [0] = new Parameter (type, lt.Value, Parameter.Modifier.NONE, (Attributes) $5, lt.Location); current_local_parameters = new Parameters (pars); @@ -2061,25 +2125,25 @@ operator_declarator } | type OPERATOR overloadable_operator open_parens - opt_parameter_modifier type IDENTIFIER COMMA - opt_parameter_modifier type IDENTIFIER + opt_attributes opt_parameter_modifier type IDENTIFIER COMMA + opt_attributes opt_parameter_modifier type IDENTIFIER CLOSE_PARENS { // TODO: wrong location - if ((Parameter.Modifier)$5 != Parameter.Modifier.NONE || (Parameter.Modifier)$9 != Parameter.Modifier.NONE) + if ((Parameter.Modifier)$6 != Parameter.Modifier.NONE || (Parameter.Modifier)$11 != Parameter.Modifier.NONE) Error_ParameterModifierNotValid ((Location) $2); - LocatedToken ltParam1 = (LocatedToken) $7; - LocatedToken ltParam2 = (LocatedToken) $11; + LocatedToken ltParam1 = (LocatedToken) $8; + LocatedToken ltParam2 = (LocatedToken) $13; CheckBinaryOperator ((Operator.OpType) $3, (Location) $2); Parameter [] pars = new Parameter [2]; - Expression typeL = (Expression) $6; - Expression typeR = (Expression) $10; + Expression typeL = (Expression) $7; + Expression typeR = (Expression) $12; - pars [0] = new Parameter (typeL, ltParam1.Value, Parameter.Modifier.NONE, null, ltParam1.Location); - pars [1] = new Parameter (typeR, ltParam2.Value, Parameter.Modifier.NONE, null, ltParam2.Location); + pars [0] = new Parameter (typeL, ltParam1.Value, Parameter.Modifier.NONE, (Attributes) $5, ltParam1.Location); + pars [1] = new Parameter (typeR, ltParam2.Value, Parameter.Modifier.NONE, (Attributes) $10, ltParam2.Location); current_local_parameters = new Parameters (pars); @@ -2095,10 +2159,8 @@ operator_declarator | conversion_operator_declarator | type OPERATOR overloadable_operator open_parens - opt_parameter_modifier type IDENTIFIER COMMA - opt_parameter_modifier type IDENTIFIER COMMA - opt_parameter_modifier type IDENTIFIER - CLOSE_PARENS + opt_attributes opt_parameter_modifier type IDENTIFIER COMMA + opt_attributes opt_parameter_modifier type IDENTIFIER COMMA error { Report.Error (1534, (Location) $2, "Overloaded binary operator `{0}' takes two parameters", Operator.GetName ((Operator.OpType) $3)); @@ -2240,6 +2302,18 @@ constructor_declaration ; constructor_declarator + : constructor_header + { + $$ = $1; + } + | constructor_header constructor_initializer + { + ((Constructor)$1).Initializer = (ConstructorInitializer) $2; + $$ = $1; + } + ; + +constructor_header : IDENTIFIER { if (RootContext.Documentation != null) { @@ -2248,27 +2322,21 @@ constructor_declarator } } open_parens opt_formal_parameter_list CLOSE_PARENS - { - current_local_parameters = (Parameters) $4; - } - opt_constructor_initializer { LocatedToken lt = (LocatedToken) $1; - $$ = new Constructor (current_class, lt.Value, 0, (Parameters) $4, - (ConstructorInitializer) $7, lt.Location); + current_local_parameters = (Parameters) $4; + current_block = new ToplevelBlock (null, current_local_parameters, null, lt.Location); + + $$ = new Constructor (current_class, lt.Value, 0, current_local_parameters, + null, lt.Location); anonymous_host = (IAnonymousHost) $$; } ; constructor_body - : block - | SEMICOLON { $$ = null; } - ; - -opt_constructor_initializer - : /* empty */ { $$ = null; } - | constructor_initializer + : block_prepared + | SEMICOLON { current_block = null; $$ = null; } ; constructor_initializer @@ -2442,11 +2510,19 @@ add_accessor_declaration current_local_parameters = new Parameters (args); lexer.EventParsing = false; + + anonymous_host = SimpleAnonymousHost.GetSimple (); } block { - $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, (Location) $2); + Accessor accessor = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, (Location) $2); lexer.EventParsing = true; + + current_local_parameters = null; + SimpleAnonymousHost.Simple.Propagate (accessor); + anonymous_host = null; + + $$ = accessor; } | opt_attributes ADD error { Report.Error (73, (Location) $2, "An add or remove accessor must have a body"); @@ -2603,8 +2679,9 @@ enum_declaration EnumMember em = null; foreach (VariableDeclaration ev in (ArrayList) $7) { - em = new EnumMember (e, em, (Expression) ev.expression_or_array_initializer, - new MemberName (ev.identifier, ev.Location), ev.OptAttributes); + em = new EnumMember ( + e, em, ev.identifier, (Expression) ev.expression_or_array_initializer, + ev.OptAttributes, ev.Location); // if (RootContext.Documentation != null) em.DocComment = ev.DocComment; @@ -2612,7 +2689,7 @@ enum_declaration e.AddEnumMember (em); } - current_container.AddEnum (e); + current_container.AddTypeContainer (e); $$ = e; } @@ -2836,6 +2913,10 @@ type } | array_type | pointer_type + | VAR + { + $$ = new VarExpr (lexer.Location); + } ; pointer_type @@ -3100,6 +3181,111 @@ invocation_expression } ; +opt_object_initializer + : /* empty */ { $$ = null; } + | OPEN_BRACE variable_declarators CLOSE_BRACE + { + ArrayList vars = (ArrayList) $2; + ArrayList inits = new ArrayList (vars.Count); + foreach (VariableDeclaration variable in vars) { + Initializer i = new Initializer (variable.identifier, variable.expression_or_array_initializer); + inits.Add (i); + } + $$ = inits; + } + ; + +opt_object_or_collection_initializer + : /* empty */ { $$ = null; } + | object_or_collection_initializer + ; + +object_or_collection_initializer + : object_initializer + | collection_initializer + ; + +object_initializer + : OPEN_BRACE opt_member_initializer_list CLOSE_BRACE + { + if ($2 == null) + $$ = null; + else + $$ = new ObjectInitializer ((ArrayList)$2); + } + | OPEN_BRACE member_initializer_list COMMA CLOSE_BRACE + { + $$ = new ObjectInitializer ((ArrayList) $2); + } + ; + +opt_member_initializer_list + : /* empty */ { $$ = null; } + | member_initializer_list + ; + +member_initializer_list + : member_initializer + { + ArrayList a = new ArrayList (); + a.Add ($1); + $$ = a; + } + | member_initializer_list COMMA member_initializer + { + ArrayList a = (ArrayList)$1; + a.Add ($3); + $$ = a; + } + ; + +member_initializer + : IDENTIFIER ASSIGN initializer_value + { + LocatedToken id = $1 as LocatedToken; + IInitializable i = $3 as IInitializable; + if (i != null) + $$ = new Initializer (id.Value, i); + else + $$ = new Initializer (id.Value, (Expression)$3); + } + ; + +initializer_value + : expression + | object_or_collection_initializer + ; + +collection_initializer + : OPEN_BRACE element_initializer_list CLOSE_BRACE + { + $$ = new CollectionInitializer ((ArrayList) $2); + } + | OPEN_BRACE element_initializer_list COMMA CLOSE_BRACE + { + $$ = new CollectionInitializer ((ArrayList) $2); + } + ; + +element_initializer_list + : element_initializer + { + ArrayList a = new ArrayList (); + a.Add ($1); + $$ = a; + } + | element_initializer_list COMMA element_initializer + { + ArrayList a = $1 as ArrayList; + a.Add ($3); + $$ = a; + } + ; + +element_initializer + : non_assignment_expression + ; + opt_argument_list : /* empty */ { $$ = null; } | argument_list @@ -3153,6 +3339,10 @@ non_simple_argument Expression expr = new Arglist (args, (Location) $1); $$ = new Argument (expr, Argument.AType.Expression); } + | ARGLIST OPEN_PARENS CLOSE_PARENS + { + $$ = new Argument (new Arglist ((Location) $1), Argument.AType.Expression); + } | ARGLIST { $$ = new Argument (new ArglistAccess ((Location) $1), Argument.AType.ArgList); @@ -3251,12 +3441,31 @@ post_decrement_expression new_expression : object_or_delegate_creation_expression | array_creation_expression + | anonymous_type_expression ; object_or_delegate_creation_expression - : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS + : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer + { + if ($6 != null) { + if (RootContext.Version < LanguageVersion.LINQ) { + Error_ExpectingTypeName ((Expression) $2); + $$ = null; + } + else + $$ = new NewInitialize ((Expression) $2, (ArrayList) $4, (IInitializable) $6, (Location) $1); + } + else + $$ = new New ((Expression) $2, (ArrayList) $4, (Location) $1); + } + | NEW type object_or_collection_initializer { - $$ = new New ((Expression) $2, (ArrayList) $4, (Location) $1); + if (RootContext.Version < LanguageVersion.LINQ) { + Report.Error (1526, (Location) $1, "A new expression requires () or [] after type"); + $$ = null; + } + else + $$ = new NewInitialize ((Expression) $2, new ArrayList (), (IInitializable) $3, (Location) $1); } ; @@ -3271,6 +3480,15 @@ array_creation_expression { $$ = new ArrayCreation ((Expression) $2, (string) $3, (ArrayList) $4, (Location) $1); } + | NEW rank_specifiers array_initializer + { + if (RootContext.Version < LanguageVersion.LINQ) { + Report.Error (1031, (Location) $1, "Type expected"); + $$ = null; + } + else + $$ = new ArrayCreation (new VarExpr((Location) $1), (string) $2, (ArrayList) $3, (Location) $1); + } | NEW error { Report.Error (1031, (Location) $1, "Type expected"); @@ -3283,6 +3501,50 @@ array_creation_expression } ; +anonymous_type_expression + : NEW OPEN_BRACE anonymous_type_parameters CLOSE_BRACE + { + if (RootContext.Version < LanguageVersion.LINQ) { + Report.Error (1031, (Location) $1, "Type expected"); + $$ = null; + } + else + $$ = new AnonymousType ((ArrayList) $3, current_container, lexer.Location); + } + ; + +anonymous_type_parameters + : anonymous_type_parameter + { + ArrayList a = new ArrayList (4); + a.Add ($1); + $$ = a; + } + | anonymous_type_parameters COMMA anonymous_type_parameter + { + ArrayList a = (ArrayList) $1; + a.Add ($3); + $$ = a; + } + ; + +anonymous_type_parameter + : variable_declarator + { + VariableDeclaration v = (VariableDeclaration) $1; + Expression e = v.expression_or_array_initializer; + if (e == null) { + e = new LocalVariableReference (current_block, v.identifier, lexer.Location); + } + $$ = new AnonymousTypeParameter (e, v.identifier); + } + | member_access + { + MemberAccess ma = (MemberAccess) $1; + $$ = new AnonymousTypeParameter (ma, ma.Identifier); + } + ; + opt_rank_specifier : /* empty */ { @@ -3449,7 +3711,7 @@ anonymous_method_expression } block { - $$ = end_anonymous ((ToplevelBlock) $4, null, (Location) $1); + $$ = end_anonymous ((ToplevelBlock) $4, (Location) $1); } ; @@ -3473,7 +3735,7 @@ anonymous_method_signature ; opt_anonymous_method_parameter_list - : /* empty */ { $$ = null; } + : /* empty */ { $$ = null; } | anonymous_method_parameter_list { $$ = $1; } ; @@ -3769,9 +4031,9 @@ conditional_expression { $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5); } - | conditional_or_expression INTERR INTERR expression + | conditional_or_expression OP_COALESCING expression { - $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $4, lexer.Location); + $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3, lexer.Location); } // We'll be resolved into a `parenthesized_expression_0' later on. | conditional_or_expression INTERR CLOSE_PARENS @@ -3909,13 +4171,11 @@ lambda_expression_body expression { Block b = end_block (lexer.Location); - oob_stack.Push ($2); b.AddStatement (new ContextualReturn ((Expression) $2)); $$ = b; } | block { $$ = $1; - oob_stack.Push (null); } ; @@ -3932,7 +4192,7 @@ lambda_expression } lambda_expression_body { - $$ = end_anonymous ((ToplevelBlock) $4, (Expression) oob_stack.Pop (), (Location) $2); + $$ = end_anonymous ((ToplevelBlock) $4, (Location) $2); } | OPEN_PARENS_LAMBDA opt_lambda_parameter_list CLOSE_PARENS ARROW { @@ -3940,14 +4200,19 @@ lambda_expression } lambda_expression_body { - $$ = end_anonymous ((ToplevelBlock) $6, (Expression) oob_stack.Pop (), (Location) $4); + $$ = end_anonymous ((ToplevelBlock) $6, (Location) $4); } ; expression + : assignment_expression + | non_assignment_expression + ; + +non_assignment_expression : conditional_expression - | assignment_expression | lambda_expression + | query_expression ; constant_expression @@ -3976,7 +4241,7 @@ class_declaration push_current_class (new Class ( current_namespace, current_class, name, - mod_flags, (Attributes) $1), false, $3); + mod_flags, (Attributes) $1), $3); } opt_class_base opt_type_parameter_constraints_clauses @@ -4149,6 +4414,14 @@ block } ; +block_prepared + : OPEN_BRACE + opt_statement_list CLOSE_BRACE + { + $$ = end_block ((Location) $3); + } + ; + opt_statement_list : /* empty */ | statement_list @@ -4330,6 +4603,10 @@ local_variable_declaration else $$ = null; } + | VAR variable_declarators + { + $$ = new DictionaryEntry (new VarExpr (lexer.Location), $2); + } | local_variable_pointer_type opt_rank_specifier_or_nullable variable_declarators { if ($1 != null){ @@ -4476,11 +4753,7 @@ switch_section } statement_list { - Block topmost = current_block; - - while (topmost.Implicit) - topmost = topmost.Parent; - $$ = new SwitchSection ((ArrayList) $1, topmost); + $$ = new SwitchSection ((ArrayList) $1, current_block.Explicit); } ; @@ -4540,8 +4813,9 @@ for_statement : FOR open_parens opt_for_initializer SEMICOLON { - Block assign_block = new Block (current_block); - current_block = assign_block; + Location l = lexer.Location; + start_block (l); + Block assign_block = current_block; if ($3 is DictionaryEntry){ DictionaryEntry de = (DictionaryEntry) $3; @@ -4557,7 +4831,6 @@ for_statement if (vi == null) continue; - Location l = lexer.Location; Expression expr = decl.expression_or_array_initializer; LocalVariableReference var; @@ -4586,10 +4859,8 @@ for_statement For f = new For ((Statement) $5, (Expression) $6, (Statement) $8, (Statement) $10, l); current_block.AddStatement (f); - while (current_block.Implicit) - current_block = current_block.Parent; - $$ = current_block; - current_block = current_block.Parent; + + $$ = end_block (lexer.Location); } ; @@ -4622,7 +4893,7 @@ statement_expression_list { // CHANGE: was `null' Statement s = (Statement) $1; - Block b = new Block (current_block, Block.Flags.Implicit, s.loc, lexer.Location); + Block b = new Block (current_block, s.loc, lexer.Location); b.AddStatement (s); $$ = b; @@ -4645,8 +4916,8 @@ foreach_statement | FOREACH open_parens type IDENTIFIER IN expression CLOSE_PARENS { - Block foreach_block = new Block (current_block); - current_block = foreach_block; + start_block (lexer.Location); + Block foreach_block = current_block; LocatedToken lt = (LocatedToken) $4; Location l = lt.Location; @@ -4675,10 +4946,7 @@ foreach_statement current_block.AddStatement (f); } - while (current_block.Implicit) - current_block = current_block.Parent; - $$ = current_block; - current_block = current_block.Parent; + $$ = end_block (lexer.Location); } ; @@ -4876,9 +5144,8 @@ catch_clause one.Add (new VariableDeclaration (lt, null)); - current_block = new Block (current_block); - Block b = declare_local_variables (type, one, lt.Location); - current_block = b; + start_block (lexer.Location); + current_block = declare_local_variables (type, one, lt.Location); } } } block { @@ -4893,10 +5160,7 @@ catch_clause if (lt != null){ id = lt.Value; - while (current_block.Implicit) - current_block = current_block.Parent; - var_block = current_block; - current_block = current_block.Parent; + var_block = end_block (lexer.Location); } } @@ -4950,8 +5214,8 @@ fixed_statement Location l = (Location) $1; int top = list.Count; - Block assign_block = new Block (current_block); - current_block = assign_block; + start_block (lexer.Location); + Block assign_block = current_block; for (int i = 0; i < top; i++){ Pair p = (Pair) list [i]; @@ -4961,6 +5225,9 @@ fixed_statement if (v == null) continue; + if (type is VarExpr) + v.VariableType = typeof(VarExpr); // Kinda lame. Avoids a problem in the VariableMap ctor + v.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Fixed); v.Pinned = true; p.First = v; @@ -4974,10 +5241,8 @@ fixed_statement Fixed f = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l); current_block.AddStatement (f); - while (current_block.Implicit) - current_block = current_block.Parent; - $$ = current_block; - current_block = current_block.Parent; + + $$ = end_block (lexer.Location); } ; @@ -5025,8 +5290,8 @@ lock_statement using_statement : USING open_parens resource_acquisition CLOSE_PARENS { - Block assign_block = new Block (current_block); - current_block = assign_block; + start_block (lexer.Location); + Block assign_block = current_block; if ($3 is DictionaryEntry){ DictionaryEntry de = (DictionaryEntry) $3; @@ -5074,10 +5339,7 @@ using_statement { Using u = new Using ($5, (Statement) $6, (Location) $1); current_block.AddStatement (u); - while (current_block.Implicit) - current_block = current_block.Parent; - $$ = current_block; - current_block = current_block.Parent; + $$ = end_block (lexer.Location); } ; @@ -5086,6 +5348,138 @@ resource_acquisition | expression ; + +// LINQ + +query_expression + : from_clause query_body + { + lexer.QueryParsing = false; + $$ = new Linq.QueryExpression (current_container, current_block, (Expression)$1, (Linq.AQueryClause)$2); + end_block (lexer.Location); + } + ; + +from_clause + : FROM IDENTIFIER IN expression opt_join_clauses + { + start_block (lexer.Location); + LocatedToken lt = (LocatedToken) $2; + + LocalInfo vi = current_block.AddVariable (TypeManager.system_object_expr, lt.Value, lt.Location); // TODO: null is var type + if (vi != null) { + $$ = new LocalVariableReference (current_block, lt.Value, lt.Location, vi, false); + } + $$ = $4; + } + | FROM type IDENTIFIER IN expression opt_join_clauses + { + start_block (lexer.Location); + LocatedToken lt = (LocatedToken) $3; + + Expression type = (Expression)$2; + LocalInfo vi = current_block.AddVariable (type, lt.Value, lt.Location); + $$ = new Linq.Cast (type, (Expression)$5, lt.Location); + } + ; + +opt_join_clauses + : /* empty */ + | join_clauses + ; + +join_clauses + : join_clause + | join_clauses join_clause + ; + +join_clause + : JOIN join_clause_body + | JOIN join_clause_body INTO IDENTIFIER + | JOIN type join_clause_body + | JOIN type join_clause_body INTO IDENTIFIER + ; + +join_clause_body + : IDENTIFIER IN expression ON expression EQUALS expression + ; + +query_body + : opt_from_let_where_clauses opt_orderby_clause SELECT expression opt_query_continuation + { + Linq.AQueryClause ret = new Linq.Select ((Expression)$4, GetLocation ($3)); + + if ($1 != null) { + ((Linq.AQueryClause)$1).Next = ret; + ret = (Linq.AQueryClause)$1; + } + + $$ = ret; + } + | opt_from_let_where_clauses opt_orderby_clause group_clause opt_query_continuation + ; + +opt_from_let_where_clauses + : /* empty */ + | from_let_where_clauses + ; + +from_let_where_clauses + : from_let_where_clause + | from_let_where_clauses from_let_where_clause + ; + +from_let_where_clause + : from_clause + | let_clause + | where_clause + ; + +let_clause + : LET IDENTIFIER ASSIGN expression + ; + +where_clause + : WHERE boolean_expression + { + $$ = new Linq.Where ((Expression)$2, GetLocation ($1)); + } + ; + +opt_orderby_clause + : /* empty */ + | orderby_clause + ; + +orderby_clause + : ORDERBY orderings + ; + +orderings + : ordering + | orderings COMMA ordering + ; + +ordering + : expression + | expression ASCENDING + | expression DESCENDING + ; + + +group_clause + : GROUP expression BY expression + ; + +opt_query_continuation + : /* empty */ + | query_continuation + ; + +query_continuation + : INTO IDENTIFIER opt_join_clauses query_body + ; + %% // @@ -5213,12 +5607,18 @@ public static void Error_ParameterModifierNotValid (Location loc) Report.Error (631, loc, "The modifiers `ref' and `out' are not valid in this context"); } -void push_current_class (TypeContainer tc, bool is_interface, object partial_token) +static void Error_DuplicateParameterModifier (Location loc, Parameter.Modifier mod) +{ + Report.Error (1107, loc, "Duplicate parameter modifier `{0}'", + Parameter.GetModifierSignature (mod)); +} + +void push_current_class (TypeContainer tc, object partial_token) { if (partial_token != null) - current_container = current_container.AddPartial (tc, is_interface); + current_container = current_container.AddPartial (tc); else - current_container = current_container.AddTypeContainer (tc, is_interface); + current_container = current_container.AddTypeContainer (tc); current_class = tc; } @@ -5272,7 +5672,7 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators, // int j = 1; int k = j + 1; // if (current_block.Used) - implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null); + implicit_block = new Block (current_block, loc, Location.Null); else implicit_block = current_block; @@ -5310,7 +5710,7 @@ Block declare_local_constants (Expression type, ArrayList declarators) Block implicit_block; if (current_block.Used) - implicit_block = new Block (current_block, Block.Flags.Implicit); + implicit_block = new Block (current_block); else implicit_block = current_block; @@ -5321,18 +5721,16 @@ Block declare_local_constants (Expression type, ArrayList declarators) return implicit_block; } -void CheckAttributeTarget (string a, Location l) +string CheckAttributeTarget (string a, Location l) { switch (a) { - case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" : - return; - - default : - Report.Error (658, l, "`" + a + "' is an invalid attribute target"); - break; + return a; } + Report.Warning (658, 1, l, + "`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a); + return string.Empty; } void CheckUnaryOperator (Operator.OpType op, Location l) @@ -5482,35 +5880,20 @@ Location GetLocation (object obj) void start_block (Location loc) { - if (parsing_anonymous_method) { - top_current_block = new ToplevelBlock ( - current_block, current_local_parameters, current_generic_method, loc); - if (current_block != null) - current_block.AddAnonymousChild ((ToplevelBlock) top_current_block); - current_block = top_current_block; + if (current_block == null || parsing_anonymous_method) { + current_block = new ToplevelBlock (current_block, current_local_parameters, current_generic_method, loc); parsing_anonymous_method = false; - } else if (current_block == null) { - current_block = new ToplevelBlock ( - (ToplevelBlock) top_current_block, current_local_parameters, - current_generic_method, loc); - top_current_block = current_block; } else { - current_block = new Block (current_block, loc, Location.Null); + current_block = new ExplicitBlock (current_block, loc, Location.Null); } } Block end_block (Location loc) { - Block retval; - - while (current_block.Implicit) - current_block = current_block.Parent; - retval = current_block; - current_block.SetEndLocation (loc); - current_block = current_block.Parent; - if (current_block == null) - top_current_block = null; + Block retval = current_block.Explicit; + retval.SetEndLocation (loc); + current_block = retval.Parent; return retval; } @@ -5522,18 +5905,17 @@ start_anonymous (bool lambda, Parameters parameters, Location loc) current_local_parameters = parameters; - // Force the next block to be created as a ToplevelBlock - oob_stack.Push (current_block); - oob_stack.Push (top_current_block); + ToplevelBlock top_current_block = current_block == null ? null : current_block.Toplevel; current_anonymous_method = lambda ? new LambdaExpression ( current_anonymous_method, current_generic_method, current_container, - parameters, (ToplevelBlock) top_current_block, loc) + parameters, top_current_block, loc) : new AnonymousMethodExpression ( current_anonymous_method, current_generic_method, current_container, - parameters, (ToplevelBlock) top_current_block, loc); + parameters, top_current_block, loc); + // Force the next block to be created as a ToplevelBlock parsing_anonymous_method = true; } @@ -5542,22 +5924,14 @@ start_anonymous (bool lambda, Parameters parameters, Location loc) * means that we have a Statement instead of an Expression embedded */ AnonymousMethodExpression -end_anonymous (ToplevelBlock anon_block, Expression lambda_expr, Location loc) +end_anonymous (ToplevelBlock anon_block, Location loc) { AnonymousMethodExpression retval; - top_current_block = (Block) oob_stack.Pop (); - current_block = (Block) oob_stack.Pop (); - if (RootContext.Version == LanguageVersion.ISO_1){ Report.FeatureIsNotISO1 (loc, "anonymous methods"); retval = null; } else { - anon_block.Parent = current_block; - - if (lambda_expr != null) - ((LambdaExpression) current_anonymous_method).SetExpression (lambda_expr); - current_anonymous_method.Block = anon_block; if ((anonymous_host != null) && (current_anonymous_method.Parent == null)) anonymous_host.AddAnonymousMethod (current_anonymous_method);