lib/strings+test: graduate concat to Hare str... variadic
concat(a, b: str) -> concat(strs: str...) per ref/hare/strings/concat.ha:5.
Drop nomem return per project no-alloc-error idiom (os.alloc aborts).
Unblocked by #16 variadic-pack store fix (3bd9b1d).
concat_cases rewritten to table-driven: flat pool + argo/argn parallel
arrays + slice-spread call. 9 rows cover Hare concat.ha:18 vectors
(0/1/2/3-arg, multibyte) plus empty-mid/first/last/2-empty edges.
Bisect via signalled = 200 + i.
trim/contains variadic held on task #36 — surfaced by worker-variadic
pre-flight: iter + match prev composition in non-leaf callees still
hits scanlocals offset divergence. Resolves via #15 size-strategy.
make test 121/121; ww2==ww3==ww4 byte-id holds.
This commit is contained in:
@@ -46,28 +46,57 @@ fn streq(a: str, b: str) bool = {
|
||||
};
|
||||
|
||||
// ---- concat -----------------------------------------------------------
|
||||
// ref/hare/strings/concat.ha:18 (2-arg subset).
|
||||
// ref/hare/strings/concat.ha:18. Rows mirror Hare's vectors (0/1/2/3-arg,
|
||||
// empty-mid, 2-empty) plus empty-first / empty-last / multibyte. The
|
||||
// per-row `signalled` bump narrows a failure exit code to the offending
|
||||
// row.
|
||||
|
||||
@test fn concat_cases() void = {
|
||||
let a: str = strings.concat("hello ", "world");
|
||||
if (!streq(a, "hello world")) { fail(); };
|
||||
defer os.free(a.ptr: *void, a.len: u64);
|
||||
let pool: [17]str;
|
||||
pool[0] = "hello";
|
||||
pool[1] = "hello ";
|
||||
pool[2] = "world";
|
||||
pool[3] = "hello";
|
||||
pool[4] = " ";
|
||||
pool[5] = "world";
|
||||
pool[6] = "hello";
|
||||
pool[7] = "";
|
||||
pool[8] = "world";
|
||||
pool[9] = "";
|
||||
pool[10] = "";
|
||||
pool[11] = "";
|
||||
pool[12] = "world";
|
||||
pool[13] = "hello";
|
||||
pool[14] = "";
|
||||
pool[15] = "こん";
|
||||
pool[16] = "にちは";
|
||||
|
||||
let e: str = strings.concat("", "");
|
||||
if (!streq(e, "")) { fail(); };
|
||||
// e.len == 0 — os.free guarded, skip.
|
||||
let argo: [9]i32;
|
||||
let argn: [9]i32;
|
||||
let want: [9]str;
|
||||
let labels: [9]str;
|
||||
argo[0]=0; argn[0]=0; want[0]=""; labels[0]="0-arg";
|
||||
argo[1]=0; argn[1]=1; want[1]="hello"; labels[1]="1-arg";
|
||||
argo[2]=1; argn[2]=2; want[2]="hello world"; labels[2]="2-arg";
|
||||
argo[3]=3; argn[3]=3; want[3]="hello world"; labels[3]="3-arg";
|
||||
argo[4]=6; argn[4]=3; want[4]="helloworld"; labels[4]="empty-mid";
|
||||
argo[5]=9; argn[5]=2; want[5]=""; labels[5]="2-empty";
|
||||
argo[6]=11; argn[6]=2; want[6]="world"; labels[6]="empty-first";
|
||||
argo[7]=13; argn[7]=2; want[7]="hello"; labels[7]="empty-last";
|
||||
argo[8]=15; argn[8]=2; want[8]="こんにちは"; labels[8]="multibyte";
|
||||
|
||||
let l: str = strings.concat("", "world");
|
||||
if (!streq(l, "world")) { fail(); };
|
||||
defer os.free(l.ptr: *void, l.len: u64);
|
||||
|
||||
let r: str = strings.concat("hello", "");
|
||||
if (!streq(r, "hello")) { fail(); };
|
||||
defer os.free(r.ptr: *void, r.len: u64);
|
||||
|
||||
let m: str = strings.concat("こん", "にちは");
|
||||
if (!streq(m, "こんにちは")) { fail(); };
|
||||
defer os.free(m.ptr: *void, m.len: u64);
|
||||
let i: i32 = 0;
|
||||
for (i < 9) {
|
||||
signalled = 200 + i;
|
||||
let argv: []str;
|
||||
argv.ptr = &pool[argo[i]];
|
||||
argv.len = argn[i];
|
||||
argv.cap = argn[i];
|
||||
let got: str = strings.concat(argv...);
|
||||
if (!streq(got, want[i])) { fail(); };
|
||||
if (got.len > 0) { os.free(got.ptr: *void, got.len: u64); };
|
||||
i += 1;
|
||||
};
|
||||
};
|
||||
|
||||
// ---- hasprefix --------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user