Write is_letter(c) and read_name(). A name is letters, digits, and underscores. read_name returns a slice into the source string.
fn is_letter(c: u8) bool {
return (c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z') or c == '_';
}
fn read_name() []const u8 {
const start: usize = pos;
while (pos < source.len and (is_letter(source[pos]) or
(source[pos] >= '0' and source[pos] <= '9')))
{
pos += 1;
}
const name: []const u8 = source[start..pos];
skip();
return name;
}
source[start..pos] is a slice -- a view into the string. No copying, no allocation. Slices are one of Zig's best features, and we'll use them constantly.