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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
9 #include "vm/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
(...skipping 7205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7216 } | 7216 } |
7217 ExpectToken(Token::kRPAREN); | 7217 ExpectToken(Token::kRPAREN); |
7218 ExpectSemicolon(); | 7218 ExpectSemicolon(); |
7219 return new(I) DoWhileNode(do_pos, label, cond_expr, dowhile_body); | 7219 return new(I) DoWhileNode(do_pos, label, cond_expr, dowhile_body); |
7220 } | 7220 } |
7221 | 7221 |
7222 | 7222 |
7223 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, | 7223 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, |
7224 SourceLabel* label) { | 7224 SourceLabel* label) { |
7225 TRACE_PARSER("ParseForInStatement"); | 7225 TRACE_PARSER("ParseForInStatement"); |
7226 bool is_final = (CurrentToken() == Token::kFINAL); | 7226 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
7227 if (CurrentToken() == Token::kCONST) { | 7227 if (CurrentToken() == Token::kCONST) { |
7228 ReportError("Loop variable cannot be 'const'"); | 7228 ReportError("Loop variable cannot be 'const'"); |
7229 } | 7229 } |
7230 const String* loop_var_name = NULL; | 7230 const String* loop_var_name = NULL; |
7231 LocalVariable* loop_var = NULL; | |
7232 intptr_t loop_var_pos = 0; | 7231 intptr_t loop_var_pos = 0; |
| 7232 bool new_loop_var = false; |
| 7233 AbstractType& loop_var_type = AbstractType::ZoneHandle(I); |
7233 if (LookaheadToken(1) == Token::kIN) { | 7234 if (LookaheadToken(1) == Token::kIN) { |
7234 loop_var_pos = TokenPos(); | 7235 loop_var_pos = TokenPos(); |
7235 loop_var_name = ExpectIdentifier("variable name expected"); | 7236 loop_var_name = ExpectIdentifier("variable name expected"); |
7236 } else { | 7237 } else { |
7237 // The case without a type is handled above, so require a type here. | 7238 // The case without a type is handled above, so require a type here. |
7238 const AbstractType& type = | 7239 new_loop_var = true; |
7239 AbstractType::ZoneHandle(I, ParseConstFinalVarOrType( | 7240 loop_var_type = ParseConstFinalVarOrType( |
7240 FLAG_enable_type_checks ? ClassFinalizer::kCanonicalize : | 7241 FLAG_enable_type_checks ? ClassFinalizer::kCanonicalize : |
7241 ClassFinalizer::kIgnore)); | 7242 ClassFinalizer::kIgnore); |
7242 loop_var_pos = TokenPos(); | |
7243 loop_var_name = ExpectIdentifier("variable name expected"); | 7243 loop_var_name = ExpectIdentifier("variable name expected"); |
7244 loop_var = new(I) LocalVariable(loop_var_pos, *loop_var_name, type); | |
7245 if (is_final) { | |
7246 loop_var->set_is_final(); | |
7247 } | |
7248 } | 7244 } |
7249 ExpectToken(Token::kIN); | 7245 ExpectToken(Token::kIN); |
7250 const intptr_t collection_pos = TokenPos(); | 7246 const intptr_t collection_pos = TokenPos(); |
7251 AstNode* collection_expr = | 7247 AstNode* collection_expr = |
7252 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 7248 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
7253 ExpectToken(Token::kRPAREN); | 7249 ExpectToken(Token::kRPAREN); |
7254 | 7250 |
7255 OpenBlock(); // Implicit block around while loop. | 7251 OpenBlock(); // Implicit block around while loop. |
7256 | 7252 |
7257 // Generate implicit iterator variable and add to scope. | 7253 // Generate implicit iterator variable and add to scope. |
(...skipping 21 matching lines...) Expand all Loading... |
7279 new(I) LoadLocalNode(collection_pos, iterator_var), | 7275 new(I) LoadLocalNode(collection_pos, iterator_var), |
7280 Symbols::MoveNext(), | 7276 Symbols::MoveNext(), |
7281 no_args); | 7277 no_args); |
7282 | 7278 |
7283 // Parse the for loop body. Ideally, we would use ParseNestedStatement() | 7279 // Parse the for loop body. Ideally, we would use ParseNestedStatement() |
7284 // here, but that does not work well because we have to insert an implicit | 7280 // here, but that does not work well because we have to insert an implicit |
7285 // variable assignment and potentially a variable declaration in the | 7281 // variable assignment and potentially a variable declaration in the |
7286 // loop body. | 7282 // loop body. |
7287 OpenLoopBlock(); | 7283 OpenLoopBlock(); |
7288 current_block_->scope->AddLabel(label); | 7284 current_block_->scope->AddLabel(label); |
| 7285 const intptr_t loop_var_assignment_pos = TokenPos(); |
7289 | 7286 |
7290 AstNode* iterator_current = new(I) InstanceGetterNode( | 7287 AstNode* iterator_current = new(I) InstanceGetterNode( |
7291 collection_pos, | 7288 loop_var_assignment_pos, |
7292 new(I) LoadLocalNode(collection_pos, iterator_var), | 7289 new(I) LoadLocalNode(loop_var_assignment_pos, iterator_var), |
7293 Symbols::Current()); | 7290 Symbols::Current()); |
7294 | 7291 |
7295 // Generate assignment of next iterator value to loop variable. | 7292 // Generate assignment of next iterator value to loop variable. |
7296 AstNode* loop_var_assignment = NULL; | 7293 AstNode* loop_var_assignment = NULL; |
7297 if (loop_var != NULL) { | 7294 if (new_loop_var) { |
7298 // The for loop declares a new variable. Add it to the loop body scope. | 7295 // The for loop variable is new for each iteration. |
| 7296 // Create a variable and add it to the loop body scope. |
| 7297 LocalVariable* loop_var = |
| 7298 new(I) LocalVariable(loop_var_assignment_pos, |
| 7299 *loop_var_name, |
| 7300 loop_var_type);; |
| 7301 if (loop_var_is_final) { |
| 7302 loop_var->set_is_final(); |
| 7303 } |
7299 current_block_->scope->AddVariable(loop_var); | 7304 current_block_->scope->AddVariable(loop_var); |
7300 loop_var_assignment = | 7305 loop_var_assignment = new(I) StoreLocalNode( |
7301 new(I) StoreLocalNode(loop_var_pos, loop_var, iterator_current); | 7306 loop_var_assignment_pos, loop_var, iterator_current); |
7302 } else { | 7307 } else { |
7303 AstNode* loop_var_primary = | 7308 AstNode* loop_var_primary = |
7304 ResolveIdent(loop_var_pos, *loop_var_name, false); | 7309 ResolveIdent(loop_var_pos, *loop_var_name, false); |
7305 ASSERT(!loop_var_primary->IsPrimaryNode()); | 7310 ASSERT(!loop_var_primary->IsPrimaryNode()); |
7306 loop_var_assignment = CreateAssignmentNode( | 7311 loop_var_assignment = CreateAssignmentNode(loop_var_primary, |
7307 loop_var_primary, iterator_current, loop_var_name, loop_var_pos); | 7312 iterator_current, |
| 7313 loop_var_name, |
| 7314 loop_var_assignment_pos); |
7308 ASSERT(loop_var_assignment != NULL); | 7315 ASSERT(loop_var_assignment != NULL); |
7309 } | 7316 } |
7310 current_block_->statements->Add(loop_var_assignment); | 7317 current_block_->statements->Add(loop_var_assignment); |
7311 | 7318 |
7312 // Now parse the for-in loop statement or block. | 7319 // Now parse the for-in loop statement or block. |
7313 if (CurrentToken() == Token::kLBRACE) { | 7320 if (CurrentToken() == Token::kLBRACE) { |
7314 ConsumeToken(); | 7321 ConsumeToken(); |
7315 ParseStatementSequence(); | 7322 ParseStatementSequence(); |
7316 ExpectToken(Token::kRBRACE); | 7323 ExpectToken(Token::kRBRACE); |
7317 } else { | 7324 } else { |
(...skipping 4456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11774 void Parser::SkipQualIdent() { | 11781 void Parser::SkipQualIdent() { |
11775 ASSERT(IsIdentifier()); | 11782 ASSERT(IsIdentifier()); |
11776 ConsumeToken(); | 11783 ConsumeToken(); |
11777 if (CurrentToken() == Token::kPERIOD) { | 11784 if (CurrentToken() == Token::kPERIOD) { |
11778 ConsumeToken(); // Consume the kPERIOD token. | 11785 ConsumeToken(); // Consume the kPERIOD token. |
11779 ExpectIdentifier("identifier expected after '.'"); | 11786 ExpectIdentifier("identifier expected after '.'"); |
11780 } | 11787 } |
11781 } | 11788 } |
11782 | 11789 |
11783 } // namespace dart | 11790 } // namespace dart |
OLD | NEW |