`define GW_F = double(GW)` was registered as an integer constant: the DefineT
registration only took the float path when the initializer contained a float
literal, and the cast was unwrapped before the value was read. A float cast
produces a float even without a literal, so the define became an i16 640 and
define GW_F = double(GW)
define GH_F = double(GH)
aspect: double = GW_F / GH_F
folded with integer division to 1 instead of 16/9, which broke Gargantua's
projection (and any aspect/scale ratio derived the same way).
- decide the constant kind from the original initializer (a cast to a float
type, a float literal, or a reference to a float define) and evaluate it as
a double, keeping the f32/f64 choice from the annotation or `float(...)`
- resolve DefineT names inside float expressions, so `double(GW)` and
`double(A) / double(B)` evaluate at compile time
- .vpi generation writes such defines as float literals (`= 640.0`) instead of
running the integer evaluator, which also fixes a SIGFPE when that evaluator
hit `0 / 0` for a float expression; integer division/modulo now guard a zero
right operand instead of trapping the compiler