selfhost: regen combined.ww for 5466ea0 strings.concat variadic

Frozen-artifact catch-up. 5466ea0 modified lib/strings/strings.ww and
lib/strings/stringstest.ww but did not regenerate the three bundled
.combined.ww files. Bisect of the frozen-fallback build path was
broken at 5466ea0..HEAD.
This commit is contained in:
2026-05-19 00:56:30 +09:00
parent 5466ea048d
commit c9cf25be28
3 changed files with 93 additions and 51 deletions

View File

@@ -1445,17 +1445,18 @@ export fn position(d: *decoder) i32 = {
//
// Documented divergences from Hare:
//
// - `concat(a, b)` is 2-arg. Hare ships `concat(strs: str...)`
// (ref/hare/strings/concat.ha:5). Blocks on task #16 (cstage
// variadic-pack drops .len of multi-field element type). Cite
// reverts on fix.
// - `trim` / `ltrim` / `rtrim` take a single rune. Hare's are
// `(exclude: rune...)` (ref/hare/strings/trim.ha:54). Same
// blocker as concat. Hare's no-rune branch (strip whitespace)
// is also dropped — depends on a rune set.
// `(trim: rune...)` (ref/hare/strings/trim.ha:11,32,54). The
// port body uses `iter`/`next` + inner match against the pack +
// `prev` step-back; that shape triggers #36 (wwstage scanlocals
// misses match-arm `case let` bindings, slot offsets diverge —
// `.ai/probe_trim_36extra.{ww,diff}`). Hare's no-rune
// strip-whitespace branch additionally needs `lib/bytes`
// variadic graduation.
// - `contains` is non-variadic. Hare's is
// `contains(haystack, needles: (str | rune)...)`
// (ref/hare/strings/contains.ha:9). Same blocker.
// (ref/hare/strings/contains.ha:9). Gated on `(str|rune)...`
// tagged-variadic gather + runtime — task #5.
// - `byteindex` / `rbyteindex` rune arms encode via
// `utf8.encoderune`; the legacy impls scanned for `r: u8` (an
// undocumented ASCII-only restriction that silently dropped
@@ -1549,17 +1550,30 @@ export fn freeall(s: []str) void = {
};
};
// concat — fresh allocation containing `a` then `b`. Caller releases
// with `os.free(r.ptr, r.len: u64)`. ref/hare/strings/concat.ha:5
// (subset: Hare's `(strs: str...)` blocks on task #16).
export fn concat(a: str, b: str) str = {
let total: i32 = a.len + b.len;
let buf: *u8 = os.alloc(total: u64): *u8;
// concat — fresh allocation containing each element of `strs` in
// order. Caller releases with `os.free(r.ptr, r.len: u64)`.
// ref/hare/strings/concat.ha:5. Hare's `nomem` return is dropped:
// `os.alloc` aborts on OOM.
export fn concat(strs: str...) str = {
let total: i32 = 0;
let i: i32 = 0;
for (i < a.len) { buf[i] = a[i]; i += 1; };
let j: i32 = 0;
for (j < b.len) { buf[a.len + j] = b[j]; j += 1; };
for (i < strs.len) { total += strs[i].len; i += 1; };
let r: str;
r.ptr = nil;
r.len = 0;
if (total == 0) { return r; };
let buf: *u8 = os.alloc(total: u64): *u8;
let off: i32 = 0;
i = 0;
for (i < strs.len) {
let j: i32 = 0;
for (j < strs[i].len) {
buf[off + j] = strs[i][j];
j += 1;
};
off += strs[i].len;
i += 1;
};
r.ptr = buf;
r.len = total;
return r;

View File

@@ -1445,17 +1445,18 @@ export fn position(d: *decoder) i32 = {
//
// Documented divergences from Hare:
//
// - `concat(a, b)` is 2-arg. Hare ships `concat(strs: str...)`
// (ref/hare/strings/concat.ha:5). Blocks on task #16 (cstage
// variadic-pack drops .len of multi-field element type). Cite
// reverts on fix.
// - `trim` / `ltrim` / `rtrim` take a single rune. Hare's are
// `(exclude: rune...)` (ref/hare/strings/trim.ha:54). Same
// blocker as concat. Hare's no-rune branch (strip whitespace)
// is also dropped — depends on a rune set.
// `(trim: rune...)` (ref/hare/strings/trim.ha:11,32,54). The
// port body uses `iter`/`next` + inner match against the pack +
// `prev` step-back; that shape triggers #36 (wwstage scanlocals
// misses match-arm `case let` bindings, slot offsets diverge —
// `.ai/probe_trim_36extra.{ww,diff}`). Hare's no-rune
// strip-whitespace branch additionally needs `lib/bytes`
// variadic graduation.
// - `contains` is non-variadic. Hare's is
// `contains(haystack, needles: (str | rune)...)`
// (ref/hare/strings/contains.ha:9). Same blocker.
// (ref/hare/strings/contains.ha:9). Gated on `(str|rune)...`
// tagged-variadic gather + runtime — task #5.
// - `byteindex` / `rbyteindex` rune arms encode via
// `utf8.encoderune`; the legacy impls scanned for `r: u8` (an
// undocumented ASCII-only restriction that silently dropped
@@ -1549,17 +1550,30 @@ export fn freeall(s: []str) void = {
};
};
// concat — fresh allocation containing `a` then `b`. Caller releases
// with `os.free(r.ptr, r.len: u64)`. ref/hare/strings/concat.ha:5
// (subset: Hare's `(strs: str...)` blocks on task #16).
export fn concat(a: str, b: str) str = {
let total: i32 = a.len + b.len;
let buf: *u8 = os.alloc(total: u64): *u8;
// concat — fresh allocation containing each element of `strs` in
// order. Caller releases with `os.free(r.ptr, r.len: u64)`.
// ref/hare/strings/concat.ha:5. Hare's `nomem` return is dropped:
// `os.alloc` aborts on OOM.
export fn concat(strs: str...) str = {
let total: i32 = 0;
let i: i32 = 0;
for (i < a.len) { buf[i] = a[i]; i += 1; };
let j: i32 = 0;
for (j < b.len) { buf[a.len + j] = b[j]; j += 1; };
for (i < strs.len) { total += strs[i].len; i += 1; };
let r: str;
r.ptr = nil;
r.len = 0;
if (total == 0) { return r; };
let buf: *u8 = os.alloc(total: u64): *u8;
let off: i32 = 0;
i = 0;
for (i < strs.len) {
let j: i32 = 0;
for (j < strs[i].len) {
buf[off + j] = strs[i][j];
j += 1;
};
off += strs[i].len;
i += 1;
};
r.ptr = buf;
r.len = total;
return r;

View File

@@ -1336,17 +1336,18 @@ export fn position(d: *decoder) i32 = {
//
// Documented divergences from Hare:
//
// - `concat(a, b)` is 2-arg. Hare ships `concat(strs: str...)`
// (ref/hare/strings/concat.ha:5). Blocks on task #16 (cstage
// variadic-pack drops .len of multi-field element type). Cite
// reverts on fix.
// - `trim` / `ltrim` / `rtrim` take a single rune. Hare's are
// `(exclude: rune...)` (ref/hare/strings/trim.ha:54). Same
// blocker as concat. Hare's no-rune branch (strip whitespace)
// is also dropped — depends on a rune set.
// `(trim: rune...)` (ref/hare/strings/trim.ha:11,32,54). The
// port body uses `iter`/`next` + inner match against the pack +
// `prev` step-back; that shape triggers #36 (wwstage scanlocals
// misses match-arm `case let` bindings, slot offsets diverge —
// `.ai/probe_trim_36extra.{ww,diff}`). Hare's no-rune
// strip-whitespace branch additionally needs `lib/bytes`
// variadic graduation.
// - `contains` is non-variadic. Hare's is
// `contains(haystack, needles: (str | rune)...)`
// (ref/hare/strings/contains.ha:9). Same blocker.
// (ref/hare/strings/contains.ha:9). Gated on `(str|rune)...`
// tagged-variadic gather + runtime — task #5.
// - `byteindex` / `rbyteindex` rune arms encode via
// `utf8.encoderune`; the legacy impls scanned for `r: u8` (an
// undocumented ASCII-only restriction that silently dropped
@@ -1440,17 +1441,30 @@ export fn freeall(s: []str) void = {
};
};
// concat — fresh allocation containing `a` then `b`. Caller releases
// with `os.free(r.ptr, r.len: u64)`. ref/hare/strings/concat.ha:5
// (subset: Hare's `(strs: str...)` blocks on task #16).
export fn concat(a: str, b: str) str = {
let total: i32 = a.len + b.len;
let buf: *u8 = os.alloc(total: u64): *u8;
// concat — fresh allocation containing each element of `strs` in
// order. Caller releases with `os.free(r.ptr, r.len: u64)`.
// ref/hare/strings/concat.ha:5. Hare's `nomem` return is dropped:
// `os.alloc` aborts on OOM.
export fn concat(strs: str...) str = {
let total: i32 = 0;
let i: i32 = 0;
for (i < a.len) { buf[i] = a[i]; i += 1; };
let j: i32 = 0;
for (j < b.len) { buf[a.len + j] = b[j]; j += 1; };
for (i < strs.len) { total += strs[i].len; i += 1; };
let r: str;
r.ptr = nil;
r.len = 0;
if (total == 0) { return r; };
let buf: *u8 = os.alloc(total: u64): *u8;
let off: i32 = 0;
i = 0;
for (i < strs.len) {
let j: i32 = 0;
for (j < strs[i].len) {
buf[off + j] = strs[i][j];
j += 1;
};
off += strs[i].len;
i += 1;
};
r.ptr = buf;
r.len = total;
return r;