Variables
factor-handles-names

Update factor() to handle names. When cur() is a letter, read_name() and return getVar(name). (We'll add function calls here later.)

Write exec_stmt() -- the statement executor. It checks for keywords (var, if, while, fn, return), assignment, or falls back to expression. Write program() -- a loop calling exec_stmt().

The var handler parses var name: i64 = expr; -- it reads the name, consumes : i64 (parsing the type but not using it yet), then evaluates the initializer.

    check("var x: i64 = 42; x", 42);
    check("var x: i64 = 5; x + 1", 6);
    check("var x: i64 = 5; x = x + 1; x", 6);
    check("var a: i64 = 10; var b: i64 = 20; a + b", 30);
fn exec_stmt() i64 {
    if (is_letter(cur())) {
        const save: usize = pos;
        const word: []const u8 = read_name();

        if (streq(word, "var") or streq(word, "const")) {
            const vname: []const u8 = read_name();
            if (cur() == ':') { pos += 1; skip(); _ = read_name(); } // parse type, ignore
            if (cur() == '=') { pos += 1; skip(); }
            const val: i64 = expression();
            if (cur() == ';') { pos += 1; skip(); }
            setVar(vname, val);
            return val;
        }

        // assignment: name = expr; (but not == comparison)
        if (cur() == '=' and (pos + 1 >= source.len or source[pos + 1] != '=')) {
            pos += 1;
            skip();
            const val: i64 = expression();
            if (cur() == ';') { pos += 1; skip(); }
            setVar(word, val);
            return val;
        }

        // backtrack -- it's an expression starting with a name
        pos = save;
    }
    const val: i64 = expression();
    if (cur() == ';') { pos += 1; skip(); }
    return val;
}

fn program() i64 {
    var last: i64 = 0;
    while (cur() != 0 and cur() != '}') {
        last = exec_stmt();
    }
    return last;
}

We parse : i64 and throw it away. Feels wasteful? It's not. When we compile to WAT, we'll emit (local $x i64) using that type. The groundwork is being laid quietly.