test: migrate 949_dotbase_addr_slice to @test + byteid carve-out seam, retire C twin (fold-3)
#252/#253/#257 N_DOT-base addr-of-slice: 105 byteid=1 rows -> test/lang/dotbase_addr_slice_test.ww (primitive-only); 6 #254 run-only rows (4 chain_val_* + letcopy_dot_struct/letcopy_nest_struct, value-nested-struct frame divergence) -> dotbase_addr_slice_runonly_test.ww. New byteid-exclusion seam: LANGBYTEID_FILES filter-out %_runonly_test.ww (suffix convention; T1 value-runs both, T2 byteid skips runonly). byteid floor 54->55. Carve-out preserves the .c byteid field 1:1; all 105 byteid=1 rows verified cs==ww under the live sepwork gate.
This commit is contained in:
10
Makefile
10
Makefile
@@ -544,7 +544,6 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
|
|||||||
$(BIN)/test_checked_run \
|
$(BIN)/test_checked_run \
|
||||||
$(BIN)/test_floatarr_run \
|
$(BIN)/test_floatarr_run \
|
||||||
$(BIN)/test_inferred_scalar_global_run \
|
$(BIN)/test_inferred_scalar_global_run \
|
||||||
$(BIN)/test_dotbase_addr_slice_run \
|
|
||||||
$(BIN)/test_globalslice_arg_run \
|
$(BIN)/test_globalslice_arg_run \
|
||||||
$(BIN)/test_structlit_arrfield_run \
|
$(BIN)/test_structlit_arrfield_run \
|
||||||
$(BIN)/test_defdim_struct_run \
|
$(BIN)/test_defdim_struct_run \
|
||||||
@@ -3024,11 +3023,6 @@ $(BIN)/test_inferred_scalar_global_run: test/wcc/947_inferred_scalar_global_run.
|
|||||||
$(LIB)/libwwrt.a | $(BIN)
|
$(LIB)/libwwrt.a | $(BIN)
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
$(BIN)/test_dotbase_addr_slice_run: test/wcc/949_dotbase_addr_slice_run.c \
|
|
||||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6c_ww $(BIN)/w6a $(BIN)/w6l \
|
|
||||||
$(LIB)/libwwrt.a | $(BIN)
|
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
$(BIN)/test_globalslice_arg_run: test/wcc/953_globalslice_arg_run.c \
|
$(BIN)/test_globalslice_arg_run: test/wcc/953_globalslice_arg_run.c \
|
||||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6c_ww $(BIN)/w6a $(BIN)/w6l \
|
$(BIN)/ww $(BIN)/w6c $(BIN)/w6c_ww $(BIN)/w6a $(BIN)/w6l \
|
||||||
$(LIB)/libwwrt.a | $(BIN)
|
$(LIB)/libwwrt.a | $(BIN)
|
||||||
@@ -3278,9 +3272,9 @@ test-lang: all
|
|||||||
# (`ww build --sep` over selfhost/data) plus //ww:error reject-routing (assert
|
# (`ww build --sep` over selfhost/data) plus //ww:error reject-routing (assert
|
||||||
# both legs fail) — no reject cases exist in test/lang today.
|
# both legs fail) — no reject cases exist in test/lang today.
|
||||||
LANGBYTEID_DIR = $(OUT)/langbyteid
|
LANGBYTEID_DIR = $(OUT)/langbyteid
|
||||||
LANGBYTEID_FILES = $(wildcard test/lang/*_test.ww)
|
LANGBYTEID_FILES = $(filter-out %_runonly_test.ww,$(wildcard test/lang/*_test.ww))
|
||||||
LANGBYTEID_VERB = test -c
|
LANGBYTEID_VERB = test -c
|
||||||
LANGBYTEID_EXPECTED_MIN = 54
|
LANGBYTEID_EXPECTED_MIN = 55
|
||||||
$(if $(LANGBYTEID_FILES),,$(error test-lang-byteid: empty corpus))
|
$(if $(LANGBYTEID_FILES),,$(error test-lang-byteid: empty corpus))
|
||||||
test-lang-byteid: all
|
test-lang-byteid: all
|
||||||
@set -e; \
|
@set -e; \
|
||||||
|
|||||||
69
test/lang/dotbase_addr_slice_runonly_test.ww
Normal file
69
test/lang/dotbase_addr_slice_runonly_test.ww
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
// dotbase_addr_slice_runonly_test — the VALUE-nested-struct cell of the
|
||||||
|
// array-field-base-address family (#253 chained-base / #270-3a aggregate
|
||||||
|
// index-base copy), migrated from test/wcc/949_dotbase_addr_slice_run.c.
|
||||||
|
//
|
||||||
|
// RUN-ONLY (#254): these rows exercise the SAME fixed cg_dotbase_addr /
|
||||||
|
// dotchainaddr helper as their sibling dotbase_addr_slice_test.ww rows and
|
||||||
|
// run CORRECTLY — the #253 segfault is gone for the value-container cell.
|
||||||
|
// But a value nested-struct instance trips TWO orthogonal pre-existing
|
||||||
|
// cs!=ww emission divergences, unrelated to the base-address fix:
|
||||||
|
// 1. bare-let zero-init policy — wwstage emits an extra `MOVQ $0,off(BP)`
|
||||||
|
// for a value nested-struct local that cstage does not;
|
||||||
|
// 2. global DATAW byte count — wwstage over-emits.
|
||||||
|
// Until #254 fixes both, the rule-10 T2 byte-id gate cannot apply to these
|
||||||
|
// rows. The `_runonly_test.ww` filename suffix is the EXPLICIT opt-out that
|
||||||
|
// excludes this file from LANGBYTEID_FILES (Makefile) — value-run only, no
|
||||||
|
// byteid. They stay as LIVE run-only value pins proving the segfault is gone
|
||||||
|
// for the value cell; never dropped. PRIMITIVE-only asserts (read back the
|
||||||
|
// value; a wrong base yields a wrong readback) — no fmt/strconv.
|
||||||
|
|
||||||
|
package dotbase_addr_slice_runonly_test;
|
||||||
|
|
||||||
|
type vinner = struct { m: [4]u8 };
|
||||||
|
type outv = struct { i: vinner };
|
||||||
|
|
||||||
|
// #253 chained VALUE-container arm (o.i.m — inner is a value nested struct).
|
||||||
|
@test fn chain_val_rd() void = {
|
||||||
|
let o: outv; o.i.m[1] = 66u8;
|
||||||
|
assert(o.i.m[1]: i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn chain_val_addr() void = {
|
||||||
|
let o: outv; o.i.m[2] = 55u8;
|
||||||
|
let q: *u8 = &o.i.m[2];
|
||||||
|
assert((*q): i32 == 55i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn chain_val_slice() void = {
|
||||||
|
let o: outv; o.i.m[1] = 66u8;
|
||||||
|
let s: []u8 = o.i.m[1:4];
|
||||||
|
assert(len(s): i32 == 3i32);
|
||||||
|
assert(s[0]: i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
type vmid = struct { b: vinner };
|
||||||
|
type vtop = struct { a: vmid };
|
||||||
|
@test fn chain_deep_val() void = {
|
||||||
|
let o: vtop; o.a.b.m[1] = 66u8;
|
||||||
|
assert(o.a.b.m[1]: i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
// #270-3a value-struct aggregate index-base let-init copy. Same #254
|
||||||
|
// carve-out as chain_val_* above (the .c marked these byteid=0 explicitly).
|
||||||
|
type lcinner = struct { a: u32, b: u32, c: u32 };
|
||||||
|
type lcbox = struct { arr: [3]lcinner };
|
||||||
|
@test fn letcopy_dot_struct() void = {
|
||||||
|
let x: lcbox;
|
||||||
|
let v: lcinner; v.a = 10u32; v.b = 20u32; v.c = 30u32;
|
||||||
|
x.arr[1] = v;
|
||||||
|
let c: lcinner = x.arr[1];
|
||||||
|
assert((c.a + c.b + c.c): i32 == 60i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn letcopy_nest_struct() void = {
|
||||||
|
let a: [2][2]lcinner;
|
||||||
|
let v: lcinner; v.a = 11u32; v.b = 22u32; v.c = 33u32;
|
||||||
|
a[1][0] = v;
|
||||||
|
let c: lcinner = a[1][0];
|
||||||
|
assert((c.a + c.b + c.c): i32 == 66i32);
|
||||||
|
};
|
||||||
914
test/lang/dotbase_addr_slice_test.ww
Normal file
914
test/lang/dotbase_addr_slice_test.ww
Normal file
@@ -0,0 +1,914 @@
|
|||||||
|
// dotbase_addr_slice_test — the array-field-base-address family: addr-of +
|
||||||
|
// slice of a struct's `[N]T` FIELD (#252), the CHAINED-base close-out (#253),
|
||||||
|
// the signed-narrow N_DOT-base index load (#255), the call-arg consumption
|
||||||
|
// axis (#257), the tagged-element store/read/return cluster (#259/#261/#263),
|
||||||
|
// the aggregate addressable-rhs let-init / arg / return copy axes
|
||||||
|
// (#265/#268/#271), the array return-by-value ABI (#267), nested-array stride
|
||||||
|
// + array-of-struct element store + array-literal element store (#270), and
|
||||||
|
// the aggregate def-global copy (#268). Migrated from
|
||||||
|
// test/wcc/949_dotbase_addr_slice_run.c.
|
||||||
|
//
|
||||||
|
// The shared root: taking `&x.o[i]` / slicing `x.o[lo:hi]` / indexing a
|
||||||
|
// chained `o.p.m[i]` of an `[N]T`-typed FIELD must compute the field's
|
||||||
|
// ADDRESS (LEAQ), not auto-deref its first 8 bytes AS a pointer (MOVL) —
|
||||||
|
// garbage base -> segfault. cg_dotbase_addr/dotbaseaddr (+ the dotchain spine
|
||||||
|
// for chained inners) close the whole family; every op (index r/w, addr-of,
|
||||||
|
// slice, compound, store, call-arg, copy) routes through the one helper.
|
||||||
|
// cs==ww broken IDENTICALLY pre-fix (gate-blind, pure correctness), so the
|
||||||
|
// .s is byte-identical post-fix and the T2 byteid gate is the rule-10 net;
|
||||||
|
// these behavioral @tests are the runtime net. PRIMITIVE-only asserts (read
|
||||||
|
// back the value through the &-derived pointer / slice; a wrong base or a
|
||||||
|
// dropped header/word yields a wrong readback) — no fmt/strconv anywhere.
|
||||||
|
//
|
||||||
|
// The chained VALUE-container arm (`o.i.m`, value nested struct) and the
|
||||||
|
// value-nested-struct let-init copy rows are byteid=0 (#254: bare-let
|
||||||
|
// zero-init extra MOVQ $0 + global DATAW over-emit) and live in the sibling
|
||||||
|
// dotbase_addr_slice_runonly_test.ww, excluded from T2 by the _runonly_
|
||||||
|
// suffix.
|
||||||
|
|
||||||
|
package dotbase_addr_slice_test;
|
||||||
|
|
||||||
|
// ---- shared element-array struct shapes (field `o`) --------------------
|
||||||
|
type eu8 = struct { o: [4]u8 };
|
||||||
|
type ei32 = struct { o: [4]i32 };
|
||||||
|
type ei16 = struct { o: [4]i16 };
|
||||||
|
type ei8 = struct { o: [4]i8 };
|
||||||
|
|
||||||
|
// ---- chained-base shapes (#253): inner field `m`, pointer-outer ----------
|
||||||
|
type cinner = struct { m: [4]u8 }; // also the ctrl `e` shape
|
||||||
|
type couter = struct { p: *cinner };
|
||||||
|
type cinneri = struct { m: [4]i32 };
|
||||||
|
type couteri = struct { p: *cinneri };
|
||||||
|
|
||||||
|
// ============================ #252 bare-ident ============================
|
||||||
|
@test fn addr_local_u8() void = {
|
||||||
|
let x: eu8;
|
||||||
|
x.o[1] = 66u8;
|
||||||
|
let p: *u8 = &x.o[1];
|
||||||
|
assert((*p): i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn rd_addr_ptr_u8(x: *eu8) u8 = { let p: *u8 = &x.o[2]; return *p; };
|
||||||
|
@test fn addr_ptr_u8() void = {
|
||||||
|
let x: eu8;
|
||||||
|
x.o[2] = 77u8;
|
||||||
|
assert(rd_addr_ptr_u8(&x): i32 == 77i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn addr_i32() void = {
|
||||||
|
let x: ei32;
|
||||||
|
x.o[2] = 88;
|
||||||
|
let p: *i32 = &x.o[2];
|
||||||
|
assert(*p == 88i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn slice_u8_expl() void = {
|
||||||
|
let x: eu8;
|
||||||
|
x.o[1] = 66u8;
|
||||||
|
let s: []u8 = x.o[1:4];
|
||||||
|
assert(len(s): i32 == 3i32);
|
||||||
|
assert(s[0]: i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn slice_u8_dflthi() void = {
|
||||||
|
let x: eu8;
|
||||||
|
x.o[1] = 66u8;
|
||||||
|
let s: []u8 = x.o[1:];
|
||||||
|
assert(len(s): i32 == 3i32);
|
||||||
|
assert(s[0]: i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn sl_slice_ptr_u8(x: *eu8) u8 = { let s: []u8 = x.o[1:4]; return s[0]; };
|
||||||
|
@test fn slice_ptr_u8() void = {
|
||||||
|
let x: eu8;
|
||||||
|
x.o[1] = 66u8;
|
||||||
|
assert(sl_slice_ptr_u8(&x): i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn slice_i32_expl() void = {
|
||||||
|
let x: ei32;
|
||||||
|
x.o[1] = 99;
|
||||||
|
x.o[2] = 88;
|
||||||
|
let s: []i32 = x.o[1:3];
|
||||||
|
assert(len(s): i32 == 2i32);
|
||||||
|
assert(s[1] == 88i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn slice_i32_dflt() void = {
|
||||||
|
let x: ei32;
|
||||||
|
x.o[3] = 55;
|
||||||
|
let s: []i32 = x.o[1:];
|
||||||
|
assert(len(s): i32 == 3i32);
|
||||||
|
assert(s[2] == 55i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn control_bare() void = {
|
||||||
|
let a: [4]u8;
|
||||||
|
a[2] = 44u8;
|
||||||
|
let p: *u8 = &a[1];
|
||||||
|
*p = 33u8;
|
||||||
|
let s: []u8 = a[1:4];
|
||||||
|
assert(s[0]: i32 == 33i32); // the &a[1] write landed
|
||||||
|
assert(s[1]: i32 == 44i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================ #253 chained-base ==========================
|
||||||
|
@test fn chain_ptr_rd() void = {
|
||||||
|
let a: cinner; a.m[1] = 66u8;
|
||||||
|
let o: couter; o.p = &a;
|
||||||
|
assert(o.p.m[1]: i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn chain_ptr_wr() void = {
|
||||||
|
let a: cinner;
|
||||||
|
let o: couter; o.p = &a;
|
||||||
|
o.p.m[2] = 77u8;
|
||||||
|
assert(a.m[2]: i32 == 77i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn chain_ptr_addr() void = {
|
||||||
|
let a: cinner; a.m[2] = 55u8;
|
||||||
|
let o: couter; o.p = &a;
|
||||||
|
let q: *u8 = &o.p.m[2];
|
||||||
|
assert((*q): i32 == 55i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn chain_ptr_sl_e() void = {
|
||||||
|
let a: cinner; a.m[1] = 66u8;
|
||||||
|
let o: couter; o.p = &a;
|
||||||
|
let s: []u8 = o.p.m[1:4];
|
||||||
|
assert(len(s): i32 == 3i32);
|
||||||
|
assert(s[0]: i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn chain_ptr_sl_d() void = {
|
||||||
|
let a: cinner; a.m[1] = 66u8;
|
||||||
|
let o: couter; o.p = &a;
|
||||||
|
let s: []u8 = o.p.m[1:];
|
||||||
|
assert(len(s): i32 == 3i32);
|
||||||
|
assert(s[0]: i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn chain_ptr_comp() void = {
|
||||||
|
let a: cinner; a.m[1] = 60u8;
|
||||||
|
let o: couter; o.p = &a;
|
||||||
|
o.p.m[1] += 6u8;
|
||||||
|
assert(o.p.m[1]: i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
type cmid = struct { b: *cinner };
|
||||||
|
type ctop = struct { a: cmid };
|
||||||
|
@test fn chain_deep_lf() void = {
|
||||||
|
let z: cinner; z.m[1] = 66u8;
|
||||||
|
let o: ctop; o.a.b = &z;
|
||||||
|
assert(o.a.b.m[1]: i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
type camid = struct { q: *cinner };
|
||||||
|
type cotop = struct { p: *camid };
|
||||||
|
@test fn chain_triple() void = {
|
||||||
|
let z: cinner; z.m[1] = 66u8;
|
||||||
|
let aa: camid; aa.q = &z;
|
||||||
|
let o: cotop; o.p = &aa;
|
||||||
|
assert(o.p.q.m[1]: i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn chain_tri_comp() void = {
|
||||||
|
let z: cinner; z.m[1] = 60u8;
|
||||||
|
let aa: camid; aa.q = &z;
|
||||||
|
let o: cotop; o.p = &aa;
|
||||||
|
o.p.q.m[1] += 6u8;
|
||||||
|
assert(o.p.q.m[1]: i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn chain_i32_addr() void = {
|
||||||
|
let a: cinneri; a.m[2] = 88;
|
||||||
|
let o: couteri; o.p = &a;
|
||||||
|
let q: *i32 = &o.p.m[2];
|
||||||
|
assert(*q == 88i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn chain_i32_slice() void = {
|
||||||
|
let a: cinneri; a.m[1] = 99; a.m[2] = 88;
|
||||||
|
let o: couteri; o.p = &a;
|
||||||
|
let s: []i32 = o.p.m[1:3];
|
||||||
|
assert(len(s): i32 == 2i32);
|
||||||
|
assert(s[1] == 88i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn rd_ctrl_ptr_rd(p: *cinner) u8 = { return p.m[1]; };
|
||||||
|
@test fn ctrl_ptr_rd() void = {
|
||||||
|
let x: cinner; x.m[1] = 66u8;
|
||||||
|
assert(rd_ctrl_ptr_rd(&x): i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn ctrl_local_rd() void = {
|
||||||
|
let x: cinner; x.m[1] = 66u8;
|
||||||
|
assert(x.m[1]: i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================ #255 signed-narrow =========================
|
||||||
|
@test fn nload_i32() void = {
|
||||||
|
let x: ei32;
|
||||||
|
x.o[2] = -5;
|
||||||
|
let v: i32 = x.o[2];
|
||||||
|
assert(v == -5i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn nload_i16() void = {
|
||||||
|
let x: ei16;
|
||||||
|
x.o[2] = -5i16;
|
||||||
|
let v: i16 = x.o[2];
|
||||||
|
assert(v: i32 == -5i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn nload_i8() void = {
|
||||||
|
let x: ei8;
|
||||||
|
x.o[2] = -5i8;
|
||||||
|
let v: i8 = x.o[2];
|
||||||
|
assert(v: i32 == -5i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================ #257 call-arg ==============================
|
||||||
|
fn rd_callarg_u8(b: []u8) i32 = { return b[0]: i32; };
|
||||||
|
@test fn callarg_u8() void = {
|
||||||
|
let x: eu8;
|
||||||
|
x.o[1] = 66u8;
|
||||||
|
assert(rd_callarg_u8(x.o[1:4]) == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn rd_callarg_i32(b: []i32) i32 = { return b[0]; };
|
||||||
|
@test fn callarg_i32() void = {
|
||||||
|
let x: ei32;
|
||||||
|
x.o[1] = 88;
|
||||||
|
assert(rd_callarg_i32(x.o[1:3]) == 88i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn rd_callarg_ptr_u8(b: []u8) i32 = { return b[0]: i32; };
|
||||||
|
fn f_callarg_ptr_u8(p: *eu8) i32 = { return rd_callarg_ptr_u8(p.o[1:4]); };
|
||||||
|
@test fn callarg_ptr_u8() void = {
|
||||||
|
let x: eu8;
|
||||||
|
x.o[1] = 66u8;
|
||||||
|
assert(f_callarg_ptr_u8(&x) == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn rd_callarg_chain(b: []u8) i32 = { return b[0]: i32; };
|
||||||
|
@test fn callarg_chain() void = {
|
||||||
|
let a: cinner; a.m[1] = 66u8;
|
||||||
|
let o: couter; o.p = &a;
|
||||||
|
assert(rd_callarg_chain(o.p.m[1:4]) == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn rd_callarg_ctrl_local(b: []u8) i32 = { return b[0]: i32; };
|
||||||
|
@test fn callarg_ctrl_local() void = {
|
||||||
|
let x: eu8;
|
||||||
|
x.o[1] = 66u8;
|
||||||
|
let sl: []u8 = x.o[1:4];
|
||||||
|
assert(rd_callarg_ctrl_local(sl) == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn rd_callarg_ctrl_arr(b: []u8) i32 = { return b[0]: i32; };
|
||||||
|
@test fn callarg_ctrl_arr() void = {
|
||||||
|
let a: [4]u8;
|
||||||
|
a[1] = 66u8;
|
||||||
|
assert(rd_callarg_ctrl_arr(a[1:4]) == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
type wsf = struct { v: []i32 };
|
||||||
|
fn rd_callarg_slicefield(s: []i32) i32 = { return s[0]; };
|
||||||
|
@test fn callarg_slicefield() void = {
|
||||||
|
let backing: [4]i32;
|
||||||
|
backing[1] = 88;
|
||||||
|
let q: wsf;
|
||||||
|
q.v = backing[0:4];
|
||||||
|
assert(rd_callarg_slicefield(q.v[1:3]) == 88i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
type wstr = struct { v: str };
|
||||||
|
fn rd_callarg_strfield(s: str) i32 = { return len(s): i32; };
|
||||||
|
@test fn callarg_strfield() void = {
|
||||||
|
let q: wstr;
|
||||||
|
q.v = "hello";
|
||||||
|
assert(rd_callarg_strfield(q.v[1:4]) == 3i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===================== #259/#261/#263 tagged cluster =====================
|
||||||
|
type etag = struct { o: [4](i32 | void) };
|
||||||
|
type etagnull = struct { o: [4](*i32 | void) };
|
||||||
|
type mtag2d = struct { g: [2][2](i32 | void) };
|
||||||
|
|
||||||
|
@test fn tagged_store_own() void = {
|
||||||
|
let x: etag;
|
||||||
|
x.o[1] = 66;
|
||||||
|
let v: (i32 | void) = x.o[1];
|
||||||
|
let r: i32 = match (v) {
|
||||||
|
case let n: i32 => yield n;
|
||||||
|
case void => yield 0: i32;
|
||||||
|
};
|
||||||
|
assert(r == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn wr_tagged_store_ptr(x: *etag) void = { x.o[2] = 77; };
|
||||||
|
@test fn tagged_store_ptr() void = {
|
||||||
|
let x: etag;
|
||||||
|
wr_tagged_store_ptr(&x);
|
||||||
|
let v: (i32 | void) = x.o[2];
|
||||||
|
let r: i32 = match (v) {
|
||||||
|
case let n: i32 => yield n;
|
||||||
|
case void => yield 0: i32;
|
||||||
|
};
|
||||||
|
assert(r == 77i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn tagged_store_own_rd() void = {
|
||||||
|
let x: etag;
|
||||||
|
x.o[1] = 66;
|
||||||
|
let v: (i32 | void) = x.o[1];
|
||||||
|
let r: i32 = match (v) {
|
||||||
|
case let n: i32 => yield n;
|
||||||
|
case void => yield 0: i32;
|
||||||
|
};
|
||||||
|
assert(r == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn wr_tagged_store_ptr_rd(x: *etag) void = { x.o[2] = 77; };
|
||||||
|
@test fn tagged_store_ptr_rd() void = {
|
||||||
|
let x: etag;
|
||||||
|
wr_tagged_store_ptr_rd(&x);
|
||||||
|
let v: (i32 | void) = x.o[2];
|
||||||
|
let r: i32 = match (v) {
|
||||||
|
case let n: i32 => yield n;
|
||||||
|
case void => yield 0: i32;
|
||||||
|
};
|
||||||
|
assert(r == 77i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn tagged_rd_void() void = {
|
||||||
|
let x: etag;
|
||||||
|
x.o[1] = void;
|
||||||
|
let v: (i32 | void) = x.o[1];
|
||||||
|
let r: i32 = match (v) {
|
||||||
|
case let n: i32 => yield 99: i32;
|
||||||
|
case void => yield 1: i32;
|
||||||
|
};
|
||||||
|
assert(r == 1i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn take_tagged_callarg_i32(v: (i32 | void)) i32 = {
|
||||||
|
return match (v) {
|
||||||
|
case let n: i32 => yield n;
|
||||||
|
case void => yield 1: i32;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@test fn tagged_callarg_i32() void = {
|
||||||
|
let x: etag;
|
||||||
|
x.o[2] = 55;
|
||||||
|
assert(take_tagged_callarg_i32(x.o[2]) == 55i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn take_tagged_callarg_void(v: (i32 | void)) i32 = {
|
||||||
|
return match (v) {
|
||||||
|
case let n: i32 => yield 99: i32;
|
||||||
|
case void => yield 1: i32;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@test fn tagged_callarg_void() void = {
|
||||||
|
let x: etag;
|
||||||
|
x.o[2] = void;
|
||||||
|
assert(take_tagged_callarg_void(x.o[2]) == 1i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn ret_tagged_return_i32(x: *etag) (i32 | void) = { return x.o[1]; };
|
||||||
|
@test fn tagged_return_i32() void = {
|
||||||
|
let x: etag;
|
||||||
|
x.o[1] = 88;
|
||||||
|
let v: (i32 | void) = ret_tagged_return_i32(&x);
|
||||||
|
let r: i32 = match (v) {
|
||||||
|
case let n: i32 => yield n;
|
||||||
|
case void => yield 1: i32;
|
||||||
|
};
|
||||||
|
assert(r == 88i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn ret_tagged_return_void(x: *etag) (i32 | void) = { return x.o[1]; };
|
||||||
|
@test fn tagged_return_void() void = {
|
||||||
|
let x: etag;
|
||||||
|
x.o[1] = void;
|
||||||
|
let v: (i32 | void) = ret_tagged_return_void(&x);
|
||||||
|
let r: i32 = match (v) {
|
||||||
|
case let n: i32 => yield 99: i32;
|
||||||
|
case void => yield 1: i32;
|
||||||
|
};
|
||||||
|
assert(r == 1i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn tagged_chained_i32() void = {
|
||||||
|
let y: mtag2d;
|
||||||
|
y.g[1][1] = 44;
|
||||||
|
let v: (i32 | void) = y.g[1][1];
|
||||||
|
let r: i32 = match (v) {
|
||||||
|
case let n: i32 => yield n;
|
||||||
|
case void => yield 1: i32;
|
||||||
|
};
|
||||||
|
assert(r == 44i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn tagged_chained_void() void = {
|
||||||
|
let y: mtag2d;
|
||||||
|
y.g[1][1] = void;
|
||||||
|
let v: (i32 | void) = y.g[1][1];
|
||||||
|
let r: i32 = match (v) {
|
||||||
|
case let n: i32 => yield 99: i32;
|
||||||
|
case void => yield 1: i32;
|
||||||
|
};
|
||||||
|
assert(r == 1i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn tagged_ctrl_bare_rd() void = {
|
||||||
|
let a: [4](i32 | void);
|
||||||
|
a[1] = 33;
|
||||||
|
let v: (i32 | void) = a[1];
|
||||||
|
let r: i32 = match (v) {
|
||||||
|
case let n: i32 => yield n;
|
||||||
|
case void => yield 1: i32;
|
||||||
|
};
|
||||||
|
assert(r == 33i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn tagged_null_ptr_rd() void = {
|
||||||
|
let k: i32 = 7;
|
||||||
|
let x: etagnull;
|
||||||
|
x.o[1] = &k;
|
||||||
|
let v: (*i32 | void) = x.o[1];
|
||||||
|
let r: i32 = match (v) {
|
||||||
|
case let p: *i32 => yield 55: i32;
|
||||||
|
case void => yield 1: i32;
|
||||||
|
};
|
||||||
|
assert(r == 55i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn tagged_null_void_rd() void = {
|
||||||
|
let x: etagnull;
|
||||||
|
x.o[1] = void;
|
||||||
|
let v: (*i32 | void) = x.o[1];
|
||||||
|
let r: i32 = match (v) {
|
||||||
|
case let p: *i32 => yield 99: i32;
|
||||||
|
case void => yield 1: i32;
|
||||||
|
};
|
||||||
|
assert(r == 1i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn g_tagged_ident_ret_i32() (i32 | void) = { let v: (i32 | void) = 7i32; return v; };
|
||||||
|
@test fn tagged_ident_ret_i32() void = {
|
||||||
|
let r: i32 = match (g_tagged_ident_ret_i32()) {
|
||||||
|
case let n: i32 => yield n;
|
||||||
|
case void => yield 1: i32;
|
||||||
|
};
|
||||||
|
assert(r == 7i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn g_tagged_ident_ret_void() (i32 | void) = { let v: (i32 | void) = void; return v; };
|
||||||
|
@test fn tagged_ident_ret_void() void = {
|
||||||
|
let r: i32 = match (g_tagged_ident_ret_void()) {
|
||||||
|
case let n: i32 => yield 99: i32;
|
||||||
|
case void => yield 1: i32;
|
||||||
|
};
|
||||||
|
assert(r == 1i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn inner_tagged_call_ret_ctrl() (i32 | void) = { let v: (i32 | void) = 42i32; return v; };
|
||||||
|
fn outer_tagged_call_ret_ctrl() (i32 | void) = { return inner_tagged_call_ret_ctrl(); };
|
||||||
|
@test fn tagged_call_ret_ctrl() void = {
|
||||||
|
let r: i32 = match (outer_tagged_call_ret_ctrl()) {
|
||||||
|
case let n: i32 => yield n;
|
||||||
|
case void => yield 1: i32;
|
||||||
|
};
|
||||||
|
assert(r == 42i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
type wtagfield = struct { f: (i32 | void) };
|
||||||
|
fn dot_tagged_dot_ret_ctrl(x: *wtagfield) (i32 | void) = { return x.f; };
|
||||||
|
@test fn tagged_dot_ret_ctrl() void = {
|
||||||
|
let x: wtagfield;
|
||||||
|
x.f = 63;
|
||||||
|
let r: i32 = match (dot_tagged_dot_ret_ctrl(&x)) {
|
||||||
|
case let n: i32 => yield n;
|
||||||
|
case void => yield 1: i32;
|
||||||
|
};
|
||||||
|
assert(r == 63i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===================== #265 aggregate deref-rhs let-init =================
|
||||||
|
type t16 = struct { h: [4]u32 };
|
||||||
|
type t32 = struct { h: [8]u32 };
|
||||||
|
|
||||||
|
@test fn deref_struct16() void = {
|
||||||
|
let s: t16;
|
||||||
|
s.h[0]=10u32; s.h[1]=20u32; s.h[2]=30u32; s.h[3]=40u32;
|
||||||
|
let c: t16 = *(&s);
|
||||||
|
assert((c.h[0]+c.h[1]+c.h[2]+c.h[3]): i32 == 100i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn deref_struct32() void = {
|
||||||
|
let s: t32;
|
||||||
|
s.h[0]=1u32; s.h[1]=2u32; s.h[2]=3u32; s.h[3]=4u32;
|
||||||
|
s.h[4]=5u32; s.h[5]=6u32; s.h[6]=7u32; s.h[7]=8u32;
|
||||||
|
let c: t32 = *(&s);
|
||||||
|
assert((c.h[0]+c.h[1]+c.h[2]+c.h[3]
|
||||||
|
+c.h[4]+c.h[5]+c.h[6]+c.h[7]): i32 == 36i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn deref_ptr32() void = {
|
||||||
|
let s: t32;
|
||||||
|
s.h[0]=1u32; s.h[1]=2u32; s.h[2]=3u32; s.h[3]=4u32;
|
||||||
|
s.h[4]=5u32; s.h[5]=6u32; s.h[6]=7u32; s.h[7]=8u32;
|
||||||
|
let p: *t32 = &s;
|
||||||
|
let c: t32 = *p;
|
||||||
|
assert((c.h[0]+c.h[1]+c.h[2]+c.h[3]
|
||||||
|
+c.h[4]+c.h[5]+c.h[6]+c.h[7]): i32 == 36i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn deref_array16() void = {
|
||||||
|
let s: [4]u32;
|
||||||
|
s[0]=5u32; s[1]=6u32; s[2]=7u32; s[3]=8u32;
|
||||||
|
let c: [4]u32 = *(&s);
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]): i32 == 26i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn deref_tail12() void = {
|
||||||
|
let s: [3]u32;
|
||||||
|
s[0]=7u32; s[1]=8u32; s[2]=9u32;
|
||||||
|
let c: [3]u32 = *(&s);
|
||||||
|
assert((c[0]+c[1]+c[2]): i32 == 24i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn deref_tail11() void = {
|
||||||
|
let s: [11]u8;
|
||||||
|
s[0]=1u8; s[1]=2u8; s[2]=3u8; s[3]=4u8; s[4]=5u8;
|
||||||
|
s[5]=6u8; s[6]=7u8; s[7]=8u8; s[8]=9u8; s[9]=10u8;
|
||||||
|
s[10]=11u8;
|
||||||
|
let c: [11]u8 = *(&s);
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]+c[4]+c[5]
|
||||||
|
+c[6]+c[7]+c[8]+c[9]+c[10]): i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===================== #268 addressable-rhs let-init copy ================
|
||||||
|
@test fn ai_array16() void = {
|
||||||
|
let s: [4]u32;
|
||||||
|
s[0]=11u32; s[1]=22u32; s[2]=33u32; s[3]=44u32;
|
||||||
|
let c: [4]u32 = s;
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]): i32 == 110i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn ai_array32() void = {
|
||||||
|
let s: [8]u32;
|
||||||
|
s[0]=1u32; s[1]=2u32; s[2]=3u32; s[3]=4u32;
|
||||||
|
s[4]=5u32; s[5]=6u32; s[6]=7u32; s[7]=8u32;
|
||||||
|
let c: [8]u32 = s;
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]+c[4]+c[5]+c[6]+c[7]): i32 == 36i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn ai_tail12() void = {
|
||||||
|
let s: [3]u32;
|
||||||
|
s[0]=7u32; s[1]=8u32; s[2]=9u32;
|
||||||
|
let c: [3]u32 = s;
|
||||||
|
assert((c[0]+c[1]+c[2]): i32 == 24i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn ai_tail11() void = {
|
||||||
|
let s: [11]u8;
|
||||||
|
s[0]=1u8; s[1]=2u8; s[2]=3u8; s[3]=4u8; s[4]=5u8;
|
||||||
|
s[5]=6u8; s[6]=7u8; s[7]=8u8; s[8]=9u8; s[9]=10u8;
|
||||||
|
s[10]=11u8;
|
||||||
|
let c: [11]u8 = s;
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]+c[4]+c[5]
|
||||||
|
+c[6]+c[7]+c[8]+c[9]+c[10]): i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
type dinner16 = struct { m: [4]u32 };
|
||||||
|
type douter16 = struct { i: dinner16 };
|
||||||
|
@test fn dot_struct16() void = {
|
||||||
|
let o: douter16;
|
||||||
|
o.i.m[0]=10u32; o.i.m[1]=20u32; o.i.m[2]=30u32; o.i.m[3]=40u32;
|
||||||
|
let c: dinner16 = o.i;
|
||||||
|
assert((c.m[0]+c.m[1]+c.m[2]+c.m[3]): i32 == 100i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
type douter32 = struct { o: [8]u32 };
|
||||||
|
@test fn dot_arr32() void = {
|
||||||
|
let x: douter32;
|
||||||
|
x.o[0]=1u32; x.o[1]=2u32; x.o[2]=3u32; x.o[3]=4u32;
|
||||||
|
x.o[4]=5u32; x.o[5]=6u32; x.o[6]=7u32; x.o[7]=8u32;
|
||||||
|
let c: [8]u32 = x.o;
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]+c[4]+c[5]+c[6]+c[7]): i32 == 36i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
type dinner11 = struct { m: [11]u8 };
|
||||||
|
type douter11 = struct { i: dinner11 };
|
||||||
|
@test fn dot_tail11() void = {
|
||||||
|
let o: douter11;
|
||||||
|
o.i.m[0]=1u8; o.i.m[1]=2u8; o.i.m[2]=3u8; o.i.m[3]=4u8;
|
||||||
|
o.i.m[4]=5u8; o.i.m[5]=6u8; o.i.m[6]=7u8; o.i.m[7]=8u8;
|
||||||
|
o.i.m[8]=9u8; o.i.m[9]=10u8; o.i.m[10]=11u8;
|
||||||
|
let c: dinner11 = o.i;
|
||||||
|
assert((c.m[0]+c.m[1]+c.m[2]+c.m[3]+c.m[4]+c.m[5]
|
||||||
|
+c.m[6]+c.m[7]+c.m[8]+c.m[9]+c.m[10]): i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn idx_struct16() void = {
|
||||||
|
let a: [2]dinner16;
|
||||||
|
let p: *dinner16 = &a[1];
|
||||||
|
p.m[0]=10u32; p.m[1]=20u32; p.m[2]=30u32; p.m[3]=40u32;
|
||||||
|
let c: dinner16 = a[1];
|
||||||
|
assert((c.m[0]+c.m[1]+c.m[2]+c.m[3]): i32 == 100i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
type dinner32 = struct { m: [8]u32 };
|
||||||
|
@test fn idx_struct32() void = {
|
||||||
|
let a: [2]dinner32;
|
||||||
|
let p: *dinner32 = &a[1];
|
||||||
|
p.m[0]=1u32; p.m[1]=2u32; p.m[2]=3u32; p.m[3]=4u32;
|
||||||
|
p.m[4]=5u32; p.m[5]=6u32; p.m[6]=7u32; p.m[7]=8u32;
|
||||||
|
let c: dinner32 = a[1];
|
||||||
|
assert((c.m[0]+c.m[1]+c.m[2]+c.m[3]
|
||||||
|
+c.m[4]+c.m[5]+c.m[6]+c.m[7]): i32 == 36i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
def Gad: [4]u32 = [11u32, 22u32, 33u32, 44u32];
|
||||||
|
@test fn arraydef_global() void = {
|
||||||
|
let c: [4]u32 = Gad;
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]): i32 == 110i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
type gT = struct { a: u32, b: u32, c: u32, d: u32 };
|
||||||
|
def Gsd: gT = gT { a = 10u32, b = 20u32, c = 30u32, d = 40u32 };
|
||||||
|
@test fn structdef_global() void = {
|
||||||
|
let c: gT = Gsd;
|
||||||
|
assert((c.a+c.b+c.c+c.d): i32 == 100i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===================== #267 array return-by-value ABI ====================
|
||||||
|
fn mk_ret_arr_u32_8() [2]u32 = { let a: [2]u32; a[0]=3u32; a[1]=4u32; return a; };
|
||||||
|
@test fn ret_arr_u32_8() void = {
|
||||||
|
let c = mk_ret_arr_u32_8();
|
||||||
|
assert((c[0]+c[1]): i32 == 7i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn mk_ret_arr_u32_16() [4]u32 = { let a: [4]u32; a[0]=1u32;a[1]=2u32;a[2]=3u32;a[3]=4u32; return a; };
|
||||||
|
@test fn ret_arr_u32_16() void = {
|
||||||
|
let c = mk_ret_arr_u32_16();
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]): i32 == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn mk_ret_arr_u32_24() [6]u32 = { let a: [6]u32; a[0]=1u32;a[1]=2u32;a[2]=3u32;a[3]=4u32;a[4]=5u32;a[5]=6u32; return a; };
|
||||||
|
@test fn ret_arr_u32_24() void = {
|
||||||
|
let c = mk_ret_arr_u32_24();
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]+c[4]+c[5]): i32 == 21i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn mk_ret_arr_u32_32_sret() [8]u32 = { let a: [8]u32; a[0]=1u32;a[1]=2u32;a[2]=3u32;a[3]=4u32;a[4]=5u32;a[5]=6u32;a[6]=7u32;a[7]=8u32; return a; };
|
||||||
|
@test fn ret_arr_u32_32_sret() void = {
|
||||||
|
let c = mk_ret_arr_u32_32_sret();
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]+c[4]+c[5]+c[6]+c[7]): i32 == 36i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn mk_ret_arr_u8_4() [4]u8 = { let a: [4]u8; a[0]=10u8;a[1]=20u8;a[2]=30u8;a[3]=40u8; return a; };
|
||||||
|
@test fn ret_arr_u8_4() void = {
|
||||||
|
let c = mk_ret_arr_u8_4();
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]): i32 == 100i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn mk_ret_arr_u8_32_sret() [32]u8 = { let a: [32]u8; a[0]=50u8;a[15]=30u8;a[31]=40u8; return a; };
|
||||||
|
@test fn ret_arr_u8_32_sret() void = {
|
||||||
|
let c = mk_ret_arr_u8_32_sret();
|
||||||
|
assert((c[0]+c[15]+c[31]): i32 == 120i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn mk_ret_arr_assign_16() [4]u32 = { let a: [4]u32; a[0]=1u32;a[1]=2u32;a[2]=3u32;a[3]=4u32; return a; };
|
||||||
|
@test fn ret_arr_assign_16() void = {
|
||||||
|
let c: [4]u32; c = mk_ret_arr_assign_16();
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]): i32 == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn mk_ret_arr_assign_32_sret() [8]u32 = { let a: [8]u32; a[0]=1u32;a[7]=8u32; return a; };
|
||||||
|
@test fn ret_arr_assign_32_sret() void = {
|
||||||
|
let c: [8]u32; c = mk_ret_arr_assign_32_sret();
|
||||||
|
assert((c[0]+c[7]): i32 == 9i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn mk_ret_arr_fwd_16() [4]u32 = { let a: [4]u32; a[0]=1u32;a[1]=2u32;a[2]=3u32;a[3]=4u32; return a; };
|
||||||
|
fn fwd_ret_arr_fwd_16() [4]u32 = { return mk_ret_arr_fwd_16(); };
|
||||||
|
@test fn ret_arr_fwd_16() void = {
|
||||||
|
let c = fwd_ret_arr_fwd_16();
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]): i32 == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn mk_ret_arr_fwd_32_sret() [8]u32 = { let a: [8]u32; a[0]=1u32;a[7]=8u32; return a; };
|
||||||
|
fn fwd_ret_arr_fwd_32_sret() [8]u32 = { return mk_ret_arr_fwd_32_sret(); };
|
||||||
|
@test fn ret_arr_fwd_32_sret() void = {
|
||||||
|
let c = fwd_ret_arr_fwd_32_sret();
|
||||||
|
assert((c[0]+c[7]): i32 == 9i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
type sret3 = struct { a: u32, b: u32, c: u32 };
|
||||||
|
fn mk_ctrl_struct_ret() sret3 = { let s: sret3; s.a=1u32;s.b=2u32;s.c=3u32; return s; };
|
||||||
|
@test fn ctrl_struct_ret() void = {
|
||||||
|
let v = mk_ctrl_struct_ret();
|
||||||
|
assert((v.a+v.b+v.c): i32 == 6i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===================== #270-2 nested-array outer stride ==================
|
||||||
|
@test fn nest2d_u32() void = {
|
||||||
|
let a: [2][3]u32;
|
||||||
|
a[0][1] = 11u32;
|
||||||
|
a[1][1] = 22u32;
|
||||||
|
a[1][2] = 33u32;
|
||||||
|
assert((a[0][1] + a[1][1] + a[1][2]): i32 == 66i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn nest2d_u8() void = {
|
||||||
|
let a: [2][3]u8;
|
||||||
|
a[0][2] = 10u8;
|
||||||
|
a[1][0] = 20u8;
|
||||||
|
a[1][2] = 30u8;
|
||||||
|
assert((a[0][2] + a[1][0] + a[1][2]): i32 == 60i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn nest2d_i32() void = {
|
||||||
|
let a: [2][3]i32;
|
||||||
|
a[0][1] = 40;
|
||||||
|
a[1][1] = 88;
|
||||||
|
assert((a[1][1] - a[0][1]): i32 == 48i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===================== #270-1 element store axes =========================
|
||||||
|
type efinner = struct { m: [4]u32 };
|
||||||
|
@test fn elemfield_store() void = {
|
||||||
|
let a: [3]efinner;
|
||||||
|
a[0].m[1] = 5u32;
|
||||||
|
a[2].m[3] = 7u32;
|
||||||
|
a[2].m[0] = 9u32;
|
||||||
|
assert((a[0].m[1] + a[2].m[3] + a[2].m[0]): i32 == 21i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn elem_struct_store() void = {
|
||||||
|
let arr: [3]gT;
|
||||||
|
let v: gT; v.a=10u32; v.b=20u32; v.c=30u32; v.d=40u32;
|
||||||
|
arr[2] = v;
|
||||||
|
assert((arr[2].a + arr[2].b + arr[2].c + arr[2].d): i32 == 100i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn elem_arr_store() void = {
|
||||||
|
let arr: [2][4]u32;
|
||||||
|
let s: [4]u32; s[0]=1u32; s[1]=2u32; s[2]=3u32; s[3]=4u32;
|
||||||
|
arr[1] = s;
|
||||||
|
assert((arr[1][0]+arr[1][1]+arr[1][2]+arr[1][3]): i32 == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===================== #270-3a aggregate index-base copy =================
|
||||||
|
type boxprim = struct { arr: [2][4]u32 };
|
||||||
|
@test fn letcopy_dot_prim() void = {
|
||||||
|
let s: [4]u32; s[0]=1u32; s[1]=2u32; s[2]=3u32; s[3]=4u32;
|
||||||
|
let x: boxprim;
|
||||||
|
x.arr[1] = s;
|
||||||
|
let c: [4]u32 = x.arr[1];
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]): i32 == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn letcopy_nest_prim() void = {
|
||||||
|
let a: [2][2][4]u32;
|
||||||
|
let s: [4]u32; s[0]=2u32; s[1]=4u32; s[2]=6u32; s[3]=8u32;
|
||||||
|
a[1][0] = s;
|
||||||
|
let c: [4]u32 = a[1][0];
|
||||||
|
assert((c[0]+c[1]+c[2]+c[3]): i32 == 20i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn letcopy_subarr() void = {
|
||||||
|
let a: [2][3]u32;
|
||||||
|
a[1][0] = 5u32; a[1][1] = 6u32; a[1][2] = 7u32;
|
||||||
|
let c: [3]u32 = a[1];
|
||||||
|
assert((c[0] + c[1] + c[2]): i32 == 18i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===================== #270-1c array-literal element store ===============
|
||||||
|
type inner2 = struct { a: u32, b: u32 };
|
||||||
|
@test fn arrlit_structlit() void = {
|
||||||
|
let x: [2]inner2 = [inner2{a=1u32,b=2u32}, inner2{a=3u32,b=4u32}];
|
||||||
|
assert((x[0].a + x[0].b + x[1].a + x[1].b): i32 == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn arrlit_structident() void = {
|
||||||
|
let p: inner2; p.a = 7u32; p.b = 8u32;
|
||||||
|
let q: inner2; q.a = 1u32; q.b = 2u32;
|
||||||
|
let x: [2]inner2 = [p, q];
|
||||||
|
assert((x[0].a + x[0].b + x[1].a + x[1].b): i32 == 18i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===================== #271 aggregate ARG from any source ================
|
||||||
|
type argt16 = struct { x: i64, y: i64 };
|
||||||
|
type argo16 = struct { f: argt16 };
|
||||||
|
|
||||||
|
fn mk_arg_struct16_call() argt16 = { let a: argt16; a.x=3i64; a.y=7i64; return a; };
|
||||||
|
fn sum_arg_struct16_call(b: argt16) i64 = { return b.x + b.y; };
|
||||||
|
@test fn arg_struct16_call() void = {
|
||||||
|
assert(sum_arg_struct16_call(mk_arg_struct16_call()): i32 == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn sum_arg_struct16_dot(b: argt16) i64 = { return b.x + b.y; };
|
||||||
|
@test fn arg_struct16_dot() void = {
|
||||||
|
let q: argo16; q.f.x=3i64; q.f.y=7i64;
|
||||||
|
assert(sum_arg_struct16_dot(q.f): i32 == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn sum_arg_struct16_idx(b: argt16) i64 = { return b.x + b.y; };
|
||||||
|
@test fn arg_struct16_idx() void = {
|
||||||
|
let a: [2]argt16; a[1].x=3i64; a[1].y=7i64;
|
||||||
|
assert(sum_arg_struct16_idx(a[1]): i32 == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn sum_arg_struct16_deref(b: argt16) i64 = { return b.x + b.y; };
|
||||||
|
@test fn arg_struct16_deref() void = {
|
||||||
|
let v: argt16; v.x=3i64; v.y=7i64; let p: *argt16 = &v;
|
||||||
|
assert(sum_arg_struct16_deref(*p): i32 == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn sum_arg_struct16_ident(b: argt16) i64 = { return b.x + b.y; };
|
||||||
|
@test fn arg_struct16_ident() void = {
|
||||||
|
let v: argt16; v.x=3i64; v.y=7i64;
|
||||||
|
assert(sum_arg_struct16_ident(v): i32 == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn mk_arg_arr16_call() [4]u32 = { let a: [4]u32; a[0]=1u32;a[1]=2u32;a[2]=3u32;a[3]=4u32; return a; };
|
||||||
|
fn sum_arg_arr16_call(b: [4]u32) i32 = { return (b[0]+b[1]+b[2]+b[3]): i32; };
|
||||||
|
@test fn arg_arr16_call() void = {
|
||||||
|
assert(sum_arg_arr16_call(mk_arg_arr16_call()) == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
type argof = struct { f: [4]u32 };
|
||||||
|
fn sum_arg_arr16_dot(b: [4]u32) i32 = { return (b[0]+b[1]+b[2]+b[3]): i32; };
|
||||||
|
@test fn arg_arr16_dot() void = {
|
||||||
|
let q: argof; q.f[0]=1u32; q.f[1]=2u32; q.f[2]=3u32; q.f[3]=4u32;
|
||||||
|
assert(sum_arg_arr16_dot(q.f) == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn sum_arg_arr16_idx(b: [4]u32) i32 = { return (b[0]+b[1]+b[2]+b[3]): i32; };
|
||||||
|
@test fn arg_arr16_idx() void = {
|
||||||
|
let a: [2][4]u32;
|
||||||
|
a[1][0]=1u32; a[1][1]=2u32; a[1][2]=3u32; a[1][3]=4u32;
|
||||||
|
assert(sum_arg_arr16_idx(a[1]) == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn sum_arg_arr16_deref(b: [4]u32) i32 = { return (b[0]+b[1]+b[2]+b[3]): i32; };
|
||||||
|
@test fn arg_arr16_deref() void = {
|
||||||
|
let v: [4]u32; v[0]=1u32; v[1]=2u32; v[2]=3u32; v[3]=4u32;
|
||||||
|
let p: *[4]u32 = &v;
|
||||||
|
assert(sum_arg_arr16_deref(*p) == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn sum_arg_arr16_ident(b: [4]u32) i32 = { return (b[0]+b[1]+b[2]+b[3]): i32; };
|
||||||
|
@test fn arg_arr16_ident() void = {
|
||||||
|
let v: [4]u32; v[0]=1u32; v[1]=2u32; v[2]=3u32; v[3]=4u32;
|
||||||
|
assert(sum_arg_arr16_ident(v) == 10i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
type argo32 = struct { f: t32 };
|
||||||
|
|
||||||
|
fn mk_arg_struct32_call() t32 = { let a: t32; a.h[0]=1u32;a.h[1]=2u32;a.h[2]=3u32;a.h[3]=4u32;a.h[4]=5u32;a.h[5]=6u32;a.h[6]=7u32;a.h[7]=8u32; return a; };
|
||||||
|
fn sum_arg_struct32_call(b: t32) i32 = { return (b.h[0]+b.h[1]+b.h[2]+b.h[3]+b.h[4]+b.h[5]+b.h[6]+b.h[7]): i32; };
|
||||||
|
@test fn arg_struct32_call() void = {
|
||||||
|
assert(sum_arg_struct32_call(mk_arg_struct32_call()) == 36i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn sum_arg_struct32_dot(b: t32) i32 = { return (b.h[0]+b.h[1]+b.h[2]+b.h[3]+b.h[4]+b.h[5]+b.h[6]+b.h[7]): i32; };
|
||||||
|
@test fn arg_struct32_dot() void = {
|
||||||
|
let q: argo32;
|
||||||
|
q.f.h[0]=1u32;q.f.h[1]=2u32;q.f.h[2]=3u32;q.f.h[3]=4u32;
|
||||||
|
q.f.h[4]=5u32;q.f.h[5]=6u32;q.f.h[6]=7u32;q.f.h[7]=8u32;
|
||||||
|
assert(sum_arg_struct32_dot(q.f) == 36i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn sum_arg_struct32_idx(b: t32) i32 = { return (b.h[0]+b.h[1]+b.h[2]+b.h[3]+b.h[4]+b.h[5]+b.h[6]+b.h[7]): i32; };
|
||||||
|
@test fn arg_struct32_idx() void = {
|
||||||
|
let a: [2]t32;
|
||||||
|
let p: *t32 = &a[1];
|
||||||
|
p.h[0]=1u32;p.h[1]=2u32;p.h[2]=3u32;p.h[3]=4u32;
|
||||||
|
p.h[4]=5u32;p.h[5]=6u32;p.h[6]=7u32;p.h[7]=8u32;
|
||||||
|
assert(sum_arg_struct32_idx(a[1]) == 36i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn sum_arg_struct32_deref(b: t32) i32 = { return (b.h[0]+b.h[1]+b.h[2]+b.h[3]+b.h[4]+b.h[5]+b.h[6]+b.h[7]): i32; };
|
||||||
|
@test fn arg_struct32_deref() void = {
|
||||||
|
let v: t32;
|
||||||
|
v.h[0]=1u32;v.h[1]=2u32;v.h[2]=3u32;v.h[3]=4u32;
|
||||||
|
v.h[4]=5u32;v.h[5]=6u32;v.h[6]=7u32;v.h[7]=8u32;
|
||||||
|
let p: *t32 = &v;
|
||||||
|
assert(sum_arg_struct32_deref(*p) == 36i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn sum_arg_struct32_ident(b: t32) i32 = { return (b.h[0]+b.h[1]+b.h[2]+b.h[3]+b.h[4]+b.h[5]+b.h[6]+b.h[7]): i32; };
|
||||||
|
@test fn arg_struct32_ident() void = {
|
||||||
|
let v: t32;
|
||||||
|
v.h[0]=1u32;v.h[1]=2u32;v.h[2]=3u32;v.h[3]=4u32;
|
||||||
|
v.h[4]=5u32;v.h[5]=6u32;v.h[6]=7u32;v.h[7]=8u32;
|
||||||
|
assert(sum_arg_struct32_ident(v) == 36i32);
|
||||||
|
};
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user