Skip to content

@chars

Import this module with import @chars.

Scalar operations on a single char. strings provides the general classification predicates (is_alpha, is_digit, is_upper, is_lower, …); chars adds ASCII case folding plus the lexer-flavored predicates and an escape renderer.

Function Signature Description
to_upper (c char) -> char ASCII uppercase
to_lower (c char) -> char ASCII lowercase

Only the 26 ASCII letters in the relevant case are folded. Digits, symbols, whitespace, and non-ASCII codepoints (char is a full Unicode codepoint) are returned unchanged.

Function Signature Description
is_ascii (c char) -> bool 7-bit ASCII codepoint (0–127)
is_control (c char) -> bool ASCII control char: C0 range (0–31) or DEL (127)
is_printable (c char) -> bool Printable ASCII, space (32) through ~ (126)
is_punct (c char) -> bool Printable ASCII that is not a letter, digit, or space
is_hex_digit (c char) -> bool 0–9, a–f, or A–F
is_word_char (c char) -> bool Identifier char: [A-Za-z0-9_]

Every predicate is ASCII-only: a non-ASCII codepoint always returns false.

Function Signature Description
escape (c char) -> string Printable rendering for debugging or codegen

escape renders backslash and the common control characters (\n, \t, \r, \0) as two-character escapes, other control characters and DEL as \xNN, non-ASCII codepoints as \u{...}, and printable ASCII unchanged.

Function Signature Description
width (c char) -> i64 Terminal display width of c
string_width (s string) -> i64 Total terminal display width of s

width follows wcwidth semantics: -1 for a C0/C1 control character, 0 for a zero-width codepoint (combining marks, joiners, variation selectors), 2 for a wide codepoint (CJK ideographs, Hangul syllables, fullwidth forms, default-presentation emoji), 1 for everything else — including East Asian “ambiguous width” codepoints, which this module always treats as 1.

string_width sums width over the string’s codepoints, treating a -1 result as 0. It does not expand tabs — a literal \t contributes 0, not a tab stop’s worth of columns. Width is computed per codepoint: a ZWJ emoji sequence (family emoji, flag sequences) is summed from its parts rather than treated as the one terminal cell it occupies, so string_width over-counts those; grapheme-cluster segmentation is out of scope for this module.

import @chars
do main() {
println(chars.width('A')) // 1
println(chars.width('中')) // 2 (CJK ideograph)
println(chars.string_width("café")) // 4
println(chars.string_width("中文")) // 4 (two wide chars)
}

Behavior:

  • No function in this module fails.