diff options
| author | 2026-02-23 20:36:05 +0100 | |
|---|---|---|
| committer | 2026-02-23 20:36:05 +0100 | |
| commit | 052144cabb126efe925a96f8a0597a0f2005d206 (patch) | |
| tree | 4fd87244b9eef018b30e90fdff24c5b1a145a85e /test/external/metalang99/tests/gen.c | |
| parent | 4e9020dfb847d80475415f9f5914efaa50238767 (diff) | |
add metalang99 testsuite (preprocessor stress testing)
Diffstat (limited to 'test/external/metalang99/tests/gen.c')
| -rw-r--r-- | test/external/metalang99/tests/gen.c | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/test/external/metalang99/tests/gen.c b/test/external/metalang99/tests/gen.c new file mode 100644 index 0000000..bb1e163 --- /dev/null +++ b/test/external/metalang99/tests/gen.c @@ -0,0 +1,283 @@ +#include <metalang99/assert.h> +#include <metalang99/gen.h> +#include <metalang99/ident.h> +#include <metalang99/list.h> +#include <metalang99/tuple.h> + +#include <assert.h> + +// clang-format off +static void + test_indexed_params ML99_EVAL(ML99_indexedParams(ML99_list(v(int, long long, const char *)))) +// clang-format on +{ + int i = _0; + long long ll = _1; + const char *str = _2; + + (void)i; + (void)ll; + (void)str; +} + +static int test_fn_ptr(const char *str, long long x) { + (void)str; + (void)x; + return 123; +} + +int main(void) { + + // ML99_braced + { struct TestBraced ML99_EVAL(ML99_braced(v(int a, b, c;))); } + + // ML99_semicoloned + { + ML99_EVAL(ML99_semicoloned(v(struct TestSemicoloned { int a, b, c; }))); + } + + // ML99_assign(Stmt) + { + int x = 0; + + ML99_EVAL(ML99_assign(v(x), v(5))); + assert(5 == x); + + ML99_EVAL(ML99_assignStmt(v(x), v(7))) + assert(7 == x); + } + + // ML99_assignInitializerList(Stmt) + { + typedef struct { + int x, y; + } Point; + + ML99_EVAL(ML99_assignInitializerList(v(Point p1), v(.x = 2, .y = 3))); + assert(2 == p1.x); + assert(3 == p1.y); + + ML99_EVAL(ML99_assignInitializerListStmt(v(Point p2), v(.x = 5, .y = 7))) + assert(5 == p2.x); + assert(7 == p2.y); + } + +#define F(a, b, c) ML99_ASSERT_UNEVAL(a == 1 && b == 2 && c == 3) + + // ML99_invoke(Stmt) + { + ML99_EVAL(ML99_invoke(v(F), v(1, 2, 3))); + ML99_EVAL(ML99_invokeStmt(v(F), v(1, 2, 3))) + } + +#undef F + + // ML99_prefixedBlock + { + + ML99_EVAL(ML99_prefixedBlock(v(if (1)), v(goto end_prefixed_block;))) + + // Unreachable code. + assert(0); + + end_prefixed_block:; + } + + // ML99_typedef + { + + ML99_EVAL(ML99_typedef(v(Point), v(struct { int x, y; }))); + + Point point = {5, 7}; + point.x = 1; + point.y = 2; + + (void)point; + } + + // ML99_struct + { + + ML99_EVAL(ML99_struct(v(Point), v(int x, y;))); + + struct Point point = {5, 7}; + point.x = 1; + point.y = 2; + + (void)point; + } + + // ML99_anonStruct + { + typedef ML99_EVAL(ML99_anonStruct(v(int x, y;))) + Point; + + Point point = {5, 7}; + point.x = 1; + point.y = 2; + + (void)point; + } + + // ML99_union + { + ML99_EVAL(ML99_union(v(Point), v(int x, y;))); + + union Point point; + point.x = 1; + point.y = 2; + + (void)point; + } + + // ML99_anonUnion + { + typedef ML99_EVAL(ML99_anonUnion(v(int x, y;))) + Point; + + Point point; + point.x = 1; + point.y = 2; + + (void)point; + } + + // ML99_enum + { + ML99_EVAL(ML99_enum(v(MyEnum), v(Foo, Bar))); + + enum MyEnum foo = Foo, bar = Bar; + (void)foo; + (void)bar; + } + + // ML99_anonEnum + { + typedef ML99_EVAL(ML99_anonEnum(v(Foo, Bar))) + MyEnum; + + MyEnum foo = Foo, bar = Bar; + (void)foo; + (void)bar; + } + + // ML99_fnPtr(Stmt) + { + { + ML99_EVAL(ML99_fnPtr(v(int), v(ptr), v(const char *str), v(long long x))) + = test_fn_ptr; + assert(test_fn_ptr == ptr); + } + + { + ML99_EVAL(ML99_fnPtrStmt(v(int), v(ptr), v(const char *str), v(long long x))) + ptr = test_fn_ptr; + (void)ptr; + } + } + +#define CHECK_EXPAND(args) CHECK(args) + +#define CHECK(_, x, y, z) ML99_ASSERT_UNEVAL(x == 0 && y == 1 && z == 2) +#define F_IMPL(x) v(, x) +#define F_ARITY 1 + + // ML99_repeat + { CHECK_EXPAND(ML99_EVAL(ML99_repeat(v(3), v(F)))); } + +#undef CHECK +#undef F_IMPL +#undef F_ARITY + +#define CHECK(_, x, y, z) ML99_ASSERT_UNEVAL(x == 5 && y == 5 && z == 5) + + // ML99_times + { CHECK_EXPAND(ML99_EVAL(ML99_times(v(3), v(, 5)))); } + +#undef CHECK + +#undef CHECK_EXPAND + + // ML99_indexedParams + { + ML99_ASSERT_UNEVAL(ML99_IDENT_EQ( + ML99_C_KEYWORD_DETECTOR, + void, + ML99_EVAL(ML99_untuple(ML99_indexedParams(ML99_nil()))))); + + (void)test_indexed_params; + } + + // ML99_indexedFields + { + ML99_ASSERT_EMPTY(ML99_indexedFields(ML99_nil())); + + struct { + ML99_EVAL(ML99_indexedFields(ML99_list(v(int, long long, const char *)))) + } data = {0}; + + int i = data._0; + long long ll = data._1; + const char *str = data._2; + + (void)i; + (void)ll; + (void)str; + } + + // clang-format off + + // ML99_indexedInitializerList + { + // When N=0. + { + const struct { + int _0; + long long _1; + const char *_2; + } test = ML99_EVAL(ML99_indexedInitializerList(v(0))); + + assert(0 == test._0); + assert(0 == test._1); + assert(0 == test._2); + } + + // When N>0. + { + int _0 = 123; + long long _1 = 149494456; + const char *_2 = "abc"; + + struct { + int i; + long long ll; + const char *str; + } data = ML99_EVAL(ML99_indexedInitializerList(v(3))); + + (void)data; + } + } + + // ML99_indexedArgs + { + ML99_ASSERT_EMPTY(ML99_indexedArgs(v(0))); + + int _0 = 123; + long long _1 = 149494456; + const char *_2 = "abc"; + + const struct { + int i; + long long ll; + const char *str; + } test = { ML99_EVAL(ML99_indexedArgs(v(3))) }; + + assert(test.i == _0); + assert(test.ll == _1); + assert(test.str == _2); + } + + // clang-format on + + return 0; +} |