// ascii — rune-class predicates and case folding for the ASCII range. // Matches Hare's ascii::isdigit family (rune-taking signature). Runes // outside 0..127 always answer `false`. The lexer hot path uses these // inline; they are expected to inline to a couple of compares. export fn isdigit(c: rune) bool = { if (c < 48) { return false; }; if (c > 57) { return false; }; return true; }; export fn isupper(c: rune) bool = { if (c < 65) { return false; }; if (c > 90) { return false; }; return true; }; export fn islower(c: rune) bool = { if (c < 97) { return false; }; if (c > 122) { return false; }; return true; }; export fn isalpha(c: rune) bool = { if (isupper(c)) { return true; }; return islower(c); }; export fn isalnum(c: rune) bool = { if (isalpha(c)) { return true; }; return isdigit(c); }; // isspace — the C/Hare set: space, tab, NL, VT, FF, CR. export fn isspace(c: rune) bool = { if (c == 32) { return true; }; // ' ' if (c == 9) { return true; }; // '\t' if (c == 10) { return true; }; // '\n' if (c == 11) { return true; }; // '\v' if (c == 12) { return true; }; // '\f' if (c == 13) { return true; }; // '\r' return false; }; export fn isxdigit(c: rune) bool = { if (isdigit(c)) { return true; }; if (c >= 65) { if (c <= 70) { return true; }; // 'A'..'F' }; if (c >= 97) { if (c <= 102) { return true; }; // 'a'..'f' }; return false; }; // digitval — value of `c` as a hex/decimal digit. void variant means // `c` isn't a hex digit. Useful when scanning numeric literals. export fn digitval(c: rune) (i32 | void) = { if (isdigit(c)) { return (c - 48): i32; }; if (c >= 65) { if (c <= 70) { return ((c - 65) + 10): i32; }; }; if (c >= 97) { if (c <= 102) { return ((c - 97) + 10): i32; }; }; return; }; // isidstart / isidpart — identifier classes used by the lexer. // Alpha or '_' starts; alnum or '_' continues. export fn isidstart(c: rune) bool = { if (isalpha(c)) { return true; }; if (c == 95) { return true; }; // '_' return false; }; export fn isidpart(c: rune) bool = { if (isalnum(c)) { return true; }; if (c == 95) { return true; }; return false; }; // tolower / toupper — fold ASCII case. Non-letters pass through. export fn tolower(c: rune) rune = { if (isupper(c)) { return c + 32; }; return c; }; export fn toupper(c: rune) rune = { if (islower(c)) { return c - 32; }; return c; };