| 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 |