OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2617 Expect(Token::LPAREN, CHECK_OK); | 2617 Expect(Token::LPAREN, CHECK_OK); |
2618 Expression* cond = ParseExpression(true, CHECK_OK); | 2618 Expression* cond = ParseExpression(true, CHECK_OK); |
2619 Expect(Token::RPAREN, CHECK_OK); | 2619 Expect(Token::RPAREN, CHECK_OK); |
2620 Statement* body = ParseStatement(NULL, CHECK_OK); | 2620 Statement* body = ParseStatement(NULL, CHECK_OK); |
2621 | 2621 |
2622 if (loop != NULL) loop->Initialize(cond, body); | 2622 if (loop != NULL) loop->Initialize(cond, body); |
2623 return loop; | 2623 return loop; |
2624 } | 2624 } |
2625 | 2625 |
2626 | 2626 |
2627 bool Parser::CheckInOrOf(ForEachStatement::VisitMode* visit_mode) { | 2627 bool Parser::CheckInOrOf(bool accept_OF, |
| 2628 ForEachStatement::VisitMode* visit_mode) { |
2628 if (Check(Token::IN)) { | 2629 if (Check(Token::IN)) { |
2629 *visit_mode = ForEachStatement::ENUMERATE; | 2630 *visit_mode = ForEachStatement::ENUMERATE; |
2630 return true; | 2631 return true; |
2631 } else if (allow_for_of() && CheckContextualKeyword(CStrVector("of"))) { | 2632 } else if (allow_for_of() && accept_OF && |
| 2633 CheckContextualKeyword(CStrVector("of"))) { |
2632 *visit_mode = ForEachStatement::ITERATE; | 2634 *visit_mode = ForEachStatement::ITERATE; |
2633 return true; | 2635 return true; |
2634 } | 2636 } |
2635 return false; | 2637 return false; |
2636 } | 2638 } |
2637 | 2639 |
2638 | 2640 |
2639 void Parser::InitializeForEachStatement(ForEachStatement* stmt, | 2641 void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
2640 Expression* each, | 2642 Expression* each, |
2641 Expression* subject, | 2643 Expression* subject, |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2719 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); | 2721 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); |
2720 top_scope_ = for_scope; | 2722 top_scope_ = for_scope; |
2721 | 2723 |
2722 Expect(Token::FOR, CHECK_OK); | 2724 Expect(Token::FOR, CHECK_OK); |
2723 Expect(Token::LPAREN, CHECK_OK); | 2725 Expect(Token::LPAREN, CHECK_OK); |
2724 for_scope->set_start_position(scanner().location().beg_pos); | 2726 for_scope->set_start_position(scanner().location().beg_pos); |
2725 if (peek() != Token::SEMICOLON) { | 2727 if (peek() != Token::SEMICOLON) { |
2726 if (peek() == Token::VAR || peek() == Token::CONST) { | 2728 if (peek() == Token::VAR || peek() == Token::CONST) { |
2727 bool is_const = peek() == Token::CONST; | 2729 bool is_const = peek() == Token::CONST; |
2728 Handle<String> name; | 2730 Handle<String> name; |
| 2731 VariableDeclarationProperties decl_props = kHasNoInitializers; |
2729 Block* variable_statement = | 2732 Block* variable_statement = |
2730 ParseVariableDeclarations(kForStatement, NULL, NULL, &name, CHECK_OK); | 2733 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
| 2734 CHECK_OK); |
| 2735 bool accept_OF = decl_props == kHasNoInitializers; |
2731 ForEachStatement::VisitMode mode; | 2736 ForEachStatement::VisitMode mode; |
2732 | 2737 |
2733 if (!name.is_null() && CheckInOrOf(&mode)) { | 2738 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { |
2734 Interface* interface = | 2739 Interface* interface = |
2735 is_const ? Interface::NewConst() : Interface::NewValue(); | 2740 is_const ? Interface::NewConst() : Interface::NewValue(); |
2736 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); | 2741 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); |
2737 Target target(&this->target_stack_, loop); | 2742 Target target(&this->target_stack_, loop); |
2738 | 2743 |
2739 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2744 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2740 Expect(Token::RPAREN, CHECK_OK); | 2745 Expect(Token::RPAREN, CHECK_OK); |
2741 | 2746 |
2742 VariableProxy* each = | 2747 VariableProxy* each = |
2743 top_scope_->NewUnresolved(factory(), name, interface); | 2748 top_scope_->NewUnresolved(factory(), name, interface); |
(...skipping 11 matching lines...) Expand all Loading... |
2755 } else { | 2760 } else { |
2756 init = variable_statement; | 2761 init = variable_statement; |
2757 } | 2762 } |
2758 } else if (peek() == Token::LET) { | 2763 } else if (peek() == Token::LET) { |
2759 Handle<String> name; | 2764 Handle<String> name; |
2760 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2765 VariableDeclarationProperties decl_props = kHasNoInitializers; |
2761 Block* variable_statement = | 2766 Block* variable_statement = |
2762 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 2767 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
2763 CHECK_OK); | 2768 CHECK_OK); |
2764 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; | 2769 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; |
| 2770 bool accept_OF = decl_props == kHasNoInitializers; |
2765 ForEachStatement::VisitMode mode; | 2771 ForEachStatement::VisitMode mode; |
2766 | 2772 |
2767 if (accept_IN && CheckInOrOf(&mode)) { | 2773 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { |
2768 // Rewrite a for-in statement of the form | 2774 // Rewrite a for-in statement of the form |
2769 // | 2775 // |
2770 // for (let x in e) b | 2776 // for (let x in e) b |
2771 // | 2777 // |
2772 // into | 2778 // into |
2773 // | 2779 // |
2774 // <let x' be a temporary variable> | 2780 // <let x' be a temporary variable> |
2775 // for (x' in e) { | 2781 // for (x' in e) { |
2776 // let x; | 2782 // let x; |
2777 // x = x'; | 2783 // x = x'; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2813 body_block->set_scope(for_scope); | 2819 body_block->set_scope(for_scope); |
2814 // Parsed for-in loop w/ let declaration. | 2820 // Parsed for-in loop w/ let declaration. |
2815 return loop; | 2821 return loop; |
2816 | 2822 |
2817 } else { | 2823 } else { |
2818 init = variable_statement; | 2824 init = variable_statement; |
2819 } | 2825 } |
2820 } else { | 2826 } else { |
2821 Expression* expression = ParseExpression(false, CHECK_OK); | 2827 Expression* expression = ParseExpression(false, CHECK_OK); |
2822 ForEachStatement::VisitMode mode; | 2828 ForEachStatement::VisitMode mode; |
| 2829 bool accept_OF = expression->AsVariableProxy(); |
2823 | 2830 |
2824 if (CheckInOrOf(&mode)) { | 2831 if (CheckInOrOf(accept_OF, &mode)) { |
2825 // Signal a reference error if the expression is an invalid | 2832 // Signal a reference error if the expression is an invalid |
2826 // left-hand side expression. We could report this as a syntax | 2833 // left-hand side expression. We could report this as a syntax |
2827 // error here but for compatibility with JSC we choose to report | 2834 // error here but for compatibility with JSC we choose to report |
2828 // the error at runtime. | 2835 // the error at runtime. |
2829 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2836 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2830 Handle<String> message = | 2837 Handle<String> message = |
2831 isolate()->factory()->invalid_lhs_in_for_in_string(); | 2838 isolate()->factory()->invalid_lhs_in_for_in_string(); |
2832 expression = NewThrowReferenceError(message); | 2839 expression = NewThrowReferenceError(message); |
2833 } | 2840 } |
2834 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); | 2841 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); |
(...skipping 3095 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5930 ASSERT(info()->isolate()->has_pending_exception()); | 5937 ASSERT(info()->isolate()->has_pending_exception()); |
5931 } else { | 5938 } else { |
5932 result = ParseProgram(); | 5939 result = ParseProgram(); |
5933 } | 5940 } |
5934 } | 5941 } |
5935 info()->SetFunction(result); | 5942 info()->SetFunction(result); |
5936 return (result != NULL); | 5943 return (result != NULL); |
5937 } | 5944 } |
5938 | 5945 |
5939 } } // namespace v8::internal | 5946 } } // namespace v8::internal |
OLD | NEW |