Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: src/preparser.h

Issue 160073006: Implement handling of arrow functions in the parser (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Implement handling of arrow functions in the parser Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 // typedef ObjectLiteralProperty; 71 // typedef ObjectLiteralProperty;
72 // typedef Literal; 72 // typedef Literal;
73 // typedef ExpressionList; 73 // typedef ExpressionList;
74 // typedef PropertyList; 74 // typedef PropertyList;
75 // // For constructing objects returned by the traversing functions. 75 // // For constructing objects returned by the traversing functions.
76 // typedef Factory; 76 // typedef Factory;
77 // }; 77 // };
78 // // ... 78 // // ...
79 // }; 79 // };
80 80
81 enum FunctionParsingMode {
82 kNormalFunction,
83 kArrowFunction,
84 kGeneratorFunction
85 };
86
87
81 template <typename Traits> 88 template <typename Traits>
82 class ParserBase : public Traits { 89 class ParserBase : public Traits {
83 public: 90 public:
84 // Shorten type names defined by Traits. 91 // Shorten type names defined by Traits.
85 typedef typename Traits::Type::Expression ExpressionT; 92 typedef typename Traits::Type::Expression ExpressionT;
86 typedef typename Traits::Type::Identifier IdentifierT; 93 typedef typename Traits::Type::Identifier IdentifierT;
87 94
88 ParserBase(Scanner* scanner, uintptr_t stack_limit, 95 ParserBase(Scanner* scanner, uintptr_t stack_limit,
89 v8::Extension* extension, 96 v8::Extension* extension,
90 ParserRecorder* log, 97 ParserRecorder* log,
91 typename Traits::Type::Zone* zone, 98 typename Traits::Type::Zone* zone,
92 typename Traits::Type::Parser this_object) 99 typename Traits::Type::Parser this_object)
93 : Traits(this_object), 100 : Traits(this_object),
94 parenthesized_function_(false), 101 parenthesized_function_(false),
95 scope_(NULL), 102 scope_(NULL),
96 function_state_(NULL), 103 function_state_(NULL),
97 extension_(extension), 104 extension_(extension),
98 fni_(NULL), 105 fni_(NULL),
99 log_(log), 106 log_(log),
100 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. 107 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
101 scanner_(scanner), 108 scanner_(scanner),
102 stack_limit_(stack_limit), 109 stack_limit_(stack_limit),
103 stack_overflow_(false), 110 stack_overflow_(false),
104 allow_lazy_(false), 111 allow_lazy_(false),
105 allow_natives_syntax_(false), 112 allow_natives_syntax_(false),
106 allow_generators_(false), 113 allow_generators_(false),
107 allow_for_of_(false), 114 allow_for_of_(false),
115 allow_arrow_functions_(false),
108 zone_(zone) { } 116 zone_(zone) { }
109 117
110 // Getters that indicate whether certain syntactical constructs are 118 // Getters that indicate whether certain syntactical constructs are
111 // allowed to be parsed by this instance of the parser. 119 // allowed to be parsed by this instance of the parser.
112 bool allow_lazy() const { return allow_lazy_; } 120 bool allow_lazy() const { return allow_lazy_; }
113 bool allow_natives_syntax() const { return allow_natives_syntax_; } 121 bool allow_natives_syntax() const { return allow_natives_syntax_; }
114 bool allow_generators() const { return allow_generators_; } 122 bool allow_generators() const { return allow_generators_; }
115 bool allow_for_of() const { return allow_for_of_; } 123 bool allow_for_of() const { return allow_for_of_; }
124 bool allow_arrow_functions() const { return allow_arrow_functions_; }
116 bool allow_modules() const { return scanner()->HarmonyModules(); } 125 bool allow_modules() const { return scanner()->HarmonyModules(); }
117 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } 126 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
118 bool allow_harmony_numeric_literals() const { 127 bool allow_harmony_numeric_literals() const {
119 return scanner()->HarmonyNumericLiterals(); 128 return scanner()->HarmonyNumericLiterals();
120 } 129 }
121 130
122 // Setters that determine whether certain syntactical constructs are 131 // Setters that determine whether certain syntactical constructs are
123 // allowed to be parsed by this instance of the parser. 132 // allowed to be parsed by this instance of the parser.
124 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } 133 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
125 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } 134 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
126 void set_allow_generators(bool allow) { allow_generators_ = allow; } 135 void set_allow_generators(bool allow) { allow_generators_ = allow; }
127 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } 136 void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
137 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; }
128 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } 138 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
129 void set_allow_harmony_scoping(bool allow) { 139 void set_allow_harmony_scoping(bool allow) {
130 scanner()->SetHarmonyScoping(allow); 140 scanner()->SetHarmonyScoping(allow);
131 } 141 }
132 void set_allow_harmony_numeric_literals(bool allow) { 142 void set_allow_harmony_numeric_literals(bool allow) {
133 scanner()->SetHarmonyNumericLiterals(allow); 143 scanner()->SetHarmonyNumericLiterals(allow);
134 } 144 }
135 145
136 protected: 146 protected:
137 enum AllowEvalOrArgumentsAsIdentifier { 147 enum AllowEvalOrArgumentsAsIdentifier {
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 504
495 private: 505 private:
496 Scanner* scanner_; 506 Scanner* scanner_;
497 uintptr_t stack_limit_; 507 uintptr_t stack_limit_;
498 bool stack_overflow_; 508 bool stack_overflow_;
499 509
500 bool allow_lazy_; 510 bool allow_lazy_;
501 bool allow_natives_syntax_; 511 bool allow_natives_syntax_;
502 bool allow_generators_; 512 bool allow_generators_;
503 bool allow_for_of_; 513 bool allow_for_of_;
514 bool allow_arrow_functions_;
504 515
505 typename Traits::Type::Zone* zone_; // Only used by Parser. 516 typename Traits::Type::Zone* zone_; // Only used by Parser.
506 }; 517 };
507 518
508 519
509 class PreParserIdentifier { 520 class PreParserIdentifier {
510 public: 521 public:
511 PreParserIdentifier() : type_(kUnknownIdentifier) {} 522 PreParserIdentifier() : type_(kUnknownIdentifier) {}
512 static PreParserIdentifier Default() { 523 static PreParserIdentifier Default() {
513 return PreParserIdentifier(kUnknownIdentifier); 524 return PreParserIdentifier(kUnknownIdentifier);
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
983 static PreParserExpressionList NewPropertyList(int size, void* zone) { 994 static PreParserExpressionList NewPropertyList(int size, void* zone) {
984 return PreParserExpressionList(); 995 return PreParserExpressionList();
985 } 996 }
986 997
987 // Temporary glue; these functions will move to ParserBase. 998 // Temporary glue; these functions will move to ParserBase.
988 PreParserExpression ParseV8Intrinsic(bool* ok); 999 PreParserExpression ParseV8Intrinsic(bool* ok);
989 PreParserExpression ParseFunctionLiteral( 1000 PreParserExpression ParseFunctionLiteral(
990 PreParserIdentifier name, 1001 PreParserIdentifier name,
991 Scanner::Location function_name_location, 1002 Scanner::Location function_name_location,
992 bool name_is_strict_reserved, 1003 bool name_is_strict_reserved,
993 bool is_generator, 1004 FunctionParsingMode parsing_mode,
1005 PreParserExpression params_ast,
994 int function_token_position, 1006 int function_token_position,
995 FunctionLiteral::FunctionType type, 1007 FunctionLiteral::FunctionType type,
996 bool* ok); 1008 bool* ok);
997 1009
998 private: 1010 private:
999 PreParser* pre_parser_; 1011 PreParser* pre_parser_;
1000 }; 1012 };
1001 1013
1002 1014
1003 // Preparsing checks a JavaScript program and emits preparse-data that helps 1015 // Preparsing checks a JavaScript program and emits preparse-data that helps
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 Statement ParseTryStatement(bool* ok); 1169 Statement ParseTryStatement(bool* ok);
1158 Statement ParseDebuggerStatement(bool* ok); 1170 Statement ParseDebuggerStatement(bool* ok);
1159 Expression ParseConditionalExpression(bool accept_IN, bool* ok); 1171 Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1160 Expression ParseObjectLiteral(bool* ok); 1172 Expression ParseObjectLiteral(bool* ok);
1161 Expression ParseV8Intrinsic(bool* ok); 1173 Expression ParseV8Intrinsic(bool* ok);
1162 1174
1163 Expression ParseFunctionLiteral( 1175 Expression ParseFunctionLiteral(
1164 Identifier name, 1176 Identifier name,
1165 Scanner::Location function_name_location, 1177 Scanner::Location function_name_location,
1166 bool name_is_strict_reserved, 1178 bool name_is_strict_reserved,
1167 bool is_generator, 1179 FunctionParsingMode parsing_mode,
1180 Expression params_ast,
1168 int function_token_pos, 1181 int function_token_pos,
1169 FunctionLiteral::FunctionType function_type, 1182 FunctionLiteral::FunctionType function_type,
1170 bool* ok); 1183 bool* ok);
1171 void ParseLazyFunctionLiteralBody(bool* ok); 1184 void ParseLazyFunctionLiteralBody(bool* ok);
1172 1185
1173 // Logs the currently parsed literal as a symbol in the preparser data. 1186 // Logs the currently parsed literal as a symbol in the preparser data.
1174 void LogSymbol(); 1187 void LogSymbol();
1175 // Log the currently parsed string literal. 1188 // Log the currently parsed string literal.
1176 Expression GetStringSymbol(); 1189 Expression GetStringSymbol();
1177 1190
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
1441 } 1454 }
1442 1455
1443 // Precedence = 1 1456 // Precedence = 1
1444 template <class Traits> 1457 template <class Traits>
1445 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( 1458 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1446 bool accept_IN, bool* ok) { 1459 bool accept_IN, bool* ok) {
1447 // Expression :: 1460 // Expression ::
1448 // AssignmentExpression 1461 // AssignmentExpression
1449 // Expression ',' AssignmentExpression 1462 // Expression ',' AssignmentExpression
1450 1463
1464 if (allow_arrow_functions() && peek() == Token::RPAREN) {
marja 2014/03/24 09:04:06 This doesn't sound right. I guess the idea is that
aperez 2014/04/09 08:47:16 It was causing an unexpected token error most of t
1465 // Empty argument list for arrow functions: () => ...
1466 return this->EmptyExpression();
1467 }
1468
1451 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK); 1469 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1452 while (peek() == Token::COMMA) { 1470 while (peek() == Token::COMMA) {
1453 Expect(Token::COMMA, CHECK_OK); 1471 Expect(Token::COMMA, CHECK_OK);
1454 int pos = position(); 1472 int pos = position();
1455 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); 1473 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1456 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); 1474 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
1457 } 1475 }
1458 return result; 1476 return result;
1459 } 1477 }
1460 1478
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1543 return this->EmptyLiteral(); 1561 return this->EmptyLiteral();
1544 } 1562 }
1545 // Validate the property. 1563 // Validate the property.
1546 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; 1564 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1547 checker.CheckProperty(next, type, CHECK_OK); 1565 checker.CheckProperty(next, type, CHECK_OK);
1548 IdentifierT name = this->GetSymbol(scanner_); 1566 IdentifierT name = this->GetSymbol(scanner_);
1549 typename Traits::Type::FunctionLiteral value = 1567 typename Traits::Type::FunctionLiteral value =
1550 this->ParseFunctionLiteral( 1568 this->ParseFunctionLiteral(
1551 name, scanner()->location(), 1569 name, scanner()->location(),
1552 false, // reserved words are allowed here 1570 false, // reserved words are allowed here
1553 false, // not a generator 1571 kNormalFunction,
1572 this->EmptyExpression(),
1554 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, 1573 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
1555 CHECK_OK); 1574 CHECK_OK);
1556 // Allow any number of parameters for compatibilty with JSC. 1575 // Allow any number of parameters for compatibilty with JSC.
1557 // Specification only allows zero parameters for get and one for set. 1576 // Specification only allows zero parameters for get and one for set.
1558 typename Traits::Type::ObjectLiteralProperty property = 1577 typename Traits::Type::ObjectLiteralProperty property =
1559 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); 1578 factory()->NewObjectLiteralProperty(is_getter, value, next_pos);
1560 if (this->IsBoilerplateProperty(property)) { 1579 if (this->IsBoilerplateProperty(property)) {
1561 number_of_boilerplate_properties++; 1580 number_of_boilerplate_properties++;
1562 } 1581 }
1563 properties->Add(property, zone()); 1582 properties->Add(property, zone());
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1681 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 1700 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1682 return result; 1701 return result;
1683 } 1702 }
1684 1703
1685 // Precedence = 2 1704 // Precedence = 2
1686 template <class Traits> 1705 template <class Traits>
1687 typename ParserBase<Traits>::ExpressionT 1706 typename ParserBase<Traits>::ExpressionT
1688 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { 1707 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
1689 // AssignmentExpression :: 1708 // AssignmentExpression ::
1690 // ConditionalExpression 1709 // ConditionalExpression
1710 // ArrowFunction
1691 // YieldExpression 1711 // YieldExpression
1692 // LeftHandSideExpression AssignmentOperator AssignmentExpression 1712 // LeftHandSideExpression AssignmentOperator AssignmentExpression
1693 1713
1694 Scanner::Location lhs_location = scanner()->peek_location(); 1714 Scanner::Location lhs_location = scanner()->peek_location();
1695 1715
1696 if (peek() == Token::YIELD && is_generator()) { 1716 if (peek() == Token::YIELD && is_generator()) {
1697 return this->ParseYieldExpression(ok); 1717 return this->ParseYieldExpression(ok);
1698 } 1718 }
1699 1719
1700 if (fni_ != NULL) fni_->Enter(); 1720 if (fni_ != NULL) fni_->Enter();
1701 ExpressionT expression = 1721 ExpressionT expression =
1702 this->ParseConditionalExpression(accept_IN, CHECK_OK); 1722 this->ParseConditionalExpression(accept_IN, CHECK_OK);
1703 1723
1724 if (allow_arrow_functions() && peek() == Token::ARROW) {
1725 return this->ParseFunctionLiteral(Traits::EmptyIdentifier(),
1726 Scanner::Location::invalid(),
1727 false,
1728 kArrowFunction,
1729 expression,
1730 lhs_location.beg_pos,
1731 FunctionLiteral::ANONYMOUS_EXPRESSION,
1732 CHECK_OK);
1733 }
1734
1704 if (!Token::IsAssignmentOp(peek())) { 1735 if (!Token::IsAssignmentOp(peek())) {
1705 if (fni_ != NULL) fni_->Leave(); 1736 if (fni_ != NULL) fni_->Leave();
1706 // Parsed conditional expression only (no assignment). 1737 // Parsed conditional expression only (no assignment).
1707 return expression; 1738 return expression;
1708 } 1739 }
1709 1740
1710 if (!expression->IsValidLeftHandSide()) { 1741 if (!expression->IsValidLeftHandSide()) {
1711 this->ReportMessageAt(lhs_location, "invalid_lhs_in_assignment", true); 1742 this->ReportMessageAt(lhs_location, "invalid_lhs_in_assignment", true);
1712 *ok = false; 1743 *ok = false;
1713 return this->EmptyExpression(); 1744 return this->EmptyExpression();
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
2055 2086
2056 // The '[' Expression ']' and '.' Identifier parts are parsed by 2087 // The '[' Expression ']' and '.' Identifier parts are parsed by
2057 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the 2088 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
2058 // caller. 2089 // caller.
2059 2090
2060 // Parse the initial primary or function expression. 2091 // Parse the initial primary or function expression.
2061 ExpressionT result = this->EmptyExpression(); 2092 ExpressionT result = this->EmptyExpression();
2062 if (peek() == Token::FUNCTION) { 2093 if (peek() == Token::FUNCTION) {
2063 Consume(Token::FUNCTION); 2094 Consume(Token::FUNCTION);
2064 int function_token_position = position(); 2095 int function_token_position = position();
2065 bool is_generator = allow_generators() && Check(Token::MUL); 2096 FunctionParsingMode parsing_mode =
2097 (allow_generators() && Check(Token::MUL))
2098 ? kGeneratorFunction
2099 : kNormalFunction;
2066 IdentifierT name; 2100 IdentifierT name;
2067 bool is_strict_reserved_name = false; 2101 bool is_strict_reserved_name = false;
2068 Scanner::Location function_name_location = Scanner::Location::invalid(); 2102 Scanner::Location function_name_location = Scanner::Location::invalid();
2069 FunctionLiteral::FunctionType function_type = 2103 FunctionLiteral::FunctionType function_type =
2070 FunctionLiteral::ANONYMOUS_EXPRESSION; 2104 FunctionLiteral::ANONYMOUS_EXPRESSION;
2071 if (peek_any_identifier()) { 2105 if (peek_any_identifier()) {
2072 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, 2106 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
2073 CHECK_OK); 2107 CHECK_OK);
2074 function_name_location = scanner()->location(); 2108 function_name_location = scanner()->location();
2075 function_type = FunctionLiteral::NAMED_EXPRESSION; 2109 function_type = FunctionLiteral::NAMED_EXPRESSION;
2076 } 2110 }
2077 result = this->ParseFunctionLiteral(name, 2111 result = this->ParseFunctionLiteral(name,
2078 function_name_location, 2112 function_name_location,
2079 is_strict_reserved_name, 2113 is_strict_reserved_name,
2080 is_generator, 2114 parsing_mode,
2115 this->EmptyExpression(),
2081 function_token_position, 2116 function_token_position,
2082 function_type, 2117 function_type,
2083 CHECK_OK); 2118 CHECK_OK);
2084 } else { 2119 } else {
2085 result = ParsePrimaryExpression(CHECK_OK); 2120 result = ParsePrimaryExpression(CHECK_OK);
2086 } 2121 }
2087 2122
2088 result = ParseMemberExpressionContinuation(result, CHECK_OK); 2123 result = ParseMemberExpressionContinuation(result, CHECK_OK);
2089 return result; 2124 return result;
2090 } 2125 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2162 "accessor_get_set"); 2197 "accessor_get_set");
2163 } 2198 }
2164 *ok = false; 2199 *ok = false;
2165 } 2200 }
2166 } 2201 }
2167 2202
2168 2203
2169 } } // v8::internal 2204 } } // v8::internal
2170 2205
2171 #endif // V8_PREPARSER_H 2206 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698