Function calls. We need to pre-scan the WAT for (func $name ... lines to know where each function starts and ends, and what its parameters are.
var vm_fn_names: [32][]const u8 = undefined;
var vm_fn_start: [32]usize = undefined;
var vm_fn_end: [32]usize = undefined;
var vm_fn_params: [32][8][]const u8 = undefined;
var vm_fn_param_count: [32]usize = undefined;
var vm_fn_count: usize = 0;
Write vm_scan_functions() -- scan through vm_lines, find each (func $name, extract the name and parameter names, find the matching ) that closes the function.
fn vm_scan_functions() void {
vm_fn_count = 0;
var i: usize = 0;
while (i < vm_line_count) {
const line: []const u8 = vm_trim(vm_lines[i]);
if (starts_with(line, "(func $")) {
const name: []const u8 = parse_name(line, 0);
vm_fn_names[vm_fn_count] = name;
vm_fn_start[vm_fn_count] = i + 1; // first line of body
// extract param names
var pc: usize = 0;
var j: usize = i;
// params are on the same line or nearby
// scan this line for (param $name
var p: usize = 0;
while (p < line.len) {
if (p + 7 < line.len and starts_with(line[p..], "(param $")) {
const pname: []const u8 = parse_name(line, p);
vm_fn_params[vm_fn_count][pc] = pname;
pc += 1;
}
p += 1;
}
vm_fn_param_count[vm_fn_count] = pc;
// find closing ) -- a line that is just ")"
j = i + 1;
while (j < vm_line_count) {
const ln: []const u8 = vm_trim(vm_lines[j]);
if (streq(ln, ")")) {
break;
}
j += 1;
}
vm_fn_end[vm_fn_count] = j;
vm_fn_count += 1;
}
// Also handle (func (export "main") -- no $name
if (starts_with(line, "(func (export")) {
vm_fn_names[vm_fn_count] = "main";
vm_fn_start[vm_fn_count] = i + 1;
vm_fn_param_count[vm_fn_count] = 0;
var j: usize = i + 1;
while (j < vm_line_count) {
if (streq(vm_trim(vm_lines[j]), ")")) { break; }
j += 1;
}
vm_fn_end[vm_fn_count] = j;
vm_fn_count += 1;
}
i += 1;
}
}