Appendix B: Floating Point
compiler-float-types

Track types in the compiler. Maintain a parallel array of type flags for globals and locals. When c_factor() encounters a float variable or float literal, set a flag. When c_term() / c_add_sub() emit arithmetic, choose based on the flag:

var c_expr_is_float: bool = false;

fn c_factor() void {
    // Float literal
    if (cur() >= '0' and cur() <= '9') {
        const val: i64 = number();
        if (cur() == '.' and pos + 1 < source.len and source[pos + 1] >= '0') {
            // Parse float, emit f64.const
            c_expr_is_float = true;
            emit_str("  f64.const ");
            emit_num(val);
            emit_byte('.');
            pos += 1;
            while (cur() >= '0' and cur() <= '9') {
                emit_byte(cur());
                pos += 1;
            }
            emit_byte('\n');
            skip();
            return;
        }
        emit_const(val);
        return;
    }
    // Variable reference
    if (is_letter(cur())) {
        const name: []const u8 = read_name();
        if (c_is_float(name)) { c_expr_is_float = true; }
        // ... emit local.get/global.get as before
    }
}

fn c_term() void {
    c_factor();
    while (cur() == '*' or cur() == '/' or cur() == '%') {
        const op: u8 = cur();
        pos += 1; skip();
        c_factor();
        if (c_expr_is_float) {
            if (op == '*') { emit_op("f64.mul"); }
            else if (op == '/') { emit_op("f64.div"); }
        } else {
            if (op == '*') { emit_op("i64.mul"); }
            else if (op == '/') { emit_op("i64.div_s"); }
            else { emit_op("i64.rem_s"); }
        }
    }
}

Same pattern for c_add_sub() and c_comparison().

For local declarations, emit the right type:

    if (c_is_float(local_names[i])) {
        emit_str("  (local $"); emit_str(local_names[i]); emit_str(" f64)\n");
    } else {
        emit_str("  (local $"); emit_str(local_names[i]); emit_str(" i64)\n");
    }

For globals:

    emit_str("(global $"); emit_str(name);
    if (is_float) {
        emit_str(" (mut f64) (f64.const 0))\n");
    } else {
        emit_str(" (mut i64) (i64.const 0))\n");
    }