The Compiler, in Its Own Language
self-scanner

The core scanner:

var src_pos: i64 = 0;
var src_len: i64 = 0;

fn cur() i64 {
    if (src_pos >= src_len) { return 0; }
    return load8(src_pos);
}

fn skip() i64 {
    while (is_space(cur()) == 1) { src_pos += 1; }
    return 0;
}

fn number() i64 {
    var val: i64 = 0;
    while (is_digit(cur()) == 1) {
        val = val * 10 + (cur() - '0');
        src_pos += 1;
    }
    skip();
    return val;
}

fn read_name() i64 {
    var start: i64 = src_pos;
    while (is_alnum(cur()) == 1) { src_pos += 1; }
    var len: i64 = src_pos - start;
    skip();
    return start * 65536 + len;
}

cur() - '0' instead of cur() - 48. src_pos += 1 instead of src_pos = src_pos + 1. The scanner reads like the Zig version.