blob: b7d3805e7a5dea89f733fddab545be9a4d7ebf41 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
#include <stdbool.h>
#include "parser/parser.h"
#include "sema/sema.h"
#include "tests.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;
}
bool ok = analyze_program(&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"));
}
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);
}
|