From d5bdd5467cc522b3087355b2d7ff0704a0aeb4e1 Mon Sep 17 00:00:00 2001 From: Robert Muth Date: Sat, 1 Jun 2024 09:18:28 -0400 Subject: [PATCH] more concrete syntax examples --- .../ConcreteSyntax/LangTest/array_test.cw | 130 +++++++++++++++++ .../ConcreteSyntax/LangTest/assign_test.cw | 85 +++++++++++ .../ConcreteSyntax/LangTest/defer_test.cw | 34 +++++ FrontEnd/ConcreteSyntax/LangTest/enum_test.cw | 72 ++++++++++ .../LangTest/sum_tagged_test.cw | 135 ++++++++++++++++++ .../LangTest/sum_untagged_test.cw | 127 ++++++++++++++++ 6 files changed, 583 insertions(+) create mode 100644 FrontEnd/ConcreteSyntax/LangTest/array_test.cw create mode 100644 FrontEnd/ConcreteSyntax/LangTest/assign_test.cw create mode 100644 FrontEnd/ConcreteSyntax/LangTest/defer_test.cw create mode 100644 FrontEnd/ConcreteSyntax/LangTest/enum_test.cw create mode 100644 FrontEnd/ConcreteSyntax/LangTest/sum_tagged_test.cw create mode 100644 FrontEnd/ConcreteSyntax/LangTest/sum_untagged_test.cw diff --git a/FrontEnd/ConcreteSyntax/LangTest/array_test.cw b/FrontEnd/ConcreteSyntax/LangTest/array_test.cw new file mode 100644 index 00000000..31126bf4 --- /dev/null +++ b/FrontEnd/ConcreteSyntax/LangTest/array_test.cw @@ -0,0 +1,130 @@ +module main: + +import test + +type type_array = [3]bool + +type type_slice = slice(s32) + +global c1 = [10]s32{1, 2, 3} + +global! c2 = [10]s32{1, 2, 3} + +-- (let c20 auto (len c1)") +-- "(let c21 auto (at c1 2))") +global dim = 5_u16 + +fun foo(a [10]u8, b [dim]u64) u8: + let v2 = c1[0] + let v3 = &c1[0] + let v4 = &!c2[0] + set c2[0] = 666 + return 66 + +fun update_array(s slice!(u8), pos uint, new u8) u8: + let old = s[pos] + set s[pos] = new + return old + +-- ERROR: (let f4 (slice mut s32) e1) +fun baz() void: + -- ERROR: (= (at c1 5) 0) + let pc1 ^s32 = front(c1) + set c2[5] = 0 + +@pub rec type_rec3: + u2 u16 + u3 u64 + u5 [10]u8 + u6 u64 + +global! r1 = type_rec3{u5 : [10]u8{77, 88, 99}} + +global! c4 = [10]u8{41, 51, 61} + +fun test_mixed_array() void: + -- + @ref let! a = [10]u8{1, 2, 3} + let pa = &a + let pa_mut = &!a + test::AssertEq#(c4[2], 61_u8) + set c4 = a + test::AssertEq#(c4[2], 3_u8) + set c4[2] = 4_u8 + set a = c4 + test::AssertEq#(a[2], 4_u8) + test::AssertEq#(r1.u5[1], 88_u8) + set r1.u5 = a + test::AssertEq#(r1.u5[1], 2_u8) + set r1.u5[1] = 111 + set a = r1.u5 + test::AssertEq#(a[1], 111_u8) + +fun test_local_array() void: + -- + @ref let! a = [10]u8{1, 2, 3} + @ref let b = [10]u8{4, 5, 6} + let pa = &a + let pa_mut = &!a + let pb = &b + test::AssertEq#(a[0], 1_u8) + test::AssertEq#(b[2], 6_u8) + set a[0] = 6 + test::AssertEq#(a[0], 6_u8) + set pa_mut^[2] = 77_u8 + test::AssertEq#(pa^[2], 77_u8) + test::AssertEq#(pa_mut^[2], 77_u8) + test::AssertEq#(pb^[0], 4_u8) + set pa_mut^[0] = 66 + test::AssertEq#(a[0], 66_u8) + set a = b + test::AssertEq#(a[0], 4_u8) + test::AssertEq#(update_array(a, 0, 2), 4_u8) + test::AssertEq#(update_array(a, 0, 3), 2_u8) + test::AssertEq#(update_array(pa_mut^, 0, 2), 3_u8) + +global d1 = [10]s32{11, 22, 33} + +global! d2 = [10]s32{111, 222, 333} + +global! c3 = [10]u8{4, 5, 6} + +global e1 slice(s32) = d1 + +global e2 slice!(s32) = d2 + +global e3 = [5]s32{0, 1, 2, 3, 4} + +global e4 = [2]slice(s32){e1, e1} + +-- ERROR +-- (global e5 (slice (slice s32)) e4) +-- (global e3 (slice mut s32) d2) +global f1 slice(s32) = e1 + +global f3 slice(s32) = e2 + +global f2 slice!(s32) = e2 + +fun test_global_array() void: + -- basic + test::AssertEq#(c1[1], 2_s32) + test::AssertEq#(c2[2], 3_s32) + test::AssertEq#(e1[1], 22_s32) + test::AssertEq#(e2[2], 333_s32) + test::AssertEq#(f1[1], 22_s32) + test::AssertEq#(f2[2], 333_s32) + test::AssertEq#(f3[0], 111_s32) + -- basic + test::AssertEq#(c3[0], 4_u8) + test::AssertEq#(update_array(c3, 0, 77), 4_u8) + test::AssertEq#(update_array(c3, 0, 5), 77_u8) + test::AssertEq#(len(e1), 10_uint) + +@cdecl fun main(argc s32, argv ^^u8) s32: + shed test_global_array() + shed test_local_array() + shed test_mixed_array() + -- test end + test::Success#() + return 0 diff --git a/FrontEnd/ConcreteSyntax/LangTest/assign_test.cw b/FrontEnd/ConcreteSyntax/LangTest/assign_test.cw new file mode 100644 index 00000000..ddbbff4e --- /dev/null +++ b/FrontEnd/ConcreteSyntax/LangTest/assign_test.cw @@ -0,0 +1,85 @@ +module main: + +import test + +@pub rec type_rec1: + -- this is a comment with \" with quotes \t + i1 s64 + i2 u64 + i3 s32 + i4 u32 + i5 s16 + i6 u16 + i7 s8 + i8 u8 + f1 r64 + f2 r32 + b1 bool + a1 [7]u8 + a2 [7]u16 + a3 [7]u32 + a4 [7]u64 + a5 [7]r32 + a6 [7]r64 + +@pub rec type_rec2: + t1 bool + t2 u32 + t3 type_rec1 + t4 bool + +@pub rec type_rec3: + u2 u16 + u3 u64 + u4 type_rec2 + u5 [13]u16 + u6 u64 + +global! ga1 [5]s64 = undef + +global! gr1 type_rec1 = undef + +global! gar1 [5]type_rec1 = undef + +global! gr2 type_rec2 = undef + +global! gar2 [5]type_rec2 = undef + +fun get_addr() ^!type_rec1: + return &!gr1 + +@cdecl fun main(argc s32, argv ^^u8) s32: + -- a1 u32 + set ga1[3] = 0x8765432187654321 + test::AssertEq#(ga1[3], 0x8765432187654321_s64) + set ga1[3] += 0x1 + test::AssertEq#(ga1[3], 0x8765432187654322_s64) + -- gr1 s64 + set gr1.i1 = 0x8765432187654321 + test::AssertEq#(gr1.i1, 0x8765432187654321_s64) + set gr1.i1 += 0x1 + test::AssertEq#(gr1.i1, 0x8765432187654322_s64) + -- gr1 u64 + set gr1.i2 = 0x1234567812345678 + test::AssertEq#(gr1.i2, 0x1234567812345678_u64) + set gr1.i2 -= 0x1 + test::AssertEq#(gr1.i2, 0x1234567812345677_u64) + -- gr1 u64 via pointer + set get_addr()^.i2 = 0x1234567812345678 + test::AssertEq#(get_addr()^.i2, 0x1234567812345678_u64) + set get_addr()^.i2 -= 0x1 + test::AssertEq#(get_addr()^.i2, 0x1234567812345677_u64) + -- gar1 s64 + set gar1[3].i1 = 0x8765432187654321 + test::AssertEq#(gar1[3].i1, 0x8765432187654321_s64) + -- gr2 s64 + set gr2.t3.i1 = 0x8765432187654321 + test::AssertEq#(gr2.t3.i1, 0x8765432187654321_s64) + set gr2.t3.i1 += 0x1 + test::AssertEq#(gr2.t3.i1, 0x8765432187654322_s64) + -- gr2 u64 + set gr2.t3.i2 = 0x1234567812345678 + test::AssertEq#(gr2.t3.i2, 0x1234567812345678_u64) + -- test end + test::Success#() + return 0 diff --git a/FrontEnd/ConcreteSyntax/LangTest/defer_test.cw b/FrontEnd/ConcreteSyntax/LangTest/defer_test.cw new file mode 100644 index 00000000..b81d0198 --- /dev/null +++ b/FrontEnd/ConcreteSyntax/LangTest/defer_test.cw @@ -0,0 +1,34 @@ +-- defer +module main: + +import test + +global! gIndex uint = 0 + +global! gSequence = [10]u8{0} + +fun store(c u8) void: + set gSequence[gIndex] = c + set gIndex += 1 + +fun foo() void: + defer: + shed store('h') + defer: + shed store('g') + shed store('a') + block _: + shed store('b') + defer: + shed store('e') + defer: + shed store('d') + shed store('c') + shed store('f') + +@cdecl fun main(argc s32, argv ^^u8) s32: + shed foo() + test::AssertSliceEq#(slice(front(gSequence), gIndex), "abcdefgh") + -- test end + test::Success#() + return 0 diff --git a/FrontEnd/ConcreteSyntax/LangTest/enum_test.cw b/FrontEnd/ConcreteSyntax/LangTest/enum_test.cw new file mode 100644 index 00000000..7ba99739 --- /dev/null +++ b/FrontEnd/ConcreteSyntax/LangTest/enum_test.cw @@ -0,0 +1,72 @@ +module main: + +import test + +@pub enum enum8 u8: + e1 7 + e2 auto + e3 19 + e4 auto + +@pub enum enum16 u16: + e1 70 + e2 auto + e3 190 + e4 auto + +@pub enum enum32 u32: + e1 700 + e2 auto + e3 1900 + e4 auto + +-- GLOBAL +global! g1 = enum8:e1 + +global! g2 = enum16:e2 + +global! g3 = enum32:e3 + +@pub rec rec1: + -- this is a comment with \" with quotes \t + f1 s32 + f2 s32 + f3 s32 + f4 bool + f5 enum8 + f6 enum16 + f7 enum32 + f8 u64 + f9 u64 + +global! gr1 rec1 = undef + +@cdecl fun main(argc s32, argv ^^u8) s32: + -- LOCAL + let! v1 = enum8:e2 + let! v2 = enum16:e3 + let! v3 = enum32:e4 + test::AssertEq#(g1, enum8:e1) + test::AssertEq#(g2, enum16:e2) + test::AssertEq#(g3, enum32:e3) + set g1 = v1 + set g2 = v2 + set g3 = v3 + test::AssertEq#(g1, enum8:e2) + test::AssertEq#(g2, enum16:e3) + test::AssertEq#(g3, enum32:e4) + set v1 = enum8:e3 + set v2 = enum16:e4 + set v3 = enum32:e1 + test::AssertEq#(v1, enum8:e3) + test::AssertEq#(v2, enum16:e4) + test::AssertEq#(v3, enum32:e1) + set gr1.f5 = enum8:e3 + set gr1.f6 = enum16:e4 + set gr1.f7 = enum32:e1 + test::AssertEq#(gr1.f5, enum8:e3) + test::AssertEq#(gr1.f6, enum16:e4) + test::AssertEq#(gr1.f7, enum32:e1) + -- test end + test::Success#() + return 0 diff --git a/FrontEnd/ConcreteSyntax/LangTest/sum_tagged_test.cw b/FrontEnd/ConcreteSyntax/LangTest/sum_tagged_test.cw new file mode 100644 index 00000000..bb6817ed --- /dev/null +++ b/FrontEnd/ConcreteSyntax/LangTest/sum_tagged_test.cw @@ -0,0 +1,135 @@ +module main: + +import test + +@wrapped type t1 = s32 + +@wrapped type t2 = void + +@wrapped type t3 = void + +type type_ptr = ^!s32 + +type Union1 = union(s32, void, type_ptr) + +static_assert sizeof(Union1) == 16 + +type Union2 = union(s32, void, union(Union1, u8)) + +static_assert sizeof(Union2) == 16 + +type Union2Simplified = union(s32, void, u8, type_ptr) + +static_assert typeid(Union2) == typeid(Union2Simplified) + +type Union3 = union(bool, u8, s32, s64) + +static_assert sizeof(Union3) == 16 + +type Delta1 = uniondelta(Union3, union(bool, u8, s32)) + +static_assert sizeof(Delta1) == 8 + +static_assert typeid(Delta1) == typeid(s64) + +type Delta2 = uniondelta(Union3, union(bool, u8)) + +static_assert typeid(Delta2) == typeid(union(s32, s64)) + +type Delta3 = uniondelta(Union3, union(bool, u8, s64)) + +static_assert typeid(Delta3) == typeid(s32) + +@pub type Union5 = union(t2, t3, s8) + +static_assert sizeof(Union5) == 3 + +type Union6 = union(bool, u16) + +static_assert sizeof(Union6) == 4 + +type Union = union(bool, u64, u32, r32, r64, [32]u8) + +static_assert sizeof(Union) == 40 + +rec rec1: + s1 Union5 + s2 Union5 + +@pub rec rec2: + s1 Union1 + s2 Union2 + +global global_rec1 = rec1{1_s8, 2_s8} + +-- +-- @pub (type sum11_t (union [bool u16])) +-- @pub (type sum12_t (union [type_ptr u16])) +fun test_tagged_union_basic() void: + let! x Union3 = true + let! y Union3 = undef + let! z s32 = 777 + set y = x + test::AssertTrue#(is(x, bool)) + test::AssertFalse#(is(x, s32)) + test::AssertTrue#(is(y, bool)) + test::AssertFalse#(is(y, s32)) + set x = 777_s32 + set x = z + set y = x + test::AssertFalse#(is(x, bool)) + test::AssertTrue#(is(x, s32)) + test::AssertFalse#(is(y, bool)) + test::AssertTrue#(is(y, s32)) + test::AssertTrue#(y == 777_s32) + test::AssertTrue#(777_s32 == y) + +@pub type UnionVoid = union(void, t2, t3) + +fun test_tagged_union_void() void: + let! x UnionVoid = void + +fun fun_param(a bool, b bool, c s32, x Union3) void: + if a: + test::AssertTrue#(is(x, bool)) + else: + test::AssertTrue#(is(x, s32)) + +fun test_tagged_union_parameter() void: + let! x Union3 = true + shed fun_param(true, true, 0, x) + set x = 666_s32 + shed fun_param(false, true, 666, x) + +fun fun_result(a bool, b bool, c s32) Union3: + let! out Union3 = undef + if a: + set out = b + else: + set out = c + return out + +fun test_tagged_union_result() void: + let! x = fun_result(true, false, 2) + test::AssertTrue#(is(x, bool)) + test::AssertFalse#(is(x, s32)) + set x = fun_result(false, false, 2) + test::AssertFalse#(is(x, bool)) + test::AssertTrue#(is(x, s32)) + +fun test_tagged_union_narrowto() void: + let! x Union3 = true + let! y = narrowto(x, bool) + test::AssertTrue#(y) + test::AssertTrue#(narrowto(x, bool)) + let! z = narrowto(x, union(u8, bool)) + +@cdecl fun main(argc s32, argv ^^u8) s32: + shed test_tagged_union_basic() + shed test_tagged_union_void() + shed test_tagged_union_result() + shed test_tagged_union_parameter() + shed test_tagged_union_narrowto() + -- test end + test::Success#() + return 0 diff --git a/FrontEnd/ConcreteSyntax/LangTest/sum_untagged_test.cw b/FrontEnd/ConcreteSyntax/LangTest/sum_untagged_test.cw new file mode 100644 index 00000000..45f5952b --- /dev/null +++ b/FrontEnd/ConcreteSyntax/LangTest/sum_untagged_test.cw @@ -0,0 +1,127 @@ +-- union +module main: + +import test + +@wrapped type t1 = s32 + +@wrapped type t2 = void + +@wrapped type t3 = void + +type type_ptr = ^!s32 + +type UntaggedUnion1 = @untagged union(s32, void, type_ptr) + +static_assert sizeof(UntaggedUnion1) == 8 + +type UntaggedUnion2 = @untagged union( + s32, void, @untagged union(UntaggedUnion1, u8)) + +static_assert sizeof(UntaggedUnion2) == 8 + +type UntaggedUnion3 = @untagged union(bool, s32, s64) + +static_assert sizeof(UntaggedUnion2) == 8 + +type UntaggedUnion4 = @untagged union(bool, s32) + +static_assert sizeof(UntaggedUnion4) == 4 + +@pub type UntaggedUnion5 = @untagged union(t2, t3, s8) + +static_assert sizeof(UntaggedUnion5) == 1 + +type UntaggedUnion6 = @untagged union(bool, u16) + +static_assert sizeof(UntaggedUnion6) == 2 + +type UntaggedUnion = @untagged union(bool, u64, u32, r32, r64, [32]u8) + +type TaggedUnion = union(bool, u64, u32, r32, r64, [32]u8) + +static_assert sizeof(UntaggedUnion) == 32 + +rec RecordWithUntaggedUnion: + t1 bool + t2 u32 + t3 UntaggedUnion + t4 bool + +fun with_union_result(a bool, b u32, c r32) UntaggedUnion: + let! out UntaggedUnion = undef + if a: + set out = b + else: + set out = c + return out + +fun test_untagged_union() void: + -- straight up union + let! u1 UntaggedUnion + let! u2 UntaggedUnion = undef + let! u3 UntaggedUnion = 2.0_r32 + let! u4 UntaggedUnion = 777_u32 + let s1 u32 = narrowto(u3, u32) + test::AssertEq#(s1, 0x40000000_u32) + test::AssertEq#(narrowto(u3, [32]u8)[0], 0_u8) + test::AssertEq#(narrowto(u3, [32]u8)[1], 0_u8) + test::AssertEq#(narrowto(u3, [32]u8)[2], 0_u8) + test::AssertEq#(narrowto(u3, [32]u8)[3], 0x40_u8) + set narrowto(u3, [32]u8)[2] = 0x28_u8 + set narrowto(u3, [32]u8)[3] = 0x42_u8 + test::AssertEq#(narrowto(u3, u32), 0x42280000_u32) + test::AssertEq#(narrowto(u3, r32), 42_r32) + set u3 = 2.0_r64 + test::AssertEq#(narrowto(u3, u64), 0x4000000000000000_u64) + test::AssertEq#(narrowto(u3, [32]u8)[3], 0_u8) + test::AssertEq#(narrowto(u3, [32]u8)[7], 0x40_u8) + -- union embedded in record + let! rec1 RecordWithUntaggedUnion = undef + set rec1.t3 = 2.0_r32 + test::AssertEq#(narrowto(rec1.t3, u32), 0x40000000_u32) + test::AssertEq#(narrowto(rec1.t3, [32]u8)[0], 0_u8) + test::AssertEq#(narrowto(rec1.t3, [32]u8)[1], 0_u8) + test::AssertEq#(narrowto(rec1.t3, [32]u8)[2], 0_u8) + test::AssertEq#(narrowto(rec1.t3, [32]u8)[3], 0x40_u8) + -- union embedded in record 2 + let! rec2 = RecordWithUntaggedUnion{false, 0x12344321, 2.0_r32, true} + test::AssertEq#(rec2.t1, false) + test::AssertEq#(rec2.t2, 0x12344321_u32) + test::AssertEq#(narrowto(rec2.t3, u32), 0x40000000_u32) + test::AssertEq#(rec2.t4, true) + -- + set narrowto(rec1.t3, [32]u8)[2] = 0x28_u8 + set narrowto(rec1.t3, [32]u8)[3] = 0x42_u8 + test::AssertEq#(narrowto(rec1.t3, u32), 0x42280000_u32) + test::AssertEq#(narrowto(rec1.t3, r32), 42_r32) + set rec1.t3 = 2.0_r64 + test::AssertEq#(narrowto(rec1.t3, u64), 0x4000000000000000_u64) + test::AssertEq#(narrowto(rec1.t3, [32]u8)[3], 0_u8) + test::AssertEq#(narrowto(rec1.t3, [32]u8)[7], 0x40_u8) + -- array of union + let! array1 [16]UntaggedUnion = undef + set array1[13] = 2.0_r32 + test::AssertEq#(narrowto(array1[13], u32), 0x40000000_u32) + test::AssertEq#(narrowto(array1[13], [32]u8)[0], 0_u8) + test::AssertEq#(narrowto(array1[13], [32]u8)[1], 0_u8) + test::AssertEq#(narrowto(array1[13], [32]u8)[2], 0_u8) + test::AssertEq#(narrowto(array1[13], [32]u8)[3], 0x40_u8) + set narrowto(array1[13], [32]u8)[2] = 0x28_u8 + set narrowto(array1[13], [32]u8)[3] = 0x42_u8 + test::AssertEq#(narrowto(array1[13], u32), 0x42280000_u32) + test::AssertEq#(narrowto(array1[13], r32), 42_r32) + set u1 = with_union_result(true, 10, 2.0) + test::AssertEq#(narrowto(u1, u32), 10_u32) + set u1 = with_union_result(false, 10, 2.0) + test::AssertEq#(narrowto(u1, u32), 0x40000000_u32) + set array1[13] = 2.0_r64 + test::AssertEq#(narrowto(array1[13], u64), 0x4000000000000000_u64) + test::AssertEq#(narrowto(array1[13], [32]u8)[3], 0_u8) + test::AssertEq#(narrowto(array1[13], [32]u8)[7], 0x40_u8) + +@cdecl fun main(argc s32, argv ^^u8) s32: + shed test_untagged_union() + -- test end + test::Success#() + return 0