Modify term() to handle float arithmetic:
var expr_is_float: bool = false;
fn factor() i64 {
// ... existing code ...
if (is_letter(cur())) {
const name: []const u8 = read_name();
if (isFloat(name)) { expr_is_float = true; }
// ...
}
// float literal detected -> expr_is_float = true
}
fn term() i64 {
var val: i64 = factor();
while (cur() == '*' or cur() == '/' or cur() == '%') {
const op: u8 = cur();
pos += 1; skip();
const right: i64 = factor();
if (expr_is_float) {
const a: f64 = @bitCast(val);
const b: f64 = @bitCast(right);
if (op == '*') { val = @bitCast(a * b); }
else if (op == '/') { val = @bitCast(a / b); }
else { val = @bitCast(@rem(a, b)); }
} else {
if (op == '*') { val = val * right; }
else if (op == '/') { val = @divTrunc(val, right); }
else { val = @rem(val, right); }
}
}
return val;
}
Same structure as before. The if (expr_is_float) branch bitcasts to f64, operates, bitcasts back. The else branch does integer math as before.
Apply the same pattern to add_sub() and comparison().
Test -- we need a helper to compare float results since bitcast i64 values aren't human-readable:
fn check_float(input: []const u8, expected: f64) void {
source = input; pos = 0; num_vars = 0; num_globals = 0;
fn_count = 0; return_flag = false; in_function = false;
save_depth = 0; expr_is_float = false; skip();
const got: i64 = program();
const got_f: f64 = @bitCast(got);
if (@abs(got_f - expected) < 0.0001) {
print(" ok {d:.4}\n", .{got_f});
} else {
print(" FAIL got={d:.4} want={d:.4}\n", .{ got_f, expected });
}
}
check_float("3.14", 3.14);
check_float("2.0 + 3.0", 5.0);
check_float("6.0 * 7.0", 42.0);
check_float("22.0 / 7.0", 3.142857);
check_float("var r: f64 = 2.5; r * r * 3.14159", 19.6349);
### Type conversion
Integer and float are separate worlds. 3 + 2.5 doesn't automatically work -- the 3 is an i64 and the 2.5 is an f64 bit pattern. We need explicit conversion.