Add float instructions to the VM. Each one bitcasts the i64 stack values to f64, operates, and bitcasts back:
if (streq(line, "f64.add")) {
const b: f64 = @bitCast(vm_pop());
const a: f64 = @bitCast(vm_pop());
vm_push(@bitCast(a + b));
return;
}
if (streq(line, "f64.sub")) {
const b: f64 = @bitCast(vm_pop());
const a: f64 = @bitCast(vm_pop());
vm_push(@bitCast(a - b));
return;
}
if (streq(line, "f64.mul")) {
const b: f64 = @bitCast(vm_pop());
const a: f64 = @bitCast(vm_pop());
vm_push(@bitCast(a * b));
return;
}
if (streq(line, "f64.div")) {
const b: f64 = @bitCast(vm_pop());
const a: f64 = @bitCast(vm_pop());
vm_push(@bitCast(a / b));
return;
}
if (starts_with(line, "f64.const ")) {
// Parse the float from the text
const f: f64 = parse_f64_from_line(line, 10);
vm_push(@bitCast(f));
return;
}
if (streq(line, "f64.convert_i64_s")) {
const i: i64 = vm_pop();
const f: f64 = @floatFromInt(i);
vm_push(@bitCast(f));
return;
}
if (streq(line, "i64.trunc_f64_s")) {
const f: f64 = @bitCast(vm_pop());
const i: i64 = @intFromFloat(f);
vm_push(i);
return;
}
Also add float comparisons: f64.gt, f64.lt, f64.ge, f64.le, f64.eq, f64.ne. These return i64 (1 or 0), not f64 -- a comparison's result is always boolean.
if (streq(line, "f64.gt")) {
const b: f64 = @bitCast(vm_pop());
const a: f64 = @bitCast(vm_pop());
vm_push(if (a > b) @as(i64, 1) else 0);
return;
}
// ... same pattern for lt, ge, le, eq, ne