//! Lookup helpers over the generated tables in the `*_data.mbt` files.
///|
/// Returns the expansion of the entity whose name is exactly `bytes`, or `None`.
fn get_entity(bytes : BytesView) -> String? {
let mut lo = 0
let mut hi = entities_table.length() - 1
while lo <= hi {
let mid = (lo + hi) / 2
let cmp = bytes.lexical_compare(entities_table[mid].0.view())
guard cmp != 0 else { return Some(entities_table[mid].1) }
if cmp < 0 {
hi = mid - 1
} else {
lo = mid + 1
}
}
None
}
///|
fn is_ascii_punctuation(c : Int) -> Bool {
c < 128 && (punct_masks_ascii[c / 16] & (1 << (c & 15))) != 0
}
///|
fn is_punctuation(c : Int) -> Bool {
guard c >= 128 else { return is_ascii_punctuation(c) }
guard c <= 0x1FBCA else { return false }
let high = c / 16
match punct_tab.binary_search(high) {
Ok(index) => (punct_masks[index] & (1 << (c & 15))) != 0
Err(_) => false
}
}
///|
/// Returns the case-folded form of `c`, as an array of chars (0-3 entries).
fn unicase_lookup(c : Char) -> Array[Char] {
let cp = c.to_int()
// The table is sorted by codepoint; binary search.
let mut lo = 0
let mut hi = unicase_fold_table.length() - 1
while lo <= hi {
let mid = (lo + hi) / 2
let (entry_cp, folds) = unicase_fold_table[mid]
guard entry_cp != cp else { return folds }
if entry_cp < cp {
lo = mid + 1
} else {
hi = mid - 1
}
}
// Not found: identity fold.
[c]
}
///|
/// Returns the case-folded representation of the string.
fn unicase_fold(s : String) -> String {
let out = StringBuilder::new()
for c in s.iter() {
for fc in unicase_lookup(c) {
out.write_char(fc)
}
}
out.to_string()
}