The Compiler, in Its Own Language
self-c-call-fn

c_call and c_fn:

fn c_call(name: i64) i64 {
    src_pos += 1; skip();
    while (cur() != ')') {
        if (cur() == 0) { return 0; }
        c_expression();
        if (cur() == ',') { src_pos += 1; skip(); }
    }
    if (cur() == ')') { src_pos += 1; skip(); }
    emit_s("  call $"); emit_s(name); emit_byte('\n');
    return 0;
}

fn c_fn() i64 {
    var fname: i64 = read_name();
    emit_s("(func $"); emit_s(fname);

    if (cur() == '(') { src_pos += 1; skip(); }
    while (cur() != ')') {
        if (cur() == 0) { return 0; }
        var pname: i64 = read_name();
        emit_s(" (param $"); emit_s(pname);
        if (cur() == ':') {
            src_pos += 1; skip();
            var ptype: i64 = read_name();
            emit_s(" "); emit_s(ptype);
        }
        emit_s(")");
        if (cur() == ',') { src_pos += 1; skip(); }
    }
    if (cur() == ')') { src_pos += 1; skip(); }

    if (is_letter(cur()) == 1) {
        var rtype: i64 = read_name();
        emit_s(" (result "); emit_s(rtype); emit_s(")");
    }
    emit_byte('\n');

    var body_start: i64 = src_pos;
    scan_locals();
    src_pos = body_start;
    c_block();
    emit_s("  drop\n  i64.const 0\n)\n");
    return 0;
}