(&mut self)
| 791 | } |
| 792 | |
| 793 | fn consume_unicode_range_token(&mut self) -> Token { |
| 794 | // Step 1: Consume U/u and + |
| 795 | self.pos += 1; // U or u |
| 796 | self.pos += 1; // + |
| 797 | let mut len: u32 = 2; |
| 798 | |
| 799 | // Step 2: Consume hex digits (up to 6) |
| 800 | let mut hex_count: u32 = 0; |
| 801 | let mut hex_value: u32 = 0; |
| 802 | while hex_count < 6 { |
| 803 | let b = self.peek_byte(0); |
| 804 | if b < 128 { |
| 805 | if let Some(d) = (b as char).to_digit(16) { |
| 806 | self.pos += 1; |
| 807 | hex_value = (hex_value << 4) | d; |
| 808 | hex_count += 1; |
| 809 | len += 1; |
| 810 | } else { |
| 811 | break; |
| 812 | } |
| 813 | } else { |
| 814 | break; |
| 815 | } |
| 816 | } |
| 817 | |
| 818 | // Consume ? placeholders |
| 819 | let mut question_count: u32 = 0; |
| 820 | while hex_count + question_count < 6 && self.peek_byte(0) == b'?' { |
| 821 | self.pos += 1; |
| 822 | question_count += 1; |
| 823 | len += 1; |
| 824 | } |
| 825 | |
| 826 | if question_count > 0 { |
| 827 | let start = hex_value << (question_count * 4); |
| 828 | let end = start | ((1 << (question_count * 4)) - 1); |
| 829 | return Token::new_unicode_range(start, end, len); |
| 830 | } |
| 831 | |
| 832 | let start = hex_value; |
| 833 | |
| 834 | // Check for range: - followed by hex digit |
| 835 | if self.peek_byte(0) == b'-' && (self.peek_byte(1) as char).is_ascii_hexdigit() { |
| 836 | self.pos += 1; // - |
| 837 | len += 1; |
| 838 | |
| 839 | let mut end_hex_count: u32 = 0; |
| 840 | let mut end_value: u32 = 0; |
| 841 | while end_hex_count < 6 { |
| 842 | let b = self.peek_byte(0); |
| 843 | if b < 128 { |
| 844 | if let Some(d) = (b as char).to_digit(16) { |
| 845 | self.pos += 1; |
| 846 | end_value = (end_value << 4) | d; |
| 847 | end_hex_count += 1; |
| 848 | len += 1; |
| 849 | } else { |
| 850 | break; |
no test coverage detected