// Small internal helpers shared by the identifier validators.
///|
/// ASCII-only uppercase. Non-letters (and non-ASCII) are returned unchanged.
fn upper_ascii(c : Char) -> Char {
match c {
'a' => 'A'
'b' => 'B'
'c' => 'C'
'd' => 'D'
'e' => 'E'
'f' => 'F'
'g' => 'G'
'h' => 'H'
'i' => 'I'
'j' => 'J'
'k' => 'K'
'l' => 'L'
'm' => 'M'
'n' => 'N'
'o' => 'O'
'p' => 'P'
'q' => 'Q'
'r' => 'R'
's' => 'S'
't' => 'T'
'u' => 'U'
'v' => 'V'
'w' => 'W'
'x' => 'X'
'y' => 'Y'
'z' => 'Z'
_ => c
}
}
///|
/// Extract `len` characters starting at `start`. Returns None when the range
/// falls outside the string.
fn substring(s : String, start : Int, len : Int) -> String? {
let chars : Array[Char] = []
for ch in s {
chars.push(ch)
}
if start < 0 || len < 0 || start + len > chars.length() {
return None
}
let buf = StringBuilder()
for i = start; i < start + len; i = i + 1 {
buf.write_char(chars[i])
}
Some(buf.to_string())
}
///|
/// Split a string into its characters.
fn chars_of(s : String) -> Array[Char] {
let chars : Array[Char] = []
for ch in s {
chars.push(ch)
}
chars
}