OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 24 matching lines...) Expand all Loading... |
35 namespace v8 { | 35 namespace v8 { |
36 namespace internal { | 36 namespace internal { |
37 | 37 |
38 // ---------------------------------------------------------------------------- | 38 // ---------------------------------------------------------------------------- |
39 // Scanner | 39 // Scanner |
40 | 40 |
41 Scanner::Scanner(UnicodeCache* unicode_cache) | 41 Scanner::Scanner(UnicodeCache* unicode_cache) |
42 : unicode_cache_(unicode_cache), | 42 : unicode_cache_(unicode_cache), |
43 octal_pos_(Location::invalid()), | 43 octal_pos_(Location::invalid()), |
44 harmony_scoping_(false), | 44 harmony_scoping_(false), |
45 harmony_modules_(false) { } | 45 harmony_modules_(false), |
| 46 harmony_numeric_literals_(false) { } |
46 | 47 |
47 | 48 |
48 void Scanner::Initialize(Utf16CharacterStream* source) { | 49 void Scanner::Initialize(Utf16CharacterStream* source) { |
49 source_ = source; | 50 source_ = source; |
50 // Need to capture identifiers in order to recognize "get" and "set" | 51 // Need to capture identifiers in order to recognize "get" and "set" |
51 // in object literals. | 52 // in object literals. |
52 Init(); | 53 Init(); |
53 // Skip initial whitespace allowing HTML comment ends just like | 54 // Skip initial whitespace allowing HTML comment ends just like |
54 // after a newline and scan first token. | 55 // after a newline and scan first token. |
55 has_line_terminator_before_next_ = true; | 56 has_line_terminator_before_next_ = true; |
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 | 713 |
713 void Scanner::ScanDecimalDigits() { | 714 void Scanner::ScanDecimalDigits() { |
714 while (IsDecimalDigit(c0_)) | 715 while (IsDecimalDigit(c0_)) |
715 AddLiteralCharAdvance(); | 716 AddLiteralCharAdvance(); |
716 } | 717 } |
717 | 718 |
718 | 719 |
719 Token::Value Scanner::ScanNumber(bool seen_period) { | 720 Token::Value Scanner::ScanNumber(bool seen_period) { |
720 ASSERT(IsDecimalDigit(c0_)); // the first digit of the number or the fraction | 721 ASSERT(IsDecimalDigit(c0_)); // the first digit of the number or the fraction |
721 | 722 |
722 enum { DECIMAL, HEX, OCTAL } kind = DECIMAL; | 723 enum { DECIMAL, HEX, OCTAL, IMPLICIT_OCTAL, BINARY } kind = DECIMAL; |
723 | 724 |
724 LiteralScope literal(this); | 725 LiteralScope literal(this); |
725 if (seen_period) { | 726 if (seen_period) { |
726 // we have already seen a decimal point of the float | 727 // we have already seen a decimal point of the float |
727 AddLiteralChar('.'); | 728 AddLiteralChar('.'); |
728 ScanDecimalDigits(); // we know we have at least one digit | 729 ScanDecimalDigits(); // we know we have at least one digit |
729 | 730 |
730 } else { | 731 } else { |
731 // if the first character is '0' we must check for octals and hex | 732 // if the first character is '0' we must check for octals and hex |
732 if (c0_ == '0') { | 733 if (c0_ == '0') { |
733 int start_pos = source_pos(); // For reporting octal positions. | 734 int start_pos = source_pos(); // For reporting octal positions. |
734 AddLiteralCharAdvance(); | 735 AddLiteralCharAdvance(); |
735 | 736 |
736 // either 0, 0exxx, 0Exxx, 0.xxx, an octal number, or a hex number | 737 // either 0, 0exxx, 0Exxx, 0.xxx, a hex number, a binary number or |
| 738 // an octal number. |
737 if (c0_ == 'x' || c0_ == 'X') { | 739 if (c0_ == 'x' || c0_ == 'X') { |
738 // hex number | 740 // hex number |
739 kind = HEX; | 741 kind = HEX; |
740 AddLiteralCharAdvance(); | 742 AddLiteralCharAdvance(); |
741 if (!IsHexDigit(c0_)) { | 743 if (!IsHexDigit(c0_)) { |
742 // we must have at least one hex digit after 'x'/'X' | 744 // we must have at least one hex digit after 'x'/'X' |
743 return Token::ILLEGAL; | 745 return Token::ILLEGAL; |
744 } | 746 } |
745 while (IsHexDigit(c0_)) { | 747 while (IsHexDigit(c0_)) { |
746 AddLiteralCharAdvance(); | 748 AddLiteralCharAdvance(); |
747 } | 749 } |
| 750 } else if (harmony_numeric_literals_ && (c0_ == 'o' || c0_ == 'O')) { |
| 751 kind = OCTAL; |
| 752 AddLiteralCharAdvance(); |
| 753 if (!IsOctalDigit(c0_)) { |
| 754 // we must have at least one octal digit after 'o'/'O' |
| 755 return Token::ILLEGAL; |
| 756 } |
| 757 while (IsOctalDigit(c0_)) { |
| 758 AddLiteralCharAdvance(); |
| 759 } |
| 760 } else if (harmony_numeric_literals_ && (c0_ == 'b' || c0_ == 'B')) { |
| 761 kind = BINARY; |
| 762 AddLiteralCharAdvance(); |
| 763 if (!IsBinaryDigit(c0_)) { |
| 764 // we must have at least one binary digit after 'b'/'B' |
| 765 return Token::ILLEGAL; |
| 766 } |
| 767 while (IsBinaryDigit(c0_)) { |
| 768 AddLiteralCharAdvance(); |
| 769 } |
748 } else if ('0' <= c0_ && c0_ <= '7') { | 770 } else if ('0' <= c0_ && c0_ <= '7') { |
749 // (possible) octal number | 771 // (possible) octal number |
750 kind = OCTAL; | 772 kind = IMPLICIT_OCTAL; |
751 while (true) { | 773 while (true) { |
752 if (c0_ == '8' || c0_ == '9') { | 774 if (c0_ == '8' || c0_ == '9') { |
753 kind = DECIMAL; | 775 kind = DECIMAL; |
754 break; | 776 break; |
755 } | 777 } |
756 if (c0_ < '0' || '7' < c0_) { | 778 if (c0_ < '0' || '7' < c0_) { |
757 // Octal literal finished. | 779 // Octal literal finished. |
758 octal_pos_ = Location(start_pos, source_pos()); | 780 octal_pos_ = Location(start_pos, source_pos()); |
759 break; | 781 break; |
760 } | 782 } |
761 AddLiteralCharAdvance(); | 783 AddLiteralCharAdvance(); |
762 } | 784 } |
763 } | 785 } |
764 } | 786 } |
765 | 787 |
766 // Parse decimal digits and allow trailing fractional part. | 788 // Parse decimal digits and allow trailing fractional part. |
767 if (kind == DECIMAL) { | 789 if (kind == DECIMAL) { |
768 ScanDecimalDigits(); // optional | 790 ScanDecimalDigits(); // optional |
769 if (c0_ == '.') { | 791 if (c0_ == '.') { |
770 AddLiteralCharAdvance(); | 792 AddLiteralCharAdvance(); |
771 ScanDecimalDigits(); // optional | 793 ScanDecimalDigits(); // optional |
772 } | 794 } |
773 } | 795 } |
774 } | 796 } |
775 | 797 |
776 // scan exponent, if any | 798 // scan exponent, if any |
777 if (c0_ == 'e' || c0_ == 'E') { | 799 if (c0_ == 'e' || c0_ == 'E') { |
778 ASSERT(kind != HEX); // 'e'/'E' must be scanned as part of the hex number | 800 ASSERT(kind != HEX); // 'e'/'E' must be scanned as part of the hex number |
779 if (kind == OCTAL) return Token::ILLEGAL; // no exponent for octals allowed | 801 if (kind != DECIMAL) return Token::ILLEGAL; |
780 // scan exponent | 802 // scan exponent |
781 AddLiteralCharAdvance(); | 803 AddLiteralCharAdvance(); |
782 if (c0_ == '+' || c0_ == '-') | 804 if (c0_ == '+' || c0_ == '-') |
783 AddLiteralCharAdvance(); | 805 AddLiteralCharAdvance(); |
784 if (!IsDecimalDigit(c0_)) { | 806 if (!IsDecimalDigit(c0_)) { |
785 // we must have at least one decimal digit after 'e'/'E' | 807 // we must have at least one decimal digit after 'e'/'E' |
786 return Token::ILLEGAL; | 808 return Token::ILLEGAL; |
787 } | 809 } |
788 ScanDecimalDigits(); | 810 ScanDecimalDigits(); |
789 } | 811 } |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1080 Advance(); | 1102 Advance(); |
1081 } | 1103 } |
1082 } | 1104 } |
1083 literal.Complete(); | 1105 literal.Complete(); |
1084 | 1106 |
1085 next_.location.end_pos = source_pos() - 1; | 1107 next_.location.end_pos = source_pos() - 1; |
1086 return true; | 1108 return true; |
1087 } | 1109 } |
1088 | 1110 |
1089 } } // namespace v8::internal | 1111 } } // namespace v8::internal |
OLD | NEW |