Port four of the five c3 strings functions per ref/hare/strings/iter.ha; strings.slice deferred behind task #34 (wwstage fnretlookup same-name cross-module phantom return-ABI fixup, sub-bug of #4e). - prev ref/hare/strings/iter.ha:49 - riter ref/hare/strings/iter.ha:32 - iterstr ref/hare/strings/iter.ha:63 - position ref/hare/strings/iter.ha:82 Also adds a private move() helper (ref/hare/strings/iter.ha:51) shared by next/prev. Hare's move picks the utf8 function via a fn-pointer (`let fun = if (forward) &utf8::next else &utf8::prev`); ww has no fn-pointers in scope yet, so move branches on `forward` and calls utf8.next or utf8.prev directly at each site. strings.next is updated to dispatch via move(!it.reverse, it) — c2's implementation always called utf8.next regardless of iter.reverse, which was correct for forward iter() but would walk forward on riter()-produced iterators too. With riter landed in this commit, next() now correctly walks backward on reverse iterators per Hare's ref/hare/strings/iter.ha:45. No in-tree consumer regression: only stringstest constructs iterators today. strings.iterstr uses ww's `[lo:hi]` slice syntax instead of Hare's `[lo..hi]`; same semantics (borrowed []u8 view). strings.slice deferred — Hare's body is `fromutf8_unsafe(utf8::slice(begin, end))` (ref/hare/strings/iter.ha:76). That delegation form triggers a wwstage fnretlookup miscompile when the caller module has a function of the same name as the callee (here: both strings::slice and utf8::slice exist), causing wwstage to emit the wrong return-ABI fixup (MOVQ DX, BX, str's AX/DX→AX/BX shim) after the cross-module CALL. Cstage handles the collision correctly; wwstage routes through the same-module function's return type and the byte-id checks (993_ww_ww + 995_self_rebuild) trip. Filed as task #34 with minimal repro; will land strings.slice when the fnretlookup graduate-by-module sub-bug in #34 is fixed. Top-of-file divergence note lists slice in the deferred set; the landing site keeps a comment-only stub. The public strings c3 surface ships 4-of-5 in this commit; slice + #34 land together in a follow-up. Tests: 5 new @test fns in stringstest.ww (signalled 22-26): iter_prev_at_start_cases (prev at offs=0 → done), iter_prev_ascii_cases (round-trip on forward iter), iter_full_cases (mirror of ref/hare/strings/iter.ha:84-108 — iter "こんにちは" with mid-walk iterstr + prev + next, then s = riter(...) sret-into-existing-slot for the reverse iterator pass), iter_position_cases (position tracks offs through a multibyte walk), iter_iterstr_reverse_cases (riter iterstr is bytes BEFORE the cursor, dual to forward iter's bytes-AFTER). The Hare @test fn iter body uses `s = riter("にちは")` mid-test to swap the iterator's direction (ref/hare/strings/iter.ha:101); ww's sret-into-existing-slot path handles that fine (probed pre-port). struct-copy let-from-ident (task #32) is sidestepped because no test creates a duplicate iterator via `let dup = it;`. 117/117 ok. 995_self_rebuild stays green (ww2==ww3==ww4 byte-id). 993_ww_ww + 994_w6c_ww also green (cstage/wwstage byte-identical on every corpus input including selfhost/cmd/wwdump/main.combined.ww).
12 KiB
12 KiB