Add function calls to factor(). When we see name(, it's a call.
check("fn add(a: i64, b: i64) i64 { return a + b; } add(3, 5)", 8);
check("fn double(x: i64) i64 { return x * 2; } double(21)", 42);
In factor(), where we handle names:
if (is_letter(cur())) {
const name: []const u8 = read_name();
if (cur() == '(') {
pos += 1;
skip();
var args: [8]i64 = undefined;
var ac: usize = 0;
while (cur() != ')' and cur() != 0) {
args[ac] = expression();
ac += 1;
if (cur() == ',') { pos += 1; skip(); }
}
if (cur() == ')') { pos += 1; skip(); }
return call_fn(name, &args, ac);
}
return getVar(name);
}
var save_vn: [32][256][]const u8 = undefined;
var save_vv: [32][256]i64 = undefined;
var save_nv: [32]usize = undefined;
var save_depth: usize = 0;
fn call_fn(name: []const u8, args: *const [8]i64, ac: usize) i64 {
_ = ac;
// Find function
var fi: usize = 0;
while (fi < fn_count) {
if (streq(fn_names[fi], name)) { break; }
fi += 1;
}
if (fi >= fn_count) { return 0; }
// Save caller state
const d: usize = save_depth;
save_nv[d] = num_vars;
const saved_pos: usize = pos;
for (0..num_vars) |i| {
save_vn[d][i] = var_names[i];
save_vv[d][i] = var_values[i];
}
save_depth += 1;
// Bind parameters
num_vars = 0;
for (0..fn_pcounts[fi]) |i| {
setVar(fn_params[fi][i], args[i]);
}
// Execute body
pos = fn_starts[fi];
return_flag = false;
const result: i64 = exec_block();
// Restore
save_depth -= 1;
pos = saved_pos;
num_vars = save_nv[d];
for (0..num_vars) |i| {
var_names[i] = save_vn[d][i];
var_values[i] = save_vv[d][i];
}
return_flag = false;
return result;
}