Final fold-2 chunk. The 12 Fam13 single-file value drivers move from test/wcc/*_run.c into in-language @test row-tables under test/lang/: - value rows -> test/lang/*_test.ww (12 files) - reject rows -> runww //ww:error carriers (13, dual-stage non-vacuous) - nullable abort rows -> runww //ww:run-exit 1 carriers (3) - 953_globalslice_arg -> _runonly (cs!=ww checker divergence, #28) - 788 value_not_type_neg + 953_arrlit_slice reject_assign kept as slim rc-only .c pins (divergent-diag dual-reject, mutation-gated); 788 #29 Coverage parity verified row-by-row vs each retired driver; advisor- ratified carve taxonomy; two-round reviewed. Floor ratchet follows.
88 lines
2.3 KiB
Plaintext
88 lines
2.3 KiB
Plaintext
// forrange_fieldbase_test — #70: by-value for-range over a NON-IDENT slice/str
|
|
// base (field chain, indexed element, call result). Migrated from
|
|
// test/wcc/937_forrange_fieldbase_run.c (value rows; cs==ww byte-id rides T2).
|
|
// The two LOUD-reject rows (deref base #11, non-ident array base #70) stay as
|
|
// runww //ww:error carriers under test/wcc/data/.
|
|
//
|
|
// Pre-#70 the range header stored the data POINTER into the bound temp and the
|
|
// per-iteration code reused it as the base, so i was compared against the
|
|
// pointer and the loop walked off the end (regex.finish SEGV); empty slices
|
|
// coincidentally exited on ptr==0, so the byte-id gate held on both-wrong. Now
|
|
// bound = len, base ptr spilled to its own slot. field_base_24B is the live
|
|
// SEGV repro (24B str-header elements through a ptr field); eval_once pins the
|
|
// range operand is captured once (a per-iteration field re-read would mis-sum).
|
|
|
|
package forrange_fieldbase_test;
|
|
|
|
type holder = struct { xs: []i64, name: str };
|
|
type holder2 = struct { xs: []i64, n: i64 };
|
|
type bag = struct { names: []str, n: i64 };
|
|
|
|
fn mk() []i64 = {
|
|
let xs: []i64;
|
|
append(xs, 7);
|
|
append(xs, 8);
|
|
return xs;
|
|
};
|
|
|
|
@test fn field_base() void = {
|
|
let h: holder = holder { xs = mk(), name = "h" };
|
|
let s1: i64 = 0;
|
|
for (let v .. h.xs) { s1 += v; };
|
|
assert(s1 == 15);
|
|
let p: *holder = &h;
|
|
let s2: i64 = 0;
|
|
for (let v .. p.xs) { s2 += v; };
|
|
assert(s2 == 15);
|
|
};
|
|
|
|
@test fn field_base_24B() void = {
|
|
let names: []str;
|
|
append(names, "ab");
|
|
append(names, "cde");
|
|
let b: bag = bag { names = names, n = 2 };
|
|
let p: *bag = &b;
|
|
let total: i64 = 0;
|
|
for (let nm .. p.names) {
|
|
total += (len(nm): i64);
|
|
};
|
|
assert(total == 5);
|
|
};
|
|
|
|
@test fn indexed_base() void = {
|
|
let m: [][]i64;
|
|
append(m, mk());
|
|
let s: i64 = 0;
|
|
for (let v .. m[0]) { s += v; };
|
|
assert(s == 15);
|
|
};
|
|
|
|
@test fn call_base() void = {
|
|
let s: i64 = 0;
|
|
for (let v .. mk()) { s += v; };
|
|
assert(s == 15);
|
|
};
|
|
|
|
@test fn empty_field() void = {
|
|
let h: holder = holder { name = "e", ... };
|
|
let hit: bool = false;
|
|
for (let v .. h.xs) { hit = true; };
|
|
assert(!hit);
|
|
};
|
|
|
|
@test fn eval_once() void = {
|
|
let a: []i64;
|
|
append(a, 7);
|
|
append(a, 8);
|
|
let b: []i64;
|
|
append(b, 100);
|
|
let h: holder2 = holder2 { xs = a, n = 0 };
|
|
let s: i64 = 0;
|
|
for (let v .. h.xs) {
|
|
s += v;
|
|
h.xs = b;
|
|
};
|
|
assert(s == 15);
|
|
assert(len(h.xs) == 1);
|
|
};
|