test: migrate Fam4 static-init/DATA-emit value tests to @test (#30)
Continues the test-arch tower past Fam8-13. 11 module-level static-init / DATA-emit value drivers move from test/wcc/*_run.c into @test row- tables under test/lang/; every classification empirically re-probed at HEAD (refuting two stale worklist tags). - value rows -> test/lang/*_test.ww (11 files) - reject rows -> runww //ww:error carriers (3, dual-stage non-vacuous; 947 const-divzero confirmed a both-stage compile-reject, not run-exit) - 840_zeroinit, 944_array_zeroinit, 989_arrlit_tail_zero kept as byte-id .c pins (zero-over-dirtied-frame / DATAW-length is byte-id-blind to a runtime @test; #263), mutation-gated - repoint two stale comment refs to deleted test names (719, 989_structlocal_frame) Migrated static-init @test ride the cs==ww T2 byte-id gate, preserving DATA-emit byte-id. 2D global-struct array-field read (#137/#150) confirmed cs==ww + correct at HEAD. Coverage parity verified row-by-row; two-round reviewed. Floor ratchet follows.
This commit is contained in:
41
test/lang/arr_u16_store_test.ww
Normal file
41
test/lang/arr_u16_store_test.ww
Normal file
@@ -0,0 +1,41 @@
|
||||
// arr_u16_store_test — [N]u16/[N]i16 array-literal init stores MOVW per slot.
|
||||
// Migrated from test/wcc/914_arr_u16_store_run.c. Pre-fix a [4]u16 init emitted
|
||||
// overlapping MOVQ stores (accident-corrected for some values); the fix dispatches
|
||||
// a proper MOVW per 2-byte slot (op chosen by esz, not signedness). cstage
|
||||
// build+run was T1; cs==ww .s byte-id rides T2 (test-lang-byteid). The full_init
|
||||
// row asserts each element to catch any value drift; the [4]u8 control pins the
|
||||
// MOVB path is unchanged; i16_signed pins the dispatch is not signedness-gated.
|
||||
|
||||
package arr_u16_store_test;
|
||||
|
||||
@test fn u16_full_init() void = {
|
||||
let a: [4]u16 = [0xABCDu16, 0xBEEFu16, 0xC0DEu16, 0xDEADu16];
|
||||
assert(a[0] == 0xABCDu16);
|
||||
assert(a[1] == 0xBEEFu16);
|
||||
assert(a[2] == 0xC0DEu16);
|
||||
assert(a[3] == 0xDEADu16);
|
||||
};
|
||||
|
||||
@test fn u16_small_values() void = {
|
||||
let a: [4]u16 = [10u16, 20u16, 30u16, 40u16];
|
||||
let s: i32 = 0;
|
||||
s += a[0]: i32; s += a[1]: i32;
|
||||
s += a[2]: i32; s += a[3]: i32;
|
||||
assert(s == 100);
|
||||
};
|
||||
|
||||
@test fn u8_control() void = {
|
||||
let a: [4]u8 = [10u8, 20u8, 30u8, 40u8];
|
||||
let s: i32 = 0;
|
||||
s += a[0]: i32; s += a[1]: i32;
|
||||
s += a[2]: i32; s += a[3]: i32;
|
||||
assert(s == 100);
|
||||
};
|
||||
|
||||
@test fn i16_signed() void = {
|
||||
let a: [4]i16 = [10i16, 20i16, 30i16, -5i16];
|
||||
let s: i32 = 0;
|
||||
s += a[0]: i32; s += a[1]: i32;
|
||||
s += a[2]: i32; s += a[3]: i32;
|
||||
assert(s == 55);
|
||||
};
|
||||
99
test/lang/array_static_init_test.ww
Normal file
99
test/lang/array_static_init_test.ww
Normal file
@@ -0,0 +1,99 @@
|
||||
// array_static_init_test — module-level 1D/2D/3D array static-init, element
|
||||
// read. Migrated from test/wcc/919_array_static_init_run.c (#129 Phase A.3,
|
||||
// #156). emit_array_lit_bytes recurses on a TY_ARRAY element (esz=etype->size,
|
||||
// rule 13); cgindex leaves the sub-array ADDRESS for an array element so the
|
||||
// outer index dereferences the right cell (#135 sister). cstage build+run was
|
||||
// T1; cs==ww .s byte-id rides T2 (test-lang-byteid). The nested-array `...`
|
||||
// repeat reject is the runww carrier test/wcc/data/arr_nested_ellipsis_reject.
|
||||
//
|
||||
// Float-element rows assert bit-exact incl negative elements (drew: exercise the
|
||||
// sign-XOR byte-loop per element). The struct-with-array-field rows read the
|
||||
// array-field elements directly (D1.buf[k], D2.m[i][j]): the old #137/#150 cs≠ww
|
||||
// global-struct-field-base bug is CLOSED at HEAD, so the read is now cs==ww IDENT
|
||||
// — the original deferred this to byte-id only because the bug was then open.
|
||||
|
||||
package array_static_init_test;
|
||||
|
||||
let A_U8: [4]u8 = [1u8, 2u8, 3u8, 4u8];
|
||||
let A_U32: [4]u32 = [1u32, 2u32, 3u32, 4u32];
|
||||
let A_U64: [2]u64 = [1u64, 2u64];
|
||||
let A_INEG: [4]i32 = [-1, -2, -3, -4];
|
||||
let A_F64: [4]f64 = [1.5, -2.5, 3.5, -4.5];
|
||||
let A_F32: [4]f32 = [1.5f32, -2.5f32, 3.5f32, -4.5f32];
|
||||
def DA_U32: [4]u32 = [11u32, 22u32, 33u32, 44u32];
|
||||
def DA_F64: [4]f64 = [1.5, 2.5, 3.5, 4.5];
|
||||
let A_UZ: [4]u8 = [0u8, 0u8, 0u8, 0u8];
|
||||
let A_U1: [1]u8 = [7u8];
|
||||
let A2D: [3][2]u64 = [[1u64,2u64],[3u64,4u64],[5u64,6u64]];
|
||||
def DA2D: [3][2]u64 = [[1u64,2u64],[3u64,4u64],[5u64,6u64]];
|
||||
let A2V: [3][2]u64 = [[10u64,11u64],[20u64,21u64],[30u64,31u64]];
|
||||
let A28: [2][1]u32 = [[7u32],[9u32]];
|
||||
let A2W: [2][2]u64 = [[1u64,2u64],[3u64,4u64]];
|
||||
let A3D: [2][2][2]u8 = [[[1u8,2u8],[3u8,4u8]],[[5u8,6u8],[7u8,8u8]]];
|
||||
|
||||
type dt1 = struct { tag: i32, buf: [4]u8 };
|
||||
let D1: dt1 = dt1{tag=42, buf=[1u8, 2u8, 3u8, 4u8]};
|
||||
type dt2 = struct { tag: i32, m: [2][2]u64 };
|
||||
let D2: dt2 = dt2{tag=42, m=[[1u64,2u64],[3u64,4u64]]};
|
||||
|
||||
fn bits64(v: f64) u64 = {
|
||||
let x: f64 = v;
|
||||
let p: *u64 = (&x): *u64;
|
||||
return *p;
|
||||
};
|
||||
|
||||
fn bits32(v: f32) u32 = {
|
||||
let x: f32 = v;
|
||||
let p: *u32 = (&x): *u32;
|
||||
return *p;
|
||||
};
|
||||
|
||||
fn at(i: i32, j: i32) u64 = { return A2V[i][j]; };
|
||||
|
||||
@test fn let_u8_arr() void = { assert(A_U8[0]: i32 == 1); };
|
||||
@test fn let_u32_arr() void = { assert(A_U32[0]: i32 == 1); };
|
||||
@test fn let_u64_arr() void = { assert(A_U64[0]: i32 == 1); };
|
||||
@test fn let_i32_neg_arr() void = { assert(A_INEG[0] == -1); };
|
||||
|
||||
@test fn let_f64_arr() void = {
|
||||
assert(bits64(A_F64[0]) == 0x3FF8000000000000u64);
|
||||
assert(bits64(A_F64[1]) == 0xC004000000000000u64);
|
||||
assert(bits64(A_F64[3]) == 0xC012000000000000u64);
|
||||
};
|
||||
|
||||
@test fn let_f32_arr() void = {
|
||||
assert(bits32(A_F32[0]) == 0x3FC00000u32);
|
||||
assert(bits32(A_F32[1]) == 0xC0200000u32);
|
||||
assert(bits32(A_F32[3]) == 0xC0900000u32);
|
||||
};
|
||||
|
||||
@test fn def_u32_arr() void = { assert(DA_U32[0]: i32 == 11); };
|
||||
|
||||
@test fn def_f64_arr() void = {
|
||||
assert(bits64(DA_F64[0]) == 0x3FF8000000000000u64);
|
||||
assert(bits64(DA_F64[3]) == 0x4012000000000000u64);
|
||||
};
|
||||
|
||||
@test fn let_struct_with_arr_field() void = {
|
||||
assert(D1.tag == 42);
|
||||
assert(D1.buf[0]: i32 == 1);
|
||||
assert(D1.buf[3]: i32 == 4);
|
||||
};
|
||||
@test fn let_u8_zero_arr() void = { assert(A_UZ[0]: i32 == 0); };
|
||||
@test fn let_u8_single() void = { assert(A_U1[0]: i32 == 7); };
|
||||
@test fn let_2d_u64() void = { assert(A2D[1][0]: i32 == 3); };
|
||||
@test fn def_2d_u64() void = { assert(DA2D[2][1]: i32 == 6); };
|
||||
@test fn let_2d_varidx() void = { assert((at(1, 1) + at(2, 0)): i32 == 51); };
|
||||
@test fn let_2d_u32_8byte() void = { assert(A28[1][0]: i32 == 9); };
|
||||
|
||||
@test fn let_2d_write() void = {
|
||||
A2W[1][0] = 99u64;
|
||||
assert((A2W[0][0] + A2W[0][1] + A2W[1][0] + A2W[1][1]): i32 == 106);
|
||||
};
|
||||
|
||||
@test fn let_struct_2d_field() void = {
|
||||
assert(D2.tag == 42);
|
||||
assert(D2.m[1][0]: i32 == 3);
|
||||
assert(D2.m[1][1]: i32 == 4);
|
||||
};
|
||||
@test fn let_3d_u8() void = { assert(A3D[1][1][0]: i32 == 7); };
|
||||
62
test/lang/const_slice_aggregate_test.ww
Normal file
62
test/lang/const_slice_aggregate_test.ww
Normal file
@@ -0,0 +1,62 @@
|
||||
// const_slice_aggregate_test — module-level const slice of (str,*fn) tuple rows
|
||||
// + scalar &fn globals, DATA emit with element relocations. Migrated from
|
||||
// test/wcc/946_const_slice_aggregate_run.c (#117/#119). cstage build+run was T1;
|
||||
// cs==ww .s byte-id rides T2 (test-lang-byteid). The loud non-tuple-aggregate
|
||||
// reject is the runww carrier test/wcc/data/slice_of_str_reject.
|
||||
//
|
||||
// drew: CALL THROUGH the *fn reloc — a scalar-only / len-only assert is
|
||||
// reloc-blind. Each row calls each distinct fn back so a wrong/swapped reloc is
|
||||
// caught; the str-element relocs + per-row backing stride ride the T2 byte-id.
|
||||
// Whole-element word0 is the only correctly-loaded backing word (#121 read
|
||||
// constraint), so the fn-first / scalar-first orderings put the read target at
|
||||
// word0.
|
||||
|
||||
package const_slice_aggregate_test;
|
||||
|
||||
fn fa(c: rune) bool = { return c == 'a'; };
|
||||
fn fz(c: rune) bool = { return c == 'z'; };
|
||||
|
||||
const TBL_FN: [](*fn(c: rune) bool, str) = [(&fa, "aa"), (&fz, "zzz")];
|
||||
const TBL_SF: [](str, *fn(c: rune) bool) = [("aa", &fa), ("zzz", &fz)];
|
||||
const TBL_3: [](str, *fn(c: rune) bool) =
|
||||
[("a", &fa), ("bb", &fa), ("ccc", &fa)];
|
||||
const TSCAL: [](i64, str) = [(10i64, "a"), (20i64, "bb")];
|
||||
let PF: *fn(c: rune) bool = &fa;
|
||||
let PG: *fn(c: rune) bool = &fz;
|
||||
|
||||
@test fn fnfirst_reloc() void = {
|
||||
let e0 = TBL_FN[0];
|
||||
let e1 = TBL_FN[1];
|
||||
let f0 = e0.0;
|
||||
let f1 = e1.0;
|
||||
assert((*f0)('a'));
|
||||
assert(!(*f0)('z'));
|
||||
assert((*f1)('z'));
|
||||
assert(!(*f1)('a'));
|
||||
assert(len(TBL_FN) == 2);
|
||||
};
|
||||
|
||||
@test fn consumer_str_fn() void = {
|
||||
assert(len(TBL_SF) == 2);
|
||||
};
|
||||
|
||||
@test fn consumer_3row() void = {
|
||||
assert(len(TBL_3) == 3);
|
||||
};
|
||||
|
||||
@test fn scalar_tuple_slice() void = {
|
||||
let e0 = TSCAL[0];
|
||||
let e1 = TSCAL[1];
|
||||
let v0 = e0.0;
|
||||
let v1 = e1.0;
|
||||
assert(v0 == 10);
|
||||
assert(v1 == 20);
|
||||
assert(len(TSCAL) == 2);
|
||||
};
|
||||
|
||||
@test fn scalar_fnptr() void = {
|
||||
assert((*PF)('a'));
|
||||
assert(!(*PF)('z'));
|
||||
assert((*PG)('z'));
|
||||
assert(!(*PG)('a'));
|
||||
};
|
||||
62
test/lang/def_float_lit_test.ww
Normal file
62
test/lang/def_float_lit_test.ww
Normal file
@@ -0,0 +1,62 @@
|
||||
// def_float_lit_test — module-level `def`/`let` f64/f32 literal (incl negation)
|
||||
// emits DATA, read back from a fn. Migrated from test/wcc/917_def_float_lit_run.c
|
||||
// (#129 Phase A.1). Pre-fix `def K: f64 = lit;` fell through emit_defs's int-only
|
||||
// fold gate so no DATAW landed (link: `undefined reference to main.K`); emit_lets's
|
||||
// float arm never peeled N_UN(MINUS/PLUS, N_FLOATLIT) so `let g: f64 = -1.5;`
|
||||
// silently zero-emitted. Fix = shared emit_floatlit_data helper (negation via
|
||||
// IEEE-754 sign-bit XOR). cstage build+run was T1; cs==ww .s byte-id rides T2
|
||||
// (test-lang-byteid).
|
||||
//
|
||||
// drew: assert BIT-EXACT incl sign — the bits()-reinterpret reads the full IEEE
|
||||
// pattern, so a sign-bit or mantissa drift fails (a truncating `: i32` read would
|
||||
// alias 1.5 and 1.9). The negative rows pin the sign-XOR byte path.
|
||||
|
||||
package def_float_lit_test;
|
||||
|
||||
def KDPOS: f64 = 1.5;
|
||||
def KDNEG: f64 = -1.5;
|
||||
def KFPOS: f32 = 1.5f32;
|
||||
def KFNEG: f32 = -1.5f32;
|
||||
let GDNEG: f64 = -1.5;
|
||||
let GDPOS: f64 = 1.5;
|
||||
let GFPOS: f32 = 1.5f32;
|
||||
|
||||
fn bits64(v: f64) u64 = {
|
||||
let x: f64 = v;
|
||||
let p: *u64 = (&x): *u64;
|
||||
return *p;
|
||||
};
|
||||
|
||||
fn bits32(v: f32) u32 = {
|
||||
let x: f32 = v;
|
||||
let p: *u32 = (&x): *u32;
|
||||
return *p;
|
||||
};
|
||||
|
||||
@test fn def_f64_pos() void = {
|
||||
assert(bits64(KDPOS) == 0x3FF8000000000000u64);
|
||||
};
|
||||
|
||||
@test fn def_f64_neg() void = {
|
||||
assert(bits64(KDNEG) == 0xBFF8000000000000u64);
|
||||
};
|
||||
|
||||
@test fn def_f32_pos() void = {
|
||||
assert(bits32(KFPOS) == 0x3FC00000u32);
|
||||
};
|
||||
|
||||
@test fn def_f32_neg() void = {
|
||||
assert(bits32(KFNEG) == 0xBFC00000u32);
|
||||
};
|
||||
|
||||
@test fn let_f64_neg() void = {
|
||||
assert(bits64(GDNEG) == 0xBFF8000000000000u64);
|
||||
};
|
||||
|
||||
@test fn let_f64_pos() void = {
|
||||
assert(bits64(GDPOS) == 0x3FF8000000000000u64);
|
||||
};
|
||||
|
||||
@test fn let_f32_pos() void = {
|
||||
assert(bits32(GFPOS) == 0x3FC00000u32);
|
||||
};
|
||||
33
test/lang/inferred_scalar_global_test.ww
Normal file
33
test/lang/inferred_scalar_global_test.ww
Normal file
@@ -0,0 +1,33 @@
|
||||
// inferred_scalar_global_test — module-level inferred/const-expr scalar global
|
||||
// emit + read. Migrated from test/wcc/947_inferred_scalar_global_run.c
|
||||
// (#66 b-i, #134 neg, #133 const-expr). An inferred / unary / const-expr int
|
||||
// global once emitted no DATAW on wwstage (MOVSXD on stale AX) and link-failed
|
||||
// on cstage; the let pass-2 arm now const-folds the rhs and stamps an N_INTLIT
|
||||
// so cgen's literal DATA emitter fires in BOTH stages. cstage build+run was T1;
|
||||
// cs==ww .s byte-id rides T2 (test-lang-byteid). The div-by-zero const-expr
|
||||
// reject is the runww carrier test/wcc/data/const_divzero_reject.
|
||||
//
|
||||
// The typed controls (typed_ctrl/neg_typed_ctrl/const_typed) lock the
|
||||
// construction proof: the inferred decl's emitted .s equals the typed decl's
|
||||
// after defaulting.
|
||||
|
||||
package inferred_scalar_global_test;
|
||||
|
||||
let SI = 42;
|
||||
let STC: i64 = 42;
|
||||
let SNI = -42;
|
||||
let SNT: int = -42;
|
||||
let SCI = 7 * 6;
|
||||
let SCT: i64 = 7 * 6;
|
||||
def KD: int = 6;
|
||||
let SDR = KD * 7;
|
||||
let SUB = -(2 * 3);
|
||||
|
||||
@test fn inferred() void = { assert(SI: i64 == 42); };
|
||||
@test fn typed_ctrl() void = { assert(STC == 42); };
|
||||
@test fn neg_inferred() void = { assert(SNI: i64 == -42); };
|
||||
@test fn neg_typed_ctrl() void = { assert(SNT == -42); };
|
||||
@test fn const_inferred() void = { assert(SCI: i64 == 42); };
|
||||
@test fn const_typed() void = { assert(SCT == 42); };
|
||||
@test fn const_defref() void = { assert(SDR: i64 == 42); };
|
||||
@test fn const_unary_binop() void = { assert(SUB: i64 == -6); };
|
||||
38
test/lang/nestfield_test.ww
Normal file
38
test/lang/nestfield_test.ww
Normal file
@@ -0,0 +1,38 @@
|
||||
// nestfield_test — nested sub-8 composite struct field at natural offsets.
|
||||
// Migrated from test/wcc/989_nestfield_run.c (#44/#55). For outer{a:u8, p:inner}
|
||||
// the natural offset of p is 1, but a pre-fix slot-padded layout put it at 8, so
|
||||
// construction (write) and field-access (read) disagreed and o.p.x / o.p.y read
|
||||
// wrong. cstage build+run was T1; the original cat-A invariant (cs==ww exit)
|
||||
// now rides the stronger T2 .s byte-id (test-lang-byteid).
|
||||
//
|
||||
// nested3's z proves post-composite accumulation stays natural (z follows the
|
||||
// 1-byte-padded inner, not the 8-byte-padded one). flat_ctl is the no-sub-8-field
|
||||
// control where natural and slot-padded layouts coincide.
|
||||
|
||||
package nestfield_test;
|
||||
|
||||
type inr = struct { x: u8, y: u8 };
|
||||
type ot2 = struct { a: u8, p: inr };
|
||||
type ot3 = struct { a: u8, p: inr, z: i64 };
|
||||
type flt = struct { a: u8, b: i64 };
|
||||
|
||||
@test fn nested2() void = {
|
||||
let o: ot2 = ot2 { a = 5, p = inr { x = 6, y = 7 } };
|
||||
assert(o.a: int == 5);
|
||||
assert(o.p.x: int == 6);
|
||||
assert(o.p.y: int == 7);
|
||||
};
|
||||
|
||||
@test fn nested3() void = {
|
||||
let o: ot3 = ot3 { a = 1, p = inr { x = 2, y = 3 }, z = 0x44444444i64 };
|
||||
assert(o.a: int == 1);
|
||||
assert(o.p.x: int == 2);
|
||||
assert(o.p.y: int == 3);
|
||||
assert(o.z == 0x44444444i64);
|
||||
};
|
||||
|
||||
@test fn flat_ctl() void = {
|
||||
let o: flt = flt { a = 9, b = 0x33333333i64 };
|
||||
assert(o.a: int == 9);
|
||||
assert(o.b == 0x33333333i64);
|
||||
};
|
||||
66
test/lang/signed_data_emit_test.ww
Normal file
66
test/lang/signed_data_emit_test.ww
Normal file
@@ -0,0 +1,66 @@
|
||||
// signed_data_emit_test — module-level signed i8..i64 scalar + 1D-array DATA
|
||||
// emit, self-asserting the sign survives exactly. Migrated from
|
||||
// test/wcc/923_signed_data_emit_run.c. Pre-fix wwstage silently zeroed negative
|
||||
// array entries; cstage emitted nothing (link failed). cstage build+run was T1;
|
||||
// cs==ww .s byte-id rides T2 (test-lang-byteid).
|
||||
//
|
||||
// drew: assert SIGN survives exactly — every row compares against the signed
|
||||
// typed literal, so a sign-extension or zero-fill drift fails. i64_tilde pins
|
||||
// the N_UN(TK_TILDE) fold (~0u64 == -1i64). The arrays mirror the utf8 DFA shape.
|
||||
|
||||
package signed_data_emit_test;
|
||||
|
||||
let X_I8N: i8 = -1i8;
|
||||
let X_I8P: i8 = 42i8;
|
||||
let X_I16N: i16 = -2i16;
|
||||
let X_I16P: i16 = 1000i16;
|
||||
let X_I32N: i32 = -100i32;
|
||||
let X_I32P: i32 = 100000i32;
|
||||
let X_I64N: i64 = -1000i64;
|
||||
let X_I64P: i64 = 1000000i64;
|
||||
let X_TILDE: i64 = (~0u64): i64;
|
||||
|
||||
let DFA: [8]i8 = [0i8, -1i8, 1i8, 2i8, 0i8, 0i8, -1i8, -1i8];
|
||||
let A16: [4]i16 = [1i16, -2i16, 3i16, -4i16];
|
||||
let A32: [4]i32 = [10i32, -20i32, 30i32, -40i32];
|
||||
let A64: [4]i64 = [100i64, -200i64, 300i64, -400i64];
|
||||
|
||||
@test fn i8_neg_scalar() void = { assert(X_I8N == -1i8); };
|
||||
@test fn i8_pos_scalar() void = { assert(X_I8P == 42i8); };
|
||||
@test fn i16_neg_scalar() void = { assert(X_I16N == -2i16); };
|
||||
@test fn i16_pos_scalar() void = { assert(X_I16P == 1000i16); };
|
||||
@test fn i32_neg_scalar() void = { assert(X_I32N == -100i32); };
|
||||
@test fn i32_pos_scalar() void = { assert(X_I32P == 100000i32); };
|
||||
@test fn i64_neg_scalar() void = { assert(X_I64N == -1000i64); };
|
||||
@test fn i64_pos_scalar() void = { assert(X_I64P == 1000000i64); };
|
||||
@test fn i64_tilde_scalar() void = { assert(X_TILDE == -1i64); };
|
||||
|
||||
@test fn i8_arr_dfa() void = {
|
||||
assert(DFA[0] == 0i8);
|
||||
assert(DFA[1] == -1i8);
|
||||
assert(DFA[2] == 1i8);
|
||||
assert(DFA[3] == 2i8);
|
||||
assert(DFA[6] == -1i8);
|
||||
assert(DFA[7] == -1i8);
|
||||
};
|
||||
|
||||
@test fn i16_arr_mixed() void = {
|
||||
assert(A16[0] == 1i16);
|
||||
assert(A16[1] == -2i16);
|
||||
assert(A16[2] == 3i16);
|
||||
assert(A16[3] == -4i16);
|
||||
};
|
||||
|
||||
@test fn i32_arr_mixed() void = {
|
||||
assert(A32[0] == 10i32);
|
||||
assert(A32[1] == -20i32);
|
||||
assert(A32[2] == 30i32);
|
||||
assert(A32[3] == -40i32);
|
||||
};
|
||||
|
||||
@test fn i64_arr_mixed() void = {
|
||||
assert(A64[0] == 100i64);
|
||||
assert(A64[1] == -200i64);
|
||||
assert(A64[2] == 300i64);
|
||||
assert(A64[3] == -400i64);
|
||||
};
|
||||
44
test/lang/strarray_static_test.ww
Normal file
44
test/lang/strarray_static_test.ww
Normal file
@@ -0,0 +1,44 @@
|
||||
// strarray_static_test — module-level [N]str static-init: per-element .len
|
||||
// header sums + per-element .ptr RELOC dereferenced to chars. Migrated from
|
||||
// test/wcc/919_strarray_static_run.c. cstage build+run was T1; cs==ww .s byte-id
|
||||
// rides T2 (test-lang-byteid).
|
||||
//
|
||||
// drew: assert THROUGH the per-element .ptr deref (not just .len) — a reloc-blind
|
||||
// .len-only check would miss a wrong/swapped element relocation. The empty-slot
|
||||
// and `...` repeat-suffix rows pin that an empty element doesn't shift the
|
||||
// following element's reloc and that the repeat-fill row's DATAR resolves to the
|
||||
// last explicit element.
|
||||
|
||||
package strarray_static_test;
|
||||
|
||||
let TLEN: [3]str = ["ab", "cde", "f"];
|
||||
let TPTR: [3]str = ["A", "B", "C"];
|
||||
let TVAR: [3]str = ["xx", "yyy", "z"];
|
||||
let TEMP: [2]str = ["", "Z"];
|
||||
let TREP: [3]str = ["X", "Y"...];
|
||||
|
||||
@test fn strtab_len() void = {
|
||||
assert((TLEN[0].len + TLEN[1].len + TLEN[2].len): i32 == 6);
|
||||
};
|
||||
|
||||
@test fn strtab_ptr_elem2() void = {
|
||||
let p: *u8 = TPTR[2].ptr;
|
||||
assert((*p): i32 == 67);
|
||||
};
|
||||
|
||||
@test fn strtab_ptr_varindex() void = {
|
||||
let i: i32 = 1;
|
||||
let p: *u8 = TVAR[i].ptr;
|
||||
assert((*p): i32 == 121);
|
||||
};
|
||||
|
||||
@test fn strtab_empty_then_ptr() void = {
|
||||
assert(TEMP[0].len == 0);
|
||||
let p: *u8 = TEMP[1].ptr;
|
||||
assert((*p): i32 == 90);
|
||||
};
|
||||
|
||||
@test fn strtab_repeat_suffix() void = {
|
||||
let p: *u8 = TREP[2].ptr;
|
||||
assert((*p): i32 == 89);
|
||||
};
|
||||
66
test/lang/struct_composite_init_test.ww
Normal file
66
test/lang/struct_composite_init_test.ww
Normal file
@@ -0,0 +1,66 @@
|
||||
// struct_composite_init_test — module-level `let`/`def` composite-struct
|
||||
// static-init, field read. Migrated from test/wcc/918_struct_composite_init_run.c
|
||||
// (#129 Phase A.2). Pre-fix emit_lets/emit_defs skipped struct-typed decls
|
||||
// (link: `undefined reference to main.NAME`) and a struct def read MOVSXD'd
|
||||
// stack byte 0. Fix = emit_struct_data/emit_struct_lit_bytes walking the field
|
||||
// list with per-field-offset zero-fill (rule 13). cstage build+run was T1;
|
||||
// cs==ww .s byte-id rides T2 (test-lang-byteid).
|
||||
//
|
||||
// The float-field rows assert bit-exact (drew) via bits64. let_empty/norhs read
|
||||
// 0 from the statically zero-filled DATA (a global, not a dirtied stack — no
|
||||
// benign-zero trap; an under-emit would shorten the symbol, not pad zero). The
|
||||
// 8B-struct row pins the !is_struct gate over the sz==8 scalar short-circuit.
|
||||
|
||||
package struct_composite_init_test;
|
||||
|
||||
type cfg_t = struct { a: i32, b: u64 };
|
||||
type ft = struct { a: f64, b: u32 };
|
||||
type s8 = struct { a: i32, b: i32 };
|
||||
|
||||
let CFG_L: cfg_t = cfg_t{a=1, b=2u64};
|
||||
def CFG_D: cfg_t = cfg_t{a=1, b=2u64};
|
||||
let F_L: ft = ft{a=1.5, b=99u32};
|
||||
def F_D: ft = ft{a=1.5, b=99u32};
|
||||
let Z: cfg_t = cfg_t{};
|
||||
let X8: s8 = s8{a=7, b=42};
|
||||
let CFG_NR: cfg_t;
|
||||
|
||||
fn bits64(v: f64) u64 = {
|
||||
let x: f64 = v;
|
||||
let p: *u64 = (&x): *u64;
|
||||
return *p;
|
||||
};
|
||||
|
||||
@test fn let_int_struct() void = {
|
||||
assert(CFG_L.a == 1);
|
||||
assert(CFG_L.b == 2u64);
|
||||
};
|
||||
|
||||
@test fn def_int_struct() void = {
|
||||
assert(CFG_D.a == 1);
|
||||
assert(CFG_D.b == 2u64);
|
||||
};
|
||||
|
||||
@test fn let_float_field() void = {
|
||||
assert(bits64(F_L.a) == 0x3FF8000000000000u64);
|
||||
assert(F_L.b == 99u32);
|
||||
};
|
||||
|
||||
@test fn def_float_field() void = {
|
||||
assert(bits64(F_D.a) == 0x3FF8000000000000u64);
|
||||
assert(F_D.b == 99u32);
|
||||
};
|
||||
|
||||
@test fn let_empty_struct() void = {
|
||||
assert(Z.a == 0);
|
||||
assert(Z.b == 0u64);
|
||||
};
|
||||
|
||||
@test fn let_int_struct_8b() void = {
|
||||
assert(X8.a == 7);
|
||||
assert(X8.b == 42);
|
||||
};
|
||||
|
||||
@test fn let_norhs_struct() void = {
|
||||
assert(CFG_NR.a == 0);
|
||||
};
|
||||
34
test/lang/structlit_arrfield_test.ww
Normal file
34
test/lang/structlit_arrfield_test.ww
Normal file
@@ -0,0 +1,34 @@
|
||||
// structlit_arrfield_test — struct array-field init + read (global let/def and
|
||||
// local lit). Migrated from test/wcc/949_structlit_arrfield_run.c (#249). BUG B:
|
||||
// reading a [4]u8 field of a module-global struct SEGFAULTed on wwstage; BUG A:
|
||||
// a local struct-lit array field fell to the scalar tail and dropped every
|
||||
// element but the first. Fix = cg_structlit_fill array arm + def_isstructdef
|
||||
// LOAD widening (ADDQ $field_off). cstage build+run was T1; cs==ww .s byte-id
|
||||
// rides T2 (test-lang-byteid). The def row has a [3]u8 pad ahead of encmap, so
|
||||
// the read exercises a non-zero field offset (the base64 std_encoding shape).
|
||||
|
||||
package structlit_arrfield_test;
|
||||
|
||||
type e1 = struct { encmap: [4]u8 };
|
||||
let GE: e1 = e1 { encmap = [65u8, 66u8, 67u8, 68u8] };
|
||||
|
||||
type e2 = struct { pad: [3]u8, encmap: [4]u8 };
|
||||
def GD: e2 = e2 { pad = [9u8, 9u8, 9u8], encmap = [65u8, 66u8, 67u8, 68u8] };
|
||||
|
||||
@test fn global_let_read() void = {
|
||||
assert(GE.encmap[0]: i32 == 65);
|
||||
};
|
||||
|
||||
@test fn global_def_read_off() void = {
|
||||
assert(GD.encmap[2]: i32 == 67);
|
||||
};
|
||||
|
||||
@test fn local_lit_read0() void = {
|
||||
let g: e1 = e1 { encmap = [65u8, 66u8, 67u8, 68u8] };
|
||||
assert(g.encmap[0]: i32 == 65);
|
||||
};
|
||||
|
||||
@test fn local_lit_read3() void = {
|
||||
let g: e1 = e1 { encmap = [65u8, 66u8, 67u8, 68u8] };
|
||||
assert(g.encmap[3]: i32 == 68);
|
||||
};
|
||||
70
test/lang/valstruct_subsize_test.ww
Normal file
70
test/lang/valstruct_subsize_test.ww
Normal file
@@ -0,0 +1,70 @@
|
||||
// valstruct_subsize_test — sub-8 nested value-struct zero-init extent, local +
|
||||
// global, distinct byte asserts. Migrated from
|
||||
// test/wcc/949_valstruct_subsize_run.c. A nested {[N]u8} value-struct of ABI
|
||||
// size 1/2/4 once emitted a stray MOVQ $0 (local) / 8 zero DATA bytes (global)
|
||||
// on wwstage that cstage didn't. cstage build+run was T1; cs==ww .s byte-id
|
||||
// rides T2 (test-lang-byteid).
|
||||
//
|
||||
// The D1/D2 rows WRITE then READ a byte so the value is deterministic (the
|
||||
// robust falsifiable dimension). The ctl_*_16 rows are the negative control: a
|
||||
// >8 multi-word value-struct still zero-inits — a wrongly-suppressed >8 zero arm
|
||||
// would read stack garbage (and diverge from the still-zeroing cstage on the T2
|
||||
// byte-id, which is the real guarantee for the unwritten read).
|
||||
|
||||
package valstruct_subsize_test;
|
||||
|
||||
type in4 = struct { m: [4]u8 };
|
||||
type ov4 = struct { i: in4 };
|
||||
type in2 = struct { m: [2]u8 };
|
||||
type ov2 = struct { i: in2 };
|
||||
type in1 = struct { m: [1]u8 };
|
||||
type ov1 = struct { i: in1 };
|
||||
type in16 = struct { m: [16]u8 };
|
||||
type ov16 = struct { i: in16 };
|
||||
|
||||
let G4: ov4;
|
||||
let G2: ov2;
|
||||
let G1: ov1;
|
||||
let G16: ov16;
|
||||
|
||||
@test fn d1_local_4() void = {
|
||||
let o: ov4;
|
||||
o.i.m[0] = 66u8;
|
||||
assert(o.i.m[0]: i32 == 66);
|
||||
};
|
||||
|
||||
@test fn d1_local_2() void = {
|
||||
let o: ov2;
|
||||
o.i.m[1] = 55u8;
|
||||
assert(o.i.m[1]: i32 == 55);
|
||||
};
|
||||
|
||||
@test fn d1_local_1() void = {
|
||||
let o: ov1;
|
||||
o.i.m[0] = 44u8;
|
||||
assert(o.i.m[0]: i32 == 44);
|
||||
};
|
||||
|
||||
@test fn d2_global_4() void = {
|
||||
G4.i.m[0] = 66u8;
|
||||
assert(G4.i.m[0]: i32 == 66);
|
||||
};
|
||||
|
||||
@test fn d2_global_2() void = {
|
||||
G2.i.m[1] = 55u8;
|
||||
assert(G2.i.m[1]: i32 == 55);
|
||||
};
|
||||
|
||||
@test fn d2_global_1() void = {
|
||||
G1.i.m[0] = 44u8;
|
||||
assert(G1.i.m[0]: i32 == 44);
|
||||
};
|
||||
|
||||
@test fn ctl_local_16() void = {
|
||||
let o: ov16;
|
||||
assert(o.i.m[7]: i32 == 0);
|
||||
};
|
||||
|
||||
@test fn ctl_global_16() void = {
|
||||
assert(G16.i.m[7]: i32 == 0);
|
||||
};
|
||||
Reference in New Issue
Block a user