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

Side by Side Diff: src/preparser.h

Issue 663683006: Implement ES6 Template Literals (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month 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 // 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 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/bailout-reason.h" 10 #include "src/bailout-reason.h"
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 bool allow_arrow_functions() const { return allow_arrow_functions_; } 95 bool allow_arrow_functions() const { return allow_arrow_functions_; }
96 bool allow_modules() const { return scanner()->HarmonyModules(); } 96 bool allow_modules() const { return scanner()->HarmonyModules(); }
97 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } 97 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
98 bool allow_harmony_numeric_literals() const { 98 bool allow_harmony_numeric_literals() const {
99 return scanner()->HarmonyNumericLiterals(); 99 return scanner()->HarmonyNumericLiterals();
100 } 100 }
101 bool allow_classes() const { return scanner()->HarmonyClasses(); } 101 bool allow_classes() const { return scanner()->HarmonyClasses(); }
102 bool allow_harmony_object_literals() const { 102 bool allow_harmony_object_literals() const {
103 return allow_harmony_object_literals_; 103 return allow_harmony_object_literals_;
104 } 104 }
105 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); }
105 106
106 // Setters that determine whether certain syntactical constructs are 107 // Setters that determine whether certain syntactical constructs are
107 // allowed to be parsed by this instance of the parser. 108 // allowed to be parsed by this instance of the parser.
108 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } 109 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
109 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } 110 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
110 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; } 111 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; }
111 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } 112 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
112 void set_allow_harmony_scoping(bool allow) { 113 void set_allow_harmony_scoping(bool allow) {
113 scanner()->SetHarmonyScoping(allow); 114 scanner()->SetHarmonyScoping(allow);
114 } 115 }
115 void set_allow_harmony_numeric_literals(bool allow) { 116 void set_allow_harmony_numeric_literals(bool allow) {
116 scanner()->SetHarmonyNumericLiterals(allow); 117 scanner()->SetHarmonyNumericLiterals(allow);
117 } 118 }
118 void set_allow_classes(bool allow) { scanner()->SetHarmonyClasses(allow); } 119 void set_allow_classes(bool allow) { scanner()->SetHarmonyClasses(allow); }
119 void set_allow_harmony_object_literals(bool allow) { 120 void set_allow_harmony_object_literals(bool allow) {
120 allow_harmony_object_literals_ = allow; 121 allow_harmony_object_literals_ = allow;
121 } 122 }
123 void set_allow_harmony_templates(bool allow) {
124 scanner()->SetHarmonyTemplates(allow);
125 }
122 126
123 protected: 127 protected:
124 enum AllowEvalOrArgumentsAsIdentifier { 128 enum AllowEvalOrArgumentsAsIdentifier {
125 kAllowEvalOrArguments, 129 kAllowEvalOrArguments,
126 kDontAllowEvalOrArguments 130 kDontAllowEvalOrArguments
127 }; 131 };
128 132
129 enum Mode { 133 enum Mode {
130 PARSE_LAZILY, 134 PARSE_LAZILY,
131 PARSE_EAGERLY 135 PARSE_EAGERLY
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 bool stack_overflow() const { return stack_overflow_; } 278 bool stack_overflow() const { return stack_overflow_; }
275 void set_stack_overflow() { stack_overflow_ = true; } 279 void set_stack_overflow() { stack_overflow_ = true; }
276 Mode mode() const { return mode_; } 280 Mode mode() const { return mode_; }
277 typename Traits::Type::Zone* zone() const { return zone_; } 281 typename Traits::Type::Zone* zone() const { return zone_; }
278 282
279 INLINE(Token::Value peek()) { 283 INLINE(Token::Value peek()) {
280 if (stack_overflow_) return Token::ILLEGAL; 284 if (stack_overflow_) return Token::ILLEGAL;
281 return scanner()->peek(); 285 return scanner()->peek();
282 } 286 }
283 287
284 INLINE(Token::Value Next()) { 288 INLINE(Token::Value Next(Scanner::Mode mode = Scanner::None)) {
285 if (stack_overflow_) return Token::ILLEGAL; 289 if (stack_overflow_) return Token::ILLEGAL;
286 { 290 {
287 if (GetCurrentStackPosition() < stack_limit_) { 291 if (GetCurrentStackPosition() < stack_limit_) {
288 // Any further calls to Next or peek will return the illegal token. 292 // Any further calls to Next or peek will return the illegal token.
289 // The current call must return the next token, which might already 293 // The current call must return the next token, which might already
290 // have been peek'ed. 294 // have been peek'ed.
291 stack_overflow_ = true; 295 stack_overflow_ = true;
292 } 296 }
293 } 297 }
294 return scanner()->Next(); 298 return scanner()->Next(mode);
295 } 299 }
296 300
297 void Consume(Token::Value token) { 301 void Consume(Token::Value token) {
298 Token::Value next = Next(); 302 Token::Value next = Next();
299 USE(next); 303 USE(next);
300 USE(token); 304 USE(token);
301 DCHECK(next == token); 305 DCHECK(next == token);
302 } 306 }
303 307
304 bool Check(Token::Value token) { 308 bool Check(Token::Value token) {
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 ExpressionT ParseMemberExpression(bool* ok); 493 ExpressionT ParseMemberExpression(bool* ok);
490 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 494 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
491 bool* ok); 495 bool* ok);
492 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, 496 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
493 bool* ok); 497 bool* ok);
494 ExpressionT ParseClassLiteral(IdentifierT name, 498 ExpressionT ParseClassLiteral(IdentifierT name,
495 Scanner::Location function_name_location, 499 Scanner::Location function_name_location,
496 bool name_is_strict_reserved, int pos, 500 bool name_is_strict_reserved, int pos,
497 bool* ok); 501 bool* ok);
498 502
503 void AddTemplateSpan();
504 void AddTemplateExpression(ExpressionT);
505
499 // Checks if the expression is a valid reference expression (e.g., on the 506 // Checks if the expression is a valid reference expression (e.g., on the
500 // left-hand side of assignments). Although ruled out by ECMA as early errors, 507 // left-hand side of assignments). Although ruled out by ECMA as early errors,
501 // we allow calls for web compatibility and rewrite them to a runtime throw. 508 // we allow calls for web compatibility and rewrite them to a runtime throw.
502 ExpressionT CheckAndRewriteReferenceExpression( 509 ExpressionT CheckAndRewriteReferenceExpression(
503 ExpressionT expression, 510 ExpressionT expression,
504 Scanner::Location location, const char* message, bool* ok); 511 Scanner::Location location, const char* message, bool* ok);
505 512
506 // Used to detect duplicates in object literals. Each of the values 513 // Used to detect duplicates in object literals. Each of the values
507 // kGetterProperty, kSetterProperty and kValueProperty represents 514 // kGetterProperty, kSetterProperty and kValueProperty represents
508 // a type of object literal property. When parsing a property, its 515 // a type of object literal property. When parsing a property, its
(...skipping 860 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 // Utility functions 1376 // Utility functions
1370 int DeclareArrowParametersFromExpression(PreParserExpression expression, 1377 int DeclareArrowParametersFromExpression(PreParserExpression expression,
1371 PreParserScope* scope, 1378 PreParserScope* scope,
1372 Scanner::Location* dupe_loc, 1379 Scanner::Location* dupe_loc,
1373 bool* ok) { 1380 bool* ok) {
1374 // TODO(aperez): Detect duplicated identifiers in paramlists. 1381 // TODO(aperez): Detect duplicated identifiers in paramlists.
1375 *ok = expression.IsValidArrowParamList(); 1382 *ok = expression.IsValidArrowParamList();
1376 return 0; 1383 return 0;
1377 } 1384 }
1378 1385
1386 struct TemplateLiteralState {};
1387
1388 TemplateLiteralState OpenTemplateLiteral() { return TemplateLiteralState(); }
1389 void AddTemplateSpan(TemplateLiteralState* state) { USE(state); }
1390 void AddTemplateExpression(TemplateLiteralState* state,
1391 PreParserExpression expression) {
1392 USE(state);
1393 USE(expression);
1394 }
1395 PreParserExpression CloseTemplateLiteral(TemplateLiteralState* state,
1396 int pos) {
1397 USE(state);
1398 USE(pos);
1399 return EmptyExpression();
1400 }
1401
1379 static AstValueFactory* ast_value_factory() { return NULL; } 1402 static AstValueFactory* ast_value_factory() { return NULL; }
1380 1403
1381 void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {} 1404 void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {}
1382 1405
1383 // Temporary glue; these functions will move to ParserBase. 1406 // Temporary glue; these functions will move to ParserBase.
1384 PreParserExpression ParseV8Intrinsic(bool* ok); 1407 PreParserExpression ParseV8Intrinsic(bool* ok);
1385 PreParserExpression ParseFunctionLiteral( 1408 PreParserExpression ParseFunctionLiteral(
1386 PreParserIdentifier name, Scanner::Location function_name_location, 1409 PreParserIdentifier name, Scanner::Location function_name_location,
1387 bool name_is_strict_reserved, FunctionKind kind, 1410 bool name_is_strict_reserved, FunctionKind kind,
1388 int function_token_position, FunctionLiteral::FunctionType type, 1411 int function_token_position, FunctionLiteral::FunctionType type,
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
1738 // 'true' 1761 // 'true'
1739 // 'false' 1762 // 'false'
1740 // Identifier 1763 // Identifier
1741 // Number 1764 // Number
1742 // String 1765 // String
1743 // ArrayLiteral 1766 // ArrayLiteral
1744 // ObjectLiteral 1767 // ObjectLiteral
1745 // RegExpLiteral 1768 // RegExpLiteral
1746 // ClassLiteral 1769 // ClassLiteral
1747 // '(' Expression ')' 1770 // '(' Expression ')'
1771 // TemplateLiteral
1748 1772
1749 int pos = peek_position(); 1773 int pos = peek_position();
1750 ExpressionT result = this->EmptyExpression(); 1774 ExpressionT result = this->EmptyExpression();
1751 Token::Value token = peek(); 1775 Token::Value token = peek();
1752 switch (token) { 1776 switch (token) {
1753 case Token::THIS: { 1777 case Token::THIS: {
1754 Consume(Token::THIS); 1778 Consume(Token::THIS);
1755 scope_->RecordThisUsage(); 1779 scope_->RecordThisUsage();
1756 result = this->ThisExpression(scope_, factory()); 1780 result = this->ThisExpression(scope_, factory());
1757 break; 1781 break;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1833 } 1857 }
1834 1858
1835 case Token::MOD: 1859 case Token::MOD:
1836 if (allow_natives_syntax() || extension_ != NULL) { 1860 if (allow_natives_syntax() || extension_ != NULL) {
1837 result = this->ParseV8Intrinsic(CHECK_OK); 1861 result = this->ParseV8Intrinsic(CHECK_OK);
1838 break; 1862 break;
1839 } 1863 }
1840 // If we're not allowing special syntax we fall-through to the 1864 // If we're not allowing special syntax we fall-through to the
1841 // default case. 1865 // default case.
1842 1866
1867 case Token::TEMPLATE_SPAN: {
1868 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral();
1869 // Add TV / TRV
1870 Consume(Token::TEMPLATE_SPAN);
1871 int pos = position();
1872 Traits::AddTemplateSpan(&ts);
1873
1874 for (;;) {
1875 Token::Value next = peek();
1876 if (next < 0) {
1877 ReportMessage("unterminated_template");
1878 *ok = false;
1879 return Traits::EmptyExpression();
1880 }
1881
1882 // Parse an Expression
1883 ExpressionT expression = this->ParseExpression(false, CHECK_OK);
1884 Traits::AddTemplateExpression(&ts, expression);
1885
1886 // If we didn't die parsing that expression, our next token should be a
1887 // TEMPLATE_SPAN or
1888 // TEMPLATE_TAIL.
1889 next = Next(Scanner::TemplateLiteral);
1890 if (next == Token::ILLEGAL || next < 0) {
1891 ReportMessage("unterminated_template");
1892 *ok = false;
1893 return Traits::EmptyExpression();
1894 }
1895
1896 CHECK(next == Token::TEMPLATE_SPAN || next == Token::TEMPLATE_TAIL);
1897 Traits::AddTemplateSpan(&ts);
1898
1899 if (next == Token::TEMPLATE_TAIL) {
1900 break;
1901 }
1902 }
1903 result = Traits::CloseTemplateLiteral(&ts, pos);
1904 } break;
1905
1906 case Token::TEMPLATE_TAIL: {
1907 // Close TemplateLiteral
1908 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral();
1909 Consume(Token::TEMPLATE_TAIL);
1910 int pos = position();
1911 Traits::AddTemplateSpan(&ts);
1912 result = Traits::CloseTemplateLiteral(&ts, pos);
1913 } break;
1914
1843 default: { 1915 default: {
1844 Next(); 1916 Next();
1845 ReportUnexpectedToken(token); 1917 ReportUnexpectedToken(token);
1846 *ok = false; 1918 *ok = false;
1847 } 1919 }
1848 } 1920 }
1849 1921
1850 return result; 1922 return result;
1851 } 1923 }
1852 1924
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after
2436 // direct eval calls. These calls are all of the form eval(...), with 2508 // direct eval calls. These calls are all of the form eval(...), with
2437 // no explicit receiver. 2509 // no explicit receiver.
2438 // These calls are marked as potentially direct eval calls. Whether 2510 // These calls are marked as potentially direct eval calls. Whether
2439 // they are actually direct calls to eval is determined at run time. 2511 // they are actually direct calls to eval is determined at run time.
2440 this->CheckPossibleEvalCall(result, scope_); 2512 this->CheckPossibleEvalCall(result, scope_);
2441 result = factory()->NewCall(result, args, pos); 2513 result = factory()->NewCall(result, args, pos);
2442 if (fni_ != NULL) fni_->RemoveLastFunction(); 2514 if (fni_ != NULL) fni_->RemoveLastFunction();
2443 break; 2515 break;
2444 } 2516 }
2445 2517
2518 case Token::TEMPLATE_SPAN:
2519 case Token::TEMPLATE_TAIL: {
2520 ExpressionT templateLiteral = ParsePrimaryExpression(CHECK_OK);
2521 USE(templateLiteral);
2522 // TODO: Make sure we can invoke the tag with the expected parameters.
2523 break;
2524 }
2525
2446 case Token::PERIOD: { 2526 case Token::PERIOD: {
2447 Consume(Token::PERIOD); 2527 Consume(Token::PERIOD);
2448 int pos = position(); 2528 int pos = position();
2449 IdentifierT name = ParseIdentifierName(CHECK_OK); 2529 IdentifierT name = ParseIdentifierName(CHECK_OK);
2450 result = factory()->NewProperty( 2530 result = factory()->NewProperty(
2451 result, factory()->NewStringLiteral(name, pos), pos); 2531 result, factory()->NewStringLiteral(name, pos), pos);
2452 if (fni_ != NULL) this->PushLiteralName(fni_, name); 2532 if (fni_ != NULL) this->PushLiteralName(fni_, name);
2453 break; 2533 break;
2454 } 2534 }
2455 2535
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
2831 DCHECK(IsAccessorAccessorConflict(old_type, type)); 2911 DCHECK(IsAccessorAccessorConflict(old_type, type));
2832 // Both accessors of the same type. 2912 // Both accessors of the same type.
2833 parser()->ReportMessage("accessor_get_set"); 2913 parser()->ReportMessage("accessor_get_set");
2834 } 2914 }
2835 *ok = false; 2915 *ok = false;
2836 } 2916 }
2837 } 2917 }
2838 } } // v8::internal 2918 } } // v8::internal
2839 2919
2840 #endif // V8_PREPARSER_H 2920 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698