| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 | 768 |
| 769 // Static const fields must have an initializer. | 769 // Static const fields must have an initializer. |
| 770 ExpectToken(Token::kASSIGN); | 770 ExpectToken(Token::kASSIGN); |
| 771 | 771 |
| 772 // We don't want to use ParseConstExpr() here because we don't want | 772 // We don't want to use ParseConstExpr() here because we don't want |
| 773 // the constant folding code to create, compile and execute a code | 773 // the constant folding code to create, compile and execute a code |
| 774 // fragment to evaluate the expression. Instead, we just make sure | 774 // fragment to evaluate the expression. Instead, we just make sure |
| 775 // the static const field initializer is a constant expression and | 775 // the static const field initializer is a constant expression and |
| 776 // leave the evaluation to the getter function. | 776 // leave the evaluation to the getter function. |
| 777 const intptr_t expr_pos = TokenPos(); | 777 const intptr_t expr_pos = TokenPos(); |
| 778 AstNode* expr = ParseExpr(kAllowConst); | 778 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 779 if (field.is_const()) { | 779 if (field.is_const()) { |
| 780 // This getter will only be called once at compile time. | 780 // This getter will only be called once at compile time. |
| 781 if (expr->EvalConstExpr() == NULL) { | 781 if (expr->EvalConstExpr() == NULL) { |
| 782 ErrorMsg(expr_pos, "initializer must be a compile time constant"); | 782 ErrorMsg(expr_pos, "initializer must be a compile time constant"); |
| 783 } | 783 } |
| 784 ReturnNode* return_node = new ReturnNode(TokenPos(), expr); | 784 ReturnNode* return_node = new ReturnNode(TokenPos(), expr); |
| 785 current_block_->statements->Add(return_node); | 785 current_block_->statements->Add(return_node); |
| 786 } else { | 786 } else { |
| 787 // This getter may be called each time the static field is accessed. | 787 // This getter may be called each time the static field is accessed. |
| 788 // The following generated code lazily initializes the field: | 788 // The following generated code lazily initializes the field: |
| (...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1329 } | 1329 } |
| 1330 | 1330 |
| 1331 | 1331 |
| 1332 AstNode* Parser::ParseSuperOperator() { | 1332 AstNode* Parser::ParseSuperOperator() { |
| 1333 TRACE_PARSER("ParseSuperOperator"); | 1333 TRACE_PARSER("ParseSuperOperator"); |
| 1334 AstNode* super_op = NULL; | 1334 AstNode* super_op = NULL; |
| 1335 const intptr_t operator_pos = TokenPos(); | 1335 const intptr_t operator_pos = TokenPos(); |
| 1336 | 1336 |
| 1337 if (CurrentToken() == Token::kLBRACK) { | 1337 if (CurrentToken() == Token::kLBRACK) { |
| 1338 ConsumeToken(); | 1338 ConsumeToken(); |
| 1339 AstNode* index_expr = ParseExpr(kAllowConst); | 1339 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1340 ExpectToken(Token::kRBRACK); | 1340 ExpectToken(Token::kRBRACK); |
| 1341 | 1341 |
| 1342 if (Token::IsAssignmentOperator(CurrentToken()) && | 1342 if (Token::IsAssignmentOperator(CurrentToken()) && |
| 1343 (CurrentToken() != Token::kASSIGN)) { | 1343 (CurrentToken() != Token::kASSIGN)) { |
| 1344 // Compound assignment. Ensure side effects in index expression | 1344 // Compound assignment. Ensure side effects in index expression |
| 1345 // only execute once. If the index is not a local variable or an | 1345 // only execute once. If the index is not a local variable or an |
| 1346 // literal, evaluate and save in a temporary local. | 1346 // literal, evaluate and save in a temporary local. |
| 1347 if (!IsSimpleLocalOrLiteralNode(index_expr)) { | 1347 if (!IsSimpleLocalOrLiteralNode(index_expr)) { |
| 1348 LocalVariable* temp = | 1348 LocalVariable* temp = |
| 1349 CreateTempConstVariable(operator_pos, index_expr->id(), "lix"); | 1349 CreateTempConstVariable(operator_pos, index_expr->id(), "lix"); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1371 if (is_no_such_method) { | 1371 if (is_no_such_method) { |
| 1372 index_op_arguments = BuildNoSuchMethodArguments(index_operator_name, | 1372 index_op_arguments = BuildNoSuchMethodArguments(index_operator_name, |
| 1373 *index_op_arguments); | 1373 *index_op_arguments); |
| 1374 } | 1374 } |
| 1375 super_op = new StaticCallNode( | 1375 super_op = new StaticCallNode( |
| 1376 operator_pos, index_operator, index_op_arguments); | 1376 operator_pos, index_operator, index_op_arguments); |
| 1377 | 1377 |
| 1378 if (Token::IsAssignmentOperator(CurrentToken())) { | 1378 if (Token::IsAssignmentOperator(CurrentToken())) { |
| 1379 Token::Kind assignment_op = CurrentToken(); | 1379 Token::Kind assignment_op = CurrentToken(); |
| 1380 ConsumeToken(); | 1380 ConsumeToken(); |
| 1381 AstNode* value = ParseExpr(kAllowConst); | 1381 AstNode* value = ParseExpr(kAllowConst, kConsumeCascades); |
| 1382 | 1382 |
| 1383 value = ExpandAssignableOp(operator_pos, assignment_op, super_op, value); | 1383 value = ExpandAssignableOp(operator_pos, assignment_op, super_op, value); |
| 1384 | 1384 |
| 1385 // Resolve the []= operator function in the superclass. | 1385 // Resolve the []= operator function in the superclass. |
| 1386 const String& assign_index_operator_name = String::ZoneHandle( | 1386 const String& assign_index_operator_name = String::ZoneHandle( |
| 1387 Symbols::New(Token::Str(Token::kASSIGN_INDEX))); | 1387 Symbols::New(Token::Str(Token::kASSIGN_INDEX))); |
| 1388 bool is_no_such_method = false; | 1388 bool is_no_such_method = false; |
| 1389 const Function& assign_index_operator = Function::ZoneHandle( | 1389 const Function& assign_index_operator = Function::ZoneHandle( |
| 1390 GetSuperFunction(operator_pos, | 1390 GetSuperFunction(operator_pos, |
| 1391 assign_index_operator_name, | 1391 assign_index_operator_name, |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1499 if (super_setter.IsNull()) { | 1499 if (super_setter.IsNull()) { |
| 1500 ErrorMsg(field_pos, | 1500 ErrorMsg(field_pos, |
| 1501 "field '%s' not assignable in superclass", | 1501 "field '%s' not assignable in superclass", |
| 1502 field_name.ToCString()); | 1502 field_name.ToCString()); |
| 1503 } | 1503 } |
| 1504 // All dynamic setters take two arguments and no named arguments. | 1504 // All dynamic setters take two arguments and no named arguments. |
| 1505 ASSERT(super_setter.AreValidArgumentCounts(2, 0, NULL)); | 1505 ASSERT(super_setter.AreValidArgumentCounts(2, 0, NULL)); |
| 1506 | 1506 |
| 1507 Token::Kind assignment_op = CurrentToken(); | 1507 Token::Kind assignment_op = CurrentToken(); |
| 1508 ConsumeToken(); | 1508 ConsumeToken(); |
| 1509 AstNode* value = ParseExpr(kAllowConst); | 1509 AstNode* value = ParseExpr(kAllowConst, kConsumeCascades); |
| 1510 value = ExpandAssignableOp(field_pos, assignment_op, super_field, value); | 1510 value = ExpandAssignableOp(field_pos, assignment_op, super_field, value); |
| 1511 | 1511 |
| 1512 ArgumentListNode* setter_arguments = new ArgumentListNode(field_pos); | 1512 ArgumentListNode* setter_arguments = new ArgumentListNode(field_pos); |
| 1513 setter_arguments->Add(implicit_argument); | 1513 setter_arguments->Add(implicit_argument); |
| 1514 setter_arguments->Add(value); | 1514 setter_arguments->Add(value); |
| 1515 super_field = new StaticCallNode(field_pos, super_setter, setter_arguments); | 1515 super_field = new StaticCallNode(field_pos, super_setter, setter_arguments); |
| 1516 } | 1516 } |
| 1517 return super_field; | 1517 return super_field; |
| 1518 } | 1518 } |
| 1519 | 1519 |
| (...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2171 } | 2171 } |
| 2172 | 2172 |
| 2173 OpenBlock(); // Open a nested scope for the outermost function block. | 2173 OpenBlock(); // Open a nested scope for the outermost function block. |
| 2174 if (CurrentToken() == Token::kLBRACE) { | 2174 if (CurrentToken() == Token::kLBRACE) { |
| 2175 ConsumeToken(); | 2175 ConsumeToken(); |
| 2176 ParseStatementSequence(); | 2176 ParseStatementSequence(); |
| 2177 ExpectToken(Token::kRBRACE); | 2177 ExpectToken(Token::kRBRACE); |
| 2178 } else if (CurrentToken() == Token::kARROW) { | 2178 } else if (CurrentToken() == Token::kARROW) { |
| 2179 ConsumeToken(); | 2179 ConsumeToken(); |
| 2180 const intptr_t expr_pos = TokenPos(); | 2180 const intptr_t expr_pos = TokenPos(); |
| 2181 AstNode* expr = ParseExpr(kAllowConst); | 2181 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 2182 ASSERT(expr != NULL); | 2182 ASSERT(expr != NULL); |
| 2183 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 2183 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
| 2184 } else if (IsLiteral("native")) { | 2184 } else if (IsLiteral("native")) { |
| 2185 ParseNativeFunctionBlock(¶ms, func); | 2185 ParseNativeFunctionBlock(¶ms, func); |
| 2186 } else { | 2186 } else { |
| 2187 UnexpectedToken(); | 2187 UnexpectedToken(); |
| 2188 } | 2188 } |
| 2189 SequenceNode* body = CloseBlock(); | 2189 SequenceNode* body = CloseBlock(); |
| 2190 current_block_->statements->Add(body); | 2190 current_block_->statements->Add(body); |
| 2191 innermost_function_ = saved_innermost_function.raw(); | 2191 innermost_function_ = saved_innermost_function.raw(); |
| (...skipping 1899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4091 LocalVariable* variable = | 4091 LocalVariable* variable = |
| 4092 new LocalVariable(ident_pos, *CurrentLiteral(), type); | 4092 new LocalVariable(ident_pos, *CurrentLiteral(), type); |
| 4093 ASSERT(current_block_ != NULL); | 4093 ASSERT(current_block_ != NULL); |
| 4094 ASSERT(current_block_->scope != NULL); | 4094 ASSERT(current_block_->scope != NULL); |
| 4095 ConsumeToken(); // Variable identifier. | 4095 ConsumeToken(); // Variable identifier. |
| 4096 AstNode* initialization = NULL; | 4096 AstNode* initialization = NULL; |
| 4097 if (CurrentToken() == Token::kASSIGN) { | 4097 if (CurrentToken() == Token::kASSIGN) { |
| 4098 // Variable initialization. | 4098 // Variable initialization. |
| 4099 const intptr_t assign_pos = TokenPos(); | 4099 const intptr_t assign_pos = TokenPos(); |
| 4100 ConsumeToken(); | 4100 ConsumeToken(); |
| 4101 AstNode* expr = ParseExpr(kAllowConst); | 4101 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 4102 initialization = new StoreLocalNode(assign_pos, *variable, expr); | 4102 initialization = new StoreLocalNode(assign_pos, *variable, expr); |
| 4103 } else if (is_final) { | 4103 } else if (is_final) { |
| 4104 ErrorMsg(ident_pos, "missing initialization of 'final' variable"); | 4104 ErrorMsg(ident_pos, "missing initialization of 'final' variable"); |
| 4105 } else { | 4105 } else { |
| 4106 // Initialize variable with null. | 4106 // Initialize variable with null. |
| 4107 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle()); | 4107 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle()); |
| 4108 initialization = new StoreLocalNode(ident_pos, *variable, null_expr); | 4108 initialization = new StoreLocalNode(ident_pos, *variable, null_expr); |
| 4109 } | 4109 } |
| 4110 // Add variable to cope after parsing the initalizer expression. | 4110 // Add variable to cope after parsing the initalizer expression. |
| 4111 // The expression must not be able to refer to the variable. | 4111 // The expression must not be able to refer to the variable. |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4665 ASSERT(CurrentToken() == Token::kIF); | 4665 ASSERT(CurrentToken() == Token::kIF); |
| 4666 const intptr_t if_pos = TokenPos(); | 4666 const intptr_t if_pos = TokenPos(); |
| 4667 SourceLabel* label = NULL; | 4667 SourceLabel* label = NULL; |
| 4668 if (label_name != NULL) { | 4668 if (label_name != NULL) { |
| 4669 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); | 4669 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); |
| 4670 OpenBlock(); | 4670 OpenBlock(); |
| 4671 current_block_->scope->AddLabel(label); | 4671 current_block_->scope->AddLabel(label); |
| 4672 } | 4672 } |
| 4673 ConsumeToken(); | 4673 ConsumeToken(); |
| 4674 ExpectToken(Token::kLPAREN); | 4674 ExpectToken(Token::kLPAREN); |
| 4675 AstNode* cond_expr = ParseExpr(kAllowConst); | 4675 AstNode* cond_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 4676 ExpectToken(Token::kRPAREN); | 4676 ExpectToken(Token::kRPAREN); |
| 4677 const bool parsing_loop_body = false; | 4677 const bool parsing_loop_body = false; |
| 4678 SequenceNode* true_branch = ParseNestedStatement(parsing_loop_body, NULL); | 4678 SequenceNode* true_branch = ParseNestedStatement(parsing_loop_body, NULL); |
| 4679 SequenceNode* false_branch = NULL; | 4679 SequenceNode* false_branch = NULL; |
| 4680 if (CurrentToken() == Token::kELSE) { | 4680 if (CurrentToken() == Token::kELSE) { |
| 4681 ConsumeToken(); | 4681 ConsumeToken(); |
| 4682 false_branch = ParseNestedStatement(parsing_loop_body, NULL); | 4682 false_branch = ParseNestedStatement(parsing_loop_body, NULL); |
| 4683 } | 4683 } |
| 4684 AstNode* if_node = new IfNode(if_pos, cond_expr, true_branch, false_branch); | 4684 AstNode* if_node = new IfNode(if_pos, cond_expr, true_branch, false_branch); |
| 4685 if (label != NULL) { | 4685 if (label != NULL) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 4699 const intptr_t case_pos = TokenPos(); | 4699 const intptr_t case_pos = TokenPos(); |
| 4700 // The case expressions node sequence does not own the enclosing scope. | 4700 // The case expressions node sequence does not own the enclosing scope. |
| 4701 SequenceNode* case_expressions = new SequenceNode(case_pos, NULL); | 4701 SequenceNode* case_expressions = new SequenceNode(case_pos, NULL); |
| 4702 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { | 4702 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
| 4703 if (CurrentToken() == Token::kCASE) { | 4703 if (CurrentToken() == Token::kCASE) { |
| 4704 if (default_seen) { | 4704 if (default_seen) { |
| 4705 ErrorMsg("default clause must be last case"); | 4705 ErrorMsg("default clause must be last case"); |
| 4706 } | 4706 } |
| 4707 ConsumeToken(); // Keyword case. | 4707 ConsumeToken(); // Keyword case. |
| 4708 const intptr_t expr_pos = TokenPos(); | 4708 const intptr_t expr_pos = TokenPos(); |
| 4709 AstNode* expr = ParseExpr(kAllowConst); | 4709 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 4710 AstNode* switch_expr_load = new LoadLocalNode(case_pos, | 4710 AstNode* switch_expr_load = new LoadLocalNode(case_pos, |
| 4711 *switch_expr_value); | 4711 *switch_expr_value); |
| 4712 AstNode* case_comparison = new ComparisonNode(expr_pos, | 4712 AstNode* case_comparison = new ComparisonNode(expr_pos, |
| 4713 Token::kEQ, | 4713 Token::kEQ, |
| 4714 expr, | 4714 expr, |
| 4715 switch_expr_load); | 4715 switch_expr_load); |
| 4716 case_expressions->Add(case_comparison); | 4716 case_expressions->Add(case_comparison); |
| 4717 } else { | 4717 } else { |
| 4718 if (default_seen) { | 4718 if (default_seen) { |
| 4719 ErrorMsg("only one default clause is allowed"); | 4719 ErrorMsg("only one default clause is allowed"); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4775 ConsumeToken(); | 4775 ConsumeToken(); |
| 4776 const bool parens_are_mandatory = false; | 4776 const bool parens_are_mandatory = false; |
| 4777 bool paren_found = false; | 4777 bool paren_found = false; |
| 4778 if (CurrentToken() == Token::kLPAREN) { | 4778 if (CurrentToken() == Token::kLPAREN) { |
| 4779 paren_found = true; | 4779 paren_found = true; |
| 4780 ConsumeToken(); | 4780 ConsumeToken(); |
| 4781 } else if (parens_are_mandatory) { | 4781 } else if (parens_are_mandatory) { |
| 4782 ErrorMsg("'(' expected"); | 4782 ErrorMsg("'(' expected"); |
| 4783 } | 4783 } |
| 4784 const intptr_t expr_pos = TokenPos(); | 4784 const intptr_t expr_pos = TokenPos(); |
| 4785 AstNode* switch_expr = ParseExpr(kAllowConst); | 4785 AstNode* switch_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 4786 if (paren_found) { | 4786 if (paren_found) { |
| 4787 ExpectToken(Token::kRPAREN); | 4787 ExpectToken(Token::kRPAREN); |
| 4788 } | 4788 } |
| 4789 ExpectToken(Token::kLBRACE); | 4789 ExpectToken(Token::kLBRACE); |
| 4790 OpenBlock(); | 4790 OpenBlock(); |
| 4791 current_block_->scope->AddLabel(label); | 4791 current_block_->scope->AddLabel(label); |
| 4792 | 4792 |
| 4793 // Store switch expression in temporary local variable. | 4793 // Store switch expression in temporary local variable. |
| 4794 LocalVariable* temp_variable = | 4794 LocalVariable* temp_variable = |
| 4795 new LocalVariable(expr_pos, | 4795 new LocalVariable(expr_pos, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4858 } | 4858 } |
| 4859 | 4859 |
| 4860 | 4860 |
| 4861 AstNode* Parser::ParseWhileStatement(String* label_name) { | 4861 AstNode* Parser::ParseWhileStatement(String* label_name) { |
| 4862 TRACE_PARSER("ParseWhileStatement"); | 4862 TRACE_PARSER("ParseWhileStatement"); |
| 4863 const intptr_t while_pos = TokenPos(); | 4863 const intptr_t while_pos = TokenPos(); |
| 4864 SourceLabel* label = | 4864 SourceLabel* label = |
| 4865 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); | 4865 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); |
| 4866 ConsumeToken(); | 4866 ConsumeToken(); |
| 4867 ExpectToken(Token::kLPAREN); | 4867 ExpectToken(Token::kLPAREN); |
| 4868 AstNode* cond_expr = ParseExpr(kAllowConst); | 4868 AstNode* cond_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 4869 ExpectToken(Token::kRPAREN); | 4869 ExpectToken(Token::kRPAREN); |
| 4870 const bool parsing_loop_body = true; | 4870 const bool parsing_loop_body = true; |
| 4871 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); | 4871 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); |
| 4872 return new WhileNode(while_pos, label, cond_expr, while_body); | 4872 return new WhileNode(while_pos, label, cond_expr, while_body); |
| 4873 } | 4873 } |
| 4874 | 4874 |
| 4875 | 4875 |
| 4876 AstNode* Parser::ParseDoWhileStatement(String* label_name) { | 4876 AstNode* Parser::ParseDoWhileStatement(String* label_name) { |
| 4877 TRACE_PARSER("ParseDoWhileStatement"); | 4877 TRACE_PARSER("ParseDoWhileStatement"); |
| 4878 const intptr_t do_pos = TokenPos(); | 4878 const intptr_t do_pos = TokenPos(); |
| 4879 SourceLabel* label = | 4879 SourceLabel* label = |
| 4880 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); | 4880 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); |
| 4881 ConsumeToken(); | 4881 ConsumeToken(); |
| 4882 const bool parsing_loop_body = true; | 4882 const bool parsing_loop_body = true; |
| 4883 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); | 4883 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); |
| 4884 ExpectToken(Token::kWHILE); | 4884 ExpectToken(Token::kWHILE); |
| 4885 ExpectToken(Token::kLPAREN); | 4885 ExpectToken(Token::kLPAREN); |
| 4886 AstNode* cond_expr = ParseExpr(kAllowConst); | 4886 AstNode* cond_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 4887 ExpectToken(Token::kRPAREN); | 4887 ExpectToken(Token::kRPAREN); |
| 4888 ExpectSemicolon(); | 4888 ExpectSemicolon(); |
| 4889 return new DoWhileNode(do_pos, label, cond_expr, dowhile_body); | 4889 return new DoWhileNode(do_pos, label, cond_expr, dowhile_body); |
| 4890 } | 4890 } |
| 4891 | 4891 |
| 4892 | 4892 |
| 4893 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, | 4893 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, |
| 4894 SourceLabel* label) { | 4894 SourceLabel* label) { |
| 4895 TRACE_PARSER("ParseForInStatement"); | 4895 TRACE_PARSER("ParseForInStatement"); |
| 4896 bool is_final = (CurrentToken() == Token::kFINAL); | 4896 bool is_final = (CurrentToken() == Token::kFINAL); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4907 ClassFinalizer::kIgnore)); | 4907 ClassFinalizer::kIgnore)); |
| 4908 loop_var_pos = TokenPos(); | 4908 loop_var_pos = TokenPos(); |
| 4909 loop_var_name = ExpectIdentifier("variable name expected"); | 4909 loop_var_name = ExpectIdentifier("variable name expected"); |
| 4910 loop_var = new LocalVariable(loop_var_pos, *loop_var_name, type); | 4910 loop_var = new LocalVariable(loop_var_pos, *loop_var_name, type); |
| 4911 if (is_final) { | 4911 if (is_final) { |
| 4912 loop_var->set_is_final(); | 4912 loop_var->set_is_final(); |
| 4913 } | 4913 } |
| 4914 } | 4914 } |
| 4915 ExpectToken(Token::kIN); | 4915 ExpectToken(Token::kIN); |
| 4916 const intptr_t collection_pos = TokenPos(); | 4916 const intptr_t collection_pos = TokenPos(); |
| 4917 AstNode* collection_expr = ParseExpr(kAllowConst); | 4917 AstNode* collection_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 4918 ExpectToken(Token::kRPAREN); | 4918 ExpectToken(Token::kRPAREN); |
| 4919 | 4919 |
| 4920 OpenBlock(); // Implicit block around while loop. | 4920 OpenBlock(); // Implicit block around while loop. |
| 4921 | 4921 |
| 4922 // Generate implicit iterator variable and add to scope. | 4922 // Generate implicit iterator variable and add to scope. |
| 4923 const String& iterator_name = | 4923 const String& iterator_name = |
| 4924 String::ZoneHandle(Symbols::New(":for-in-iter")); | 4924 String::ZoneHandle(Symbols::New(":for-in-iter")); |
| 4925 // We could set the type of the implicit iterator variable to Iterator<T> | 4925 // We could set the type of the implicit iterator variable to Iterator<T> |
| 4926 // where T is the type of the for loop variable. However, the type error | 4926 // where T is the type of the for loop variable. However, the type error |
| 4927 // would refer to the compiler generated iterator and could confuse the user. | 4927 // would refer to the compiler generated iterator and could confuse the user. |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5017 // The label is added to the implicit scope that also contains | 5017 // The label is added to the implicit scope that also contains |
| 5018 // the loop variable declarations. | 5018 // the loop variable declarations. |
| 5019 current_block_->scope->AddLabel(label); | 5019 current_block_->scope->AddLabel(label); |
| 5020 AstNode* initializer = NULL; | 5020 AstNode* initializer = NULL; |
| 5021 const intptr_t init_pos = TokenPos(); | 5021 const intptr_t init_pos = TokenPos(); |
| 5022 LocalScope* init_scope = current_block_->scope; | 5022 LocalScope* init_scope = current_block_->scope; |
| 5023 if (CurrentToken() != Token::kSEMICOLON) { | 5023 if (CurrentToken() != Token::kSEMICOLON) { |
| 5024 if (IsVariableDeclaration()) { | 5024 if (IsVariableDeclaration()) { |
| 5025 initializer = ParseVariableDeclarationList(); | 5025 initializer = ParseVariableDeclarationList(); |
| 5026 } else { | 5026 } else { |
| 5027 initializer = ParseExpr(kAllowConst); | 5027 initializer = ParseExpr(kAllowConst, kConsumeCascades); |
| 5028 } | 5028 } |
| 5029 } | 5029 } |
| 5030 ExpectSemicolon(); | 5030 ExpectSemicolon(); |
| 5031 AstNode* condition = NULL; | 5031 AstNode* condition = NULL; |
| 5032 if (CurrentToken() != Token::kSEMICOLON) { | 5032 if (CurrentToken() != Token::kSEMICOLON) { |
| 5033 condition = ParseExpr(kAllowConst); | 5033 condition = ParseExpr(kAllowConst, kConsumeCascades); |
| 5034 } | 5034 } |
| 5035 ExpectSemicolon(); | 5035 ExpectSemicolon(); |
| 5036 AstNode* increment = NULL; | 5036 AstNode* increment = NULL; |
| 5037 const intptr_t incr_pos = TokenPos(); | 5037 const intptr_t incr_pos = TokenPos(); |
| 5038 LocalScope* incr_scope = current_block_->scope; | 5038 LocalScope* incr_scope = current_block_->scope; |
| 5039 if (CurrentToken() != Token::kRPAREN) { | 5039 if (CurrentToken() != Token::kRPAREN) { |
| 5040 increment = ParseExprList(); | 5040 increment = ParseExprList(); |
| 5041 } | 5041 } |
| 5042 ExpectToken(Token::kRPAREN); | 5042 ExpectToken(Token::kRPAREN); |
| 5043 const bool parsing_loop_body = true; | 5043 const bool parsing_loop_body = true; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5121 AstNode* Parser::ParseAssertStatement() { | 5121 AstNode* Parser::ParseAssertStatement() { |
| 5122 TRACE_PARSER("ParseAssertStatement"); | 5122 TRACE_PARSER("ParseAssertStatement"); |
| 5123 ConsumeToken(); // Consume assert keyword. | 5123 ConsumeToken(); // Consume assert keyword. |
| 5124 ExpectToken(Token::kLPAREN); | 5124 ExpectToken(Token::kLPAREN); |
| 5125 const intptr_t condition_pos = TokenPos(); | 5125 const intptr_t condition_pos = TokenPos(); |
| 5126 if (!FLAG_enable_asserts && !FLAG_enable_type_checks) { | 5126 if (!FLAG_enable_asserts && !FLAG_enable_type_checks) { |
| 5127 SkipExpr(); | 5127 SkipExpr(); |
| 5128 ExpectToken(Token::kRPAREN); | 5128 ExpectToken(Token::kRPAREN); |
| 5129 return NULL; | 5129 return NULL; |
| 5130 } | 5130 } |
| 5131 AstNode* condition = ParseExpr(kAllowConst); | 5131 AstNode* condition = ParseExpr(kAllowConst, kConsumeCascades); |
| 5132 const intptr_t condition_end = TokenPos(); | 5132 const intptr_t condition_end = TokenPos(); |
| 5133 ExpectToken(Token::kRPAREN); | 5133 ExpectToken(Token::kRPAREN); |
| 5134 condition = InsertClosureCallNodes(condition); | 5134 condition = InsertClosureCallNodes(condition); |
| 5135 condition = new UnaryOpNode(condition_pos, Token::kNOT, condition); | 5135 condition = new UnaryOpNode(condition_pos, Token::kNOT, condition); |
| 5136 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); | 5136 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); |
| 5137 return new IfNode(condition_pos, | 5137 return new IfNode(condition_pos, |
| 5138 condition, | 5138 condition, |
| 5139 NodeAsSequenceNode(condition_pos, assert_throw, NULL), | 5139 NodeAsSequenceNode(condition_pos, assert_throw, NULL), |
| 5140 NULL); | 5140 NULL); |
| 5141 } | 5141 } |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5595 } else if (CurrentToken() == Token::kTRY) { | 5595 } else if (CurrentToken() == Token::kTRY) { |
| 5596 statement = ParseTryStatement(label_name); | 5596 statement = ParseTryStatement(label_name); |
| 5597 } else if (CurrentToken() == Token::kRETURN) { | 5597 } else if (CurrentToken() == Token::kRETURN) { |
| 5598 const intptr_t return_pos = TokenPos(); | 5598 const intptr_t return_pos = TokenPos(); |
| 5599 ConsumeToken(); | 5599 ConsumeToken(); |
| 5600 if (CurrentToken() != Token::kSEMICOLON) { | 5600 if (CurrentToken() != Token::kSEMICOLON) { |
| 5601 if (current_function().IsConstructor() && | 5601 if (current_function().IsConstructor() && |
| 5602 (current_block_->scope->function_level() == 0)) { | 5602 (current_block_->scope->function_level() == 0)) { |
| 5603 ErrorMsg(return_pos, "return of a value not allowed in constructors"); | 5603 ErrorMsg(return_pos, "return of a value not allowed in constructors"); |
| 5604 } | 5604 } |
| 5605 AstNode* expr = ParseExpr(kAllowConst); | 5605 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 5606 statement = new ReturnNode(statement_pos, expr); | 5606 statement = new ReturnNode(statement_pos, expr); |
| 5607 } else { | 5607 } else { |
| 5608 statement = new ReturnNode(statement_pos); | 5608 statement = new ReturnNode(statement_pos); |
| 5609 } | 5609 } |
| 5610 AddNodeForFinallyInlining(statement); | 5610 AddNodeForFinallyInlining(statement); |
| 5611 ExpectSemicolon(); | 5611 ExpectSemicolon(); |
| 5612 } else if (CurrentToken() == Token::kIF) { | 5612 } else if (CurrentToken() == Token::kIF) { |
| 5613 statement = ParseIfStatement(label_name); | 5613 statement = ParseIfStatement(label_name); |
| 5614 } else if ((CurrentToken() == Token::kASSERT) && | 5614 } else if ((CurrentToken() == Token::kASSERT) && |
| 5615 !IsDefinedInLexicalScope(*CurrentLiteral())) { | 5615 !IsDefinedInLexicalScope(*CurrentLiteral())) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 5642 statement = ParseJump(label_name); | 5642 statement = ParseJump(label_name); |
| 5643 AddNodeForFinallyInlining(statement); | 5643 AddNodeForFinallyInlining(statement); |
| 5644 ExpectSemicolon(); | 5644 ExpectSemicolon(); |
| 5645 } else if (CurrentToken() == Token::kSEMICOLON) { | 5645 } else if (CurrentToken() == Token::kSEMICOLON) { |
| 5646 // Empty statement, nothing to do. | 5646 // Empty statement, nothing to do. |
| 5647 ConsumeToken(); | 5647 ConsumeToken(); |
| 5648 } else if (CurrentToken() == Token::kTHROW) { | 5648 } else if (CurrentToken() == Token::kTHROW) { |
| 5649 ConsumeToken(); | 5649 ConsumeToken(); |
| 5650 AstNode* expr = NULL; | 5650 AstNode* expr = NULL; |
| 5651 if (CurrentToken() != Token::kSEMICOLON) { | 5651 if (CurrentToken() != Token::kSEMICOLON) { |
| 5652 expr = ParseExpr(kAllowConst); | 5652 expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 5653 ExpectSemicolon(); | 5653 ExpectSemicolon(); |
| 5654 statement = new ThrowNode(statement_pos, expr, NULL); | 5654 statement = new ThrowNode(statement_pos, expr, NULL); |
| 5655 } else { // No exception object seen so must be a rethrow. | 5655 } else { // No exception object seen so must be a rethrow. |
| 5656 // Check if it is ok to do a rethrow. | 5656 // Check if it is ok to do a rethrow. |
| 5657 SourceLabel* label = current_block_->scope->LookupInnermostCatchLabel(); | 5657 SourceLabel* label = current_block_->scope->LookupInnermostCatchLabel(); |
| 5658 if (label == NULL || | 5658 if (label == NULL || |
| 5659 label->FunctionLevel() != current_block_->scope->function_level()) { | 5659 label->FunctionLevel() != current_block_->scope->function_level()) { |
| 5660 ErrorMsg("rethrow of an exception is not valid here"); | 5660 ErrorMsg("rethrow of an exception is not valid here"); |
| 5661 } | 5661 } |
| 5662 ASSERT(label->owner() != NULL); | 5662 ASSERT(label->owner() != NULL); |
| 5663 LocalScope* scope = label->owner()->parent(); | 5663 LocalScope* scope = label->owner()->parent(); |
| 5664 ASSERT(scope != NULL); | 5664 ASSERT(scope != NULL); |
| 5665 LocalVariable* excp_var = scope->LocalLookupVariable( | 5665 LocalVariable* excp_var = scope->LocalLookupVariable( |
| 5666 String::ZoneHandle(Symbols::New(":exception_var"))); | 5666 String::ZoneHandle(Symbols::New(":exception_var"))); |
| 5667 ASSERT(excp_var != NULL); | 5667 ASSERT(excp_var != NULL); |
| 5668 LocalVariable* trace_var = scope->LocalLookupVariable( | 5668 LocalVariable* trace_var = scope->LocalLookupVariable( |
| 5669 String::ZoneHandle(Symbols::New(":stacktrace_var"))); | 5669 String::ZoneHandle(Symbols::New(":stacktrace_var"))); |
| 5670 ASSERT(trace_var != NULL); | 5670 ASSERT(trace_var != NULL); |
| 5671 statement = new ThrowNode(statement_pos, | 5671 statement = new ThrowNode(statement_pos, |
| 5672 new LoadLocalNode(statement_pos, *excp_var), | 5672 new LoadLocalNode(statement_pos, *excp_var), |
| 5673 new LoadLocalNode(statement_pos, *trace_var)); | 5673 new LoadLocalNode(statement_pos, *trace_var)); |
| 5674 } | 5674 } |
| 5675 } else { | 5675 } else { |
| 5676 statement = ParseExpr(kAllowConst); | 5676 statement = ParseExpr(kAllowConst, kConsumeCascades); |
| 5677 ExpectSemicolon(); | 5677 ExpectSemicolon(); |
| 5678 } | 5678 } |
| 5679 return statement; | 5679 return statement; |
| 5680 } | 5680 } |
| 5681 | 5681 |
| 5682 | 5682 |
| 5683 RawError* Parser::FormatErrorWithAppend(const Error& prev_error, | 5683 RawError* Parser::FormatErrorWithAppend(const Error& prev_error, |
| 5684 const Script& script, | 5684 const Script& script, |
| 5685 intptr_t token_pos, | 5685 intptr_t token_pos, |
| 5686 const char* message_header, | 5686 const char* message_header, |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6037 || (expr->IsLoadLocalNode() && !expr->AsLoadLocalNode()->HasPseudo()) | 6037 || (expr->IsLoadLocalNode() && !expr->AsLoadLocalNode()->HasPseudo()) |
| 6038 || expr->IsLoadStaticFieldNode() | 6038 || expr->IsLoadStaticFieldNode() |
| 6039 || expr->IsStaticGetterNode() | 6039 || expr->IsStaticGetterNode() |
| 6040 || expr->IsInstanceGetterNode() | 6040 || expr->IsInstanceGetterNode() |
| 6041 || expr->IsLoadIndexedNode(); | 6041 || expr->IsLoadIndexedNode(); |
| 6042 } | 6042 } |
| 6043 | 6043 |
| 6044 | 6044 |
| 6045 AstNode* Parser::ParseExprList() { | 6045 AstNode* Parser::ParseExprList() { |
| 6046 TRACE_PARSER("ParseExprList"); | 6046 TRACE_PARSER("ParseExprList"); |
| 6047 AstNode* expressions = ParseExpr(kAllowConst); | 6047 AstNode* expressions = ParseExpr(kAllowConst, kConsumeCascades); |
| 6048 if (CurrentToken() == Token::kCOMMA) { | 6048 if (CurrentToken() == Token::kCOMMA) { |
| 6049 // Collect comma-separated expressions in a non scope owning sequence node. | 6049 // Collect comma-separated expressions in a non scope owning sequence node. |
| 6050 SequenceNode* list = new SequenceNode(TokenPos(), NULL); | 6050 SequenceNode* list = new SequenceNode(TokenPos(), NULL); |
| 6051 list->Add(expressions); | 6051 list->Add(expressions); |
| 6052 while (CurrentToken() == Token::kCOMMA) { | 6052 while (CurrentToken() == Token::kCOMMA) { |
| 6053 ConsumeToken(); | 6053 ConsumeToken(); |
| 6054 AstNode* expr = ParseExpr(kAllowConst); | 6054 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 6055 list->Add(expr); | 6055 list->Add(expr); |
| 6056 } | 6056 } |
| 6057 expressions = list; | 6057 expressions = list; |
| 6058 } | 6058 } |
| 6059 return expressions; | 6059 return expressions; |
| 6060 } | 6060 } |
| 6061 | 6061 |
| 6062 | 6062 |
| 6063 const LocalVariable& Parser::GetIncrementTempLocal() { | 6063 const LocalVariable& Parser::GetIncrementTempLocal() { |
| 6064 if (expression_temp_ == NULL) { | 6064 if (expression_temp_ == NULL) { |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6237 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) { | 6237 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) { |
| 6238 AstNode* result = original->MakeAssignmentNode(rhs); | 6238 AstNode* result = original->MakeAssignmentNode(rhs); |
| 6239 if ((result != NULL) && | 6239 if ((result != NULL) && |
| 6240 (result->IsStoreIndexedNode() || result->IsInstanceSetterNode())) { | 6240 (result->IsStoreIndexedNode() || result->IsInstanceSetterNode())) { |
| 6241 EnsureExpressionTemp(); | 6241 EnsureExpressionTemp(); |
| 6242 } | 6242 } |
| 6243 return result; | 6243 return result; |
| 6244 } | 6244 } |
| 6245 | 6245 |
| 6246 | 6246 |
| 6247 AstNode* Parser::ParseExpr(bool require_compiletime_const) { | 6247 AstNode* Parser::ParseCascades(AstNode* expr) { |
| 6248 intptr_t cascade_pos = TokenPos(); |
| 6249 LocalVariable* cascade_receiver_var = |
| 6250 CreateTempConstVariable(cascade_pos, expr->id(), "casc"); |
| 6251 StoreLocalNode* save_cascade = |
| 6252 new StoreLocalNode(cascade_pos, *cascade_receiver_var, expr); |
| 6253 current_block_->statements->Add(save_cascade); |
| 6254 while (CurrentToken() == Token::kCASCADE) { |
| 6255 cascade_pos = TokenPos(); |
| 6256 LoadLocalNode* load_cascade_receiver = |
| 6257 new LoadLocalNode(cascade_pos, *cascade_receiver_var); |
| 6258 if (Token::IsIdentifier(LookaheadToken(1))) { |
| 6259 // Replace .. with . for ParseSelectors(). |
| 6260 token_kind_ = Token::kPERIOD; |
| 6261 } else if (LookaheadToken(1) == Token::kLBRACK) { |
| 6262 ConsumeToken(); |
| 6263 } else { |
| 6264 ErrorMsg("identifier or [ expected after .."); |
| 6265 } |
| 6266 expr = ParseSelectors(load_cascade_receiver, true); |
| 6267 current_block_->statements->Add(expr); |
| 6268 } |
| 6269 // Result of the cascade is the receiver. |
| 6270 return new LoadLocalNode(cascade_pos, *cascade_receiver_var); |
| 6271 } |
| 6272 |
| 6273 |
| 6274 AstNode* Parser::ParseExpr(bool require_compiletime_const, |
| 6275 bool consume_cascades) { |
| 6248 TRACE_PARSER("ParseExpr"); | 6276 TRACE_PARSER("ParseExpr"); |
| 6249 const intptr_t expr_pos = TokenPos(); | 6277 const intptr_t expr_pos = TokenPos(); |
| 6250 AstNode* expr = ParseConditionalExpr(); | 6278 AstNode* expr = ParseConditionalExpr(); |
| 6251 if (!Token::IsAssignmentOperator(CurrentToken())) { | 6279 if (!Token::IsAssignmentOperator(CurrentToken())) { |
| 6280 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { |
| 6281 return ParseCascades(expr); |
| 6282 } |
| 6252 if (require_compiletime_const) { | 6283 if (require_compiletime_const) { |
| 6253 expr = FoldConstExpr(expr_pos, expr); | 6284 expr = FoldConstExpr(expr_pos, expr); |
| 6254 } | 6285 } |
| 6255 return expr; | 6286 return expr; |
| 6256 } | 6287 } |
| 6257 // Assignment expressions. | 6288 // Assignment expressions. |
| 6258 Token::Kind assignment_op = CurrentToken(); | 6289 Token::Kind assignment_op = CurrentToken(); |
| 6259 const intptr_t assignment_pos = TokenPos(); | 6290 const intptr_t assignment_pos = TokenPos(); |
| 6260 ConsumeToken(); | 6291 ConsumeToken(); |
| 6261 const intptr_t right_expr_pos = TokenPos(); | 6292 const intptr_t right_expr_pos = TokenPos(); |
| 6262 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { | 6293 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { |
| 6263 ErrorMsg(right_expr_pos, "expression must be a compile time constant"); | 6294 ErrorMsg(right_expr_pos, "expression must be a compile time constant"); |
| 6264 } | 6295 } |
| 6265 AstNode* right_expr = ParseExpr(require_compiletime_const); | 6296 AstNode* right_expr = ParseExpr(require_compiletime_const, kConsumeCascades); |
| 6266 AstNode* left_expr = expr; | 6297 AstNode* left_expr = expr; |
| 6267 if (assignment_op != Token::kASSIGN) { | 6298 if (assignment_op != Token::kASSIGN) { |
| 6268 // Compound assignment: store inputs with side effects into temp. locals. | 6299 // Compound assignment: store inputs with side effects into temp. locals. |
| 6269 left_expr = PrepareCompoundAssignmentNodes(&expr); | 6300 left_expr = PrepareCompoundAssignmentNodes(&expr); |
| 6270 } | 6301 } |
| 6271 right_expr = | 6302 right_expr = |
| 6272 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 6303 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 6273 AstNode* assign_expr = CreateAssignmentNode(left_expr, right_expr); | 6304 AstNode* assign_expr = CreateAssignmentNode(left_expr, right_expr); |
| 6274 if (assign_expr == NULL) { | 6305 if (assign_expr == NULL) { |
| 6275 ErrorMsg(assignment_pos, | 6306 ErrorMsg(assignment_pos, |
| 6276 "left hand side of '%s' is not assignable", | 6307 "left hand side of '%s' is not assignable", |
| 6277 Token::Str(assignment_op)); | 6308 Token::Str(assignment_op)); |
| 6278 } | 6309 } |
| 6279 return assign_expr; | 6310 return assign_expr; |
| 6280 } | 6311 } |
| 6281 | 6312 |
| 6282 | 6313 |
| 6283 LiteralNode* Parser::ParseConstExpr() { | 6314 LiteralNode* Parser::ParseConstExpr() { |
| 6284 TRACE_PARSER("ParseConstExpr"); | 6315 TRACE_PARSER("ParseConstExpr"); |
| 6285 AstNode* expr = ParseExpr(kRequireConst); | 6316 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); |
| 6286 ASSERT(expr->IsLiteralNode()); | 6317 ASSERT(expr->IsLiteralNode()); |
| 6287 return expr->AsLiteralNode(); | 6318 return expr->AsLiteralNode(); |
| 6288 } | 6319 } |
| 6289 | 6320 |
| 6290 | 6321 |
| 6291 AstNode* Parser::ParseConditionalExpr() { | 6322 AstNode* Parser::ParseConditionalExpr() { |
| 6292 TRACE_PARSER("ParseConditionalExpr"); | 6323 TRACE_PARSER("ParseConditionalExpr"); |
| 6293 const intptr_t expr_pos = TokenPos(); | 6324 const intptr_t expr_pos = TokenPos(); |
| 6294 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); | 6325 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); |
| 6295 if (CurrentToken() == Token::kCONDITIONAL) { | 6326 if (CurrentToken() == Token::kCONDITIONAL) { |
| 6296 EnsureExpressionTemp(); | 6327 EnsureExpressionTemp(); |
| 6297 ConsumeToken(); | 6328 ConsumeToken(); |
| 6298 AstNode* expr1 = ParseExpr(kAllowConst); | 6329 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); |
| 6299 ExpectToken(Token::kCOLON); | 6330 ExpectToken(Token::kCOLON); |
| 6300 AstNode* expr2 = ParseExpr(kAllowConst); | 6331 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); |
| 6301 expr = new ConditionalExprNode(expr_pos, expr, expr1, expr2); | 6332 expr = new ConditionalExprNode(expr_pos, expr, expr1, expr2); |
| 6302 } | 6333 } |
| 6303 return expr; | 6334 return expr; |
| 6304 } | 6335 } |
| 6305 | 6336 |
| 6306 | 6337 |
| 6307 AstNode* Parser::ParseUnaryExpr() { | 6338 AstNode* Parser::ParseUnaryExpr() { |
| 6308 TRACE_PARSER("ParseUnaryExpr"); | 6339 TRACE_PARSER("ParseUnaryExpr"); |
| 6309 AstNode* expr = NULL; | 6340 AstNode* expr = NULL; |
| 6310 const intptr_t op_pos = TokenPos(); | 6341 const intptr_t op_pos = TokenPos(); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6378 if (CurrentLiteral()->Equals(arg_name)) { | 6409 if (CurrentLiteral()->Equals(arg_name)) { |
| 6379 ErrorMsg("duplicate named argument"); | 6410 ErrorMsg("duplicate named argument"); |
| 6380 } | 6411 } |
| 6381 } | 6412 } |
| 6382 names.Add(*CurrentLiteral()); | 6413 names.Add(*CurrentLiteral()); |
| 6383 ConsumeToken(); // ident. | 6414 ConsumeToken(); // ident. |
| 6384 ConsumeToken(); // colon. | 6415 ConsumeToken(); // colon. |
| 6385 } else if (named_argument_seen) { | 6416 } else if (named_argument_seen) { |
| 6386 ErrorMsg("named argument expected"); | 6417 ErrorMsg("named argument expected"); |
| 6387 } | 6418 } |
| 6388 arguments->Add(ParseExpr(require_const)); | 6419 arguments->Add(ParseExpr(require_const, kConsumeCascades)); |
| 6389 } while (CurrentToken() == Token::kCOMMA); | 6420 } while (CurrentToken() == Token::kCOMMA); |
| 6390 } else { | 6421 } else { |
| 6391 ConsumeToken(); | 6422 ConsumeToken(); |
| 6392 } | 6423 } |
| 6393 ExpectToken(Token::kRPAREN); | 6424 ExpectToken(Token::kRPAREN); |
| 6394 SetAllowFunctionLiterals(saved_mode); | 6425 SetAllowFunctionLiterals(saved_mode); |
| 6395 if (named_argument_seen) { | 6426 if (named_argument_seen) { |
| 6396 arguments->set_names(Array::Handle(Array::MakeArray(names))); | 6427 arguments->set_names(Array::Handle(Array::MakeArray(names))); |
| 6397 } | 6428 } |
| 6398 return arguments; | 6429 return arguments; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6480 TRACE_PARSER("ParseClosureCall"); | 6511 TRACE_PARSER("ParseClosureCall"); |
| 6481 const intptr_t call_pos = TokenPos(); | 6512 const intptr_t call_pos = TokenPos(); |
| 6482 ASSERT(CurrentToken() == Token::kLPAREN); | 6513 ASSERT(CurrentToken() == Token::kLPAREN); |
| 6483 EnsureExpressionTemp(); | 6514 EnsureExpressionTemp(); |
| 6484 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 6515 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 6485 return new ClosureCallNode(call_pos, closure, arguments); | 6516 return new ClosureCallNode(call_pos, closure, arguments); |
| 6486 } | 6517 } |
| 6487 | 6518 |
| 6488 | 6519 |
| 6489 AstNode* Parser::ParseInstanceFieldAccess(AstNode* receiver, | 6520 AstNode* Parser::ParseInstanceFieldAccess(AstNode* receiver, |
| 6490 const String& field_name) { | 6521 const String& field_name, |
| 6522 bool consume_cascades) { |
| 6491 TRACE_PARSER("ParseInstanceFieldAccess"); | 6523 TRACE_PARSER("ParseInstanceFieldAccess"); |
| 6492 AstNode* access = NULL; | 6524 AstNode* access = NULL; |
| 6493 const intptr_t call_pos = TokenPos(); | 6525 const intptr_t call_pos = TokenPos(); |
| 6494 if (Token::IsAssignmentOperator(CurrentToken())) { | 6526 if (Token::IsAssignmentOperator(CurrentToken())) { |
| 6495 Token::Kind assignment_op = CurrentToken(); | 6527 Token::Kind assignment_op = CurrentToken(); |
| 6496 ConsumeToken(); | 6528 ConsumeToken(); |
| 6497 AstNode* value = ParseExpr(kAllowConst); | 6529 AstNode* value = ParseExpr(kAllowConst, consume_cascades); |
| 6498 AstNode* load_access = | 6530 AstNode* load_access = |
| 6499 new InstanceGetterNode(call_pos, receiver, field_name); | 6531 new InstanceGetterNode(call_pos, receiver, field_name); |
| 6500 AstNode* left_load_access = load_access; | 6532 AstNode* left_load_access = load_access; |
| 6501 if (assignment_op != Token::kASSIGN) { | 6533 if (assignment_op != Token::kASSIGN) { |
| 6502 // Compound assignment: store inputs with side effects into temp. locals. | 6534 // Compound assignment: store inputs with side effects into temp. locals. |
| 6503 left_load_access = PrepareCompoundAssignmentNodes(&load_access); | 6535 left_load_access = PrepareCompoundAssignmentNodes(&load_access); |
| 6504 } | 6536 } |
| 6505 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value); | 6537 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value); |
| 6506 access = CreateAssignmentNode(left_load_access, value); | 6538 access = CreateAssignmentNode(left_load_access, value); |
| 6507 } else { | 6539 } else { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 6527 ASSERT(field.value() != Object::transition_sentinel()); | 6559 ASSERT(field.value() != Object::transition_sentinel()); |
| 6528 return new LiteralNode(ident_pos, Instance::ZoneHandle(field.value())); | 6560 return new LiteralNode(ident_pos, Instance::ZoneHandle(field.value())); |
| 6529 } | 6561 } |
| 6530 // Access the field directly. | 6562 // Access the field directly. |
| 6531 return new LoadStaticFieldNode(ident_pos, Field::ZoneHandle(field.raw())); | 6563 return new LoadStaticFieldNode(ident_pos, Field::ZoneHandle(field.raw())); |
| 6532 } | 6564 } |
| 6533 | 6565 |
| 6534 | 6566 |
| 6535 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, | 6567 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, |
| 6536 const String& field_name, | 6568 const String& field_name, |
| 6537 intptr_t ident_pos) { | 6569 intptr_t ident_pos, |
| 6570 bool consume_cascades) { |
| 6538 TRACE_PARSER("ParseStaticFieldAccess"); | 6571 TRACE_PARSER("ParseStaticFieldAccess"); |
| 6539 AstNode* access = NULL; | 6572 AstNode* access = NULL; |
| 6540 const intptr_t call_pos = TokenPos(); | 6573 const intptr_t call_pos = TokenPos(); |
| 6541 const Field& field = Field::ZoneHandle(cls.LookupStaticField(field_name)); | 6574 const Field& field = Field::ZoneHandle(cls.LookupStaticField(field_name)); |
| 6542 Function& func = Function::ZoneHandle(); | 6575 Function& func = Function::ZoneHandle(); |
| 6543 if (Token::IsAssignmentOperator(CurrentToken())) { | 6576 if (Token::IsAssignmentOperator(CurrentToken())) { |
| 6544 Token::Kind assignment_op = CurrentToken(); | 6577 Token::Kind assignment_op = CurrentToken(); |
| 6545 if (field.IsNull()) { | 6578 if (field.IsNull()) { |
| 6546 // No field, check if we have an explicit setter function. | 6579 // No field, check if we have an explicit setter function. |
| 6547 const String& setter_name = | 6580 const String& setter_name = |
| 6548 String::ZoneHandle(Field::SetterName(field_name)); | 6581 String::ZoneHandle(Field::SetterName(field_name)); |
| 6549 const int kNumArguments = 1; // value. | 6582 const int kNumArguments = 1; // value. |
| 6550 const Array& kNoArgumentNames = Array::Handle(); | 6583 const Array& kNoArgumentNames = Array::Handle(); |
| 6551 func = Resolver::ResolveStatic(cls, | 6584 func = Resolver::ResolveStatic(cls, |
| 6552 setter_name, | 6585 setter_name, |
| 6553 kNumArguments, | 6586 kNumArguments, |
| 6554 kNoArgumentNames, | 6587 kNoArgumentNames, |
| 6555 Resolver::kIsQualified); | 6588 Resolver::kIsQualified); |
| 6556 if (func.IsNull()) { | 6589 if (func.IsNull()) { |
| 6557 // No field or explicit setter function, this is an error. | 6590 // No field or explicit setter function, this is an error. |
| 6558 ErrorMsg(ident_pos, "unknown static field '%s'", | 6591 ErrorMsg(ident_pos, "unknown static field '%s'", |
| 6559 field_name.ToCString()); | 6592 field_name.ToCString()); |
| 6560 return access; | 6593 return access; |
| 6561 } | 6594 } |
| 6562 } | 6595 } |
| 6563 ConsumeToken(); | 6596 ConsumeToken(); |
| 6564 AstNode* value = ParseExpr(kAllowConst); | 6597 AstNode* value = ParseExpr(kAllowConst, consume_cascades); |
| 6565 AstNode* load_access = NULL; | 6598 AstNode* load_access = NULL; |
| 6566 if (field.IsNull()) { | 6599 if (field.IsNull()) { |
| 6567 // No field found, we must have at least a setter function defined. | 6600 // No field found, we must have at least a setter function defined. |
| 6568 ASSERT(!func.IsNull()); | 6601 ASSERT(!func.IsNull()); |
| 6569 // Explicit setter function for the field found, field does not exist. | 6602 // Explicit setter function for the field found, field does not exist. |
| 6570 // Create a getter node first in case it is needed. If getter node | 6603 // Create a getter node first in case it is needed. If getter node |
| 6571 // is used as part of, e.g., "+=", and the explicit getter does not | 6604 // is used as part of, e.g., "+=", and the explicit getter does not |
| 6572 // exist, and error will be reported by the code generator. | 6605 // exist, and error will be reported by the code generator. |
| 6573 load_access = new StaticGetterNode(call_pos, | 6606 load_access = new StaticGetterNode(call_pos, |
| 6574 NULL, | 6607 NULL, |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6667 "cannot access instance method '%s' from static method", | 6700 "cannot access instance method '%s' from static method", |
| 6668 funcname.ToCString()); | 6701 funcname.ToCString()); |
| 6669 } | 6702 } |
| 6670 AstNode* receiver = LoadReceiver(primary->token_pos()); | 6703 AstNode* receiver = LoadReceiver(primary->token_pos()); |
| 6671 closure = CallGetter(primary->token_pos(), receiver, funcname); | 6704 closure = CallGetter(primary->token_pos(), receiver, funcname); |
| 6672 } | 6705 } |
| 6673 return closure; | 6706 return closure; |
| 6674 } | 6707 } |
| 6675 | 6708 |
| 6676 | 6709 |
| 6677 AstNode* Parser::ParsePostfixExpr() { | 6710 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { |
| 6678 TRACE_PARSER("ParsePostfixExpr"); | 6711 AstNode* left = primary; |
| 6679 const intptr_t postfix_expr_pos = TokenPos(); | |
| 6680 AstNode* postfix_expr = ParsePrimary(); | |
| 6681 while (true) { | 6712 while (true) { |
| 6682 AstNode* selector = NULL; | 6713 AstNode* selector = NULL; |
| 6683 AstNode* left = postfix_expr; | |
| 6684 if (CurrentToken() == Token::kPERIOD) { | 6714 if (CurrentToken() == Token::kPERIOD) { |
| 6685 ConsumeToken(); | 6715 ConsumeToken(); |
| 6686 if (left->IsPrimaryNode()) { | 6716 if (left->IsPrimaryNode()) { |
| 6687 if (left->AsPrimaryNode()->primary().IsFunction()) { | 6717 if (left->AsPrimaryNode()->primary().IsFunction()) { |
| 6688 left = LoadClosure(left->AsPrimaryNode()); | 6718 left = LoadClosure(left->AsPrimaryNode()); |
| 6689 } else { | 6719 } else { |
| 6690 left = LoadFieldIfUnresolved(left); | 6720 left = LoadFieldIfUnresolved(left); |
| 6691 } | 6721 } |
| 6692 } | 6722 } |
| 6693 const intptr_t ident_pos = TokenPos(); | 6723 const intptr_t ident_pos = TokenPos(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 6709 if (left->IsPrimaryNode()) { | 6739 if (left->IsPrimaryNode()) { |
| 6710 PrimaryNode* primary_node = left->AsPrimaryNode(); | 6740 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 6711 if (primary_node->primary().IsClass()) { | 6741 if (primary_node->primary().IsClass()) { |
| 6712 // If the primary node referred to a class we are loading a | 6742 // If the primary node referred to a class we are loading a |
| 6713 // qualified static field. | 6743 // qualified static field. |
| 6714 cls ^= primary_node->primary().raw(); | 6744 cls ^= primary_node->primary().raw(); |
| 6715 } | 6745 } |
| 6716 } | 6746 } |
| 6717 if (cls.IsNull()) { | 6747 if (cls.IsNull()) { |
| 6718 // Instance field access. | 6748 // Instance field access. |
| 6719 selector = ParseInstanceFieldAccess(left, *ident); | 6749 selector = ParseInstanceFieldAccess(left, *ident, !is_cascade); |
| 6720 } else { | 6750 } else { |
| 6721 // Static field access. | 6751 // Static field access. |
| 6722 selector = ParseStaticFieldAccess(cls, *ident, ident_pos); | 6752 selector = |
| 6753 ParseStaticFieldAccess(cls, *ident, ident_pos, !is_cascade); |
| 6723 } | 6754 } |
| 6724 } | 6755 } |
| 6725 } else if (CurrentToken() == Token::kLBRACK) { | 6756 } else if (CurrentToken() == Token::kLBRACK) { |
| 6726 const intptr_t bracket_pos = TokenPos(); | 6757 const intptr_t bracket_pos = TokenPos(); |
| 6727 ConsumeToken(); | 6758 ConsumeToken(); |
| 6728 left = LoadFieldIfUnresolved(left); | 6759 left = LoadFieldIfUnresolved(left); |
| 6729 const bool saved_mode = SetAllowFunctionLiterals(true); | 6760 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 6730 AstNode* index = ParseExpr(kAllowConst); | 6761 AstNode* index = ParseExpr(kAllowConst, kConsumeCascades); |
| 6731 SetAllowFunctionLiterals(saved_mode); | 6762 SetAllowFunctionLiterals(saved_mode); |
| 6732 ExpectToken(Token::kRBRACK); | 6763 ExpectToken(Token::kRBRACK); |
| 6733 AstNode* array = left; | 6764 AstNode* array = left; |
| 6734 if (left->IsPrimaryNode()) { | 6765 if (left->IsPrimaryNode()) { |
| 6735 PrimaryNode* primary = left->AsPrimaryNode(); | 6766 PrimaryNode* primary = left->AsPrimaryNode(); |
| 6736 if (primary->primary().IsFunction()) { | 6767 if (primary->primary().IsFunction()) { |
| 6737 array = LoadClosure(primary); | 6768 array = LoadClosure(primary); |
| 6738 } else if (primary->primary().IsClass()) { | 6769 } else if (primary->primary().IsClass()) { |
| 6739 ErrorMsg(bracket_pos, "cannot apply index operator to class"); | 6770 ErrorMsg(bracket_pos, "cannot apply index operator to class"); |
| 6740 } else { | 6771 } else { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6780 "must use 'new' or 'const' to construct new instance"); | 6811 "must use 'new' or 'const' to construct new instance"); |
| 6781 } else { | 6812 } else { |
| 6782 UNREACHABLE(); // Internal parser error. | 6813 UNREACHABLE(); // Internal parser error. |
| 6783 } | 6814 } |
| 6784 } else { | 6815 } else { |
| 6785 // Left is not a primary node; this must be a closure call. | 6816 // Left is not a primary node; this must be a closure call. |
| 6786 AstNode* closure = left; | 6817 AstNode* closure = left; |
| 6787 selector = ParseClosureCall(closure); | 6818 selector = ParseClosureCall(closure); |
| 6788 } | 6819 } |
| 6789 } else { | 6820 } else { |
| 6790 // No (more) selector to parse. | 6821 // No (more) selectors to parse. |
| 6791 left = LoadFieldIfUnresolved(left); | 6822 left = LoadFieldIfUnresolved(left); |
| 6792 if (left->IsPrimaryNode()) { | 6823 if (left->IsPrimaryNode()) { |
| 6793 PrimaryNode* primary = left->AsPrimaryNode(); | 6824 PrimaryNode* primary = left->AsPrimaryNode(); |
| 6794 if (primary->primary().IsFunction()) { | 6825 if (primary->primary().IsFunction()) { |
| 6795 // Treat as implicit closure. | 6826 // Treat as implicit closure. |
| 6796 left = LoadClosure(primary); | 6827 left = LoadClosure(primary); |
| 6797 } else if (left->AsPrimaryNode()->primary().IsClass()) { | 6828 } else if (left->AsPrimaryNode()->primary().IsClass()) { |
| 6798 Class& cls = Class::CheckedHandle( | 6829 Class& cls = Class::CheckedHandle( |
| 6799 left->AsPrimaryNode()->primary().raw()); | 6830 left->AsPrimaryNode()->primary().raw()); |
| 6800 String& cls_name = String::Handle(cls.Name()); | 6831 String& cls_name = String::Handle(cls.Name()); |
| 6801 ErrorMsg(left->token_pos(), | 6832 ErrorMsg(left->token_pos(), |
| 6802 "illegal use of class name '%s'", | 6833 "illegal use of class name '%s'", |
| 6803 cls_name.ToCString()); | 6834 cls_name.ToCString()); |
| 6804 } else { | 6835 } else { |
| 6805 UNREACHABLE(); // Internal parser error. | 6836 UNREACHABLE(); // Internal parser error. |
| 6806 } | 6837 } |
| 6807 } | 6838 } |
| 6808 postfix_expr = left; | |
| 6809 // Done parsing selectors. | 6839 // Done parsing selectors. |
| 6810 break; | 6840 return left; |
| 6811 } | 6841 } |
| 6812 ASSERT(selector != NULL); | 6842 ASSERT(selector != NULL); |
| 6813 postfix_expr = selector; | 6843 left = selector; |
| 6814 } | 6844 } |
| 6845 } |
| 6846 |
| 6847 |
| 6848 AstNode* Parser::ParsePostfixExpr() { |
| 6849 TRACE_PARSER("ParsePostfixExpr"); |
| 6850 const intptr_t postfix_expr_pos = TokenPos(); |
| 6851 AstNode* postfix_expr = ParsePrimary(); |
| 6852 postfix_expr = ParseSelectors(postfix_expr, false); |
| 6815 if (IsIncrementOperator(CurrentToken())) { | 6853 if (IsIncrementOperator(CurrentToken())) { |
| 6816 TRACE_PARSER("IncrementOperator"); | 6854 TRACE_PARSER("IncrementOperator"); |
| 6817 Token::Kind incr_op = CurrentToken(); | 6855 Token::Kind incr_op = CurrentToken(); |
| 6818 if (!IsAssignableExpr(postfix_expr)) { | 6856 if (!IsAssignableExpr(postfix_expr)) { |
| 6819 ErrorMsg("expression is not assignable"); | 6857 ErrorMsg("expression is not assignable"); |
| 6820 } | 6858 } |
| 6821 ConsumeToken(); | 6859 ConsumeToken(); |
| 6822 // Not prefix. | 6860 // Not prefix. |
| 6823 AstNode* left_expr = PrepareCompoundAssignmentNodes(&postfix_expr); | 6861 AstNode* left_expr = PrepareCompoundAssignmentNodes(&postfix_expr); |
| 6824 const LocalVariable& temp = GetIncrementTempLocal(); | 6862 const LocalVariable& temp = GetIncrementTempLocal(); |
| (...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7517 | 7555 |
| 7518 // Parse the list elements. Note: there may be an optional extra | 7556 // Parse the list elements. Note: there may be an optional extra |
| 7519 // comma after the last element. | 7557 // comma after the last element. |
| 7520 ArrayNode* list = new ArrayNode(TokenPos(), type_arguments); | 7558 ArrayNode* list = new ArrayNode(TokenPos(), type_arguments); |
| 7521 if (!is_empty_literal) { | 7559 if (!is_empty_literal) { |
| 7522 const bool saved_mode = SetAllowFunctionLiterals(true); | 7560 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7523 const String& dst_name = String::ZoneHandle( | 7561 const String& dst_name = String::ZoneHandle( |
| 7524 Symbols::New("list literal element")); | 7562 Symbols::New("list literal element")); |
| 7525 while (CurrentToken() != Token::kRBRACK) { | 7563 while (CurrentToken() != Token::kRBRACK) { |
| 7526 const intptr_t element_pos = TokenPos(); | 7564 const intptr_t element_pos = TokenPos(); |
| 7527 AstNode* element = ParseExpr(is_const); | 7565 AstNode* element = ParseExpr(is_const, kConsumeCascades); |
| 7528 if (FLAG_enable_type_checks && | 7566 if (FLAG_enable_type_checks && |
| 7529 !is_const && | 7567 !is_const && |
| 7530 !element_type.IsDynamicType()) { | 7568 !element_type.IsDynamicType()) { |
| 7531 element = new AssignableNode(element_pos, | 7569 element = new AssignableNode(element_pos, |
| 7532 element, | 7570 element, |
| 7533 element_type, | 7571 element_type, |
| 7534 dst_name); | 7572 dst_name); |
| 7535 } | 7573 } |
| 7536 list->AddElement(element); | 7574 list->AddElement(element); |
| 7537 if (CurrentToken() == Token::kCOMMA) { | 7575 if (CurrentToken() == Token::kCOMMA) { |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7712 key = ParseStringLiteral(); | 7750 key = ParseStringLiteral(); |
| 7713 } | 7751 } |
| 7714 if (key == NULL) { | 7752 if (key == NULL) { |
| 7715 ErrorMsg("map entry key must be string literal"); | 7753 ErrorMsg("map entry key must be string literal"); |
| 7716 } else if (is_const && !key->IsLiteralNode()) { | 7754 } else if (is_const && !key->IsLiteralNode()) { |
| 7717 ErrorMsg("map entry key must be compile time constant string"); | 7755 ErrorMsg("map entry key must be compile time constant string"); |
| 7718 } | 7756 } |
| 7719 ExpectToken(Token::kCOLON); | 7757 ExpectToken(Token::kCOLON); |
| 7720 const bool saved_mode = SetAllowFunctionLiterals(true); | 7758 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7721 const intptr_t value_pos = TokenPos(); | 7759 const intptr_t value_pos = TokenPos(); |
| 7722 AstNode* value = ParseExpr(is_const); | 7760 AstNode* value = ParseExpr(is_const, kConsumeCascades); |
| 7723 SetAllowFunctionLiterals(saved_mode); | 7761 SetAllowFunctionLiterals(saved_mode); |
| 7724 if (FLAG_enable_type_checks && | 7762 if (FLAG_enable_type_checks && |
| 7725 !is_const && | 7763 !is_const && |
| 7726 !value_type.IsDynamicType()) { | 7764 !value_type.IsDynamicType()) { |
| 7727 value = new AssignableNode(value_pos, | 7765 value = new AssignableNode(value_pos, |
| 7728 value, | 7766 value, |
| 7729 value_type, | 7767 value_type, |
| 7730 dst_name); | 7768 dst_name); |
| 7731 } | 7769 } |
| 7732 AddKeyValuePair(kv_pairs, is_const, key, value); | 7770 AddKeyValuePair(kv_pairs, is_const, key, value); |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8171 while ((CurrentToken() == Token::kINTERPOL_VAR) || | 8209 while ((CurrentToken() == Token::kINTERPOL_VAR) || |
| 8172 (CurrentToken() == Token::kINTERPOL_START)) { | 8210 (CurrentToken() == Token::kINTERPOL_START)) { |
| 8173 AstNode* expr = NULL; | 8211 AstNode* expr = NULL; |
| 8174 const intptr_t expr_pos = TokenPos(); | 8212 const intptr_t expr_pos = TokenPos(); |
| 8175 if (CurrentToken() == Token::kINTERPOL_VAR) { | 8213 if (CurrentToken() == Token::kINTERPOL_VAR) { |
| 8176 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true); | 8214 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true); |
| 8177 ConsumeToken(); | 8215 ConsumeToken(); |
| 8178 } else { | 8216 } else { |
| 8179 ASSERT(CurrentToken() == Token::kINTERPOL_START); | 8217 ASSERT(CurrentToken() == Token::kINTERPOL_START); |
| 8180 ConsumeToken(); | 8218 ConsumeToken(); |
| 8181 expr = ParseExpr(kAllowConst); | 8219 expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 8182 ExpectToken(Token::kINTERPOL_END); | 8220 ExpectToken(Token::kINTERPOL_END); |
| 8183 } | 8221 } |
| 8184 // Check if this interpolated string is still considered a compile time | 8222 // Check if this interpolated string is still considered a compile time |
| 8185 // constant. If it is we need to evaluate if the current string part is | 8223 // constant. If it is we need to evaluate if the current string part is |
| 8186 // a constant or not. | 8224 // a constant or not. |
| 8187 if (is_compiletime_const) { | 8225 if (is_compiletime_const) { |
| 8188 const Object* const_expr = expr->EvalConstExpr(); | 8226 const Object* const_expr = expr->EvalConstExpr(); |
| 8189 if (const_expr != NULL) { | 8227 if (const_expr != NULL) { |
| 8190 // Change expr into a literal. | 8228 // Change expr into a literal. |
| 8191 expr = new LiteralNode(expr_pos, EvaluateConstExpr(expr)); | 8229 expr = new LiteralNode(expr_pos, EvaluateConstExpr(expr)); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8329 ConsumeToken(); | 8367 ConsumeToken(); |
| 8330 } else if (CurrentToken() == Token::kFALSE) { | 8368 } else if (CurrentToken() == Token::kFALSE) { |
| 8331 primary = new LiteralNode(TokenPos(), Bool::ZoneHandle(Bool::False())); | 8369 primary = new LiteralNode(TokenPos(), Bool::ZoneHandle(Bool::False())); |
| 8332 ConsumeToken(); | 8370 ConsumeToken(); |
| 8333 } else if (CurrentToken() == Token::kNULL) { | 8371 } else if (CurrentToken() == Token::kNULL) { |
| 8334 primary = new LiteralNode(TokenPos(), Instance::ZoneHandle()); | 8372 primary = new LiteralNode(TokenPos(), Instance::ZoneHandle()); |
| 8335 ConsumeToken(); | 8373 ConsumeToken(); |
| 8336 } else if (CurrentToken() == Token::kLPAREN) { | 8374 } else if (CurrentToken() == Token::kLPAREN) { |
| 8337 ConsumeToken(); | 8375 ConsumeToken(); |
| 8338 const bool saved_mode = SetAllowFunctionLiterals(true); | 8376 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 8339 primary = ParseExpr(kAllowConst); | 8377 primary = ParseExpr(kAllowConst, kConsumeCascades); |
| 8340 SetAllowFunctionLiterals(saved_mode); | 8378 SetAllowFunctionLiterals(saved_mode); |
| 8341 ExpectToken(Token::kRPAREN); | 8379 ExpectToken(Token::kRPAREN); |
| 8342 } else if (CurrentToken() == Token::kDOUBLE) { | 8380 } else if (CurrentToken() == Token::kDOUBLE) { |
| 8343 Double& double_value = Double::ZoneHandle(CurrentDoubleLiteral()); | 8381 Double& double_value = Double::ZoneHandle(CurrentDoubleLiteral()); |
| 8344 if (double_value.IsNull()) { | 8382 if (double_value.IsNull()) { |
| 8345 ErrorMsg("invalid double literal"); | 8383 ErrorMsg("invalid double literal"); |
| 8346 } | 8384 } |
| 8347 primary = new LiteralNode(TokenPos(), double_value); | 8385 primary = new LiteralNode(TokenPos(), double_value); |
| 8348 ConsumeToken(); | 8386 ConsumeToken(); |
| 8349 } else if (CurrentToken() == Token::kSTRING) { | 8387 } else if (CurrentToken() == Token::kSTRING) { |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8667 void Parser::SkipQualIdent() { | 8705 void Parser::SkipQualIdent() { |
| 8668 ASSERT(IsIdentifier()); | 8706 ASSERT(IsIdentifier()); |
| 8669 ConsumeToken(); | 8707 ConsumeToken(); |
| 8670 if (CurrentToken() == Token::kPERIOD) { | 8708 if (CurrentToken() == Token::kPERIOD) { |
| 8671 ConsumeToken(); // Consume the kPERIOD token. | 8709 ConsumeToken(); // Consume the kPERIOD token. |
| 8672 ExpectIdentifier("identifier expected after '.'"); | 8710 ExpectIdentifier("identifier expected after '.'"); |
| 8673 } | 8711 } |
| 8674 } | 8712 } |
| 8675 | 8713 |
| 8676 } // namespace dart | 8714 } // namespace dart |
| OLD | NEW |