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 5930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5941 const intptr_t ident_pos = TokenPos(); | 5941 const intptr_t ident_pos = TokenPos(); |
| 5942 const String& ident = *CurrentLiteral(); | 5942 const String& ident = *CurrentLiteral(); |
| 5943 LocalVariable* variable = new(I) LocalVariable( | 5943 LocalVariable* variable = new(I) LocalVariable( |
| 5944 ident_pos, ident, type); | 5944 ident_pos, ident, type); |
| 5945 ConsumeToken(); // Variable identifier. | 5945 ConsumeToken(); // Variable identifier. |
| 5946 AstNode* initialization = NULL; | 5946 AstNode* initialization = NULL; |
| 5947 if (CurrentToken() == Token::kASSIGN) { | 5947 if (CurrentToken() == Token::kASSIGN) { |
| 5948 // Variable initialization. | 5948 // Variable initialization. |
| 5949 const intptr_t assign_pos = TokenPos(); | 5949 const intptr_t assign_pos = TokenPos(); |
| 5950 ConsumeToken(); | 5950 ConsumeToken(); |
| 5951 AstNode* expr = ParseAwaitableExpr(is_const, kConsumeCascades); | 5951 AstNode* expr = ParseAwaitableExpr(is_const, kConsumeCascades, NULL); |
| 5952 initialization = new(I) StoreLocalNode( | 5952 initialization = new(I) StoreLocalNode( |
| 5953 assign_pos, variable, expr); | 5953 assign_pos, variable, expr); |
| 5954 if (is_const) { | 5954 if (is_const) { |
| 5955 ASSERT(expr->IsLiteralNode()); | 5955 ASSERT(expr->IsLiteralNode()); |
| 5956 variable->SetConstValue(expr->AsLiteralNode()->literal()); | 5956 variable->SetConstValue(expr->AsLiteralNode()->literal()); |
| 5957 } | 5957 } |
| 5958 } else if (is_final || is_const) { | 5958 } else if (is_final || is_const) { |
| 5959 ReportError(ident_pos, | 5959 ReportError(ident_pos, |
| 5960 "missing initialization of 'final' or 'const' variable"); | 5960 "missing initialization of 'final' or 'const' variable"); |
| 5961 } else { | 5961 } else { |
| (...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6690 ASSERT(CurrentToken() == Token::kIF); | 6690 ASSERT(CurrentToken() == Token::kIF); |
| 6691 const intptr_t if_pos = TokenPos(); | 6691 const intptr_t if_pos = TokenPos(); |
| 6692 SourceLabel* label = NULL; | 6692 SourceLabel* label = NULL; |
| 6693 if (label_name != NULL) { | 6693 if (label_name != NULL) { |
| 6694 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); | 6694 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); |
| 6695 OpenBlock(); | 6695 OpenBlock(); |
| 6696 current_block_->scope->AddLabel(label); | 6696 current_block_->scope->AddLabel(label); |
| 6697 } | 6697 } |
| 6698 ConsumeToken(); | 6698 ConsumeToken(); |
| 6699 ExpectToken(Token::kLPAREN); | 6699 ExpectToken(Token::kLPAREN); |
| 6700 AstNode* cond_expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades); | 6700 AstNode* cond_expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 6701 ExpectToken(Token::kRPAREN); | 6701 ExpectToken(Token::kRPAREN); |
| 6702 const bool parsing_loop_body = false; | 6702 const bool parsing_loop_body = false; |
| 6703 SequenceNode* true_branch = ParseNestedStatement(parsing_loop_body, NULL); | 6703 SequenceNode* true_branch = ParseNestedStatement(parsing_loop_body, NULL); |
| 6704 SequenceNode* false_branch = NULL; | 6704 SequenceNode* false_branch = NULL; |
| 6705 if (CurrentToken() == Token::kELSE) { | 6705 if (CurrentToken() == Token::kELSE) { |
| 6706 ConsumeToken(); | 6706 ConsumeToken(); |
| 6707 false_branch = ParseNestedStatement(parsing_loop_body, NULL); | 6707 false_branch = ParseNestedStatement(parsing_loop_body, NULL); |
| 6708 } | 6708 } |
| 6709 AstNode* if_node = new(I) IfNode( | 6709 AstNode* if_node = new(I) IfNode( |
| 6710 if_pos, cond_expr, true_branch, false_branch); | 6710 if_pos, cond_expr, true_branch, false_branch); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6863 | 6863 |
| 6864 AstNode* Parser::ParseSwitchStatement(String* label_name) { | 6864 AstNode* Parser::ParseSwitchStatement(String* label_name) { |
| 6865 TRACE_PARSER("ParseSwitchStatement"); | 6865 TRACE_PARSER("ParseSwitchStatement"); |
| 6866 ASSERT(CurrentToken() == Token::kSWITCH); | 6866 ASSERT(CurrentToken() == Token::kSWITCH); |
| 6867 const intptr_t switch_pos = TokenPos(); | 6867 const intptr_t switch_pos = TokenPos(); |
| 6868 SourceLabel* label = | 6868 SourceLabel* label = |
| 6869 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); | 6869 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); |
| 6870 ConsumeToken(); | 6870 ConsumeToken(); |
| 6871 ExpectToken(Token::kLPAREN); | 6871 ExpectToken(Token::kLPAREN); |
| 6872 const intptr_t expr_pos = TokenPos(); | 6872 const intptr_t expr_pos = TokenPos(); |
| 6873 AstNode* switch_expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades); | 6873 AstNode* switch_expr = ParseAwaitableExpr( |
| 6874 kAllowConst, kConsumeCascades, NULL); | |
| 6874 ExpectToken(Token::kRPAREN); | 6875 ExpectToken(Token::kRPAREN); |
| 6875 ExpectToken(Token::kLBRACE); | 6876 ExpectToken(Token::kLBRACE); |
| 6876 OpenBlock(); | 6877 OpenBlock(); |
| 6877 current_block_->scope->AddLabel(label); | 6878 current_block_->scope->AddLabel(label); |
| 6878 | 6879 |
| 6879 // Store switch expression in temporary local variable. The type of the | 6880 // Store switch expression in temporary local variable. The type of the |
| 6880 // variable is set to dynamic. It will later be patched to match the | 6881 // variable is set to dynamic. It will later be patched to match the |
| 6881 // type of the case clause expressions. Therefore, we have to allocate | 6882 // type of the case clause expressions. Therefore, we have to allocate |
| 6882 // a new type representing dynamic and can't reuse the canonical | 6883 // a new type representing dynamic and can't reuse the canonical |
| 6883 // type object for dynamic. | 6884 // type object for dynamic. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6960 } | 6961 } |
| 6961 | 6962 |
| 6962 | 6963 |
| 6963 AstNode* Parser::ParseWhileStatement(String* label_name) { | 6964 AstNode* Parser::ParseWhileStatement(String* label_name) { |
| 6964 TRACE_PARSER("ParseWhileStatement"); | 6965 TRACE_PARSER("ParseWhileStatement"); |
| 6965 const intptr_t while_pos = TokenPos(); | 6966 const intptr_t while_pos = TokenPos(); |
| 6966 SourceLabel* label = | 6967 SourceLabel* label = |
| 6967 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); | 6968 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); |
| 6968 ConsumeToken(); | 6969 ConsumeToken(); |
| 6969 ExpectToken(Token::kLPAREN); | 6970 ExpectToken(Token::kLPAREN); |
| 6970 AstNode* cond_expr = ParseExpr(kAllowConst, kConsumeCascades); | 6971 SequenceNode* await_preamble = NULL; |
| 6972 AstNode* cond_expr = ParseAwaitableExpr( | |
| 6973 kAllowConst, kConsumeCascades, &await_preamble); | |
| 6971 ExpectToken(Token::kRPAREN); | 6974 ExpectToken(Token::kRPAREN); |
| 6972 const bool parsing_loop_body = true; | 6975 const bool parsing_loop_body = true; |
| 6973 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); | 6976 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); |
| 6974 return new(I) WhileNode(while_pos, label, cond_expr, while_body); | 6977 WhileNode* while_node = |
| 6978 new (I) WhileNode(while_pos, label, cond_expr, while_body); | |
| 6979 if (await_preamble != NULL) { | |
| 6980 while_node->set_condition_preamble(await_preamble); | |
|
hausner
2014/09/03 21:37:57
Would it make sense to add the preamble to the Whi
Michael Lippautz (Google)
2014/09/03 21:49:43
Yes, done.
| |
| 6981 } | |
| 6982 return while_node; | |
| 6975 } | 6983 } |
| 6976 | 6984 |
| 6977 | 6985 |
| 6978 AstNode* Parser::ParseDoWhileStatement(String* label_name) { | 6986 AstNode* Parser::ParseDoWhileStatement(String* label_name) { |
| 6979 TRACE_PARSER("ParseDoWhileStatement"); | 6987 TRACE_PARSER("ParseDoWhileStatement"); |
| 6980 const intptr_t do_pos = TokenPos(); | 6988 const intptr_t do_pos = TokenPos(); |
| 6981 SourceLabel* label = | 6989 SourceLabel* label = |
| 6982 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); | 6990 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); |
| 6983 ConsumeToken(); | 6991 ConsumeToken(); |
| 6984 const bool parsing_loop_body = true; | 6992 const bool parsing_loop_body = true; |
| 6985 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); | 6993 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); |
| 6986 ExpectToken(Token::kWHILE); | 6994 ExpectToken(Token::kWHILE); |
| 6987 ExpectToken(Token::kLPAREN); | 6995 ExpectToken(Token::kLPAREN); |
| 6988 AstNode* cond_expr = ParseExpr(kAllowConst, kConsumeCascades); | 6996 SequenceNode* await_preamble = NULL; |
| 6997 AstNode* cond_expr = ParseAwaitableExpr( | |
| 6998 kAllowConst, kConsumeCascades, &await_preamble); | |
| 6999 // No need for special handling of the await preamble as we can just append o | |
| 7000 // it to the loop body. | |
| 7001 if (await_preamble != NULL) { | |
| 7002 dowhile_body->Add(await_preamble); | |
| 7003 } | |
| 6989 ExpectToken(Token::kRPAREN); | 7004 ExpectToken(Token::kRPAREN); |
| 6990 ExpectSemicolon(); | 7005 ExpectSemicolon(); |
| 6991 return new(I) DoWhileNode(do_pos, label, cond_expr, dowhile_body); | 7006 return new(I) DoWhileNode(do_pos, label, cond_expr, dowhile_body); |
| 6992 } | 7007 } |
| 6993 | 7008 |
| 6994 | 7009 |
| 6995 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, | 7010 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, |
| 6996 SourceLabel* label) { | 7011 SourceLabel* label) { |
| 6997 TRACE_PARSER("ParseForInStatement"); | 7012 TRACE_PARSER("ParseForInStatement"); |
| 6998 bool is_final = (CurrentToken() == Token::kFINAL); | 7013 bool is_final = (CurrentToken() == Token::kFINAL); |
| (...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7842 statement = ParseTryStatement(label_name); | 7857 statement = ParseTryStatement(label_name); |
| 7843 } else if (token == Token::kRETURN) { | 7858 } else if (token == Token::kRETURN) { |
| 7844 const intptr_t return_pos = TokenPos(); | 7859 const intptr_t return_pos = TokenPos(); |
| 7845 ConsumeToken(); | 7860 ConsumeToken(); |
| 7846 if (CurrentToken() != Token::kSEMICOLON) { | 7861 if (CurrentToken() != Token::kSEMICOLON) { |
| 7847 if (current_function().IsConstructor() && | 7862 if (current_function().IsConstructor() && |
| 7848 (current_block_->scope->function_level() == 0)) { | 7863 (current_block_->scope->function_level() == 0)) { |
| 7849 ReportError(return_pos, | 7864 ReportError(return_pos, |
| 7850 "return of a value not allowed in constructors"); | 7865 "return of a value not allowed in constructors"); |
| 7851 } | 7866 } |
| 7852 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades); | 7867 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 7853 statement = new(I) ReturnNode(statement_pos, expr); | 7868 statement = new(I) ReturnNode(statement_pos, expr); |
| 7854 } else { | 7869 } else { |
| 7855 statement = new(I) ReturnNode(statement_pos); | 7870 statement = new(I) ReturnNode(statement_pos); |
| 7856 } | 7871 } |
| 7857 AddNodeForFinallyInlining(statement); | 7872 AddNodeForFinallyInlining(statement); |
| 7858 ExpectSemicolon(); | 7873 ExpectSemicolon(); |
| 7859 } else if (token == Token::kIF) { | 7874 } else if (token == Token::kIF) { |
| 7860 statement = ParseIfStatement(label_name); | 7875 statement = ParseIfStatement(label_name); |
| 7861 } else if (token == Token::kASSERT) { | 7876 } else if (token == Token::kASSERT) { |
| 7862 statement = ParseAssertStatement(); | 7877 statement = ParseAssertStatement(); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7907 scope->LocalLookupVariable(Symbols::ExceptionVar()); | 7922 scope->LocalLookupVariable(Symbols::ExceptionVar()); |
| 7908 ASSERT(excp_var != NULL); | 7923 ASSERT(excp_var != NULL); |
| 7909 LocalVariable* trace_var = | 7924 LocalVariable* trace_var = |
| 7910 scope->LocalLookupVariable(Symbols::StackTraceVar()); | 7925 scope->LocalLookupVariable(Symbols::StackTraceVar()); |
| 7911 ASSERT(trace_var != NULL); | 7926 ASSERT(trace_var != NULL); |
| 7912 statement = new(I) ThrowNode( | 7927 statement = new(I) ThrowNode( |
| 7913 statement_pos, | 7928 statement_pos, |
| 7914 new(I) LoadLocalNode(statement_pos, excp_var), | 7929 new(I) LoadLocalNode(statement_pos, excp_var), |
| 7915 new(I) LoadLocalNode(statement_pos, trace_var)); | 7930 new(I) LoadLocalNode(statement_pos, trace_var)); |
| 7916 } else { | 7931 } else { |
| 7917 statement = ParseAwaitableExpr(kAllowConst, kConsumeCascades); | 7932 statement = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 7918 ExpectSemicolon(); | 7933 ExpectSemicolon(); |
| 7919 } | 7934 } |
| 7920 return statement; | 7935 return statement; |
| 7921 } | 7936 } |
| 7922 | 7937 |
| 7923 | 7938 |
| 7924 void Parser::ReportError(const Error& error) { | 7939 void Parser::ReportError(const Error& error) { |
| 7925 Report::LongJump(error); | 7940 Report::LongJump(error); |
| 7926 UNREACHABLE(); | 7941 UNREACHABLE(); |
| 7927 } | 7942 } |
| (...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8570 ASSERT(field.value() != Object::transition_sentinel().raw()); | 8585 ASSERT(field.value() != Object::transition_sentinel().raw()); |
| 8571 return new(iso) LiteralNode(expr->token_pos(), | 8586 return new(iso) LiteralNode(expr->token_pos(), |
| 8572 Instance::ZoneHandle(iso, field.value())); | 8587 Instance::ZoneHandle(iso, field.value())); |
| 8573 } | 8588 } |
| 8574 } | 8589 } |
| 8575 return expr; | 8590 return expr; |
| 8576 } | 8591 } |
| 8577 | 8592 |
| 8578 | 8593 |
| 8579 AstNode* Parser::ParseAwaitableExpr(bool require_compiletime_const, | 8594 AstNode* Parser::ParseAwaitableExpr(bool require_compiletime_const, |
| 8580 bool consume_cascades) { | 8595 bool consume_cascades, |
| 8596 SequenceNode** await_preamble) { | |
| 8581 TRACE_PARSER("ParseAwaitableExpr"); | 8597 TRACE_PARSER("ParseAwaitableExpr"); |
| 8582 parsed_function()->reset_have_seen_await(); | 8598 parsed_function()->reset_have_seen_await(); |
| 8583 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); | 8599 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 8584 if (parsed_function()->have_seen_await()) { | 8600 if (parsed_function()->have_seen_await()) { |
| 8585 // Make sure we do not reuse the scope to avoid creating contexts that we | 8601 // Make sure we do not reuse the scope to avoid creating contexts that we |
| 8586 // are unaware of, i.e, creating contexts that have already been covered. | 8602 // are unaware of, i.e, creating contexts that have already been covered. |
| 8587 // See FlowGraphBuilder::VisitSequenceNode() for details on when contexts | 8603 // See FlowGraphBuilder::VisitSequenceNode() for details on when contexts |
| 8588 // are created. | 8604 // are created. |
| 8589 OpenBlock(); | 8605 OpenBlock(); |
| 8590 AwaitTransformer at(current_block_->statements, | 8606 AwaitTransformer at(current_block_->statements, |
| 8591 library_, | 8607 library_, |
| 8592 parsed_function(), | 8608 parsed_function(), |
| 8593 async_temp_scope_); | 8609 async_temp_scope_); |
| 8594 AstNode* result = at.Transform(expr); | 8610 AstNode* result = at.Transform(expr); |
| 8595 AstNode* await_preamble = CloseBlock(); | 8611 SequenceNode* preamble = CloseBlock(); |
| 8596 current_block_->statements->Add(await_preamble); | 8612 if (await_preamble == NULL) { |
| 8613 current_block_->statements->Add(preamble); | |
| 8614 } else { | |
| 8615 *await_preamble = preamble; | |
| 8616 } | |
| 8597 parsed_function()->reset_have_seen_await(); | 8617 parsed_function()->reset_have_seen_await(); |
| 8598 return result; | 8618 return result; |
| 8599 } | 8619 } |
| 8600 return expr; | 8620 return expr; |
| 8601 } | 8621 } |
| 8602 | 8622 |
| 8603 | 8623 |
| 8604 AstNode* Parser::ParseExpr(bool require_compiletime_const, | 8624 AstNode* Parser::ParseExpr(bool require_compiletime_const, |
| 8605 bool consume_cascades) { | 8625 bool consume_cascades) { |
| 8606 TRACE_PARSER("ParseExpr"); | 8626 TRACE_PARSER("ParseExpr"); |
| (...skipping 2913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11520 void Parser::SkipQualIdent() { | 11540 void Parser::SkipQualIdent() { |
| 11521 ASSERT(IsIdentifier()); | 11541 ASSERT(IsIdentifier()); |
| 11522 ConsumeToken(); | 11542 ConsumeToken(); |
| 11523 if (CurrentToken() == Token::kPERIOD) { | 11543 if (CurrentToken() == Token::kPERIOD) { |
| 11524 ConsumeToken(); // Consume the kPERIOD token. | 11544 ConsumeToken(); // Consume the kPERIOD token. |
| 11525 ExpectIdentifier("identifier expected after '.'"); | 11545 ExpectIdentifier("identifier expected after '.'"); |
| 11526 } | 11546 } |
| 11527 } | 11547 } |
| 11528 | 11548 |
| 11529 } // namespace dart | 11549 } // namespace dart |
| OLD | NEW |