(&mut self, atoms: &dyn DynAtomSet)
| 592 | } |
| 593 | |
| 594 | fn consume_hash_token(&mut self, atoms: &dyn DynAtomSet) -> Token { |
| 595 | self.pos += 1; // skip '#' |
| 596 | let hash_str = self.remaining_str(); |
| 597 | let first_is_ascii = is_ident(self.peek_char()); |
| 598 | let hash_start = self.pos; |
| 599 | let (len, contains_non_lower_ascii, _, contains_escape, _, _) = self.consume_ident_sequence(atoms); |
| 600 | let hash_bytes = &self.bytes[hash_start..hash_start + len as usize]; |
| 601 | let mut hex_value: u32 = 0; |
| 602 | let mut is_hex = false; |
| 603 | if (len == 3 || len == 4) && !contains_escape { |
| 604 | is_hex = true; |
| 605 | for &b in hash_bytes.iter().take(len as usize) { |
| 606 | if let Some(d) = (b as char).to_digit(16) { |
| 607 | hex_value = (hex_value << 8) | (d << 4) | d; |
| 608 | } else { |
| 609 | is_hex = false; |
| 610 | break; |
| 611 | } |
| 612 | } |
| 613 | } else if (len == 3 || len == 4) && contains_escape { |
| 614 | // Use char-based iteration for escaped sequences |
| 615 | is_hex = true; |
| 616 | for c in hash_str.chars().take(len as usize) { |
| 617 | if let Some(d) = c.to_digit(16) { |
| 618 | hex_value = (hex_value << 8) | (d << 4) | d; |
| 619 | } else { |
| 620 | is_hex = false; |
| 621 | break; |
| 622 | } |
| 623 | } |
| 624 | } else if (len == 6 || len == 8) && !contains_escape { |
| 625 | is_hex = true; |
| 626 | for &b in hash_bytes.iter().take(len as usize) { |
| 627 | if let Some(d) = (b as char).to_digit(16) { |
| 628 | hex_value = (hex_value << 4) | d; |
| 629 | } else { |
| 630 | is_hex = false; |
| 631 | break; |
| 632 | } |
| 633 | } |
| 634 | } else if (len == 6 || len == 8) && contains_escape { |
| 635 | is_hex = true; |
| 636 | for c in hash_str.chars().take(len as usize) { |
| 637 | if let Some(d) = c.to_digit(16) { |
| 638 | hex_value = (hex_value << 4) | d; |
| 639 | } else { |
| 640 | is_hex = false; |
| 641 | break; |
| 642 | } |
| 643 | } |
| 644 | } |
| 645 | if is_hex && (len == 3 || len == 6) { |
| 646 | hex_value = (hex_value << 8) | 0xFF; |
| 647 | } |
| 648 | if !is_hex { |
| 649 | hex_value = 0; |
| 650 | } |
| 651 | Token::new_hash(contains_non_lower_ascii, first_is_ascii, contains_escape, len + 1, hex_value) |
no test coverage detected