X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mcs%2Fgmcs%2Fcs-parser.jay;h=68df7ca00741aa2f52426ed8bea440c58ac8df02;hb=4f18285002b709dba48164d1bfc195601d3d0337;hp=563348112407c855e7e7905b1ee1f5419ed6c761;hpb=771e1da761f483d92a960311113176ceb212de8e;p=mono.git diff --git a/mcs/gmcs/cs-parser.jay b/mcs/gmcs/cs-parser.jay index 56334811240..68df7ca0074 100644 --- a/mcs/gmcs/cs-parser.jay +++ b/mcs/gmcs/cs-parser.jay @@ -42,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; @@ -224,6 +224,7 @@ namespace Mono.CSharp /* C# keywords which are not really keywords */ %token GET "get" %token SET "set" +%token VAR %left LAST_KEYWORD @@ -279,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" @@ -1126,6 +1128,7 @@ method_declaration anonymous_host = (IAnonymousHost) $1; if (RootContext.Documentation != null) Lexer.doc_state = XmlCommentState.NotAllowed; + Lexer.VarParsing = true; } method_body { @@ -1139,6 +1142,7 @@ method_declaration if (RootContext.Documentation != null) Lexer.doc_state = XmlCommentState.Allowed; + Lexer.VarParsing = false; } ; @@ -1511,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; @@ -1820,7 +1824,7 @@ opt_new ; interface_method_declaration_body - : open_brace + : OPEN_BRACE { lexer.ConstraintsParsing = false; } @@ -2088,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); @@ -2105,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); @@ -2121,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); @@ -2155,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)); @@ -2321,11 +2323,10 @@ constructor_header } open_parens opt_formal_parameter_list CLOSE_PARENS { - current_local_parameters = (Parameters) $4; - current_block = top_current_block = new ToplevelBlock (null, - current_local_parameters, null, Location.Null); - LocatedToken lt = (LocatedToken) $1; + 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); @@ -2335,7 +2336,7 @@ constructor_header constructor_body : block_prepared - | SEMICOLON { current_block = top_current_block = null; $$ = null; } + | SEMICOLON { current_block = null; $$ = null; } ; constructor_initializer @@ -2912,6 +2913,10 @@ type } | array_type | pointer_type + | VAR + { + $$ = new VarExpr (lexer.Location); + } ; pointer_type @@ -3176,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 @@ -3331,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); } ; @@ -3351,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"); @@ -3363,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 */ { @@ -3849,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 @@ -4421,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){ @@ -4567,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); } ; @@ -4631,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; @@ -4648,7 +4831,6 @@ for_statement if (vi == null) continue; - Location l = lexer.Location; Expression expr = decl.expression_or_array_initializer; LocalVariableReference var; @@ -4677,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); } ; @@ -4713,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; @@ -4736,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; @@ -4766,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); } ; @@ -4967,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 { @@ -4984,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); } } @@ -5041,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]; @@ -5052,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; @@ -5065,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); } ; @@ -5116,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; @@ -5165,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); } ; @@ -5184,15 +5355,15 @@ query_expression : from_clause query_body { lexer.QueryParsing = false; - $$ = new QueryExpression ((Expression)$1, (Expression)$2); - current_block = current_block.Parent; + $$ = 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 { - current_block = new Block (current_block); + 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 @@ -5203,11 +5374,12 @@ from_clause } | FROM type IDENTIFIER IN expression opt_join_clauses { - current_block = new Block (current_block); + start_block (lexer.Location); LocatedToken lt = (LocatedToken) $3; - LocalInfo vi = current_block.AddVariable ((Expression)$2, lt.Value, lt.Location); - $$ = $5; + Expression type = (Expression)$2; + LocalInfo vi = current_block.AddVariable (type, lt.Value, lt.Location); + $$ = new Linq.Cast (type, (Expression)$5, lt.Location); } ; @@ -5235,7 +5407,14 @@ join_clause_body query_body : opt_from_let_where_clauses opt_orderby_clause SELECT expression opt_query_continuation { - $$ = new Select (current_container, current_block, (Expression)$4, GetLocation ($3)); + 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 ; @@ -5262,6 +5441,9 @@ let_clause where_clause : WHERE boolean_expression + { + $$ = new Linq.Where ((Expression)$2, GetLocation ($1)); + } ; opt_orderby_clause @@ -5490,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; @@ -5528,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; @@ -5698,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; } @@ -5738,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; } @@ -5762,15 +5928,10 @@ 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; - current_anonymous_method.Block = anon_block; if ((anonymous_host != null) && (current_anonymous_method.Parent == null)) anonymous_host.AddAnonymousMethod (current_anonymous_method);