OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/ast/ast-expression-rewriter.h" | 10 #include "src/ast/ast-expression-rewriter.h" |
(...skipping 1711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1722 ReportMessageAt(scanner()->location(), | 1722 ReportMessageAt(scanner()->location(), |
1723 MessageTemplate::kGeneratorInLegacyContext); | 1723 MessageTemplate::kGeneratorInLegacyContext); |
1724 *ok = false; | 1724 *ok = false; |
1725 return nullptr; | 1725 return nullptr; |
1726 } | 1726 } |
1727 } | 1727 } |
1728 | 1728 |
1729 return ParseHoistableDeclaration(pos, flags, nullptr, false, CHECK_OK); | 1729 return ParseHoistableDeclaration(pos, flags, nullptr, false, CHECK_OK); |
1730 } | 1730 } |
1731 | 1731 |
1732 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { | 1732 Statement* Parser::RewriteSwitchStatement(Expression* tag, |
1733 // CaseClause :: | 1733 SwitchStatement* switch_statement, |
1734 // 'case' Expression ':' StatementList | 1734 ZoneList<CaseClause*>* cases, |
1735 // 'default' ':' StatementList | 1735 Scope* scope) { |
1736 | |
1737 Expression* label = NULL; // NULL expression indicates default case | |
1738 if (peek() == Token::CASE) { | |
1739 Expect(Token::CASE, CHECK_OK); | |
1740 label = ParseExpression(true, CHECK_OK); | |
1741 } else { | |
1742 Expect(Token::DEFAULT, CHECK_OK); | |
1743 if (*default_seen_ptr) { | |
1744 ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch); | |
1745 *ok = false; | |
1746 return NULL; | |
1747 } | |
1748 *default_seen_ptr = true; | |
1749 } | |
1750 Expect(Token::COLON, CHECK_OK); | |
1751 int pos = position(); | |
1752 ZoneList<Statement*>* statements = | |
1753 new(zone()) ZoneList<Statement*>(5, zone()); | |
1754 Statement* stat = NULL; | |
1755 while (peek() != Token::CASE && | |
1756 peek() != Token::DEFAULT && | |
1757 peek() != Token::RBRACE) { | |
1758 stat = ParseStatementListItem(CHECK_OK); | |
1759 statements->Add(stat, zone()); | |
1760 } | |
1761 return factory()->NewCaseClause(label, statements, pos); | |
1762 } | |
1763 | |
1764 | |
1765 Statement* Parser::ParseSwitchStatement(ZoneList<const AstRawString*>* labels, | |
1766 bool* ok) { | |
1767 // SwitchStatement :: | |
1768 // 'switch' '(' Expression ')' '{' CaseClause* '}' | |
1769 // In order to get the CaseClauses to execute in their own lexical scope, | 1736 // In order to get the CaseClauses to execute in their own lexical scope, |
1770 // but without requiring downstream code to have special scope handling | 1737 // but without requiring downstream code to have special scope handling |
1771 // code for switch statements, desugar into blocks as follows: | 1738 // code for switch statements, desugar into blocks as follows: |
1772 // { // To group the statements--harmless to evaluate Expression in scope | 1739 // { // To group the statements--harmless to evaluate Expression in scope |
1773 // .tag_variable = Expression; | 1740 // .tag_variable = Expression; |
1774 // { // To give CaseClauses a scope | 1741 // { // To give CaseClauses a scope |
1775 // switch (.tag_variable) { CaseClause* } | 1742 // switch (.tag_variable) { CaseClause* } |
1776 // } | 1743 // } |
1777 // } | 1744 // } |
1778 | 1745 |
1779 Block* switch_block = factory()->NewBlock(NULL, 2, false, kNoSourcePosition); | 1746 Block* switch_block = factory()->NewBlock(NULL, 2, false, kNoSourcePosition); |
1780 int switch_pos = peek_position(); | |
1781 | |
1782 Expect(Token::SWITCH, CHECK_OK); | |
1783 Expect(Token::LPAREN, CHECK_OK); | |
1784 Expression* tag = ParseExpression(true, CHECK_OK); | |
1785 Expect(Token::RPAREN, CHECK_OK); | |
1786 | 1747 |
1787 Variable* tag_variable = | 1748 Variable* tag_variable = |
1788 NewTemporary(ast_value_factory()->dot_switch_tag_string()); | 1749 NewTemporary(ast_value_factory()->dot_switch_tag_string()); |
1789 Assignment* tag_assign = factory()->NewAssignment( | 1750 Assignment* tag_assign = factory()->NewAssignment( |
1790 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag, | 1751 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag, |
1791 tag->position()); | 1752 tag->position()); |
1792 Statement* tag_statement = | 1753 Statement* tag_statement = |
1793 factory()->NewExpressionStatement(tag_assign, kNoSourcePosition); | 1754 factory()->NewExpressionStatement(tag_assign, kNoSourcePosition); |
1794 switch_block->statements()->Add(tag_statement, zone()); | 1755 switch_block->statements()->Add(tag_statement, zone()); |
1795 | 1756 |
1796 // make statement: undefined; | 1757 // make statement: undefined; |
1797 // This is needed so the tag isn't returned as the value, in case the switch | 1758 // This is needed so the tag isn't returned as the value, in case the switch |
1798 // statements don't have a value. | 1759 // statements don't have a value. |
1799 switch_block->statements()->Add( | 1760 switch_block->statements()->Add( |
1800 factory()->NewExpressionStatement( | 1761 factory()->NewExpressionStatement( |
1801 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition), | 1762 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition), |
1802 zone()); | 1763 zone()); |
1803 | 1764 |
| 1765 Expression* tag_read = factory()->NewVariableProxy(tag_variable); |
| 1766 switch_statement->Initialize(tag_read, cases); |
1804 Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); | 1767 Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); |
1805 | 1768 cases_block->statements()->Add(switch_statement, zone()); |
1806 SwitchStatement* switch_statement = | 1769 cases_block->set_scope(scope); |
1807 factory()->NewSwitchStatement(labels, switch_pos); | |
1808 | |
1809 { | |
1810 BlockState cases_block_state(&scope_state_); | |
1811 cases_block_state.set_start_position(scanner()->location().beg_pos); | |
1812 cases_block_state.SetNonlinear(); | |
1813 ParserTarget target(this, switch_statement); | |
1814 | |
1815 Expression* tag_read = factory()->NewVariableProxy(tag_variable); | |
1816 | |
1817 bool default_seen = false; | |
1818 ZoneList<CaseClause*>* cases = | |
1819 new (zone()) ZoneList<CaseClause*>(4, zone()); | |
1820 Expect(Token::LBRACE, CHECK_OK); | |
1821 while (peek() != Token::RBRACE) { | |
1822 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); | |
1823 cases->Add(clause, zone()); | |
1824 } | |
1825 switch_statement->Initialize(tag_read, cases); | |
1826 cases_block->statements()->Add(switch_statement, zone()); | |
1827 Expect(Token::RBRACE, CHECK_OK); | |
1828 | |
1829 cases_block_state.set_end_position(scanner()->location().end_pos); | |
1830 cases_block->set_scope(cases_block_state.FinalizedBlockScope()); | |
1831 } | |
1832 | |
1833 switch_block->statements()->Add(cases_block, zone()); | 1770 switch_block->statements()->Add(cases_block, zone()); |
1834 | |
1835 return switch_block; | 1771 return switch_block; |
1836 } | 1772 } |
1837 | 1773 |
1838 TryStatement* Parser::ParseTryStatement(bool* ok) { | 1774 TryStatement* Parser::ParseTryStatement(bool* ok) { |
1839 // TryStatement :: | 1775 // TryStatement :: |
1840 // 'try' Block Catch | 1776 // 'try' Block Catch |
1841 // 'try' Block Finally | 1777 // 'try' Block Finally |
1842 // 'try' Block Catch Finally | 1778 // 'try' Block Catch Finally |
1843 // | 1779 // |
1844 // Catch :: | 1780 // Catch :: |
(...skipping 3831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5676 node->Print(Isolate::Current()); | 5612 node->Print(Isolate::Current()); |
5677 } | 5613 } |
5678 #endif // DEBUG | 5614 #endif // DEBUG |
5679 | 5615 |
5680 #undef CHECK_OK | 5616 #undef CHECK_OK |
5681 #undef CHECK_OK_VOID | 5617 #undef CHECK_OK_VOID |
5682 #undef CHECK_FAILED | 5618 #undef CHECK_FAILED |
5683 | 5619 |
5684 } // namespace internal | 5620 } // namespace internal |
5685 } // namespace v8 | 5621 } // namespace v8 |
OLD | NEW |