Commit Graph

5 Commits

Author SHA1 Message Date
6a5cdbd779 lib/strconv: parseint sign+overflow core; stoi64/stou64 fidelity (strconv-int fold-1 C1)
Port ref/hare/strconv/stou.ha:8-65 (rune_to_integer + parseint) and the
stoi64/stou64 fidelity rewrite (stoi.ha:9-17, stou.ha:70-76) over the old
digval loop. parseint is the shared sign + per-digit + multiply-overflow
core returning ((bool, u64) | invalid | overflow); stoi64/stou64 destructure
its `(sign, u)` tuple-in-union result — the shape unblocked by #242/#241.

Wins over the prior ad-hoc parse: leading '+' accepted, '-' on stou64 is
overflow (not silently dropped), wraparound overflow detection (n < old),
and the invalid payload carries the offending byte index per Hare.

Tests: lib/strconv/test/inttest.ww (run via test/wcc/922_strconv_int_run.c),
inline per-case checks mirroring Hare's assert sequences stoi.ha:56-86 /
stou.ha:116-138 (Hare's strconv int tests are flat sequences, not row
tables; feedback_test_match_hare_source). Covers valid dec/hex/oct/bin,
+/- sign, invalid+index, overflow, and U64_MAX / I64_MAX / I64_MIN
boundaries. The I64_MIN expectation is spelled -I64_MAX-1 (Hare's own
two's-complement identity) to isolate the test from #245 (wwstage mis-lexes
the literal 9223372036854775808 -> 0); the parse INPUT is unaffected and
yields the correct value on both stages.

combined.ww regen: strconv is compiler-imported (via fmt), so w6c +
wwdump main.combined.ww are regenerated.
2026-06-01 22:26:53 +09:00
0e72556120 lib/strconv: f32tos Ryū shortest float→string (#106 fold-5b)
The f32 coda of Drew's strconv 5-fold plan — f64tos shipped in fold-5a
(0e66073); this completes the plan. Re-lands the f32-exclusive Ryū path
that fold-5a removed under the dead-code rule (it was #143-blocked):
pow5fac32/pow5multiple32/pow2multiple32, mulshift32, mulpow5inv_divpow2/
mulpow5_divpow2, decf32, f32todecf32 (ftos_ryu.ha), and the f32tos driver
(ftos.ha:448). Plus F32_POW5_*_BITCOUNT in ftos_data.ww.

The f32 path REUSES the shared u64 core (mulshiftall64/u128mul/u128rshift/
log*) and f64computeinvpow5/f64computepow5 — and thus the f64 SPLIT2
tables — exactly as ftos_ryu.ha does; there are no separate f32 tables.

Unblocked by #143 (aff7725): f32tos calls math.f32bits(n), passing an f32
arg, which now spills MOVSS (4B) in both stages. Verified: f32tos's arg
push/pop is MOVSS, w6c vs w6c_ww 0-diff on the strconv-embedding
combined.ww (w6c/wwdump/smoke regenerated).

Dodges (cgen bugs still deferred, each cited at-site): decf32.exponent:i64
sidesteps the #169 narrow-second-field struct-return unpack (byte-id
gate-confirmed, not an ABI guarantee); #168 div/mod local-bind on the two
`%10` sites; *decimal pointer field reads (#170); [32]u8 buffer reuses
f64tos's byte-id-clean band over Hare's [14] (#43). mulshift32's U32_MAX
bound inlines the literal — ww's types.U32_MAX is package-private (#172).

Test: ftostest.ww gains f32 vectors — the tcs G/void rows (shared f32/f64
shortest), the f32-exclusive tcsf32 extremes (1e-45 / 1.1754944e-38 /
3.4028235e38, full 24-bit mantissa), specials, a negative-normal, and
33554432 (the sole e2>=0/q<=9 runtime cover). make test 187/187 incl
908_ftos_run + 990-997 byte-id + combined_ww_fresh.
2026-05-27 17:18:27 +09:00
0e66073e32 lib/strconv: f64tos Ryū shortest float→string (#106 fold-5a)
Graduate f64tos from the lossy fixed-point placeholder to Ryū shortest-
round-trippable (ftos.ha:432 + ftos_ryu.ha). f64tos(n:f64) str, G-format
(void/NONE) — the faithful documented subset (full parametric fftosf is
dead code for G/void/NONE → deferred #64). Ryū core decomposed: struct-
RETURN + scalar params (Hare's r128 idiom; avoids tuple-ABI #163-166).
f64 powers tables [15][2]/[13][2]u64 (2D #156). Zero float literals.
Both E+F encode paths reachable+tested, no dead code.

Graduation (lib-note "don't keep both"): old lossy f64tos deleted; fmt
fprintf_f64_huge "huge"→"9.5e18" (improvement). 5 value-faithful filed-
bug dodges (byte-id, documented): #167/#169/#170/#43/#144. Test 908.
Make test 186/186 incl 990-997 byte-id + combined_ww_fresh.

Drew's strconv 5-fold plan — primary completion (f64tos). f32tos coda
#67 (behind #143); parametric ftosf #64.
2026-05-27 15:39:03 +09:00
81796cd533 lib/strconv: stof.ha port — Eisel-Lemire string→float (#106 fold-4)
stof64/stof32 (f64|f32 | invalid | overflow) via Eisel-Lemire fast-path
(powers_of_ten[596][2]u64 + eisel_lemire 128-bit multiply) + decimal
slow-path fallback (decimal.ww, fold-3). 16 fns + faithful powers_of_ten
(byte-identical to Hare). u128 via pure-u64 64×64→128 (ftos_ryu.ha).
Consumes &math.f64info (γ-cleanup), tagged-float-return (PREREQ-2 #157),
2D double-index (PREREQ-1 #156).

13 documented spelling-divergences (rule-9, each cites stof.ha): #155
(po10 double-index + per-field struct-copy), #161 (compound-assign explicit
form), #144 (-0.0 via 1u64<<63), #158, #138, test-only #143/parsef64.
Test 909 (DEC+hex+NaN/Inf/invalid/overflow, bit-exact, cstage ww run).
Make test 185/185 incl 990-997 byte-id + combined_ww_fresh. Makefile:
stof.ww added to w6c_ww/wwdump_ww deps (freshness, fold-3 precedent).

Drew's strconv 5-fold plan 4/5. Followup #162 (wwstage lexer parsef64
1-ULP — could adopt stof64).
2026-05-27 13:55:56 +09:00
07e57ff9a6 lib/strconv: decimal arbitrary-precision arithmetic (#106 fold-3)
Port ref/hare/strconv/decimal.ha (~202 LOC Hare) → 314 LOC
lib/strconv/decimal.ww — decimal struct + 11 fns (trim,
decimal_shift, leftshift, leftshift_newdigits, rightshift, round,
decimal_round, helpers). 1:1 mechanical Hare-fidelity with 8
documented spelling-divergences. Shared engine for stof (fold-4) +
ftos (fold-5). Built atop 5 wwstage cgen prereqs
(#131/#133-expanded/#134/#135/#138) that closed gate-blind silent
miscompiles surfaced by the port. Test 922_decimal_run +
lib/strconv/test/decimaltest.ww (6 @test fns covering all 11 impl
fns).
2026-05-27 00:44:16 +09:00