We want to read a string one character at a time. To do that we need two things: somewhere to keep the string, and a cursor that points into it.
Make two globals: source: []const u8 (the string we're reading) and pos: usize (the current index -- usize is the type Zig uses for indices and lengths). Yes, globals are bad, somebody on the internet will be very upset. We're being lazy. We'll keep being lazy with this trick the whole way through. Don't do this in your day job.
Then write cur() that returns the byte at source[pos], or 0 if we've walked off the end. The 0 is our end-of-input sentinel -- we'll lean on it constantly.
Use this main to try it out:
pub fn main() void {
source = "hi!";
pos = 0;
print("pos {d}: {c}\n", .{ pos, cur() }); // 0: h
pos += 1;
print("pos {d}: {c}\n", .{ pos, cur() }); // 1: i
pos += 1;
print("pos {d}: {c}\n", .{ pos, cur() }); // 2: !
pos += 1;
print("fell off the end, cur() = {d}\n", .{cur()}); // 0
}
var source: []const u8 = "";
var pos: usize = 0;
fn cur() u8 {
if (pos >= source.len) {
return 0;
}
return source[pos];
}