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
}