| 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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 5913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5924 | 5924 |
| 5925 AstNode* Parser::ParseForStatement(String* label_name) { | 5925 AstNode* Parser::ParseForStatement(String* label_name) { |
| 5926 TRACE_PARSER("ParseForStatement"); | 5926 TRACE_PARSER("ParseForStatement"); |
| 5927 const intptr_t for_pos = TokenPos(); | 5927 const intptr_t for_pos = TokenPos(); |
| 5928 ConsumeToken(); | 5928 ConsumeToken(); |
| 5929 ExpectToken(Token::kLPAREN); | 5929 ExpectToken(Token::kLPAREN); |
| 5930 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); | 5930 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); |
| 5931 if (IsForInStatement()) { | 5931 if (IsForInStatement()) { |
| 5932 return ParseForInStatement(for_pos, label); | 5932 return ParseForInStatement(for_pos, label); |
| 5933 } | 5933 } |
| 5934 OpenBlock(); | 5934 // Open a block that contains the loop variable. Make it a loop block so |
| 5935 // The label is added to the implicit scope that also contains | 5935 // that we allocate a new context if the loop variable is captured. |
| 5936 // the loop variable declarations. | 5936 OpenLoopBlock(); |
| 5937 current_block_->scope->AddLabel(label); | |
| 5938 AstNode* initializer = NULL; | 5937 AstNode* initializer = NULL; |
| 5939 const intptr_t init_pos = TokenPos(); | 5938 const intptr_t init_pos = TokenPos(); |
| 5940 LocalScope* init_scope = current_block_->scope; | 5939 LocalScope* init_scope = current_block_->scope; |
| 5941 if (CurrentToken() != Token::kSEMICOLON) { | 5940 if (CurrentToken() != Token::kSEMICOLON) { |
| 5942 if (IsVariableDeclaration()) { | 5941 if (IsVariableDeclaration()) { |
| 5943 initializer = ParseVariableDeclarationList(); | 5942 initializer = ParseVariableDeclarationList(); |
| 5944 } else { | 5943 } else { |
| 5945 initializer = ParseExpr(kAllowConst, kConsumeCascades); | 5944 initializer = ParseExpr(kAllowConst, kConsumeCascades); |
| 5946 } | 5945 } |
| 5947 } | 5946 } |
| 5948 ExpectSemicolon(); | 5947 ExpectSemicolon(); |
| 5949 AstNode* condition = NULL; | 5948 AstNode* condition = NULL; |
| 5950 if (CurrentToken() != Token::kSEMICOLON) { | 5949 if (CurrentToken() != Token::kSEMICOLON) { |
| 5951 condition = ParseExpr(kAllowConst, kConsumeCascades); | 5950 condition = ParseExpr(kAllowConst, kConsumeCascades); |
| 5952 } | 5951 } |
| 5953 ExpectSemicolon(); | 5952 ExpectSemicolon(); |
| 5954 AstNode* increment = NULL; | 5953 AstNode* increment = NULL; |
| 5955 const intptr_t incr_pos = TokenPos(); | 5954 const intptr_t incr_pos = TokenPos(); |
| 5956 LocalScope* incr_scope = current_block_->scope; | |
| 5957 if (CurrentToken() != Token::kRPAREN) { | 5955 if (CurrentToken() != Token::kRPAREN) { |
| 5958 increment = ParseExprList(); | 5956 increment = ParseExprList(); |
| 5959 } | 5957 } |
| 5960 ExpectToken(Token::kRPAREN); | 5958 ExpectToken(Token::kRPAREN); |
| 5961 const bool parsing_loop_body = true; | 5959 const bool parsing_loop_body = true; |
| 5962 SequenceNode* body = ParseNestedStatement(parsing_loop_body, NULL); | 5960 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); |
| 5963 | 5961 |
| 5964 // Check whether any of the variables in the initializer part of | 5962 // Check whether any of the variables in the initializer part of |
| 5965 // the for statement are captured by a closure. If so, we insert a | 5963 // the for statement are captured by a closure. If so, we insert a |
| 5966 // node that creates a new Context for the loop variable before | 5964 // node that creates a new Context for the loop variable before |
| 5967 // the increment expression is evaluated. | 5965 // the increment expression is evaluated. |
| 5968 for (int i = 0; i < init_scope->num_variables(); i++) { | 5966 for (int i = 0; i < init_scope->num_variables(); i++) { |
| 5969 if (init_scope->VariableAt(i)->is_captured() && | 5967 if (init_scope->VariableAt(i)->is_captured() && |
| 5970 (init_scope->VariableAt(i)->owner() == init_scope)) { | 5968 (init_scope->VariableAt(i)->owner() == init_scope)) { |
| 5971 SequenceNode* incr_sequence = new SequenceNode(incr_pos, incr_scope); | 5969 SequenceNode* incr_sequence = new SequenceNode(incr_pos, NULL); |
| 5972 incr_sequence->Add(new CloneContextNode(for_pos)); | 5970 incr_sequence->Add(new CloneContextNode(for_pos)); |
| 5973 if (increment != NULL) { | 5971 if (increment != NULL) { |
| 5974 incr_sequence->Add(increment); | 5972 incr_sequence->Add(increment); |
| 5975 } | 5973 } |
| 5976 increment = incr_sequence; | 5974 increment = incr_sequence; |
| 5977 break; | 5975 break; |
| 5978 } | 5976 } |
| 5979 } | 5977 } |
| 5980 CloseBlock(); | 5978 AstNode* for_node = |
| 5981 return new ForNode(for_pos, | 5979 new ForNode(for_pos, |
| 5982 label, | 5980 label, |
| 5983 NodeAsSequenceNode(init_pos, initializer, init_scope), | 5981 NodeAsSequenceNode(init_pos, initializer, NULL), |
| 5984 condition, | 5982 condition, |
| 5985 NodeAsSequenceNode(incr_pos, increment, incr_scope), | 5983 NodeAsSequenceNode(incr_pos, increment, NULL), |
| 5986 body); | 5984 body); |
| 5985 current_block_->statements->Add(for_node); |
| 5986 return CloseBlock(); |
| 5987 } | 5987 } |
| 5988 | 5988 |
| 5989 | 5989 |
| 5990 // Calling VM-internal helpers, uses implementation core library. | 5990 // Calling VM-internal helpers, uses implementation core library. |
| 5991 AstNode* Parser::MakeStaticCall(const String& cls_name, | 5991 AstNode* Parser::MakeStaticCall(const String& cls_name, |
| 5992 const String& func_name, | 5992 const String& func_name, |
| 5993 ArgumentListNode* arguments) { | 5993 ArgumentListNode* arguments) { |
| 5994 const Class& cls = Class::Handle(LookupCoreClass(cls_name)); | 5994 const Class& cls = Class::Handle(LookupCoreClass(cls_name)); |
| 5995 ASSERT(!cls.IsNull()); | 5995 ASSERT(!cls.IsNull()); |
| 5996 const Function& func = Function::ZoneHandle( | 5996 const Function& func = Function::ZoneHandle( |
| (...skipping 4067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10064 void Parser::SkipQualIdent() { | 10064 void Parser::SkipQualIdent() { |
| 10065 ASSERT(IsIdentifier()); | 10065 ASSERT(IsIdentifier()); |
| 10066 ConsumeToken(); | 10066 ConsumeToken(); |
| 10067 if (CurrentToken() == Token::kPERIOD) { | 10067 if (CurrentToken() == Token::kPERIOD) { |
| 10068 ConsumeToken(); // Consume the kPERIOD token. | 10068 ConsumeToken(); // Consume the kPERIOD token. |
| 10069 ExpectIdentifier("identifier expected after '.'"); | 10069 ExpectIdentifier("identifier expected after '.'"); |
| 10070 } | 10070 } |
| 10071 } | 10071 } |
| 10072 | 10072 |
| 10073 } // namespace dart | 10073 } // namespace dart |
| OLD | NEW |