Write a helper to parse a number from a string at a given offset:
fn parse_int(s: []const u8, from: usize) i64 {
var i: usize = from;
var neg: bool = false;
if (i < s.len and s[i] == '-') {
neg = true;
i += 1;
}
var val: i64 = 0;
while (i < s.len and s[i] >= '0' and s[i] <= '9') {
val = val * 10 + digit(s[i]);
i += 1;
}
return if (neg) -val else val;
}
And one to extract a name after $:
fn parse_name(s: []const u8, from: usize) []const u8 {
var i: usize = from;
// find the $
while (i < s.len and s[i] != '$') {
i += 1;
}
if (i < s.len) {
i += 1; // skip $
}
const start: usize = i;
while (i < s.len and s[i] != ' ' and s[i] != ')' and s[i] != '\n') {
i += 1;
}
return s[start..i];
}
These are boring but necessary. The VM spends most of its time extracting numbers and names from text lines. In a real implementation, you'd use binary bytecode and skip all this parsing. We use text because we can read it and debug it.