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

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

Issue 10982051: Make throw an expression (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 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 | « no previous file | tests/language/language.status » ('j') | tests/language/throw_expr_test.dart » ('J')
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 "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 6355 matching lines...) Expand 10 before | Expand all | Expand 10 after
6366 statement = ParseJump(label_name); 6366 statement = ParseJump(label_name);
6367 AddNodeForFinallyInlining(statement); 6367 AddNodeForFinallyInlining(statement);
6368 ExpectSemicolon(); 6368 ExpectSemicolon();
6369 } else if (CurrentToken() == Token::kCONTINUE) { 6369 } else if (CurrentToken() == Token::kCONTINUE) {
6370 statement = ParseJump(label_name); 6370 statement = ParseJump(label_name);
6371 AddNodeForFinallyInlining(statement); 6371 AddNodeForFinallyInlining(statement);
6372 ExpectSemicolon(); 6372 ExpectSemicolon();
6373 } else if (CurrentToken() == Token::kSEMICOLON) { 6373 } else if (CurrentToken() == Token::kSEMICOLON) {
6374 // Empty statement, nothing to do. 6374 // Empty statement, nothing to do.
6375 ConsumeToken(); 6375 ConsumeToken();
6376 } else if (CurrentToken() == Token::kTHROW) { 6376 } else if ((CurrentToken() == Token::kTHROW) &&
6377 (LookaheadToken(1) == Token::kSEMICOLON)) {
6378 // Rethrow of current exception. Throwing of an exception object
6379 // is an expression and is handled in ParseExpr().
6377 ConsumeToken(); 6380 ConsumeToken();
6378 AstNode* expr = NULL; 6381 ExpectSemicolon();
6379 if (CurrentToken() != Token::kSEMICOLON) { 6382 // Check if it is ok to do a rethrow.
6380 expr = ParseExpr(kAllowConst, kConsumeCascades); 6383 SourceLabel* label = current_block_->scope->LookupInnermostCatchLabel();
6381 ExpectSemicolon(); 6384 if (label == NULL ||
6382 statement = new ThrowNode(statement_pos, expr, NULL); 6385 label->FunctionLevel() != current_block_->scope->function_level()) {
6383 } else { // No exception object seen so must be a rethrow. 6386 ErrorMsg(statement_pos, "rethrow of an exception is not valid here");
6384 // Check if it is ok to do a rethrow.
6385 SourceLabel* label = current_block_->scope->LookupInnermostCatchLabel();
6386 if (label == NULL ||
6387 label->FunctionLevel() != current_block_->scope->function_level()) {
6388 ErrorMsg("rethrow of an exception is not valid here");
6389 }
6390 ASSERT(label->owner() != NULL);
6391 LocalScope* scope = label->owner()->parent();
6392 ASSERT(scope != NULL);
6393 LocalVariable* excp_var = scope->LocalLookupVariable(
6394 String::ZoneHandle(Symbols::ExceptionVar()));
6395 ASSERT(excp_var != NULL);
6396 LocalVariable* trace_var = scope->LocalLookupVariable(
6397 String::ZoneHandle(Symbols::StacktraceVar()));
6398 ASSERT(trace_var != NULL);
6399 statement = new ThrowNode(statement_pos,
6400 new LoadLocalNode(statement_pos, excp_var),
6401 new LoadLocalNode(statement_pos, trace_var));
6402 } 6387 }
6388 ASSERT(label->owner() != NULL);
6389 LocalScope* scope = label->owner()->parent();
6390 ASSERT(scope != NULL);
6391 LocalVariable* excp_var = scope->LocalLookupVariable(
6392 String::ZoneHandle(Symbols::ExceptionVar()));
6393 ASSERT(excp_var != NULL);
6394 LocalVariable* trace_var = scope->LocalLookupVariable(
6395 String::ZoneHandle(Symbols::StacktraceVar()));
6396 ASSERT(trace_var != NULL);
6397 statement = new ThrowNode(statement_pos,
6398 new LoadLocalNode(statement_pos, excp_var),
6399 new LoadLocalNode(statement_pos, trace_var));
6403 } else { 6400 } else {
6404 statement = ParseExpr(kAllowConst, kConsumeCascades); 6401 statement = ParseExpr(kAllowConst, kConsumeCascades);
6405 ExpectSemicolon(); 6402 ExpectSemicolon();
6406 } 6403 }
6407 return statement; 6404 return statement;
6408 } 6405 }
6409 6406
6410 6407
6411 RawError* Parser::FormatErrorWithAppend(const Error& prev_error, 6408 RawError* Parser::FormatErrorWithAppend(const Error& prev_error,
6412 const Script& script, 6409 const Script& script,
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
7000 } 6997 }
7001 // Result of the cascade is the receiver. 6998 // Result of the cascade is the receiver.
7002 return new LoadLocalNode(cascade_pos, cascade_receiver_var); 6999 return new LoadLocalNode(cascade_pos, cascade_receiver_var);
7003 } 7000 }
7004 7001
7005 7002
7006 AstNode* Parser::ParseExpr(bool require_compiletime_const, 7003 AstNode* Parser::ParseExpr(bool require_compiletime_const,
7007 bool consume_cascades) { 7004 bool consume_cascades) {
7008 TRACE_PARSER("ParseExpr"); 7005 TRACE_PARSER("ParseExpr");
7009 const intptr_t expr_pos = TokenPos(); 7006 const intptr_t expr_pos = TokenPos();
7007
7008 if (CurrentToken() == Token::kTHROW) {
7009 ConsumeToken();
7010 ASSERT(CurrentToken() != Token::kSEMICOLON);
7011 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades);
7012 return new ThrowNode(expr_pos, expr, NULL);
7013 }
7010 AstNode* expr = ParseConditionalExpr(); 7014 AstNode* expr = ParseConditionalExpr();
7011 if (!Token::IsAssignmentOperator(CurrentToken())) { 7015 if (!Token::IsAssignmentOperator(CurrentToken())) {
7012 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { 7016 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) {
7013 return ParseCascades(expr); 7017 return ParseCascades(expr);
7014 } 7018 }
7015 if (require_compiletime_const) { 7019 if (require_compiletime_const) {
7016 expr = FoldConstExpr(expr_pos, expr); 7020 expr = FoldConstExpr(expr_pos, expr);
7017 } 7021 }
7018 return expr; 7022 return expr;
7019 } 7023 }
(...skipping 2639 matching lines...) Expand 10 before | Expand all | Expand 10 after
9659 if (CurrentToken() == Token::kCONDITIONAL) { 9663 if (CurrentToken() == Token::kCONDITIONAL) {
9660 ConsumeToken(); 9664 ConsumeToken();
9661 SkipExpr(); 9665 SkipExpr();
9662 ExpectToken(Token::kCOLON); 9666 ExpectToken(Token::kCOLON);
9663 SkipExpr(); 9667 SkipExpr();
9664 } 9668 }
9665 } 9669 }
9666 9670
9667 9671
9668 void Parser::SkipExpr() { 9672 void Parser::SkipExpr() {
9673 while (CurrentToken() == Token::kTHROW) {
9674 ConsumeToken();
9675 }
9669 SkipConditionalExpr(); 9676 SkipConditionalExpr();
9670 if (CurrentToken() == Token::kCASCADE) { 9677 if (CurrentToken() == Token::kCASCADE) {
9671 SkipSelectors(); 9678 SkipSelectors();
9672 } 9679 }
9673 if (Token::IsAssignmentOperator(CurrentToken())) { 9680 if (Token::IsAssignmentOperator(CurrentToken())) {
9674 ConsumeToken(); 9681 ConsumeToken();
9675 SkipExpr(); 9682 SkipExpr();
9676 } 9683 }
9677 } 9684 }
9678 9685
9679 9686
9680 void Parser::SkipNestedExpr() { 9687 void Parser::SkipNestedExpr() {
9681 const bool saved_mode = SetAllowFunctionLiterals(true); 9688 const bool saved_mode = SetAllowFunctionLiterals(true);
9682 SkipExpr(); 9689 SkipExpr();
9683 SetAllowFunctionLiterals(saved_mode); 9690 SetAllowFunctionLiterals(saved_mode);
9684 } 9691 }
9685 9692
9686 9693
9687 void Parser::SkipQualIdent() { 9694 void Parser::SkipQualIdent() {
9688 ASSERT(IsIdentifier()); 9695 ASSERT(IsIdentifier());
9689 ConsumeToken(); 9696 ConsumeToken();
9690 if (CurrentToken() == Token::kPERIOD) { 9697 if (CurrentToken() == Token::kPERIOD) {
9691 ConsumeToken(); // Consume the kPERIOD token. 9698 ConsumeToken(); // Consume the kPERIOD token.
9692 ExpectIdentifier("identifier expected after '.'"); 9699 ExpectIdentifier("identifier expected after '.'");
9693 } 9700 }
9694 } 9701 }
9695 9702
9696 } // namespace dart 9703 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | tests/language/language.status » ('j') | tests/language/throw_expr_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698