| Index: src/parsing/parser-base.h
|
| diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
|
| index f7bde680cd6dfbebd1b3bd4fa4ee24f4f266ec8c..cc8baf03bf3a3f5533247dd689b68bdcd9f6d2b7 100644
|
| --- a/src/parsing/parser-base.h
|
| +++ b/src/parsing/parser-base.h
|
| @@ -138,6 +138,8 @@ struct FormalParametersBase {
|
| // typedef Statement;
|
| // typedef StatementList;
|
| // typedef Block;
|
| +// typedef BreakableStatement;
|
| +// typedef IterationStatement;
|
| // // For constructing objects returned by the traversing functions.
|
| // typedef Factory;
|
| // // For other implementation-specific tasks.
|
| @@ -1217,6 +1219,8 @@ class ParserBase {
|
| StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels,
|
| bool* ok);
|
| StatementT ParseThrowStatement(bool* ok);
|
| + StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
|
| + bool* ok);
|
|
|
| bool IsNextLetKeyword();
|
| bool IsTrivialExpression();
|
| @@ -4282,7 +4286,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement(
|
| case Token::WITH:
|
| return ParseWithStatement(labels, ok);
|
| case Token::SWITCH:
|
| - return impl()->ParseSwitchStatement(labels, ok);
|
| + return ParseSwitchStatement(labels, ok);
|
| case Token::FUNCTION:
|
| // FunctionDeclaration only allowed as a StatementListItem, not in
|
| // an arbitrary Statement position. Exceptions such as
|
| @@ -4519,7 +4523,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseContinueStatement(
|
| // ECMA allows "eval" or "arguments" as labels even in strict mode.
|
| label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
|
| }
|
| - typename Types::IterationStatementT target =
|
| + typename Types::IterationStatement target =
|
| impl()->LookupContinueTarget(label, CHECK_OK);
|
| if (impl()->IsNullStatement(target)) {
|
| // Illegal continue statement.
|
| @@ -4557,7 +4561,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement(
|
| ExpectSemicolon(CHECK_OK);
|
| return factory()->NewEmptyStatement(pos);
|
| }
|
| - typename Types::BreakableStatementT target =
|
| + typename Types::BreakableStatement target =
|
| impl()->LookupBreakTarget(label, CHECK_OK);
|
| if (impl()->IsNullStatement(target)) {
|
| // Illegal break statement.
|
| @@ -4718,6 +4722,66 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseThrowStatement(
|
| return impl()->NewThrowStatement(exception, pos);
|
| }
|
|
|
| +template <typename Impl>
|
| +typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseSwitchStatement(
|
| + ZoneList<const AstRawString*>* labels, bool* ok) {
|
| + // SwitchStatement ::
|
| + // 'switch' '(' Expression ')' '{' CaseClause* '}'
|
| + // CaseClause ::
|
| + // 'case' Expression ':' StatementList
|
| + // 'default' ':' StatementList
|
| +
|
| + int switch_pos = peek_position();
|
| +
|
| + Expect(Token::SWITCH, CHECK_OK);
|
| + Expect(Token::LPAREN, CHECK_OK);
|
| + ExpressionT tag = ParseExpression(true, CHECK_OK);
|
| + Expect(Token::RPAREN, CHECK_OK);
|
| +
|
| + auto switch_statement = factory()->NewSwitchStatement(labels, switch_pos);
|
| +
|
| + {
|
| + BlockState cases_block_state(&scope_state_);
|
| + cases_block_state.set_start_position(scanner()->location().beg_pos);
|
| + cases_block_state.SetNonlinear();
|
| + typename Types::Target target(this, switch_statement);
|
| +
|
| + bool default_seen = false;
|
| + auto cases = impl()->NewCaseClauseList(4);
|
| + Expect(Token::LBRACE, CHECK_OK);
|
| + while (peek() != Token::RBRACE) {
|
| + // An empty label indicates the default case.
|
| + ExpressionT label = impl()->EmptyExpression();
|
| + if (Check(Token::CASE)) {
|
| + label = ParseExpression(true, CHECK_OK);
|
| + } else {
|
| + Expect(Token::DEFAULT, CHECK_OK);
|
| + if (default_seen) {
|
| + ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
|
| + *ok = false;
|
| + return impl()->NullStatement();
|
| + }
|
| + default_seen = true;
|
| + }
|
| + Expect(Token::COLON, CHECK_OK);
|
| + int clause_pos = position();
|
| + StatementListT statements = impl()->NewStatementList(5);
|
| + while (peek() != Token::CASE && peek() != Token::DEFAULT &&
|
| + peek() != Token::RBRACE) {
|
| + StatementT stat = ParseStatementListItem(CHECK_OK);
|
| + statements->Add(stat, zone());
|
| + }
|
| + auto clause = factory()->NewCaseClause(label, statements, clause_pos);
|
| + cases->Add(clause, zone());
|
| + }
|
| + Expect(Token::RBRACE, CHECK_OK);
|
| +
|
| + cases_block_state.set_end_position(scanner()->location().end_pos);
|
| + return impl()->RewriteSwitchStatement(
|
| + tag, switch_statement, cases, cases_block_state.FinalizedBlockScope());
|
| + }
|
| +}
|
| +
|
| #undef CHECK_OK
|
| #undef CHECK_OK_CUSTOM
|
|
|
|
|