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 6355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |