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

Side by Side Diff: src/scanner.h

Issue 663683006: Implement ES6 Template Literals (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Implement tagged template literals 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
« no previous file with comments | « src/prettyprinter.cc ('k') | src/scanner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 // Features shared by parsing and pre-parsing scanners. 5 // Features shared by parsing and pre-parsing scanners.
6 6
7 #ifndef V8_SCANNER_H_ 7 #ifndef V8_SCANNER_H_
8 #define V8_SCANNER_H_ 8 #define V8_SCANNER_H_
9 9
10 #include "src/allocation.h" 10 #include "src/allocation.h"
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 bool is_literal_contextual_keyword(Vector<const char> keyword) { 384 bool is_literal_contextual_keyword(Vector<const char> keyword) {
385 DCHECK_NOT_NULL(current_.literal_chars); 385 DCHECK_NOT_NULL(current_.literal_chars);
386 return current_.literal_chars->is_contextual_keyword(keyword); 386 return current_.literal_chars->is_contextual_keyword(keyword);
387 } 387 }
388 bool is_next_contextual_keyword(Vector<const char> keyword) { 388 bool is_next_contextual_keyword(Vector<const char> keyword) {
389 DCHECK_NOT_NULL(next_.literal_chars); 389 DCHECK_NOT_NULL(next_.literal_chars);
390 return next_.literal_chars->is_contextual_keyword(keyword); 390 return next_.literal_chars->is_contextual_keyword(keyword);
391 } 391 }
392 392
393 const AstRawString* CurrentSymbol(AstValueFactory* ast_value_factory); 393 const AstRawString* CurrentSymbol(AstValueFactory* ast_value_factory);
394 const AstRawString* CurrentRawSymbol(AstValueFactory* ast_value_factory);
394 const AstRawString* NextSymbol(AstValueFactory* ast_value_factory); 395 const AstRawString* NextSymbol(AstValueFactory* ast_value_factory);
396 const AstRawString* NextRawSymbol(AstValueFactory* ast_value_factory);
395 397
396 double DoubleValue(); 398 double DoubleValue();
397 bool LiteralMatches(const char* data, int length, bool allow_escapes = true) { 399 bool LiteralMatches(const char* data, int length, bool allow_escapes = true) {
398 if (is_literal_one_byte() && 400 if (is_literal_one_byte() &&
399 literal_length() == length && 401 literal_length() == length &&
400 (allow_escapes || !literal_contains_escapes())) { 402 (allow_escapes || !literal_contains_escapes())) {
401 const char* token = 403 const char* token =
402 reinterpret_cast<const char*>(literal_one_byte_string().start()); 404 reinterpret_cast<const char*>(literal_one_byte_string().start());
403 return !strncmp(token, data, length); 405 return !strncmp(token, data, length);
404 } 406 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 } 453 }
452 void SetHarmonyNumericLiterals(bool numeric_literals) { 454 void SetHarmonyNumericLiterals(bool numeric_literals) {
453 harmony_numeric_literals_ = numeric_literals; 455 harmony_numeric_literals_ = numeric_literals;
454 } 456 }
455 bool HarmonyClasses() const { 457 bool HarmonyClasses() const {
456 return harmony_classes_; 458 return harmony_classes_;
457 } 459 }
458 void SetHarmonyClasses(bool classes) { 460 void SetHarmonyClasses(bool classes) {
459 harmony_classes_ = classes; 461 harmony_classes_ = classes;
460 } 462 }
463 bool HarmonyTemplates() const { return harmony_templates_; }
464 void SetHarmonyTemplates(bool templates) { harmony_templates_ = templates; }
461 465
462 // Returns true if there was a line terminator before the peek'ed token, 466 // Returns true if there was a line terminator before the peek'ed token,
463 // possibly inside a multi-line comment. 467 // possibly inside a multi-line comment.
464 bool HasAnyLineTerminatorBeforeNext() const { 468 bool HasAnyLineTerminatorBeforeNext() const {
465 return has_line_terminator_before_next_ || 469 return has_line_terminator_before_next_ ||
466 has_multiline_comment_before_next_; 470 has_multiline_comment_before_next_;
467 } 471 }
468 472
469 // Scans the input as a regular expression pattern, previous 473 // Scans the input as a regular expression pattern, previous
470 // character(s) must be /(=). Returns true if a pattern is scanned. 474 // character(s) must be /(=). Returns true if a pattern is scanned.
471 bool ScanRegExpPattern(bool seen_equal); 475 bool ScanRegExpPattern(bool seen_equal);
472 // Returns true if regexp flags are scanned (always since flags can 476 // Returns true if regexp flags are scanned (always since flags can
473 // be empty). 477 // be empty).
474 bool ScanRegExpFlags(); 478 bool ScanRegExpFlags();
475 479
480 // Scans the input as a template literal
481 Token::Value ScanTemplateSpan();
482
476 const LiteralBuffer* source_url() const { return &source_url_; } 483 const LiteralBuffer* source_url() const { return &source_url_; }
477 const LiteralBuffer* source_mapping_url() const { 484 const LiteralBuffer* source_mapping_url() const {
478 return &source_mapping_url_; 485 return &source_mapping_url_;
479 } 486 }
480 487
481 bool IdentifierIsFutureStrictReserved(const AstRawString* string) const; 488 bool IdentifierIsFutureStrictReserved(const AstRawString* string) const;
482 489
483 private: 490 private:
484 // The current and look-ahead token. 491 // The current and look-ahead token.
485 struct TokenDesc { 492 struct TokenDesc {
486 Token::Value token; 493 Token::Value token;
487 Location location; 494 Location location;
488 LiteralBuffer* literal_chars; 495 LiteralBuffer* literal_chars;
496 LiteralBuffer* raw_literal_chars;
489 }; 497 };
490 498
491 static const int kCharacterLookaheadBufferSize = 1; 499 static const int kCharacterLookaheadBufferSize = 1;
492 500
493 // Scans octal escape sequence. Also accepts "\0" decimal escape sequence. 501 // Scans octal escape sequence. Also accepts "\0" decimal escape sequence.
494 uc32 ScanOctalEscape(uc32 c, int length); 502 uc32 ScanOctalEscape(uc32 c, int length, bool recordRaw = false);
495 503
496 // Call this after setting source_ to the input. 504 // Call this after setting source_ to the input.
497 void Init() { 505 void Init() {
498 // Set c0_ (one character ahead) 506 // Set c0_ (one character ahead)
499 STATIC_ASSERT(kCharacterLookaheadBufferSize == 1); 507 STATIC_ASSERT(kCharacterLookaheadBufferSize == 1);
500 Advance(); 508 Advance();
501 // Initialize current_ to not refer to a literal. 509 // Initialize current_ to not refer to a literal.
502 current_.literal_chars = NULL; 510 current_.literal_chars = NULL;
511 current_.raw_literal_chars = NULL;
503 } 512 }
504 513
505 // Literal buffer support 514 // Literal buffer support
506 inline void StartLiteral() { 515 inline void StartLiteral() {
507 LiteralBuffer* free_buffer = (current_.literal_chars == &literal_buffer1_) ? 516 LiteralBuffer* free_buffer = (current_.literal_chars == &literal_buffer1_) ?
508 &literal_buffer2_ : &literal_buffer1_; 517 &literal_buffer2_ : &literal_buffer1_;
518 LiteralBuffer* raw_buffer = (current_.raw_literal_chars == &raw_buffer1_)
519 ? &raw_buffer2_
520 : &raw_buffer1_;
509 free_buffer->Reset(); 521 free_buffer->Reset();
510 next_.literal_chars = free_buffer; 522 next_.literal_chars = free_buffer;
523 next_.raw_literal_chars = raw_buffer;
511 } 524 }
512 525
513 INLINE(void AddLiteralChar(uc32 c)) { 526 INLINE(void AddLiteralChar(uc32 c)) {
514 DCHECK_NOT_NULL(next_.literal_chars); 527 DCHECK_NOT_NULL(next_.literal_chars);
515 next_.literal_chars->AddChar(c); 528 next_.literal_chars->AddChar(c);
516 } 529 }
517 530
531 INLINE(void AddRawLiteralChar(uc32 c)) {
532 DCHECK_NOT_NULL(next_.raw_literal_chars);
533 next_.raw_literal_chars->AddChar(c);
534 }
535
518 // Complete scanning of a literal. 536 // Complete scanning of a literal.
519 inline void TerminateLiteral() { 537 inline void TerminateLiteral() {
520 // Does nothing in the current implementation. 538 // Does nothing in the current implementation.
521 } 539 }
522 540
523 // Stops scanning of a literal and drop the collected characters, 541 // Stops scanning of a literal and drop the collected characters,
524 // e.g., due to an encountered error. 542 // e.g., due to an encountered error.
525 inline void DropLiteral() { 543 inline void DropLiteral() {
526 next_.literal_chars = NULL; 544 next_.literal_chars = NULL;
527 } 545 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 // These functions only give the correct result if the literal 594 // These functions only give the correct result if the literal
577 // was scanned between calls to StartLiteral() and TerminateLiteral(). 595 // was scanned between calls to StartLiteral() and TerminateLiteral().
578 Vector<const uint8_t> literal_one_byte_string() { 596 Vector<const uint8_t> literal_one_byte_string() {
579 DCHECK_NOT_NULL(current_.literal_chars); 597 DCHECK_NOT_NULL(current_.literal_chars);
580 return current_.literal_chars->one_byte_literal(); 598 return current_.literal_chars->one_byte_literal();
581 } 599 }
582 Vector<const uint16_t> literal_two_byte_string() { 600 Vector<const uint16_t> literal_two_byte_string() {
583 DCHECK_NOT_NULL(current_.literal_chars); 601 DCHECK_NOT_NULL(current_.literal_chars);
584 return current_.literal_chars->two_byte_literal(); 602 return current_.literal_chars->two_byte_literal();
585 } 603 }
604 Vector<const uint8_t> raw_one_byte_string() {
605 DCHECK_NOT_NULL(current_.raw_literal_chars);
606 return current_.raw_literal_chars->one_byte_literal();
607 }
608 Vector<const uint16_t> raw_two_byte_string() {
609 DCHECK_NOT_NULL(current_.raw_literal_chars);
610 return current_.raw_literal_chars->two_byte_literal();
611 }
586 bool is_literal_one_byte() { 612 bool is_literal_one_byte() {
587 DCHECK_NOT_NULL(current_.literal_chars); 613 DCHECK_NOT_NULL(current_.literal_chars);
588 return current_.literal_chars->is_one_byte(); 614 return current_.literal_chars->is_one_byte();
589 } 615 }
616 bool is_raw_one_byte() {
617 DCHECK_NOT_NULL(current_.raw_literal_chars);
618 return current_.raw_literal_chars->is_one_byte();
619 }
590 int literal_length() const { 620 int literal_length() const {
591 DCHECK_NOT_NULL(current_.literal_chars); 621 DCHECK_NOT_NULL(current_.literal_chars);
592 return current_.literal_chars->length(); 622 return current_.literal_chars->length();
593 } 623 }
594 // Returns the literal string for the next token (the token that 624 // Returns the literal string for the next token (the token that
595 // would be returned if Next() were called). 625 // would be returned if Next() were called).
596 Vector<const uint8_t> next_literal_one_byte_string() { 626 Vector<const uint8_t> next_literal_one_byte_string() {
597 DCHECK_NOT_NULL(next_.literal_chars); 627 DCHECK_NOT_NULL(next_.literal_chars);
598 return next_.literal_chars->one_byte_literal(); 628 return next_.literal_chars->one_byte_literal();
599 } 629 }
600 Vector<const uint16_t> next_literal_two_byte_string() { 630 Vector<const uint16_t> next_literal_two_byte_string() {
601 DCHECK_NOT_NULL(next_.literal_chars); 631 DCHECK_NOT_NULL(next_.literal_chars);
602 return next_.literal_chars->two_byte_literal(); 632 return next_.literal_chars->two_byte_literal();
603 } 633 }
634 Vector<const uint8_t> next_raw_one_byte_string() {
635 DCHECK_NOT_NULL(next_.raw_literal_chars);
636 return next_.raw_literal_chars->one_byte_literal();
637 }
638 Vector<const uint16_t> next_raw_two_byte_string() {
639 DCHECK_NOT_NULL(next_.raw_literal_chars);
640 return next_.raw_literal_chars->two_byte_literal();
641 }
604 bool is_next_literal_one_byte() { 642 bool is_next_literal_one_byte() {
605 DCHECK_NOT_NULL(next_.literal_chars); 643 DCHECK_NOT_NULL(next_.literal_chars);
606 return next_.literal_chars->is_one_byte(); 644 return next_.literal_chars->is_one_byte();
607 } 645 }
646 bool is_next_raw_one_byte() {
647 DCHECK_NOT_NULL(next_.raw_literal_chars);
648 return next_.raw_literal_chars->is_one_byte();
649 }
608 int next_literal_length() const { 650 int next_literal_length() const {
609 DCHECK_NOT_NULL(next_.literal_chars); 651 DCHECK_NOT_NULL(next_.literal_chars);
610 return next_.literal_chars->length(); 652 return next_.literal_chars->length();
611 } 653 }
612 654
613 uc32 ScanHexNumber(int expected_length); 655 uc32 ScanHexNumber(int expected_length, bool recordRaw = false);
614 656
615 // Scans a single JavaScript token. 657 // Scans a single JavaScript token.
616 void Scan(); 658 void Scan();
617 659
618 bool SkipWhiteSpace(); 660 bool SkipWhiteSpace();
619 Token::Value SkipSingleLineComment(); 661 Token::Value SkipSingleLineComment();
620 Token::Value SkipSourceURLComment(); 662 Token::Value SkipSourceURLComment();
621 void TryToParseSourceURLComment(); 663 void TryToParseSourceURLComment();
622 Token::Value SkipMultiLineComment(); 664 Token::Value SkipMultiLineComment();
623 // Scans a possible HTML comment -- begins with '<!'. 665 // Scans a possible HTML comment -- begins with '<!'.
624 Token::Value ScanHtmlComment(); 666 Token::Value ScanHtmlComment();
625 667
626 void ScanDecimalDigits(); 668 void ScanDecimalDigits();
627 Token::Value ScanNumber(bool seen_period); 669 Token::Value ScanNumber(bool seen_period);
628 Token::Value ScanIdentifierOrKeyword(); 670 Token::Value ScanIdentifierOrKeyword();
629 Token::Value ScanIdentifierSuffix(LiteralScope* literal); 671 Token::Value ScanIdentifierSuffix(LiteralScope* literal);
630 672
631 Token::Value ScanString(); 673 Token::Value ScanString();
632 674
633 // Scans an escape-sequence which is part of a string and adds the 675 // Scans an escape-sequence which is part of a string and adds the
634 // decoded character to the current literal. Returns true if a pattern 676 // decoded character to the current literal. Returns true if a pattern
635 // is scanned. 677 // is scanned.
636 bool ScanEscape(); 678 bool ScanEscape(bool recordRaw = false);
637 // Decodes a Unicode escape-sequence which is part of an identifier. 679 // Decodes a Unicode escape-sequence which is part of an identifier.
638 // If the escape sequence cannot be decoded the result is kBadChar. 680 // If the escape sequence cannot be decoded the result is kBadChar.
639 uc32 ScanIdentifierUnicodeEscape(); 681 uc32 ScanIdentifierUnicodeEscape();
640 // Scans a Unicode escape-sequence and adds its characters, 682 // Scans a Unicode escape-sequence and adds its characters,
641 // uninterpreted, to the current literal. Used for parsing RegExp 683 // uninterpreted, to the current literal. Used for parsing RegExp
642 // flags. 684 // flags.
643 bool ScanLiteralUnicodeEscape(); 685 bool ScanLiteralUnicodeEscape();
644 686
645 // Return the current source position. 687 // Return the current source position.
646 int source_pos() { 688 int source_pos() {
647 return source_->pos() - kCharacterLookaheadBufferSize; 689 return source_->pos() - kCharacterLookaheadBufferSize;
648 } 690 }
649 691
650 UnicodeCache* unicode_cache_; 692 UnicodeCache* unicode_cache_;
651 693
652 // Buffers collecting literal strings, numbers, etc. 694 // Buffers collecting literal strings, numbers, etc.
653 LiteralBuffer literal_buffer1_; 695 LiteralBuffer literal_buffer1_;
654 LiteralBuffer literal_buffer2_; 696 LiteralBuffer literal_buffer2_;
655 697
698 // Buffer to store raw string values
699 LiteralBuffer raw_buffer1_;
700 LiteralBuffer raw_buffer2_;
701
656 // Values parsed from magic comments. 702 // Values parsed from magic comments.
657 LiteralBuffer source_url_; 703 LiteralBuffer source_url_;
658 LiteralBuffer source_mapping_url_; 704 LiteralBuffer source_mapping_url_;
659 705
660 TokenDesc current_; // desc for current token (as returned by Next()) 706 TokenDesc current_; // desc for current token (as returned by Next())
661 TokenDesc next_; // desc for next token (one token look-ahead) 707 TokenDesc next_; // desc for next token (one token look-ahead)
662 708
663 // Input stream. Must be initialized to an Utf16CharacterStream. 709 // Input stream. Must be initialized to an Utf16CharacterStream.
664 Utf16CharacterStream* source_; 710 Utf16CharacterStream* source_;
665 711
(...skipping 12 matching lines...) Expand all
678 // line-terminator after the current token, and before the next. 724 // line-terminator after the current token, and before the next.
679 bool has_multiline_comment_before_next_; 725 bool has_multiline_comment_before_next_;
680 // Whether we scan 'let' as a keyword for harmony block-scoped let bindings. 726 // Whether we scan 'let' as a keyword for harmony block-scoped let bindings.
681 bool harmony_scoping_; 727 bool harmony_scoping_;
682 // Whether we scan 'module', 'import', 'export' as keywords. 728 // Whether we scan 'module', 'import', 'export' as keywords.
683 bool harmony_modules_; 729 bool harmony_modules_;
684 // Whether we scan 0o777 and 0b111 as numbers. 730 // Whether we scan 0o777 and 0b111 as numbers.
685 bool harmony_numeric_literals_; 731 bool harmony_numeric_literals_;
686 // Whether we scan 'class', 'extends', 'static' and 'super' as keywords. 732 // Whether we scan 'class', 'extends', 'static' and 'super' as keywords.
687 bool harmony_classes_; 733 bool harmony_classes_;
734 // Whether we scan TEMPLATE_SPAN and TEMPLATE_TAIL
735 bool harmony_templates_;
688 }; 736 };
689 737
690 } } // namespace v8::internal 738 } } // namespace v8::internal
691 739
692 #endif // V8_SCANNER_H_ 740 #endif // V8_SCANNER_H_
OLDNEW
« no previous file with comments | « src/prettyprinter.cc ('k') | src/scanner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698