| 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 5917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5928 AstNode* Parser::CallGetter(intptr_t token_pos, | 5928 AstNode* Parser::CallGetter(intptr_t token_pos, |
| 5929 AstNode* object, | 5929 AstNode* object, |
| 5930 const String& name) { | 5930 const String& name) { |
| 5931 return new(I) InstanceGetterNode(token_pos, object, name); | 5931 return new(I) InstanceGetterNode(token_pos, object, name); |
| 5932 } | 5932 } |
| 5933 | 5933 |
| 5934 | 5934 |
| 5935 // Returns ast nodes of the variable initialization. | 5935 // Returns ast nodes of the variable initialization. |
| 5936 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, | 5936 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, |
| 5937 bool is_final, | 5937 bool is_final, |
| 5938 bool is_const) { | 5938 bool is_const, |
| 5939 SequenceNode** await_preamble) { |
| 5939 TRACE_PARSER("ParseVariableDeclaration"); | 5940 TRACE_PARSER("ParseVariableDeclaration"); |
| 5940 ASSERT(IsIdentifier()); | 5941 ASSERT(IsIdentifier()); |
| 5941 const intptr_t ident_pos = TokenPos(); | 5942 const intptr_t ident_pos = TokenPos(); |
| 5942 const String& ident = *CurrentLiteral(); | 5943 const String& ident = *CurrentLiteral(); |
| 5943 LocalVariable* variable = new(I) LocalVariable( | 5944 LocalVariable* variable = new(I) LocalVariable( |
| 5944 ident_pos, ident, type); | 5945 ident_pos, ident, type); |
| 5945 ConsumeToken(); // Variable identifier. | 5946 ConsumeToken(); // Variable identifier. |
| 5946 AstNode* initialization = NULL; | 5947 AstNode* initialization = NULL; |
| 5947 if (CurrentToken() == Token::kASSIGN) { | 5948 if (CurrentToken() == Token::kASSIGN) { |
| 5948 // Variable initialization. | 5949 // Variable initialization. |
| 5949 const intptr_t assign_pos = TokenPos(); | 5950 const intptr_t assign_pos = TokenPos(); |
| 5950 ConsumeToken(); | 5951 ConsumeToken(); |
| 5951 AstNode* expr = ParseAwaitableExpr(is_const, kConsumeCascades, NULL); | 5952 AstNode* expr = ParseAwaitableExpr( |
| 5953 is_const, kConsumeCascades, await_preamble); |
| 5952 initialization = new(I) StoreLocalNode( | 5954 initialization = new(I) StoreLocalNode( |
| 5953 assign_pos, variable, expr); | 5955 assign_pos, variable, expr); |
| 5954 if (is_const) { | 5956 if (is_const) { |
| 5955 ASSERT(expr->IsLiteralNode()); | 5957 ASSERT(expr->IsLiteralNode()); |
| 5956 variable->SetConstValue(expr->AsLiteralNode()->literal()); | 5958 variable->SetConstValue(expr->AsLiteralNode()->literal()); |
| 5957 } | 5959 } |
| 5958 } else if (is_final || is_const) { | 5960 } else if (is_final || is_const) { |
| 5959 ReportError(ident_pos, | 5961 ReportError(ident_pos, |
| 5960 "missing initialization of 'final' or 'const' variable"); | 5962 "missing initialization of 'final' or 'const' variable"); |
| 5961 } else { | 5963 } else { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6054 SkipMetadata(); | 6056 SkipMetadata(); |
| 6055 bool is_final = (CurrentToken() == Token::kFINAL); | 6057 bool is_final = (CurrentToken() == Token::kFINAL); |
| 6056 bool is_const = (CurrentToken() == Token::kCONST); | 6058 bool is_const = (CurrentToken() == Token::kCONST); |
| 6057 const AbstractType& type = AbstractType::ZoneHandle(I, | 6059 const AbstractType& type = AbstractType::ZoneHandle(I, |
| 6058 ParseConstFinalVarOrType(FLAG_enable_type_checks ? | 6060 ParseConstFinalVarOrType(FLAG_enable_type_checks ? |
| 6059 ClassFinalizer::kCanonicalize : ClassFinalizer::kIgnore)); | 6061 ClassFinalizer::kCanonicalize : ClassFinalizer::kIgnore)); |
| 6060 if (!IsIdentifier()) { | 6062 if (!IsIdentifier()) { |
| 6061 ReportError("identifier expected"); | 6063 ReportError("identifier expected"); |
| 6062 } | 6064 } |
| 6063 | 6065 |
| 6064 AstNode* initializers = ParseVariableDeclaration(type, is_final, is_const); | 6066 SequenceNode* preamble = NULL; |
| 6067 AstNode* initializers = |
| 6068 ParseVariableDeclaration(type, is_final, is_const, &preamble); |
| 6065 ASSERT(initializers != NULL); | 6069 ASSERT(initializers != NULL); |
| 6070 if (preamble != NULL) { |
| 6071 preamble->Add(initializers); |
| 6072 initializers = preamble; |
| 6073 } |
| 6066 while (CurrentToken() == Token::kCOMMA) { | 6074 while (CurrentToken() == Token::kCOMMA) { |
| 6067 ConsumeToken(); | 6075 ConsumeToken(); |
| 6068 if (!IsIdentifier()) { | 6076 if (!IsIdentifier()) { |
| 6069 ReportError("identifier expected after comma"); | 6077 ReportError("identifier expected after comma"); |
| 6070 } | 6078 } |
| 6071 // We have a second initializer. Allocate a sequence node now. | 6079 // We have a second initializer. Allocate a sequence node now. |
| 6072 // The sequence does not own the current scope. Set its own scope to NULL. | 6080 // The sequence does not own the current scope. Set its own scope to NULL. |
| 6073 SequenceNode* sequence = NodeAsSequenceNode(initializers->token_pos(), | 6081 SequenceNode* sequence = NodeAsSequenceNode(initializers->token_pos(), |
| 6074 initializers, | 6082 initializers, |
| 6075 NULL); | 6083 NULL); |
| 6076 sequence->Add(ParseVariableDeclaration(type, is_final, is_const)); | 6084 preamble = NULL; |
| 6085 AstNode* declaration = ParseVariableDeclaration( |
| 6086 type, is_final, is_const, &preamble); |
| 6087 if (preamble != NULL) { |
| 6088 sequence->Add(preamble); |
| 6089 } |
| 6090 sequence->Add(declaration); |
| 6077 initializers = sequence; | 6091 initializers = sequence; |
| 6078 } | 6092 } |
| 6079 return initializers; | 6093 return initializers; |
| 6080 } | 6094 } |
| 6081 | 6095 |
| 6082 | 6096 |
| 6083 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 6097 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
| 6084 TRACE_PARSER("ParseFunctionStatement"); | 6098 TRACE_PARSER("ParseFunctionStatement"); |
| 6085 AbstractType& result_type = AbstractType::Handle(I); | 6099 AbstractType& result_type = AbstractType::Handle(I); |
| 6086 const String* variable_name = NULL; | 6100 const String* variable_name = NULL; |
| (...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7028 ClassFinalizer::kIgnore)); | 7042 ClassFinalizer::kIgnore)); |
| 7029 loop_var_pos = TokenPos(); | 7043 loop_var_pos = TokenPos(); |
| 7030 loop_var_name = ExpectIdentifier("variable name expected"); | 7044 loop_var_name = ExpectIdentifier("variable name expected"); |
| 7031 loop_var = new(I) LocalVariable(loop_var_pos, *loop_var_name, type); | 7045 loop_var = new(I) LocalVariable(loop_var_pos, *loop_var_name, type); |
| 7032 if (is_final) { | 7046 if (is_final) { |
| 7033 loop_var->set_is_final(); | 7047 loop_var->set_is_final(); |
| 7034 } | 7048 } |
| 7035 } | 7049 } |
| 7036 ExpectToken(Token::kIN); | 7050 ExpectToken(Token::kIN); |
| 7037 const intptr_t collection_pos = TokenPos(); | 7051 const intptr_t collection_pos = TokenPos(); |
| 7038 AstNode* collection_expr = ParseExpr(kAllowConst, kConsumeCascades); | 7052 AstNode* collection_expr = |
| 7053 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 7039 ExpectToken(Token::kRPAREN); | 7054 ExpectToken(Token::kRPAREN); |
| 7040 | 7055 |
| 7041 OpenBlock(); // Implicit block around while loop. | 7056 OpenBlock(); // Implicit block around while loop. |
| 7042 | 7057 |
| 7043 // Generate implicit iterator variable and add to scope. | 7058 // Generate implicit iterator variable and add to scope. |
| 7044 // We could set the type of the implicit iterator variable to Iterator<T> | 7059 // We could set the type of the implicit iterator variable to Iterator<T> |
| 7045 // where T is the type of the for loop variable. However, the type error | 7060 // where T is the type of the for loop variable. However, the type error |
| 7046 // would refer to the compiler generated iterator and could confuse the user. | 7061 // would refer to the compiler generated iterator and could confuse the user. |
| 7047 // It is better to leave the iterator untyped and postpone the type error | 7062 // It is better to leave the iterator untyped and postpone the type error |
| 7048 // until the loop variable is assigned to. | 7063 // until the loop variable is assigned to. |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7129 // Open a block that contains the loop variable. Make it a loop block so | 7144 // Open a block that contains the loop variable. Make it a loop block so |
| 7130 // that we allocate a new context if the loop variable is captured. | 7145 // that we allocate a new context if the loop variable is captured. |
| 7131 OpenLoopBlock(); | 7146 OpenLoopBlock(); |
| 7132 AstNode* initializer = NULL; | 7147 AstNode* initializer = NULL; |
| 7133 const intptr_t init_pos = TokenPos(); | 7148 const intptr_t init_pos = TokenPos(); |
| 7134 LocalScope* init_scope = current_block_->scope; | 7149 LocalScope* init_scope = current_block_->scope; |
| 7135 if (CurrentToken() != Token::kSEMICOLON) { | 7150 if (CurrentToken() != Token::kSEMICOLON) { |
| 7136 if (IsVariableDeclaration()) { | 7151 if (IsVariableDeclaration()) { |
| 7137 initializer = ParseVariableDeclarationList(); | 7152 initializer = ParseVariableDeclarationList(); |
| 7138 } else { | 7153 } else { |
| 7139 initializer = ParseExpr(kAllowConst, kConsumeCascades); | 7154 initializer = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 7140 } | 7155 } |
| 7141 } | 7156 } |
| 7142 ExpectSemicolon(); | 7157 ExpectSemicolon(); |
| 7143 AstNode* condition = NULL; | 7158 AstNode* condition = NULL; |
| 7159 SequenceNode* condition_preamble = NULL; |
| 7144 if (CurrentToken() != Token::kSEMICOLON) { | 7160 if (CurrentToken() != Token::kSEMICOLON) { |
| 7145 condition = ParseExpr(kAllowConst, kConsumeCascades); | 7161 condition = ParseAwaitableExpr( |
| 7162 kAllowConst, kConsumeCascades, &condition_preamble); |
| 7146 } | 7163 } |
| 7147 ExpectSemicolon(); | 7164 ExpectSemicolon(); |
| 7148 AstNode* increment = NULL; | 7165 AstNode* increment = NULL; |
| 7149 const intptr_t incr_pos = TokenPos(); | 7166 const intptr_t incr_pos = TokenPos(); |
| 7150 if (CurrentToken() != Token::kRPAREN) { | 7167 if (CurrentToken() != Token::kRPAREN) { |
| 7151 increment = ParseExprList(); | 7168 increment = ParseAwaitableExprList(); |
| 7152 } | 7169 } |
| 7153 ExpectToken(Token::kRPAREN); | 7170 ExpectToken(Token::kRPAREN); |
| 7154 const bool parsing_loop_body = true; | 7171 const bool parsing_loop_body = true; |
| 7155 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); | 7172 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); |
| 7156 | 7173 |
| 7157 // Check whether any of the variables in the initializer part of | 7174 // Check whether any of the variables in the initializer part of |
| 7158 // the for statement are captured by a closure. If so, we insert a | 7175 // the for statement are captured by a closure. If so, we insert a |
| 7159 // node that creates a new Context for the loop variable before | 7176 // node that creates a new Context for the loop variable before |
| 7160 // the increment expression is evaluated. | 7177 // the increment expression is evaluated. |
| 7161 for (int i = 0; i < init_scope->num_variables(); i++) { | 7178 for (int i = 0; i < init_scope->num_variables(); i++) { |
| 7162 if (init_scope->VariableAt(i)->is_captured() && | 7179 if (init_scope->VariableAt(i)->is_captured() && |
| 7163 (init_scope->VariableAt(i)->owner() == init_scope)) { | 7180 (init_scope->VariableAt(i)->owner() == init_scope)) { |
| 7164 SequenceNode* incr_sequence = new(I) SequenceNode(incr_pos, NULL); | 7181 SequenceNode* incr_sequence = new(I) SequenceNode(incr_pos, NULL); |
| 7165 incr_sequence->Add(new(I) CloneContextNode(for_pos)); | 7182 incr_sequence->Add(new(I) CloneContextNode(for_pos)); |
| 7166 if (increment != NULL) { | 7183 if (increment != NULL) { |
| 7167 incr_sequence->Add(increment); | 7184 incr_sequence->Add(increment); |
| 7168 } | 7185 } |
| 7169 increment = incr_sequence; | 7186 increment = incr_sequence; |
| 7170 break; | 7187 break; |
| 7171 } | 7188 } |
| 7172 } | 7189 } |
| 7173 AstNode* for_node = new(I) ForNode( | 7190 AstNode* for_node = new(I) ForNode( |
| 7174 for_pos, | 7191 for_pos, |
| 7175 label, | 7192 label, |
| 7176 NodeAsSequenceNode(init_pos, initializer, NULL), | 7193 NodeAsSequenceNode(init_pos, initializer, NULL), |
| 7177 condition, | 7194 condition, |
| 7195 condition_preamble, |
| 7178 NodeAsSequenceNode(incr_pos, increment, NULL), | 7196 NodeAsSequenceNode(incr_pos, increment, NULL), |
| 7179 body); | 7197 body); |
| 7180 current_block_->statements->Add(for_node); | 7198 current_block_->statements->Add(for_node); |
| 7181 return CloseBlock(); | 7199 return CloseBlock(); |
| 7182 } | 7200 } |
| 7183 | 7201 |
| 7184 | 7202 |
| 7185 // Calling VM-internal helpers, uses implementation core library. | 7203 // Calling VM-internal helpers, uses implementation core library. |
| 7186 AstNode* Parser::MakeStaticCall(const String& cls_name, | 7204 AstNode* Parser::MakeStaticCall(const String& cls_name, |
| 7187 const String& func_name, | 7205 const String& func_name, |
| (...skipping 1067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8255 left_operand = OptimizeBinaryOpNode( | 8273 left_operand = OptimizeBinaryOpNode( |
| 8256 op_pos, op_kind, left_operand, right_operand); | 8274 op_pos, op_kind, left_operand, right_operand); |
| 8257 } | 8275 } |
| 8258 } | 8276 } |
| 8259 current_preced--; | 8277 current_preced--; |
| 8260 } | 8278 } |
| 8261 return left_operand; | 8279 return left_operand; |
| 8262 } | 8280 } |
| 8263 | 8281 |
| 8264 | 8282 |
| 8265 AstNode* Parser::ParseExprList() { | 8283 AstNode* Parser::ParseAwaitableExprList() { |
| 8266 TRACE_PARSER("ParseExprList"); | 8284 TRACE_PARSER("ParseAwaitableExprList"); |
| 8267 AstNode* expressions = ParseExpr(kAllowConst, kConsumeCascades); | 8285 SequenceNode* preamble = NULL; |
| 8286 AstNode* expressions = ParseAwaitableExpr( |
| 8287 kAllowConst, kConsumeCascades, &preamble); |
| 8288 if (preamble != NULL) { |
| 8289 preamble->Add(expressions); |
| 8290 expressions = preamble; |
| 8291 } |
| 8268 if (CurrentToken() == Token::kCOMMA) { | 8292 if (CurrentToken() == Token::kCOMMA) { |
| 8269 // Collect comma-separated expressions in a non scope owning sequence node. | 8293 // Collect comma-separated expressions in a non scope owning sequence node. |
| 8270 SequenceNode* list = new(I) SequenceNode(TokenPos(), NULL); | 8294 SequenceNode* list = new(I) SequenceNode(TokenPos(), NULL); |
| 8271 list->Add(expressions); | 8295 list->Add(expressions); |
| 8272 while (CurrentToken() == Token::kCOMMA) { | 8296 while (CurrentToken() == Token::kCOMMA) { |
| 8273 ConsumeToken(); | 8297 ConsumeToken(); |
| 8274 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 8298 preamble = NULL; |
| 8299 AstNode* expr = ParseAwaitableExpr( |
| 8300 kAllowConst, kConsumeCascades, &preamble); |
| 8301 if (preamble != NULL) { |
| 8302 list->Add(preamble); |
| 8303 } |
| 8275 list->Add(expr); | 8304 list->Add(expr); |
| 8276 } | 8305 } |
| 8277 expressions = list; | 8306 expressions = list; |
| 8278 } | 8307 } |
| 8279 return expressions; | 8308 return expressions; |
| 8280 } | 8309 } |
| 8281 | 8310 |
| 8282 | 8311 |
| 8283 void Parser::EnsureExpressionTemp() { | 8312 void Parser::EnsureExpressionTemp() { |
| 8284 // Temporary used later by the flow_graph_builder. | 8313 // Temporary used later by the flow_graph_builder. |
| (...skipping 3250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11535 void Parser::SkipQualIdent() { | 11564 void Parser::SkipQualIdent() { |
| 11536 ASSERT(IsIdentifier()); | 11565 ASSERT(IsIdentifier()); |
| 11537 ConsumeToken(); | 11566 ConsumeToken(); |
| 11538 if (CurrentToken() == Token::kPERIOD) { | 11567 if (CurrentToken() == Token::kPERIOD) { |
| 11539 ConsumeToken(); // Consume the kPERIOD token. | 11568 ConsumeToken(); // Consume the kPERIOD token. |
| 11540 ExpectIdentifier("identifier expected after '.'"); | 11569 ExpectIdentifier("identifier expected after '.'"); |
| 11541 } | 11570 } |
| 11542 } | 11571 } |
| 11543 | 11572 |
| 11544 } // namespace dart | 11573 } // namespace dart |
| OLD | NEW |