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 5573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5584 // would refer to the compiler generated iterator and could confuse the user. | 5584 // would refer to the compiler generated iterator and could confuse the user. |
5585 // It is better to leave the iterator untyped and postpone the type error | 5585 // It is better to leave the iterator untyped and postpone the type error |
5586 // until the loop variable is assigned to. | 5586 // until the loop variable is assigned to. |
5587 const AbstractType& iterator_type = Type::ZoneHandle(Type::DynamicType()); | 5587 const AbstractType& iterator_type = Type::ZoneHandle(Type::DynamicType()); |
5588 LocalVariable* iterator_var = | 5588 LocalVariable* iterator_var = |
5589 new LocalVariable(collection_pos, Symbols::ForInIter(), iterator_type); | 5589 new LocalVariable(collection_pos, Symbols::ForInIter(), iterator_type); |
5590 current_block_->scope->AddVariable(iterator_var); | 5590 current_block_->scope->AddVariable(iterator_var); |
5591 | 5591 |
5592 // Generate initialization of iterator variable. | 5592 // Generate initialization of iterator variable. |
5593 ArgumentListNode* no_args = new ArgumentListNode(collection_pos); | 5593 ArgumentListNode* no_args = new ArgumentListNode(collection_pos); |
5594 AstNode* get_iterator = new InstanceCallNode( | 5594 AstNode* get_iterator = new InstanceGetterNode( |
5595 collection_pos, collection_expr, Symbols::GetIterator(), no_args); | 5595 collection_pos, collection_expr, Symbols::GetIterator()); |
5596 AstNode* iterator_init = | 5596 AstNode* iterator_init = |
5597 new StoreLocalNode(collection_pos, iterator_var, get_iterator); | 5597 new StoreLocalNode(collection_pos, iterator_var, get_iterator); |
5598 current_block_->statements->Add(iterator_init); | 5598 current_block_->statements->Add(iterator_init); |
5599 | 5599 |
5600 // Generate while loop condition. | 5600 // Generate while loop condition. |
5601 AstNode* iterator_has_next = new InstanceGetterNode( | 5601 AstNode* iterator_moveNext = new InstanceCallNode( |
5602 collection_pos, | 5602 collection_pos, |
5603 new LoadLocalNode(collection_pos, iterator_var), | 5603 new LoadLocalNode(collection_pos, iterator_var), |
5604 Symbols::HasNext()); | 5604 Symbols::MoveNext(), |
| 5605 no_args); |
5605 | 5606 |
5606 // Parse the for loop body. Ideally, we would use ParseNestedStatement() | 5607 // Parse the for loop body. Ideally, we would use ParseNestedStatement() |
5607 // here, but that does not work well because we have to insert an implicit | 5608 // here, but that does not work well because we have to insert an implicit |
5608 // variable assignment and potentially a variable declaration in the | 5609 // variable assignment and potentially a variable declaration in the |
5609 // loop body. | 5610 // loop body. |
5610 OpenLoopBlock(); | 5611 OpenLoopBlock(); |
5611 current_block_->scope->AddLabel(label); | 5612 current_block_->scope->AddLabel(label); |
5612 | 5613 |
5613 AstNode* iterator_next = new InstanceCallNode( | 5614 AstNode* iterator_current = new InstanceGetterNode( |
5614 collection_pos, | 5615 collection_pos, |
5615 new LoadLocalNode(collection_pos, iterator_var), | 5616 new LoadLocalNode(collection_pos, iterator_var), |
5616 Symbols::Next(), | 5617 Symbols::Current()); |
5617 no_args); | |
5618 | 5618 |
5619 // Generate assignment of next iterator value to loop variable. | 5619 // Generate assignment of next iterator value to loop variable. |
5620 AstNode* loop_var_assignment = NULL; | 5620 AstNode* loop_var_assignment = NULL; |
5621 if (loop_var != NULL) { | 5621 if (loop_var != NULL) { |
5622 // The for loop declares a new variable. Add it to the loop body scope. | 5622 // The for loop declares a new variable. Add it to the loop body scope. |
5623 current_block_->scope->AddVariable(loop_var); | 5623 current_block_->scope->AddVariable(loop_var); |
5624 loop_var_assignment = | 5624 loop_var_assignment = |
5625 new StoreLocalNode(loop_var_pos, loop_var, iterator_next); | 5625 new StoreLocalNode(loop_var_pos, loop_var, iterator_current); |
5626 } else { | 5626 } else { |
5627 AstNode* loop_var_primary = | 5627 AstNode* loop_var_primary = |
5628 ResolveIdent(loop_var_pos, *loop_var_name, false); | 5628 ResolveIdent(loop_var_pos, *loop_var_name, false); |
5629 ASSERT(!loop_var_primary->IsPrimaryNode()); | 5629 ASSERT(!loop_var_primary->IsPrimaryNode()); |
5630 loop_var_assignment = | 5630 loop_var_assignment = |
5631 CreateAssignmentNode(loop_var_primary, iterator_next); | 5631 CreateAssignmentNode(loop_var_primary, iterator_current); |
5632 if (loop_var_assignment == NULL) { | 5632 if (loop_var_assignment == NULL) { |
5633 ErrorMsg(loop_var_pos, "variable or field '%s' is not assignable", | 5633 ErrorMsg(loop_var_pos, "variable or field '%s' is not assignable", |
5634 loop_var_name->ToCString()); | 5634 loop_var_name->ToCString()); |
5635 } | 5635 } |
5636 } | 5636 } |
5637 current_block_->statements->Add(loop_var_assignment); | 5637 current_block_->statements->Add(loop_var_assignment); |
5638 | 5638 |
5639 // Now parse the for-in loop statement or block. | 5639 // Now parse the for-in loop statement or block. |
5640 if (CurrentToken() == Token::kLBRACE) { | 5640 if (CurrentToken() == Token::kLBRACE) { |
5641 ConsumeToken(); | 5641 ConsumeToken(); |
5642 ParseStatementSequence(); | 5642 ParseStatementSequence(); |
5643 ExpectToken(Token::kRBRACE); | 5643 ExpectToken(Token::kRBRACE); |
5644 } else { | 5644 } else { |
5645 AstNode* statement = ParseStatement(); | 5645 AstNode* statement = ParseStatement(); |
5646 if (statement != NULL) { | 5646 if (statement != NULL) { |
5647 current_block_->statements->Add(statement); | 5647 current_block_->statements->Add(statement); |
5648 } | 5648 } |
5649 } | 5649 } |
5650 | 5650 |
5651 SequenceNode* for_loop_statement = CloseBlock(); | 5651 SequenceNode* for_loop_statement = CloseBlock(); |
5652 | 5652 |
5653 AstNode* while_statement = | 5653 AstNode* while_statement = |
5654 new WhileNode(forin_pos, label, iterator_has_next, for_loop_statement); | 5654 new WhileNode(forin_pos, label, iterator_moveNext, for_loop_statement); |
5655 current_block_->statements->Add(while_statement); | 5655 current_block_->statements->Add(while_statement); |
5656 | 5656 |
5657 return CloseBlock(); // Implicit block around while loop. | 5657 return CloseBlock(); // Implicit block around while loop. |
5658 } | 5658 } |
5659 | 5659 |
5660 | 5660 |
5661 AstNode* Parser::ParseForStatement(String* label_name) { | 5661 AstNode* Parser::ParseForStatement(String* label_name) { |
5662 TRACE_PARSER("ParseForStatement"); | 5662 TRACE_PARSER("ParseForStatement"); |
5663 const intptr_t for_pos = TokenPos(); | 5663 const intptr_t for_pos = TokenPos(); |
5664 ConsumeToken(); | 5664 ConsumeToken(); |
(...skipping 4037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9702 void Parser::SkipQualIdent() { | 9702 void Parser::SkipQualIdent() { |
9703 ASSERT(IsIdentifier()); | 9703 ASSERT(IsIdentifier()); |
9704 ConsumeToken(); | 9704 ConsumeToken(); |
9705 if (CurrentToken() == Token::kPERIOD) { | 9705 if (CurrentToken() == Token::kPERIOD) { |
9706 ConsumeToken(); // Consume the kPERIOD token. | 9706 ConsumeToken(); // Consume the kPERIOD token. |
9707 ExpectIdentifier("identifier expected after '.'"); | 9707 ExpectIdentifier("identifier expected after '.'"); |
9708 } | 9708 } |
9709 } | 9709 } |
9710 | 9710 |
9711 } // namespace dart | 9711 } // namespace dart |
OLD | NEW |