Add float literal parsing to the interpreter's factor(). When number() reads digits and hits a . followed by more digits, it's a float.
We store floats as their IEEE 754 bit pattern inside an i64, using Zig's @bitCast:
fn parse_float(whole: i64) i64 {
var f: f64 = @floatFromInt(whole);
pos += 1; // skip the '.'
var divisor: f64 = 10.0;
while (cur() >= '0' and cur() <= '9') {
const digit: f64 = @floatFromInt(cur() - '0');
f += digit / divisor;
divisor *= 10.0;
pos += 1;
}
skip();
return @bitCast(f);
}
In factor(), after calling number(), check if the next character is .:
// In the number/expression path:
const val: i64 = number();
if (cur() == '.' and pos + 1 < source.len and source[pos + 1] >= '0' and source[pos + 1] <= '9') {
return parse_float(val);
}
The returned i64 holds the bit pattern of a float. 3.14 returns the 64 bits of IEEE 754 3.14. To the variable storage system, it's just a number. The interpretation depends on the variable's declared type.