Chromium Code Reviews| 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) { | |
|
hausner
2014/09/04 16:30:58
I don't understand this. If preamble is not NULL,
Michael Lippautz (Google)
2014/09/04 17:07:38
There's no need anymore as this was a leftover. Do
| |
| 6071 SequenceNode* sequence = NodeAsSequenceNode(initializers->token_pos(), | |
| 6072 preamble, | |
| 6073 NULL); | |
| 6074 sequence->Add(initializers); | |
| 6075 initializers = sequence; | |
| 6076 } | |
| 6066 while (CurrentToken() == Token::kCOMMA) { | 6077 while (CurrentToken() == Token::kCOMMA) { |
| 6067 ConsumeToken(); | 6078 ConsumeToken(); |
| 6068 if (!IsIdentifier()) { | 6079 if (!IsIdentifier()) { |
| 6069 ReportError("identifier expected after comma"); | 6080 ReportError("identifier expected after comma"); |
| 6070 } | 6081 } |
| 6071 // We have a second initializer. Allocate a sequence node now. | 6082 // 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. | 6083 // The sequence does not own the current scope. Set its own scope to NULL. |
| 6073 SequenceNode* sequence = NodeAsSequenceNode(initializers->token_pos(), | 6084 SequenceNode* sequence = NodeAsSequenceNode(initializers->token_pos(), |
| 6074 initializers, | 6085 initializers, |
| 6075 NULL); | 6086 NULL); |
| 6076 sequence->Add(ParseVariableDeclaration(type, is_final, is_const)); | 6087 preamble = NULL; |
| 6088 AstNode* declaration = ParseVariableDeclaration( | |
| 6089 type, is_final, is_const, &preamble); | |
| 6090 if (preamble != NULL) { | |
| 6091 sequence->Add(preamble); | |
| 6092 } | |
| 6093 sequence->Add(declaration); | |
| 6077 initializers = sequence; | 6094 initializers = sequence; |
| 6078 } | 6095 } |
| 6079 return initializers; | 6096 return initializers; |
| 6080 } | 6097 } |
| 6081 | 6098 |
| 6082 | 6099 |
| 6083 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 6100 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
| 6084 TRACE_PARSER("ParseFunctionStatement"); | 6101 TRACE_PARSER("ParseFunctionStatement"); |
| 6085 AbstractType& result_type = AbstractType::Handle(I); | 6102 AbstractType& result_type = AbstractType::Handle(I); |
| 6086 const String* variable_name = NULL; | 6103 const String* variable_name = NULL; |
| (...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7028 ClassFinalizer::kIgnore)); | 7045 ClassFinalizer::kIgnore)); |
| 7029 loop_var_pos = TokenPos(); | 7046 loop_var_pos = TokenPos(); |
| 7030 loop_var_name = ExpectIdentifier("variable name expected"); | 7047 loop_var_name = ExpectIdentifier("variable name expected"); |
| 7031 loop_var = new(I) LocalVariable(loop_var_pos, *loop_var_name, type); | 7048 loop_var = new(I) LocalVariable(loop_var_pos, *loop_var_name, type); |
| 7032 if (is_final) { | 7049 if (is_final) { |
| 7033 loop_var->set_is_final(); | 7050 loop_var->set_is_final(); |
| 7034 } | 7051 } |
| 7035 } | 7052 } |
| 7036 ExpectToken(Token::kIN); | 7053 ExpectToken(Token::kIN); |
| 7037 const intptr_t collection_pos = TokenPos(); | 7054 const intptr_t collection_pos = TokenPos(); |
| 7038 AstNode* collection_expr = ParseExpr(kAllowConst, kConsumeCascades); | 7055 AstNode* collection_expr = |
| 7056 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | |
| 7039 ExpectToken(Token::kRPAREN); | 7057 ExpectToken(Token::kRPAREN); |
| 7040 | 7058 |
| 7041 OpenBlock(); // Implicit block around while loop. | 7059 OpenBlock(); // Implicit block around while loop. |
| 7042 | 7060 |
| 7043 // Generate implicit iterator variable and add to scope. | 7061 // Generate implicit iterator variable and add to scope. |
| 7044 // We could set the type of the implicit iterator variable to Iterator<T> | 7062 // 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 | 7063 // 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. | 7064 // 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 | 7065 // It is better to leave the iterator untyped and postpone the type error |
| 7048 // until the loop variable is assigned to. | 7066 // 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 | 7147 // 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. | 7148 // that we allocate a new context if the loop variable is captured. |
| 7131 OpenLoopBlock(); | 7149 OpenLoopBlock(); |
| 7132 AstNode* initializer = NULL; | 7150 AstNode* initializer = NULL; |
| 7133 const intptr_t init_pos = TokenPos(); | 7151 const intptr_t init_pos = TokenPos(); |
| 7134 LocalScope* init_scope = current_block_->scope; | 7152 LocalScope* init_scope = current_block_->scope; |
| 7135 if (CurrentToken() != Token::kSEMICOLON) { | 7153 if (CurrentToken() != Token::kSEMICOLON) { |
| 7136 if (IsVariableDeclaration()) { | 7154 if (IsVariableDeclaration()) { |
| 7137 initializer = ParseVariableDeclarationList(); | 7155 initializer = ParseVariableDeclarationList(); |
| 7138 } else { | 7156 } else { |
| 7139 initializer = ParseExpr(kAllowConst, kConsumeCascades); | 7157 initializer = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 7140 } | 7158 } |
| 7141 } | 7159 } |
| 7142 ExpectSemicolon(); | 7160 ExpectSemicolon(); |
| 7143 AstNode* condition = NULL; | 7161 AstNode* condition = NULL; |
| 7162 SequenceNode* condition_preamble = NULL; | |
| 7144 if (CurrentToken() != Token::kSEMICOLON) { | 7163 if (CurrentToken() != Token::kSEMICOLON) { |
| 7145 condition = ParseExpr(kAllowConst, kConsumeCascades); | 7164 condition = ParseAwaitableExpr( |
| 7165 kAllowConst, kConsumeCascades, &condition_preamble); | |
| 7146 } | 7166 } |
| 7147 ExpectSemicolon(); | 7167 ExpectSemicolon(); |
| 7148 AstNode* increment = NULL; | 7168 AstNode* increment = NULL; |
| 7149 const intptr_t incr_pos = TokenPos(); | 7169 const intptr_t incr_pos = TokenPos(); |
| 7150 if (CurrentToken() != Token::kRPAREN) { | 7170 if (CurrentToken() != Token::kRPAREN) { |
| 7151 increment = ParseExprList(); | 7171 increment = ParseAwaitableExprList(); |
| 7152 } | 7172 } |
| 7153 ExpectToken(Token::kRPAREN); | 7173 ExpectToken(Token::kRPAREN); |
| 7154 const bool parsing_loop_body = true; | 7174 const bool parsing_loop_body = true; |
| 7155 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); | 7175 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); |
| 7156 | 7176 |
| 7157 // Check whether any of the variables in the initializer part of | 7177 // 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 | 7178 // 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 | 7179 // node that creates a new Context for the loop variable before |
| 7160 // the increment expression is evaluated. | 7180 // the increment expression is evaluated. |
| 7161 for (int i = 0; i < init_scope->num_variables(); i++) { | 7181 for (int i = 0; i < init_scope->num_variables(); i++) { |
| 7162 if (init_scope->VariableAt(i)->is_captured() && | 7182 if (init_scope->VariableAt(i)->is_captured() && |
| 7163 (init_scope->VariableAt(i)->owner() == init_scope)) { | 7183 (init_scope->VariableAt(i)->owner() == init_scope)) { |
| 7164 SequenceNode* incr_sequence = new(I) SequenceNode(incr_pos, NULL); | 7184 SequenceNode* incr_sequence = new(I) SequenceNode(incr_pos, NULL); |
| 7165 incr_sequence->Add(new(I) CloneContextNode(for_pos)); | 7185 incr_sequence->Add(new(I) CloneContextNode(for_pos)); |
| 7166 if (increment != NULL) { | 7186 if (increment != NULL) { |
| 7167 incr_sequence->Add(increment); | 7187 incr_sequence->Add(increment); |
| 7168 } | 7188 } |
| 7169 increment = incr_sequence; | 7189 increment = incr_sequence; |
| 7170 break; | 7190 break; |
| 7171 } | 7191 } |
| 7172 } | 7192 } |
| 7173 AstNode* for_node = new(I) ForNode( | 7193 AstNode* for_node = new(I) ForNode( |
| 7174 for_pos, | 7194 for_pos, |
| 7175 label, | 7195 label, |
| 7176 NodeAsSequenceNode(init_pos, initializer, NULL), | 7196 NodeAsSequenceNode(init_pos, initializer, NULL), |
| 7177 condition, | 7197 condition, |
| 7198 condition_preamble, | |
| 7178 NodeAsSequenceNode(incr_pos, increment, NULL), | 7199 NodeAsSequenceNode(incr_pos, increment, NULL), |
| 7179 body); | 7200 body); |
| 7180 current_block_->statements->Add(for_node); | 7201 current_block_->statements->Add(for_node); |
| 7181 return CloseBlock(); | 7202 return CloseBlock(); |
| 7182 } | 7203 } |
| 7183 | 7204 |
| 7184 | 7205 |
| 7185 // Calling VM-internal helpers, uses implementation core library. | 7206 // Calling VM-internal helpers, uses implementation core library. |
| 7186 AstNode* Parser::MakeStaticCall(const String& cls_name, | 7207 AstNode* Parser::MakeStaticCall(const String& cls_name, |
| 7187 const String& func_name, | 7208 const String& func_name, |
| (...skipping 1067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8255 left_operand = OptimizeBinaryOpNode( | 8276 left_operand = OptimizeBinaryOpNode( |
| 8256 op_pos, op_kind, left_operand, right_operand); | 8277 op_pos, op_kind, left_operand, right_operand); |
| 8257 } | 8278 } |
| 8258 } | 8279 } |
| 8259 current_preced--; | 8280 current_preced--; |
| 8260 } | 8281 } |
| 8261 return left_operand; | 8282 return left_operand; |
| 8262 } | 8283 } |
| 8263 | 8284 |
| 8264 | 8285 |
| 8265 AstNode* Parser::ParseExprList() { | 8286 AstNode* Parser::ParseAwaitableExprList() { |
| 8266 TRACE_PARSER("ParseExprList"); | 8287 TRACE_PARSER("ParseAwaitableExprList"); |
| 8267 AstNode* expressions = ParseExpr(kAllowConst, kConsumeCascades); | 8288 SequenceNode* preamble = NULL; |
| 8289 AstNode* expressions = ParseAwaitableExpr( | |
| 8290 kAllowConst, kConsumeCascades, &preamble); | |
| 8291 if (preamble != NULL) { | |
|
hausner
2014/09/04 16:30:58
Ditto.
Michael Lippautz (Google)
2014/09/04 17:07:38
Done.
| |
| 8292 SequenceNode* sequence = NodeAsSequenceNode( | |
| 8293 expressions->token_pos(), preamble, NULL); | |
| 8294 sequence->Add(expressions); | |
| 8295 expressions = sequence; | |
| 8296 } | |
| 8268 if (CurrentToken() == Token::kCOMMA) { | 8297 if (CurrentToken() == Token::kCOMMA) { |
| 8269 // Collect comma-separated expressions in a non scope owning sequence node. | 8298 // Collect comma-separated expressions in a non scope owning sequence node. |
| 8270 SequenceNode* list = new(I) SequenceNode(TokenPos(), NULL); | 8299 SequenceNode* list = new(I) SequenceNode(TokenPos(), NULL); |
| 8271 list->Add(expressions); | 8300 list->Add(expressions); |
| 8272 while (CurrentToken() == Token::kCOMMA) { | 8301 while (CurrentToken() == Token::kCOMMA) { |
| 8273 ConsumeToken(); | 8302 ConsumeToken(); |
| 8274 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 8303 preamble = NULL; |
| 8304 AstNode* expr = ParseAwaitableExpr( | |
| 8305 kAllowConst, kConsumeCascades, &preamble); | |
| 8306 if (preamble != NULL) { | |
| 8307 list->Add(preamble); | |
| 8308 } | |
| 8275 list->Add(expr); | 8309 list->Add(expr); |
| 8276 } | 8310 } |
| 8277 expressions = list; | 8311 expressions = list; |
| 8278 } | 8312 } |
| 8279 return expressions; | 8313 return expressions; |
| 8280 } | 8314 } |
| 8281 | 8315 |
| 8282 | 8316 |
| 8283 void Parser::EnsureExpressionTemp() { | 8317 void Parser::EnsureExpressionTemp() { |
| 8284 // Temporary used later by the flow_graph_builder. | 8318 // Temporary used later by the flow_graph_builder. |
| (...skipping 3255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11540 void Parser::SkipQualIdent() { | 11574 void Parser::SkipQualIdent() { |
| 11541 ASSERT(IsIdentifier()); | 11575 ASSERT(IsIdentifier()); |
| 11542 ConsumeToken(); | 11576 ConsumeToken(); |
| 11543 if (CurrentToken() == Token::kPERIOD) { | 11577 if (CurrentToken() == Token::kPERIOD) { |
| 11544 ConsumeToken(); // Consume the kPERIOD token. | 11578 ConsumeToken(); // Consume the kPERIOD token. |
| 11545 ExpectIdentifier("identifier expected after '.'"); | 11579 ExpectIdentifier("identifier expected after '.'"); |
| 11546 } | 11580 } |
| 11547 } | 11581 } |
| 11548 | 11582 |
| 11549 } // namespace dart | 11583 } // namespace dart |
| OLD | NEW |