Temporary chapter name for all chapters
variable-storage

Add variable storage: two parallel arrays and a counter. We want to avoid globals (they get nasty when functions arrive), so we keep the storage local to main and pass it around by pointer.

Declare in main:

var varNames: [256][]const u8 = undefined;
var varValues: [256]i64 = undefined;
var varCount: usize = 0;

[256] is bigger than any sane program will need. undefined means "whatever garbage is on the stack" -- we only ever read slots below varCount, so the garbage is fine.

Write two functions:

- lookupVariable -- finds a name, returns its value, or 0 if missing. Doesn't mutate anything.
- assignVariable -- finds a name and updates its slot, or adds a new one.

Both take the arrays by pointer. lookupVariable takes count by value (it only reads); assignVariable takes count: *usize because it bumps the count when adding.

fn lookupVariable(
    names: *[256][]const u8,
    values: *[256]i64,
    count: usize,
    name: []const u8,
) i64 {
    var i: usize = count;
    while (i > 0) {
        i -= 1;
        if (stringsEqual(names[i], name)) {
            return values[i];
        }
    }
    return 0;
}

fn assignVariable(
    names: *[256][]const u8,
    values: *[256]i64,
    count: *usize,
    name: []const u8,
    val: i64,
) void {
    var i: usize = 0;
    while (i < count.*) {
        if (stringsEqual(names[i], name)) {
            values[i] = val;
            return;
        }
        i += 1;
    }
    names[count.*] = name;
    values[count.*] = val;
    count.* += 1;
}

*[256][]const u8 is a pointer to an array of 256 string slices. Zig auto-dereferences for indexing -- names[i] inside the function does what you'd expect, grabbing the i-th slot.

Why search backwards in lookupVariable? So that shadowing works when we add function locals later (the newest binding for a given name wins).

Test directly from main:

pub fn main() void {
    var varNames: [256][]const u8 = undefined;
    var varValues: [256]i64 = undefined;
    var varCount: usize = 0;

    assignVariable(&varNames, &varValues, &varCount, "x", 42);
    assignVariable(&varNames, &varValues, &varCount, "y", 99);

    print("{d}\n", .{lookupVariable(&varNames, &varValues, varCount, "x")}); // 42
    print("{d}\n", .{lookupVariable(&varNames, &varValues, varCount, "y")}); // 99
    print("{d}\n", .{lookupVariable(&varNames, &varValues, varCount, "z")}); // 0
}