Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(238)

Side by Side Diff: runtime/vm/parser.cc

Issue 10796109: Implement cascade operator in VM (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/scanner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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(&params, func); 2185 ParseNativeFunctionBlock(&params, 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/scanner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698