diff options
| author | hachem <im@hachem.wtf> | 2026-10-12 11:41:05 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-10-12 11:41:05 +0200 |
| commit | 62636576bce8e8121a3d70f63547fae40a52f697 (patch) | |
| tree | 077dfe4f04235cce63b7abb1b05bb539232ae74a /tests/sema_test.c | |
| parent | c0f000ea166a24781fcdbf23c080b203cd9b8ed7 (diff) | |
chore: refactor
Diffstat (limited to 'tests/sema_test.c')
| -rw-r--r-- | tests/sema_test.c | 166 |
1 files changed, 0 insertions, 166 deletions
diff --git a/tests/sema_test.c b/tests/sema_test.c deleted file mode 100644 index 3c12001..0000000 --- a/tests/sema_test.c +++ /dev/null @@ -1,166 +0,0 @@ -#include <stdbool.h> - -#include "sema.h" -#include "tests.h" -#include "parser.h" - -static bool analyze_source(const char* source) -{ - struct Lexer lexer = create_lexer(source); - struct Program program; - if (!parse_program(&lexer, &program)) - { - free_program(&program); - return false; - } - - struct Source diagnostics = { "<test>", source }; - bool ok = analyze_program(diagnostics, &program); - free_program(&program); - return ok; -} - -static void test_valid_program(struct TestContext* context) -{ - check(context, analyze_source("const N = 1\ndata msg = \"hi\"\nproc main\n{\nsyscall\n}\n")); -} - -static void test_no_entry_is_ok(struct TestContext* context) -{ - // without an [entry: ...] directive there is no required entry point - check(context, analyze_source("proc helper\n{\nsyscall\n}\n")); -} - -static void test_defined_entry(struct TestContext* context) -{ - check(context, analyze_source("[entry: start]\nproc start\n{\nsyscall\n}\n")); -} - -static void test_undefined_entry(struct TestContext* context) -{ - check(context, !analyze_source("[entry: main]\nproc helper\n{\nsyscall\n}\n")); -} - -static void test_duplicate_const(struct TestContext* context) -{ - check(context, !analyze_source("const X = 1\nconst X = 2\nproc main\n{\nsyscall\n}\n")); -} - -static void test_duplicate_across_kinds(struct TestContext* context) -{ - check(context, !analyze_source("data foo = \"a\"\nproc foo\n{\nsyscall\n}\nproc main\n{\nsyscall\n}\n")); -} - -static void test_undefined_name(struct TestContext* context) -{ - check(context, !analyze_source("proc main\n{\nrax = MISSING\n}\n")); -} - -static void test_undefined_label(struct TestContext* context) -{ - check(context, !analyze_source("proc main\n{\ngoto nowhere\n}\n")); -} - -static void test_undefined_call(struct TestContext* context) -{ - check(context, !analyze_source("proc main\n{\nnope(rax)\n}\n")); -} - -static void test_call_arg_count(struct TestContext* context) -{ - check(context, !analyze_source("proc f(a: rdi)\n{\nsyscall\n}\nproc main\n{\nf(rax, rbx)\n}\n")); -} - -static void test_assign_to_const(struct TestContext* context) -{ - check(context, !analyze_source("const K = 5\nproc main\n{\nK = 1\n}\n")); -} - -static void test_const_expr_ok(struct TestContext* context) -{ - check(context, analyze_source("const A = 1\nconst B = A + 2 * 3\nproc main\n{\nsyscall\n}\n")); -} - -static void test_const_expr_rejects_register(struct TestContext* context) -{ - check(context, !analyze_source("const X = rax + 1\nproc main\n{\nsyscall\n}\n")); -} - -static void test_const_expr_rejects_data(struct TestContext* context) -{ - check(context, !analyze_source("data d = \"x\"\nconst X = d\nproc main\n{\nsyscall\n}\n")); -} - -static void test_deref_needs_register(struct TestContext* context) -{ - check(context, !analyze_source("proc main\n{\nrax = ^MISSING\n}\n")); - check(context, analyze_source("proc main\n{\nrax = ^rsi\n}\n")); -} - -static void test_signed_load_needs_size(struct TestContext* context) -{ - check(context, analyze_source("proc main\n{\nrax = ^signed byte rsi\n}\n")); - check(context, !analyze_source("proc main\n{\nrax = ^signed rsi\n}\n")); - check(context, !analyze_source("proc main\n{\nrax = ^signed qword rsi\n}\n")); -} - -static void test_stack_size_constant(struct TestContext* context) -{ - check(context, analyze_source( - "struct P\n{\nx\ny\n}\nconst N = 4\n" - "proc main\n{\nstack a[P.size]\nstack b[N * 2]\nsyscall\n}\n")); - check(context, !analyze_source("proc main\n{\nstack a[rax]\n}\n")); -} - -static void test_enum_struct_members(struct TestContext* context) -{ - check(context, analyze_source( - "enum Color\n{\nRed,\nGreen\n}\nstruct Point\n{\nx\ny\n}\n" - "proc main\n{\nrax = Color.Green\nrbx = Point.y\nrcx = Point.size\n}\n")); - check(context, !analyze_source( - "enum Color\n{\nRed\n}\nproc main\n{\nrax = Color.Nope\n}\n")); - check(context, !analyze_source( - "struct Point\n{\nx\n}\nproc main\n{\nrax = Point.z\n}\n")); -} - -static void test_references_resolve(struct TestContext* context) -{ - // registers, params, consts, data (+ .len), stack buffers, labels, calls - check(context, analyze_source( - "const N = 1\n" - "data msg = \"hi\"\n" - "proc helper(value: rdi)\n{\nrax = value\n}\n" - "proc main\n{\n" - "stack buf[8]\n" - "rax = N\n" - "rsi = msg\n" - "rdx = msg.len\n" - "rdi = buf + 1\n" - "helper(rax)\n" - "loop:\n" - "goto loop\n" - "}\n")); -} - -void run_sema_tests(struct TestContext* context) -{ - test_valid_program(context); - test_no_entry_is_ok(context); - test_defined_entry(context); - test_undefined_entry(context); - test_duplicate_const(context); - test_duplicate_across_kinds(context); - test_undefined_name(context); - test_undefined_label(context); - test_undefined_call(context); - test_call_arg_count(context); - test_assign_to_const(context); - test_const_expr_ok(context); - test_const_expr_rejects_register(context); - test_const_expr_rejects_data(context); - test_deref_needs_register(context); - test_signed_load_needs_size(context); - test_stack_size_constant(context); - test_enum_struct_members(context); - test_references_resolve(context); -} |
