Appendix B: Floating Point
float-conversion

Add conversion builtins:

    if (streq(name, "f64_from_i64")) {
        pos += 1; skip();
        const val: i64 = expression();
        if (cur() == ')') { pos += 1; skip(); }
        const f: f64 = @floatFromInt(val);
        expr_is_float = true;
        return @bitCast(f);
    }
    if (streq(name, "i64_from_f64")) {
        pos += 1; skip();
        const was_float: bool = expr_is_float;
        expr_is_float = true;
        const val: i64 = expression();
        if (cur() == ')') { pos += 1; skip(); }
        const f: f64 = @bitCast(val);
        expr_is_float = was_float;
        return @intFromFloat(f);
    }

f64_from_i64(42) converts integer 42 to float 42.0 (as a bitcast i64). i64_from_f64(3.7) truncates to integer 3.

Test:

    check_float("f64_from_i64(42)", 42.0);
    check("i64_from_f64(3.7)", 3);
    check("i64_from_f64(2.0 + 0.9)", 2);  // truncates, not rounds
    check_float("f64_from_i64(355) / f64_from_i64(113)", 3.14159);

The last test: 355/113 is a famous rational approximation of pi. With integer division it gives 3. With float division it gives 3.14159...

### Compiling floats

The compiler needs to emit the right WAT instructions based on types.