Chromium Code Reviews| 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 1694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1705 Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) { | 1705 Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) { |
| 1706 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); | 1706 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); |
| 1707 DoExpression* expr = factory()->NewDoExpression(body, result, pos); | 1707 DoExpression* expr = factory()->NewDoExpression(body, result, pos); |
| 1708 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) { | 1708 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) { |
| 1709 *ok = false; | 1709 *ok = false; |
| 1710 return nullptr; | 1710 return nullptr; |
| 1711 } | 1711 } |
| 1712 return expr; | 1712 return expr; |
| 1713 } | 1713 } |
| 1714 | 1714 |
| 1715 Statement* Parser::ParseFunctionDeclaration(bool* ok) { | 1715 Statement* Parser::RewriteSwitchStatement(Expression* tag, |
| 1716 Consume(Token::FUNCTION); | 1716 SwitchStatement* switch_statement, |
| 1717 int pos = position(); | 1717 ZoneList<CaseClause*>* cases, |
| 1718 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; | 1718 Scope* scope) { |
| 1719 if (Check(Token::MUL)) { | |
| 1720 flags |= ParseFunctionFlags::kIsGenerator; | |
| 1721 if (allow_harmony_restrictive_declarations()) { | |
| 1722 ReportMessageAt(scanner()->location(), | |
| 1723 MessageTemplate::kGeneratorInLegacyContext); | |
| 1724 *ok = false; | |
| 1725 return nullptr; | |
| 1726 } | |
| 1727 } | |
| 1728 | |
| 1729 return ParseHoistableDeclaration(pos, flags, nullptr, false, CHECK_OK); | |
| 1730 } | |
| 1731 | |
| 1732 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { | |
| 1733 // CaseClause :: | |
| 1734 // 'case' Expression ':' StatementList | |
| 1735 // 'default' ':' StatementList | |
| 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, | 1719 // In order to get the CaseClauses to execute in their own lexical scope, |
| 1770 // but without requiring downstream code to have special scope handling | 1720 // but without requiring downstream code to have special scope handling |
| 1771 // code for switch statements, desugar into blocks as follows: | 1721 // code for switch statements, desugar into blocks as follows: |
| 1772 // { // To group the statements--harmless to evaluate Expression in scope | 1722 // { // To group the statements--harmless to evaluate Expression in scope |
| 1773 // .tag_variable = Expression; | 1723 // .tag_variable = Expression; |
| 1774 // { // To give CaseClauses a scope | 1724 // { // To give CaseClauses a scope |
| 1775 // switch (.tag_variable) { CaseClause* } | 1725 // switch (.tag_variable) { CaseClause* } |
| 1776 // } | 1726 // } |
| 1777 // } | 1727 // } |
| 1778 | 1728 |
| 1779 Block* switch_block = factory()->NewBlock(NULL, 2, false, kNoSourcePosition); | 1729 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 | 1730 |
| 1787 Variable* tag_variable = | 1731 Variable* tag_variable = |
| 1788 NewTemporary(ast_value_factory()->dot_switch_tag_string()); | 1732 NewTemporary(ast_value_factory()->dot_switch_tag_string()); |
| 1789 Assignment* tag_assign = factory()->NewAssignment( | 1733 Assignment* tag_assign = factory()->NewAssignment( |
| 1790 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag, | 1734 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag, |
| 1791 tag->position()); | 1735 tag->position()); |
| 1792 Statement* tag_statement = | 1736 Statement* tag_statement = |
| 1793 factory()->NewExpressionStatement(tag_assign, kNoSourcePosition); | 1737 factory()->NewExpressionStatement(tag_assign, kNoSourcePosition); |
| 1794 switch_block->statements()->Add(tag_statement, zone()); | 1738 switch_block->statements()->Add(tag_statement, zone()); |
| 1795 | 1739 |
| 1796 // make statement: undefined; | 1740 // make statement: undefined; |
| 1797 // This is needed so the tag isn't returned as the value, in case the switch | 1741 // This is needed so the tag isn't returned as the value, in case the switch |
| 1798 // statements don't have a value. | 1742 // statements don't have a value. |
| 1799 switch_block->statements()->Add( | 1743 switch_block->statements()->Add( |
| 1800 factory()->NewExpressionStatement( | 1744 factory()->NewExpressionStatement( |
| 1801 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition), | 1745 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition), |
| 1802 zone()); | 1746 zone()); |
| 1803 | 1747 |
| 1748 Expression* tag_read = factory()->NewVariableProxy(tag_variable); | |
| 1749 switch_statement->Initialize(tag_read, cases); | |
| 1804 Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); | 1750 Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); |
| 1805 | 1751 cases_block->statements()->Add(switch_statement, zone()); |
| 1806 SwitchStatement* switch_statement = | 1752 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()); | 1753 switch_block->statements()->Add(cases_block, zone()); |
| 1834 | |
| 1835 return switch_block; | 1754 return switch_block; |
| 1836 } | 1755 } |
| 1837 | 1756 |
| 1757 Statement* Parser::ParseFunctionDeclaration(bool* ok) { | |
|
marja
2016/09/12 08:17:56
Hmm, why did you add this code?
nickie
2016/09/12 09:03:37
I did not add it, it's in the left column in line
| |
| 1758 Consume(Token::FUNCTION); | |
| 1759 int pos = position(); | |
| 1760 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; | |
| 1761 if (Check(Token::MUL)) { | |
| 1762 flags |= ParseFunctionFlags::kIsGenerator; | |
| 1763 if (allow_harmony_restrictive_declarations()) { | |
| 1764 ReportMessageAt(scanner()->location(), | |
| 1765 MessageTemplate::kGeneratorInLegacyContext); | |
| 1766 *ok = false; | |
| 1767 return nullptr; | |
| 1768 } | |
| 1769 } | |
| 1770 | |
| 1771 return ParseHoistableDeclaration(pos, flags, nullptr, false, CHECK_OK); | |
| 1772 } | |
| 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 :: |
| 1845 // 'catch' '(' Identifier ')' Block | 1781 // 'catch' '(' Identifier ')' Block |
| 1846 // | 1782 // |
| 1847 // Finally :: | 1783 // Finally :: |
| (...skipping 3828 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 |