Continue fold-2 (after 374e97b): migrate the remaining Family-1 str/slice
global + literal + index + call-arg group from bespoke build+run C twins to
test/lang @test, retiring each twin in the same commit. Runtime coverage MOVES
from $(TESTS) to test-lang (T1 runs+asserts via `ww test`) + test-lang-byteid
(T2 keeps cs==ww .s byte-id); coverage is preserved, the $(TESTS) headline
drops 9 (434->425). All asserts are primitive int/u8/bool comparisons (no
fmt/strconv in the assert path); the slice-store/index rows reset the global
each fn and sum ADJACENT elements so a dropped/mis-strided/over-wide word FAILS.
989_globslicefield_run.c -> glob_slice_field_test.ww (slice field of a global struct: g.f=<slice> stores full 24B header; len/cap/non-zero-offset + str/scalar controls)
989_globstrslice_run.c -> glob_str_slice_arg_test.ww (global str sliced with default hi passed as call arg loads its len word; explicit-hi control)
989_trystr_run.c -> try_str_unwrap_test.ww (`!` unwrap of str-success tagged union shuffles the str header for ident-source/error-first/success-first)
797_len_strglobal_run.c -> len_str_global_test.ww (len(str-global) loads .len via name(SB); local-str control)
801_litstr_pseudo_run.c -> lit_str_pseudo_test.ww (string-literal .len/.ptr pseudo-field; empty/multibyte + arg-passthrough)
803_globalidx_run.c -> global_index_test.ww (global str/slice index read/addr-of/store/compound, esz 1/4; local regression pins)
903_tuple_elem_slice_len.c -> tuple_elem_slice_len_test.ww (len(t.N) of a slice/str tuple element loads .len at +8; 2/3-slice, str-slice both orders)
927_composite_call_arg_run.c-> composite_call_arg_test.ww (slice-returning CALL passed inline as a composite arg; canonical/letslice/two-call/middle/nested/scalar/tagged)
952_slicecopy_assign_run.c -> slice_copy_assign_test.ww (bulk slice-copy-assign `arr[lo:hi]=bs`, esz 1/4, field/via-ptr/local bases; reslice-read companion)
rd_reslice asserts the TRUE value 360 (the .c twin's want=104 was 360 & 0xFF,
an exit-code truncation). 723_composite_call_arg.c's comment repointed to the
new test/lang location. 802_lenidx_run.c is DEFERRED (it carries //ww:error
reject rows — needs a value-rows-only split + a slim reject carrier, a fold-3
pass). Bump LANGBYTEID_EXPECTED_MIN 22->31 to ratchet the new corpus floor.
99 lines
3.4 KiB
Plaintext
99 lines
3.4 KiB
Plaintext
// slice_copy_assign_test — bulk slice-copy-assign into a range place
|
|
// `s.arr[lo:hi] = bs` (the LHS is an N_SLICE), migrated from
|
|
// test/wcc/952_slicecopy_assign_run.c (#145). No legacy N_ASSIGN arm caught an
|
|
// N_SLICE LHS, so the statement fell through to the scalar tail and emitted
|
|
// NOTHING — a silent no-op in BOTH stages, byte-id-green (#263-class). The fix
|
|
// reuses the N_SLICE READ lowering (AX = base+lo*esz, BX = hi-lo, CX = cap),
|
|
// scales BX by the SAME read-path element width (esz; [N]u8→1, [N]i32→4), and
|
|
// emits a runtime-counted byte-granular copy loop. WRITE rows assert the copy
|
|
// lands the right bytes in [lo,hi) AND leaves bytes OUTSIDE the range untouched
|
|
// (each sums members both inside and outside, so a mis-strided / over-wide copy
|
|
// fails); esz coverage [N]u8 + [N]i32; base coverage struct-field array (N_DOT),
|
|
// via-*struct-param, and bare-local (N_IDENT). READ rows lock the reslice-consume
|
|
// companion (#5, already clean).
|
|
|
|
package slice_copy_assign_test;
|
|
|
|
type buffer = struct { buf: [8]u8, end: i32 };
|
|
type box = struct { o: [8]i32 };
|
|
|
|
fn wr(s: *buffer, src: []u8) void = { s.buf[1:4] = src; };
|
|
|
|
@test fn w_u8_lo0() void = {
|
|
// struct-field [N]u8 base (the appendlit shape).
|
|
let s: buffer;
|
|
let bs: [3]u8; bs[0] = 10u8; bs[1] = 20u8; bs[2] = 30u8;
|
|
s.buf[0:3] = bs[0:3];
|
|
assert((s.buf[0] + s.buf[1] + s.buf[2] + s.buf[3]
|
|
+ s.buf[4] + s.buf[5]): i32 == 60);
|
|
};
|
|
|
|
@test fn w_u8_lo2() void = {
|
|
let s: buffer;
|
|
let bs: [3]u8; bs[0] = 10u8; bs[1] = 20u8; bs[2] = 30u8;
|
|
s.buf[2:5] = bs[0:3];
|
|
assert((s.buf[0] + s.buf[1] + s.buf[2] + s.buf[3]
|
|
+ s.buf[4] + s.buf[5]): i32 == 60);
|
|
};
|
|
|
|
@test fn w_u8_single() void = {
|
|
let s: buffer;
|
|
let bs: [1]u8; bs[0] = 42u8;
|
|
s.buf[3:4] = bs[0:1];
|
|
assert((s.buf[2] + s.buf[3] + s.buf[4]): i32 == 42);
|
|
};
|
|
|
|
@test fn w_empty() void = {
|
|
// hi==lo — count=0; the loop's CMPQ $0 guard must JLE-exit before the first
|
|
// MOVB (an off-by-one underflow would clobber buf[lo] and run away).
|
|
let s: buffer; s.buf[2] = 5u8; s.buf[3] = 7u8;
|
|
let bs: [3]u8; bs[0] = 10u8; bs[1] = 20u8; bs[2] = 30u8;
|
|
s.buf[2:2] = bs[0:0];
|
|
assert((s.buf[1] + s.buf[2] + s.buf[3] + s.buf[4]): i32 == 12);
|
|
};
|
|
|
|
@test fn w_i32() void = {
|
|
// esz=4 — [N]i32 field strides by the element width, not 1.
|
|
let s: box;
|
|
let bs: [2]i32; bs[0] = 40; bs[1] = 88;
|
|
s.o[1:3] = bs[0:2];
|
|
assert((s.o[0] + s.o[1] + s.o[2] + s.o[3]): i32 == 128);
|
|
};
|
|
|
|
@test fn w_viaptr() void = {
|
|
// the field write through a *struct param (appendlit's `buf: *buffer`).
|
|
let s: buffer;
|
|
let bs: [3]u8; bs[0] = 11u8; bs[1] = 22u8; bs[2] = 33u8;
|
|
wr(&s, bs[0:3]);
|
|
assert((s.buf[0] + s.buf[1] + s.buf[2] + s.buf[3]
|
|
+ s.buf[4]): i32 == 66);
|
|
};
|
|
|
|
@test fn w_local() void = {
|
|
// N_IDENT base — a bare-local array place.
|
|
let a: [8]u8;
|
|
let bs: [3]u8; bs[0] = 10u8; bs[1] = 20u8; bs[2] = 30u8;
|
|
a[2:5] = bs[0:3];
|
|
assert((a[0] + a[1] + a[2] + a[3] + a[4] + a[5]): i32 == 60);
|
|
};
|
|
|
|
@test fn rd_reslice() void = {
|
|
// READ twin (#5, already clean) — reslice the field array with a runtime hi
|
|
// bound, consume as []u8.
|
|
let s: buffer;
|
|
let bs: [3]u8; bs[0] = 10u8; bs[1] = 20u8; bs[2] = 30u8;
|
|
s.buf[0:3] = bs[0:3];
|
|
s.end = 3;
|
|
let v: []u8 = s.buf[0:s.end];
|
|
// 10+20+30 + 3*100 == 360 (the .c twin's want=104 was 360 & 0xFF, an
|
|
// exit-code truncation; the @test asserts the true value).
|
|
assert(v[0]: i32 + v[1]: i32 + v[2]: i32 + (v.len: i32) * 100 == 360);
|
|
};
|
|
|
|
@test fn rd_len() void = {
|
|
let s: buffer;
|
|
s.end = 5;
|
|
let v: []u8 = s.buf[0:s.end];
|
|
assert(v.len: i32 == 5);
|
|
};
|