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

Side by Side Diff: src/scanner.cc

Issue 663683006: Implement ES6 Template Literals (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix issue with line-continuation, nits 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
« src/parser.cc ('K') | « src/scanner.h ('k') | src/token.h » ('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 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <cmath> 9 #include <cmath>
10 10
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 break; 619 break;
620 620
621 case '?': 621 case '?':
622 token = Select(Token::CONDITIONAL); 622 token = Select(Token::CONDITIONAL);
623 break; 623 break;
624 624
625 case '~': 625 case '~':
626 token = Select(Token::BIT_NOT); 626 token = Select(Token::BIT_NOT);
627 break; 627 break;
628 628
629 case '`':
630 if (HarmonyTemplates()) {
631 token = ScanTemplateSpan();
632 break;
633 }
634
629 default: 635 default:
630 if (c0_ < 0) { 636 if (c0_ < 0) {
631 token = Token::EOS; 637 token = Token::EOS;
632 } else if (unicode_cache_->IsIdentifierStart(c0_)) { 638 } else if (unicode_cache_->IsIdentifierStart(c0_)) {
633 token = ScanIdentifierOrKeyword(); 639 token = ScanIdentifierOrKeyword();
634 } else if (IsDecimalDigit(c0_)) { 640 } else if (IsDecimalDigit(c0_)) {
635 token = ScanNumber(false); 641 token = ScanNumber(false);
636 } else if (SkipWhiteSpace()) { 642 } else if (SkipWhiteSpace()) {
637 token = Token::WHITESPACE; 643 token = Token::WHITESPACE;
638 } else { 644 } else {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 } 769 }
764 } 770 }
765 if (c0_ != quote) return Token::ILLEGAL; 771 if (c0_ != quote) return Token::ILLEGAL;
766 literal.Complete(); 772 literal.Complete();
767 773
768 Advance(); // consume quote 774 Advance(); // consume quote
769 return Token::STRING; 775 return Token::STRING;
770 } 776 }
771 777
772 778
779 Token::Value Scanner::ScanTemplateSpan() {
780 // When scanning a TemplateSpan, we are looking for the following construct:
781 // TEMPLATE_SPAN ::
782 // ` LiteralChars* ${
783 // | } LiteralChars* ${
784 //
785 // TEMPLATE_TAIL ::
786 // ` LiteralChars* `
787 // | } LiteralChar* `
788 //
789 // A TEMPLATE_SPAN should always be followed by an Expression, while a
790 // TEMPLATE_TAIL terminates a TemplateLiteral and does not need to be
791 // followed by an Expression.
792 //
793
794 if (next_.token == Token::RBRACE) {
795 // After parsing an Expression, the source position is incorrect due to
796 // having scanned the brace. Push the RBRACE back into the stream.
797 PushBack('}');
798 }
799
800 next_.location.beg_pos = source_pos();
801 Token::Value result = Token::ILLEGAL;
802 DCHECK(c0_ == '`' || c0_ == '}');
803 Advance(); // Consume ` or }
804
805 LiteralScope literal(this);
806 while (true) {
807 uc32 c = c0_;
808 Advance();
809 if (c == '`') {
810 result = Token::TEMPLATE_TAIL;
811 break;
812 } else if (c == '$' && c0_ == '{') {
813 Advance(); // Consume '{'
814 result = Token::TEMPLATE_SPAN;
815 break;
816 } else if (c == '\\') {
817 if (unicode_cache_->IsLineTerminator(c0_)) {
818 // The TV of LineContinuation :: \ LineTerminatorSequence is the empty
819 // code unit sequence.
820 uc32 lastChar = c0_;
821 Advance();
822 if (lastChar == '\r' && c0_ == '\n') Advance();
823 } else if (c0_ == '0') {
824 Advance();
825 AddLiteralChar('0');
826 } else {
827 ScanEscape();
828 }
829 } else if (c < 0) {
830 // Unterminated template literal
831 PushBack(c);
832 break;
833 } else {
834 // The TRV of LineTerminatorSequence :: <CR> is the CV 0x000A.
835 // The TRV of LineTerminatorSequence :: <CR><LF> is the sequence
836 // consisting of the CV 0x000A.
marja 2014/11/12 09:23:21 I know this is directly from the spec, but... wut?
837 if (c == '\r') {
838 if (c0_ == '\n') Advance();
839 c = '\n';
840 }
841 AddLiteralChar(c);
842 }
843 }
844 literal.Complete();
845 next_.location.end_pos = source_pos();
846 next_.token = result;
847 return result;
848 }
849
850
773 void Scanner::ScanDecimalDigits() { 851 void Scanner::ScanDecimalDigits() {
774 while (IsDecimalDigit(c0_)) 852 while (IsDecimalDigit(c0_))
775 AddLiteralCharAdvance(); 853 AddLiteralCharAdvance();
776 } 854 }
777 855
778 856
779 Token::Value Scanner::ScanNumber(bool seen_period) { 857 Token::Value Scanner::ScanNumber(bool seen_period) {
780 DCHECK(IsDecimalDigit(c0_)); // the first digit of the number or the fraction 858 DCHECK(IsDecimalDigit(c0_)); // the first digit of the number or the fraction
781 859
782 enum { DECIMAL, HEX, OCTAL, IMPLICIT_OCTAL, BINARY } kind = DECIMAL; 860 enum { DECIMAL, HEX, OCTAL, IMPLICIT_OCTAL, BINARY } kind = DECIMAL;
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 } 1404 }
1327 backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u)); 1405 backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u));
1328 } 1406 }
1329 backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f)); 1407 backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f));
1330 1408
1331 backing_store_.AddBlock(bytes); 1409 backing_store_.AddBlock(bytes);
1332 return backing_store_.EndSequence().start(); 1410 return backing_store_.EndSequence().start();
1333 } 1411 }
1334 1412
1335 } } // namespace v8::internal 1413 } } // namespace v8::internal
OLDNEW
« src/parser.cc ('K') | « src/scanner.h ('k') | src/token.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698