The Compiler
c-fn-def

Write c_fn_def() -- compile a function definition:

fn c_fn_def() void {
    const fname: []const u8 = read_name();
    if (cur() == '(') { pos += 1; skip(); }

    var params: [8][]const u8 = undefined;
    var ptypes: [8][]const u8 = undefined;
    var pc: usize = 0;
    while (cur() != ')' and cur() != 0) {
        params[pc] = read_name();
        if (cur() == ':') { pos += 1; skip(); ptypes[pc] = read_name(); } else { ptypes[pc] = "i64"; }
        pc += 1;
        if (cur() == ',') { pos += 1; skip(); }
    }
    if (cur() == ')') { pos += 1; skip(); }

    var rtype: []const u8 = "i64";
    if (is_letter(cur())) { rtype = read_name(); }

    const body_start: usize = pos;
    skip_block();
    const body_end: usize = pos;

    scan_for_locals(body_start, body_end);

    emit_str("(func $");
    emit_str(fname);
    for (0..pc) |i| {
        emit_str(" (param $");
        emit_str(params[i]);
        emit_str(" ");
        emit_str(ptypes[i]);
        emit_str(")");
    }
    emit_str(" (result ");
    emit_str(rtype);
    emit_str(")\n");
    emit_locals();

    pos = body_start;
    c_block();
    emit_op("drop"); // c_block always produces a value; function returns via 'return'
    emit_const(0);   // default return value if no 'return' hit

    emit_str(")\n");
}

The function body goes through c_block which produces a value. We drop it and push 0 as a default return. Functions should use explicit return expr; -- the return instruction bypasses the default.