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 "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 1681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1692 // The temporary variables are necessary so that the argument | 1692 // The temporary variables are necessary so that the argument |
| 1693 // expressions are not evaluated twice. | 1693 // expressions are not evaluated twice. |
| 1694 ArgumentListNode* ctor_args = super_call->arguments(); | 1694 ArgumentListNode* ctor_args = super_call->arguments(); |
| 1695 // The super initializer call has at least 2 arguments: the | 1695 // The super initializer call has at least 2 arguments: the |
| 1696 // implicit receiver, and the hidden construction phase. | 1696 // implicit receiver, and the hidden construction phase. |
| 1697 ASSERT(ctor_args->length() >= 2); | 1697 ASSERT(ctor_args->length() >= 2); |
| 1698 for (int i = 2; i < ctor_args->length(); i++) { | 1698 for (int i = 2; i < ctor_args->length(); i++) { |
| 1699 AstNode* arg = ctor_args->NodeAt(i); | 1699 AstNode* arg = ctor_args->NodeAt(i); |
| 1700 if (!arg->IsLoadLocalNode() && !arg->IsLiteralNode()) { | 1700 if (!arg->IsLoadLocalNode() && !arg->IsLiteralNode()) { |
| 1701 LocalVariable* temp = | 1701 LocalVariable* temp = |
| 1702 CreateTempConstVariable(arg->token_index(), arg->id(), "sca"); | 1702 CreateTempConstVariable(arg->token_index(), arg->id(), "sca"); |
| 1703 AstNode* save_temp = | 1703 AstNode* save_temp = |
| 1704 new StoreLocalNode(arg->token_index(), *temp, arg); | 1704 new StoreLocalNode(arg->token_index(), *temp, arg); |
| 1705 ctor_args->SetNodeAt(i, save_temp); | 1705 ctor_args->SetNodeAt(i, save_temp); |
| 1706 } | 1706 } |
| 1707 } | 1707 } |
| 1708 } | 1708 } |
| 1709 OpenBlock(); // Block to collect constructor body nodes. | 1709 OpenBlock(); // Block to collect constructor body nodes. |
| 1710 | 1710 |
| 1711 // Insert the implicit super call to the super constructor body. | 1711 // Insert the implicit super call to the super constructor body. |
| 1712 if (super_call != NULL) { | 1712 if (super_call != NULL) { |
| 1713 ArgumentListNode* initializer_args = super_call->arguments(); | 1713 ArgumentListNode* initializer_args = super_call->arguments(); |
| 1714 const Function& super_ctor = super_call->function(); | 1714 const Function& super_ctor = super_call->function(); |
| (...skipping 2459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4174 } | 4174 } |
| 4175 | 4175 |
| 4176 | 4176 |
| 4177 void Parser::ParseStatementSequence() { | 4177 void Parser::ParseStatementSequence() { |
| 4178 TRACE_PARSER("ParseStatementSequence"); | 4178 TRACE_PARSER("ParseStatementSequence"); |
| 4179 const bool dead_code_allowed = true; | 4179 const bool dead_code_allowed = true; |
| 4180 bool abrupt_completing_seen = false; | 4180 bool abrupt_completing_seen = false; |
| 4181 while (CurrentToken() != Token::kRBRACE) { | 4181 while (CurrentToken() != Token::kRBRACE) { |
| 4182 const intptr_t statement_pos = token_index_; | 4182 const intptr_t statement_pos = token_index_; |
| 4183 AstNode* statement = ParseStatement(); | 4183 AstNode* statement = ParseStatement(); |
| 4184 if (statement != NULL) { | 4184 // Do not add statements with no effect (e.g., LoadLocalNode). |
| 4185 if (statement != NULL && !statement->IsLoadLocalNode()) { | |
| 4185 if (!dead_code_allowed && abrupt_completing_seen) { | 4186 if (!dead_code_allowed && abrupt_completing_seen) { |
| 4186 ErrorMsg(statement_pos, "dead code after abrupt completing statement"); | 4187 ErrorMsg(statement_pos, "dead code after abrupt completing statement"); |
| 4187 } | 4188 } |
| 4188 current_block_->statements->Add(statement); | 4189 current_block_->statements->Add(statement); |
| 4189 abrupt_completing_seen |= IsAbruptCompleting(statement); | 4190 abrupt_completing_seen |= IsAbruptCompleting(statement); |
| 4190 } | 4191 } |
| 4191 } | 4192 } |
| 4192 } | 4193 } |
| 4193 | 4194 |
| 4194 | 4195 |
| (...skipping 1652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5847 } else { | 5848 } else { |
| 5848 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); | 5849 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); |
| 5849 } | 5850 } |
| 5850 } else if (IsIncrementOperator(CurrentToken())) { | 5851 } else if (IsIncrementOperator(CurrentToken())) { |
| 5851 Token::Kind incr_op = CurrentToken(); | 5852 Token::Kind incr_op = CurrentToken(); |
| 5852 ConsumeToken(); | 5853 ConsumeToken(); |
| 5853 expr = ParseUnaryExpr(); | 5854 expr = ParseUnaryExpr(); |
| 5854 if (!IsAssignableExpr(expr)) { | 5855 if (!IsAssignableExpr(expr)) { |
| 5855 ErrorMsg("expression is not assignable"); | 5856 ErrorMsg("expression is not assignable"); |
| 5856 } | 5857 } |
| 5857 // is_prefix. | 5858 // TODO(srdjan): Implement transformation for all. |
| 5858 AstNode* incr_op_node = expr->MakeIncrOpNode(op_pos, incr_op, true); | 5859 if (expr->IsLoadStaticFieldNode() || expr->IsStaticGetterNode()) { |
| 5859 if (incr_op_node == NULL) { | 5860 LocalVariable* temp = |
|
hausner
2012/03/06 23:44:13
I'm not sure why we need a temp variable at all. I
srdjan
2012/03/07 00:19:28
That is correct. Changed.
| |
| 5860 Unimplemented("incr operation not implemented"); | 5861 CreateTempConstVariable(op_pos, expr->id(), "incoplix"); |
| 5862 AstNode* save = | |
| 5863 new StoreLocalNode(op_pos, *temp, expr); | |
| 5864 current_block_->statements->Add(save); | |
| 5865 LoadLocalNode* load = new LoadLocalNode(op_pos, *temp); | |
| 5866 Token::Kind binary_op = | |
| 5867 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | |
| 5868 BinaryOpNode* add = new BinaryOpNode( | |
| 5869 op_pos, | |
| 5870 binary_op, | |
| 5871 load, | |
| 5872 new LiteralNode(op_pos, Smi::ZoneHandle(Smi::New(1)))); | |
| 5873 AstNode* store = expr->MakeAssignmentNode(add); | |
| 5874 expr = store; | |
| 5875 } else { | |
| 5876 // is_prefix. | |
| 5877 AstNode* incr_op_node = expr->MakeIncrOpNode(op_pos, incr_op, true); | |
| 5878 if (incr_op_node == NULL) { | |
| 5879 Unimplemented("incr operation not implemented"); | |
| 5880 } | |
| 5881 expr = incr_op_node; | |
| 5861 } | 5882 } |
| 5862 expr = incr_op_node; | |
| 5863 } else { | 5883 } else { |
| 5864 expr = ParsePostfixExpr(); | 5884 expr = ParsePostfixExpr(); |
| 5865 } | 5885 } |
| 5866 return expr; | 5886 return expr; |
| 5867 } | 5887 } |
| 5868 | 5888 |
| 5869 | 5889 |
| 5870 ArgumentListNode* Parser::ParseActualParameters( | 5890 ArgumentListNode* Parser::ParseActualParameters( |
| 5871 ArgumentListNode* implicit_arguments, | 5891 ArgumentListNode* implicit_arguments, |
| 5872 bool require_const) { | 5892 bool require_const) { |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6317 postfix_expr = selector; | 6337 postfix_expr = selector; |
| 6318 } | 6338 } |
| 6319 if (IsIncrementOperator(CurrentToken())) { | 6339 if (IsIncrementOperator(CurrentToken())) { |
| 6320 TRACE_PARSER("IncrementOperator"); | 6340 TRACE_PARSER("IncrementOperator"); |
| 6321 Token::Kind incr_op = CurrentToken(); | 6341 Token::Kind incr_op = CurrentToken(); |
| 6322 if (!IsAssignableExpr(postfix_expr)) { | 6342 if (!IsAssignableExpr(postfix_expr)) { |
| 6323 ErrorMsg("expression is not assignable"); | 6343 ErrorMsg("expression is not assignable"); |
| 6324 } | 6344 } |
| 6325 ConsumeToken(); | 6345 ConsumeToken(); |
| 6326 // Not prefix. | 6346 // Not prefix. |
| 6327 AstNode* incr_op_node = | 6347 if (postfix_expr->IsLoadStaticFieldNode() || |
| 6328 postfix_expr->MakeIncrOpNode(postfix_expr_pos, incr_op, false); | 6348 postfix_expr->IsStaticGetterNode()) { |
| 6329 if (incr_op_node == NULL) { | 6349 LocalVariable* temp = CreateTempConstVariable( |
| 6330 Unimplemented("incr op not implemented"); | 6350 postfix_expr_pos, postfix_expr->id(), "incoplix"); |
| 6351 AstNode* save = | |
| 6352 new StoreLocalNode(postfix_expr_pos, *temp, postfix_expr); | |
| 6353 current_block_->statements->Add(save); | |
| 6354 LoadLocalNode* load = new LoadLocalNode(postfix_expr_pos, *temp); | |
| 6355 Token::Kind binary_op = | |
| 6356 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | |
| 6357 BinaryOpNode* add = new BinaryOpNode( | |
| 6358 postfix_expr_pos, | |
| 6359 binary_op, | |
| 6360 load, | |
| 6361 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1)))); | |
| 6362 AstNode* store = postfix_expr->MakeAssignmentNode(add); | |
| 6363 current_block_->statements->Add(store); | |
| 6364 LoadLocalNode* load_res = new LoadLocalNode(postfix_expr_pos, *temp); | |
| 6365 return load_res; | |
| 6366 } else { | |
| 6367 AstNode* incr_op_node = | |
| 6368 postfix_expr->MakeIncrOpNode(postfix_expr_pos, incr_op, false); | |
| 6369 if (incr_op_node == NULL) { | |
| 6370 Unimplemented("incr op not implemented"); | |
| 6371 } | |
| 6372 postfix_expr = incr_op_node; | |
| 6331 } | 6373 } |
| 6332 postfix_expr = incr_op_node; | |
| 6333 } | 6374 } |
| 6334 return postfix_expr; | 6375 return postfix_expr; |
| 6335 } | 6376 } |
| 6336 | 6377 |
| 6337 | 6378 |
| 6338 // Resolve the given type and its type arguments from the given scope class | 6379 // Resolve the given type and its type arguments from the given scope class |
| 6339 // according to the given type finalization mode. | 6380 // according to the given type finalization mode. |
| 6340 // If the given scope class is null, use the current library, but do not try to | 6381 // If the given scope class is null, use the current library, but do not try to |
| 6341 // resolve type parameters. | 6382 // resolve type parameters. |
| 6342 // Not all involved type classes may get resolved yet, but at least the type | 6383 // Not all involved type classes may get resolved yet, but at least the type |
| (...skipping 1711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8054 void Parser::SkipQualIdent() { | 8095 void Parser::SkipQualIdent() { |
| 8055 ASSERT(IsIdentifier()); | 8096 ASSERT(IsIdentifier()); |
| 8056 ConsumeToken(); | 8097 ConsumeToken(); |
| 8057 if (CurrentToken() == Token::kPERIOD) { | 8098 if (CurrentToken() == Token::kPERIOD) { |
| 8058 ConsumeToken(); // Consume the kPERIOD token. | 8099 ConsumeToken(); // Consume the kPERIOD token. |
| 8059 ExpectIdentifier("identifier expected after '.'"); | 8100 ExpectIdentifier("identifier expected after '.'"); |
| 8060 } | 8101 } |
| 8061 } | 8102 } |
| 8062 | 8103 |
| 8063 } // namespace dart | 8104 } // namespace dart |
| OLD | NEW |