Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Side by Side Diff: runtime/vm/parser.cc

Issue 538703002: Enable await in while and do-while. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebase Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/await_future_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 = new (I) WhileNode(while_pos,
6978 label,
6979 cond_expr,
6980 await_preamble,
6981 while_body);
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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
7088 } else { 7103 } else {
7089 AstNode* statement = ParseStatement(); 7104 AstNode* statement = ParseStatement();
7090 if (statement != NULL) { 7105 if (statement != NULL) {
7091 current_block_->statements->Add(statement); 7106 current_block_->statements->Add(statement);
7092 } 7107 }
7093 } 7108 }
7094 7109
7095 SequenceNode* for_loop_statement = CloseBlock(); 7110 SequenceNode* for_loop_statement = CloseBlock();
7096 7111
7097 AstNode* while_statement = new(I) WhileNode( 7112 AstNode* while_statement = new(I) WhileNode(
7098 forin_pos, label, iterator_moveNext, for_loop_statement); 7113 forin_pos, label, iterator_moveNext, NULL, for_loop_statement);
7099 current_block_->statements->Add(while_statement); 7114 current_block_->statements->Add(while_statement);
7100 7115
7101 return CloseBlock(); // Implicit block around while loop. 7116 return CloseBlock(); // Implicit block around while loop.
7102 } 7117 }
7103 7118
7104 7119
7105 AstNode* Parser::ParseForStatement(String* label_name) { 7120 AstNode* Parser::ParseForStatement(String* label_name) {
7106 TRACE_PARSER("ParseForStatement"); 7121 TRACE_PARSER("ParseForStatement");
7107 const intptr_t for_pos = TokenPos(); 7122 const intptr_t for_pos = TokenPos();
7108 ConsumeToken(); 7123 ConsumeToken();
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/await_future_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698