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 #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/func-name-inferrer.h" | 10 #include "src/func-name-inferrer.h" |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 return; | 294 return; |
295 } | 295 } |
296 Expect(Token::SEMICOLON, ok); | 296 Expect(Token::SEMICOLON, ok); |
297 } | 297 } |
298 | 298 |
299 bool peek_any_identifier() { | 299 bool peek_any_identifier() { |
300 Token::Value next = peek(); | 300 Token::Value next = peek(); |
301 return next == Token::IDENTIFIER || | 301 return next == Token::IDENTIFIER || |
302 next == Token::FUTURE_RESERVED_WORD || | 302 next == Token::FUTURE_RESERVED_WORD || |
303 next == Token::FUTURE_STRICT_RESERVED_WORD || | 303 next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 304 next == Token::LET || |
304 next == Token::YIELD; | 305 next == Token::YIELD; |
305 } | 306 } |
306 | 307 |
307 bool CheckContextualKeyword(Vector<const char> keyword) { | 308 bool CheckContextualKeyword(Vector<const char> keyword) { |
308 if (peek() == Token::IDENTIFIER && | 309 if (peek() == Token::IDENTIFIER && |
309 scanner()->is_next_contextual_keyword(keyword)) { | 310 scanner()->is_next_contextual_keyword(keyword)) { |
310 Consume(Token::IDENTIFIER); | 311 Consume(Token::IDENTIFIER); |
311 return true; | 312 return true; |
312 } | 313 } |
313 return false; | 314 return false; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 } | 542 } |
542 static PreParserIdentifier Arguments() { | 543 static PreParserIdentifier Arguments() { |
543 return PreParserIdentifier(kArgumentsIdentifier); | 544 return PreParserIdentifier(kArgumentsIdentifier); |
544 } | 545 } |
545 static PreParserIdentifier FutureReserved() { | 546 static PreParserIdentifier FutureReserved() { |
546 return PreParserIdentifier(kFutureReservedIdentifier); | 547 return PreParserIdentifier(kFutureReservedIdentifier); |
547 } | 548 } |
548 static PreParserIdentifier FutureStrictReserved() { | 549 static PreParserIdentifier FutureStrictReserved() { |
549 return PreParserIdentifier(kFutureStrictReservedIdentifier); | 550 return PreParserIdentifier(kFutureStrictReservedIdentifier); |
550 } | 551 } |
| 552 static PreParserIdentifier Let() { |
| 553 return PreParserIdentifier(kLetIdentifier); |
| 554 } |
551 static PreParserIdentifier Yield() { | 555 static PreParserIdentifier Yield() { |
552 return PreParserIdentifier(kYieldIdentifier); | 556 return PreParserIdentifier(kYieldIdentifier); |
553 } | 557 } |
554 bool IsEval() { return type_ == kEvalIdentifier; } | 558 bool IsEval() { return type_ == kEvalIdentifier; } |
555 bool IsArguments() { return type_ == kArgumentsIdentifier; } | 559 bool IsArguments() { return type_ == kArgumentsIdentifier; } |
556 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } | 560 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } |
| 561 bool IsLet() { return type_ == kLetIdentifier; } |
557 bool IsYield() { return type_ == kYieldIdentifier; } | 562 bool IsYield() { return type_ == kYieldIdentifier; } |
558 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } | 563 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } |
559 bool IsFutureStrictReserved() { | 564 bool IsFutureStrictReserved() { |
560 return type_ == kFutureStrictReservedIdentifier; | 565 return type_ == kFutureStrictReservedIdentifier; |
561 } | 566 } |
562 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } | 567 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } |
563 | 568 |
564 private: | 569 private: |
565 enum Type { | 570 enum Type { |
566 kUnknownIdentifier, | 571 kUnknownIdentifier, |
567 kFutureReservedIdentifier, | 572 kFutureReservedIdentifier, |
568 kFutureStrictReservedIdentifier, | 573 kFutureStrictReservedIdentifier, |
| 574 kLetIdentifier, |
569 kYieldIdentifier, | 575 kYieldIdentifier, |
570 kEvalIdentifier, | 576 kEvalIdentifier, |
571 kArgumentsIdentifier | 577 kArgumentsIdentifier |
572 }; | 578 }; |
573 explicit PreParserIdentifier(Type type) : type_(type) {} | 579 explicit PreParserIdentifier(Type type) : type_(type) {} |
574 Type type_; | 580 Type type_; |
575 | 581 |
576 friend class PreParserExpression; | 582 friend class PreParserExpression; |
577 }; | 583 }; |
578 | 584 |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 case Token::EOS: | 1270 case Token::EOS: |
1265 return ReportMessageAt(source_location, "unexpected_eos"); | 1271 return ReportMessageAt(source_location, "unexpected_eos"); |
1266 case Token::NUMBER: | 1272 case Token::NUMBER: |
1267 return ReportMessageAt(source_location, "unexpected_token_number"); | 1273 return ReportMessageAt(source_location, "unexpected_token_number"); |
1268 case Token::STRING: | 1274 case Token::STRING: |
1269 return ReportMessageAt(source_location, "unexpected_token_string"); | 1275 return ReportMessageAt(source_location, "unexpected_token_string"); |
1270 case Token::IDENTIFIER: | 1276 case Token::IDENTIFIER: |
1271 return ReportMessageAt(source_location, "unexpected_token_identifier"); | 1277 return ReportMessageAt(source_location, "unexpected_token_identifier"); |
1272 case Token::FUTURE_RESERVED_WORD: | 1278 case Token::FUTURE_RESERVED_WORD: |
1273 return ReportMessageAt(source_location, "unexpected_reserved"); | 1279 return ReportMessageAt(source_location, "unexpected_reserved"); |
| 1280 case Token::LET: |
1274 case Token::YIELD: | 1281 case Token::YIELD: |
1275 case Token::FUTURE_STRICT_RESERVED_WORD: | 1282 case Token::FUTURE_STRICT_RESERVED_WORD: |
1276 return ReportMessageAt(source_location, strict_mode() == SLOPPY | 1283 return ReportMessageAt(source_location, strict_mode() == SLOPPY |
1277 ? "unexpected_token_identifier" : "unexpected_strict_reserved"); | 1284 ? "unexpected_token_identifier" : "unexpected_strict_reserved"); |
1278 default: | 1285 default: |
1279 const char* name = Token::String(token); | 1286 const char* name = Token::String(token); |
1280 ASSERT(name != NULL); | 1287 ASSERT(name != NULL); |
1281 Traits::ReportMessageAt(source_location, "unexpected_token", name); | 1288 Traits::ReportMessageAt(source_location, "unexpected_token", name); |
1282 } | 1289 } |
1283 } | 1290 } |
1284 | 1291 |
1285 | 1292 |
1286 template<class Traits> | 1293 template<class Traits> |
1287 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( | 1294 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( |
1288 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, | 1295 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, |
1289 bool* ok) { | 1296 bool* ok) { |
1290 Token::Value next = Next(); | 1297 Token::Value next = Next(); |
1291 if (next == Token::IDENTIFIER) { | 1298 if (next == Token::IDENTIFIER) { |
1292 IdentifierT name = this->GetSymbol(scanner()); | 1299 IdentifierT name = this->GetSymbol(scanner()); |
1293 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && | 1300 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && |
1294 strict_mode() == STRICT && this->IsEvalOrArguments(name)) { | 1301 strict_mode() == STRICT && this->IsEvalOrArguments(name)) { |
1295 ReportMessage("strict_eval_arguments"); | 1302 ReportMessage("strict_eval_arguments"); |
1296 *ok = false; | 1303 *ok = false; |
1297 } | 1304 } |
1298 return name; | 1305 return name; |
1299 } else if (strict_mode() == SLOPPY && | 1306 } else if (strict_mode() == SLOPPY && |
1300 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 1307 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 1308 (next == Token::LET) || |
1301 (next == Token::YIELD && !is_generator()))) { | 1309 (next == Token::YIELD && !is_generator()))) { |
1302 return this->GetSymbol(scanner()); | 1310 return this->GetSymbol(scanner()); |
1303 } else { | 1311 } else { |
1304 this->ReportUnexpectedToken(next); | 1312 this->ReportUnexpectedToken(next); |
1305 *ok = false; | 1313 *ok = false; |
1306 return Traits::EmptyIdentifier(); | 1314 return Traits::EmptyIdentifier(); |
1307 } | 1315 } |
1308 } | 1316 } |
1309 | 1317 |
1310 | 1318 |
1311 template <class Traits> | 1319 template <class Traits> |
1312 typename ParserBase<Traits>::IdentifierT ParserBase< | 1320 typename ParserBase<Traits>::IdentifierT ParserBase< |
1313 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, | 1321 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, |
1314 bool* ok) { | 1322 bool* ok) { |
1315 Token::Value next = Next(); | 1323 Token::Value next = Next(); |
1316 if (next == Token::IDENTIFIER) { | 1324 if (next == Token::IDENTIFIER) { |
1317 *is_strict_reserved = false; | 1325 *is_strict_reserved = false; |
1318 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || | 1326 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 1327 next == Token::LET || |
1319 (next == Token::YIELD && !this->is_generator())) { | 1328 (next == Token::YIELD && !this->is_generator())) { |
1320 *is_strict_reserved = true; | 1329 *is_strict_reserved = true; |
1321 } else { | 1330 } else { |
1322 ReportUnexpectedToken(next); | 1331 ReportUnexpectedToken(next); |
1323 *ok = false; | 1332 *ok = false; |
1324 return Traits::EmptyIdentifier(); | 1333 return Traits::EmptyIdentifier(); |
1325 } | 1334 } |
1326 return this->GetSymbol(scanner()); | 1335 return this->GetSymbol(scanner()); |
1327 } | 1336 } |
1328 | 1337 |
1329 | 1338 |
1330 template <class Traits> | 1339 template <class Traits> |
1331 typename ParserBase<Traits>::IdentifierT | 1340 typename ParserBase<Traits>::IdentifierT |
1332 ParserBase<Traits>::ParseIdentifierName(bool* ok) { | 1341 ParserBase<Traits>::ParseIdentifierName(bool* ok) { |
1333 Token::Value next = Next(); | 1342 Token::Value next = Next(); |
1334 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && | 1343 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && |
| 1344 next != Token::LET && next != Token::YIELD && |
1335 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { | 1345 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { |
1336 this->ReportUnexpectedToken(next); | 1346 this->ReportUnexpectedToken(next); |
1337 *ok = false; | 1347 *ok = false; |
1338 return Traits::EmptyIdentifier(); | 1348 return Traits::EmptyIdentifier(); |
1339 } | 1349 } |
1340 return this->GetSymbol(scanner()); | 1350 return this->GetSymbol(scanner()); |
1341 } | 1351 } |
1342 | 1352 |
1343 | 1353 |
1344 template <class Traits> | 1354 template <class Traits> |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1420 | 1430 |
1421 case Token::NULL_LITERAL: | 1431 case Token::NULL_LITERAL: |
1422 case Token::TRUE_LITERAL: | 1432 case Token::TRUE_LITERAL: |
1423 case Token::FALSE_LITERAL: | 1433 case Token::FALSE_LITERAL: |
1424 case Token::NUMBER: | 1434 case Token::NUMBER: |
1425 Next(); | 1435 Next(); |
1426 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); | 1436 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); |
1427 break; | 1437 break; |
1428 | 1438 |
1429 case Token::IDENTIFIER: | 1439 case Token::IDENTIFIER: |
| 1440 case Token::LET: |
1430 case Token::YIELD: | 1441 case Token::YIELD: |
1431 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1442 case Token::FUTURE_STRICT_RESERVED_WORD: { |
1432 // Using eval or arguments in this context is OK even in strict mode. | 1443 // Using eval or arguments in this context is OK even in strict mode. |
1433 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1444 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
1434 result = this->ExpressionFromIdentifier(name, pos, scope_, factory()); | 1445 result = this->ExpressionFromIdentifier(name, pos, scope_, factory()); |
1435 break; | 1446 break; |
1436 } | 1447 } |
1437 | 1448 |
1438 case Token::STRING: { | 1449 case Token::STRING: { |
1439 Consume(Token::STRING); | 1450 Consume(Token::STRING); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1557 while (peek() != Token::RBRACE) { | 1568 while (peek() != Token::RBRACE) { |
1558 if (fni_ != NULL) fni_->Enter(); | 1569 if (fni_ != NULL) fni_->Enter(); |
1559 | 1570 |
1560 typename Traits::Type::Literal key = this->EmptyLiteral(); | 1571 typename Traits::Type::Literal key = this->EmptyLiteral(); |
1561 Token::Value next = peek(); | 1572 Token::Value next = peek(); |
1562 int next_pos = peek_position(); | 1573 int next_pos = peek_position(); |
1563 | 1574 |
1564 switch (next) { | 1575 switch (next) { |
1565 case Token::FUTURE_RESERVED_WORD: | 1576 case Token::FUTURE_RESERVED_WORD: |
1566 case Token::FUTURE_STRICT_RESERVED_WORD: | 1577 case Token::FUTURE_STRICT_RESERVED_WORD: |
| 1578 case Token::LET: |
| 1579 case Token::YIELD: |
1567 case Token::IDENTIFIER: { | 1580 case Token::IDENTIFIER: { |
1568 bool is_getter = false; | 1581 bool is_getter = false; |
1569 bool is_setter = false; | 1582 bool is_setter = false; |
1570 IdentifierT id = | 1583 IdentifierT id = |
1571 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | 1584 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); |
1572 if (fni_ != NULL) this->PushLiteralName(fni_, id); | 1585 if (fni_ != NULL) this->PushLiteralName(fni_, id); |
1573 | 1586 |
1574 if ((is_getter || is_setter) && peek() != Token::COLON) { | 1587 if ((is_getter || is_setter) && peek() != Token::COLON) { |
1575 // Special handling of getter and setter syntax: | 1588 // Special handling of getter and setter syntax: |
1576 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } | 1589 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } |
1577 // We have already read the "get" or "set" keyword. | 1590 // We have already read the "get" or "set" keyword. |
1578 Token::Value next = Next(); | 1591 Token::Value next = Next(); |
1579 if (next != i::Token::IDENTIFIER && | 1592 if (next != i::Token::IDENTIFIER && |
1580 next != i::Token::FUTURE_RESERVED_WORD && | 1593 next != i::Token::FUTURE_RESERVED_WORD && |
1581 next != i::Token::FUTURE_STRICT_RESERVED_WORD && | 1594 next != i::Token::FUTURE_STRICT_RESERVED_WORD && |
| 1595 next != i::Token::LET && |
| 1596 next != i::Token::YIELD && |
1582 next != i::Token::NUMBER && | 1597 next != i::Token::NUMBER && |
1583 next != i::Token::STRING && | 1598 next != i::Token::STRING && |
1584 !Token::IsKeyword(next)) { | 1599 !Token::IsKeyword(next)) { |
1585 ReportUnexpectedToken(next); | 1600 ReportUnexpectedToken(next); |
1586 *ok = false; | 1601 *ok = false; |
1587 return this->EmptyLiteral(); | 1602 return this->EmptyLiteral(); |
1588 } | 1603 } |
1589 // Validate the property. | 1604 // Validate the property. |
1590 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; | 1605 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; |
1591 checker.CheckProperty(next, type, CHECK_OK); | 1606 checker.CheckProperty(next, type, CHECK_OK); |
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2226 parser()->ReportMessage("accessor_get_set"); | 2241 parser()->ReportMessage("accessor_get_set"); |
2227 } | 2242 } |
2228 *ok = false; | 2243 *ok = false; |
2229 } | 2244 } |
2230 } | 2245 } |
2231 | 2246 |
2232 | 2247 |
2233 } } // v8::internal | 2248 } } // v8::internal |
2234 | 2249 |
2235 #endif // V8_PREPARSER_H | 2250 #endif // V8_PREPARSER_H |
OLD | NEW |