Update getVar to check locals first, then globals:
fn getVar(name: []const u8) i64 {
// Check locals first (innermost scope wins)
var i: usize = num_vars;
while (i > 0) {
i -= 1;
if (streq(var_names[i], name)) {
return var_values[i];
}
}
// Then globals
return getGlobal(name);
}
Update setVar the same way -- check locals, then globals, then create a new local:
fn setVar(name: []const u8, val: i64) void {
// Check locals first
for (0..num_vars) |i| {
if (streq(var_names[i], name)) {
var_values[i] = val;
return;
}
}
// Check globals
for (0..num_globals) |i| {
if (streq(global_names[i], name)) {
global_values[i] = val;
return;
}
}
// Create new local
var_names[num_vars] = name;
var_values[num_vars] = val;
num_vars += 1;
}
Now setVar finds existing variables in either scope. If x is a global, assigning x = 99 inside a function updates the global. If y is a local, it updates the local. If neither exists, it creates a new local.