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

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

Issue 577423005: Fix context handling in for-in loops (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 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/debugger.cc ('k') | no next file » | 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 "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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/debugger.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698