| 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 |