The Compiler, in Its Own Language
self-c-program

c_program -- the top-level compiler:

fn c_program() i64 {
    emit_s("(module\n");
    emit_s("(memory (export \"memory\") 10)\n");

    // scan for top-level globals
    src_pos = 0; skip();
    var depth: i64 = 0;
    while (src_pos < src_len) {
        if (load8(src_pos) == '{') { depth += 1; src_pos += 1; }
        if (load8(src_pos) == '}') { depth -= 1; src_pos += 1; }
        if (depth == 0 and is_letter(cur()) == 1) {
            var s: i64 = src_pos;
            var w: i64 = read_name();
            if (streq_mem(w, "var") == 1 or streq_mem(w, "const") == 1) {
                var vn: i64 = read_name();
                if (cur() == ':') { src_pos += 1; skip(); read_name(); }
                add_global(vn);
            } else {
                if (streq_mem(w, "fn") == 1) { skip_past_block(); }
                else { src_pos = s; src_pos += 1; }
            }
        } else { src_pos += 1; }
    }

    // emit global declarations
    for (0..g_count) |gi| {
        emit_s("(global $"); emit_s(global_names[gi]);
        emit_s(" (mut i64) (i64.const 0))\n");
    }

    // compile function definitions
    src_pos = 0; skip();
    while (cur() != 0) {
        if (is_letter(cur()) == 1) {
            var s: i64 = src_pos;
            var w: i64 = read_name();
            if (streq_mem(w, "fn") == 1) { c_fn(); }
            else { src_pos = s; skip_stmt(); }
        } else { src_pos += 1; }
    }

    // compile top-level code into main
    emit_s("(func (export \"main\") (result i64)\n");
    emit_s("  (local $__tmp i64)\n");
    emit_s("  (local $__for_end i64)\n");
    src_pos = 0; skip();
    var last_v: i64 = 0;
    while (cur() != 0) {
        if (is_letter(cur()) == 1) {
            var s: i64 = src_pos;
            var w: i64 = read_name();
            if (streq_mem(w, "fn") == 1) {
                skip_past_block();
            } else {
                src_pos = s;
                if (last_v == 1) { emit_s("  drop\n"); }
                last_v = c_stmt();
            }
        } else {
            if (last_v == 1) { emit_s("  drop\n"); }
            last_v = c_stmt();
        }
    }
    if (last_v == 0) { emit_s("  i64.const 0\n"); }
    emit_s(")\n");
    emit_string_data();
    emit_s(")\n");
    return 0;
}