OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |