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;
}