Functions
function-storage

Add function storage. When exec_stmt sees fn, read the name, the parameter list (with types), the return type, and save the body position. Skip the body without executing it.

var fn_names: [64][]const u8 = undefined;
var fn_params: [64][8][]const u8 = undefined;
var fn_pcounts: [64]usize = undefined;
var fn_starts: [64]usize = undefined;
var fn_count: usize = 0;

Add to exec_stmt:

        if (streq(word, "fn")) {
            const fname: []const u8 = read_name();
            fn_names[fn_count] = fname;
            if (cur() == '(') { pos += 1; skip(); }
            var pc: usize = 0;
            while (cur() != ')' and cur() != 0) {
                fn_params[fn_count][pc] = read_name();
                if (cur() == ':') { pos += 1; skip(); _ = read_name(); }
                pc += 1;
                if (cur() == ',') { pos += 1; skip(); }
            }
            fn_pcounts[fn_count] = pc;
            if (cur() == ')') { pos += 1; skip(); }
            if (is_letter(cur())) { _ = read_name(); } // return type
            fn_starts[fn_count] = pos;
            skip_block();
            fn_count += 1;
            return 0;
        }

We parse fn fib(n: i64) i64 { ... } and store the name, parameters, and body position. The types are parsed and discarded -- for now. Later: (func $fib (param $n i64) (result i64) ...).