lib/math: re-fold F64_EXPBIAS to const f64info/f32info struct (#40)

Restore the Hare-faithful floatinfo struct defs (ref/hare/math/floats.ha
:117,126), removing the Drew-flattened-(b) #129-era bypass (F64_EXPBIAS:int
scalar). #149 (db7523e) now lowers cross-module &def to LEAQ, so the struct
exports are addressable via the stof consumer pattern (&math.f64info ->
f: *floatinfo -> f.expbias). First real consumer of A.2 struct-composite
static-init (DATA byte-validated: f64info/f32info 40B each).

ADD export def f64info/f32info: floatinfo (hex masks value-identical to
Hare's (1<<52)-1 etc.; A.2 helper folds bare literals only, documented
at-site). DELETE export def F64_EXPBIAS (zero consumers). KEEP NAN_BITS/
INF_BITS u64 sentinels (ruling b: def NAN=0.0/0.0 blocked by #147) +
F64_EXPONENT_BIAS:u64 (bit-ops alias, Hare keeps both).

Test 952: pointer-param row reads &math.f64info + &math.f32info through
*math.floatinfo, all 5 fields each (pointer-param not direct field-read,
dodges #150). Make test 184/184 incl 990-997 byte-id + combined_ww_fresh.
lib/math not compiler-imported -> no regen.

Unblocks fold-4 stof.ha.
This commit is contained in:
2026-05-27 10:55:31 +09:00
parent db7523e0e7
commit 88f3d67b28
2 changed files with 51 additions and 29 deletions

View File

@@ -327,20 +327,32 @@ static const struct row rows[] = {
" if (math.isinf(1.23)) { return 7; };\n"
" return 0;\n"
"};\n", 0 },
/* F64_EXPBIAS — the f64info.expbias-field-typed counterpart of the
* existing F64_EXPONENT_BIAS:u64. Flattened from f64info per #129.
* Round-trips into a floatinfo struct's expbias field with zero
* casts (the consumer pattern fold-4 stof will use). Cite ref/hare/
* math/floats.ha:117 (f64info struct const) + :24 (the existing
* untyped F64_EXPONENT_BIAS). */
/* f64info / f32info module-scope instances, read cross-module through
* a *floatinfo pointer parameter — the exact call shape stof's
* eisel_lemire (`f: *floatinfo`) uses in fold-4. Address-of a
* module-level def lowers to LEAQ since #149; the field reads
* round-trip the static-init DATA the #129 A.2 path emits. Mirrors
* ref/hare/math/floats.ha:117,126. Pointer-param (not direct
* math.f64info.expbias) because a cross-module struct-field direct read
* leaks the field name as an extern (#150, task list #48). */
{ "package main;\n"
"import math;\n"
"fn rdbias(f: *math.floatinfo) int = { return f.expbias; };\n"
"fn rdmant(f: *math.floatinfo) u64 = { return f.mantbits; };\n"
"fn rdmask(f: *math.floatinfo) u64 = { return f.mantmask; };\n"
"fn rdebits(f: *math.floatinfo) u64 = { return f.expbits; };\n"
"fn rdemask(f: *math.floatinfo) u64 = { return f.expmask; };\n"
"export fn main() i32 = {\n"
" if (math.F64_EXPBIAS != 1023) { return 1; };\n"
" let info: math.floatinfo;\n"
" info.expbias = math.F64_EXPBIAS;\n"
" if (info.expbias != 1023) { return 2; };\n"
" if (info.expbias != math.F64_EXPBIAS) { return 3; };\n"
" if (rdbias(&math.f64info) != 1023) { return 1; };\n"
" if (rdmant(&math.f64info) != 52u64) { return 2; };\n"
" if (rdmask(&math.f64info) != 0xFFFFFFFFFFFFFu64) { return 3; };\n"
" if (rdbias(&math.f32info) != 127) { return 4; };\n"
" if (rdmant(&math.f32info) != 23u64) { return 5; };\n"
" if (rdmask(&math.f32info) != 0x7FFFFFu64) { return 6; };\n"
" if (rdebits(&math.f64info) != 11u64) { return 7; };\n"
" if (rdemask(&math.f64info) != 0x7FFu64) { return 8; };\n"
" if (rdebits(&math.f32info) != 8u64) { return 9; };\n"
" if (rdemask(&math.f32info) != 0xFFu64) { return 10; };\n"
" return 0;\n"
"};\n", 0 },
{ NULL, 0 }