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
62
63
64
65
66
67
|
#include <stdio.h>
#include <string.h>
#include "parser/parser.h"
#include "codegen/nasm.h"
#include "tests.h"
static void test_generate_consts_and_data(struct TestContext* context)
{
struct Lexer lexer = create_lexer("const N = 5\ndata msg = \"hi\"\n");
struct Program program;
check(context, parse_program(&lexer, &program));
FILE* out = tmpfile();
generate_nasm(&program, out);
fflush(out);
rewind(out);
char buffer[1024];
size_t read = fread(buffer, 1, sizeof(buffer) - 1, out);
buffer[read] = '\0';
fclose(out);
check(context, strstr(buffer, "N equ 5") != NULL);
check(context, strstr(buffer, "section .data") != NULL);
check(context, strstr(buffer, "msg: db `hi`") != NULL);
check(context, strstr(buffer, ".len equ $ - msg") != NULL);
check(context, strstr(buffer, "section .text") != NULL);
check(context, strstr(buffer, "global _start") != NULL);
free_program(&program);
}
static void test_generate_text(struct TestContext* context)
{
struct Lexer lexer = create_lexer(
"proc main\n{\nrax = SYS_WRITE\nrsi = message\nrdx = message.len\n^rdi = rax\nloop:\nsyscall\ngoto loop\n}\n");
struct Program program;
check(context, parse_program(&lexer, &program));
FILE* out = tmpfile();
generate_nasm(&program, out);
fflush(out);
rewind(out);
char buffer[1024];
size_t read = fread(buffer, 1, sizeof(buffer) - 1, out);
buffer[read] = '\0';
fclose(out);
check(context, strstr(buffer, "_start:") != NULL);
check(context, strstr(buffer, "mov rax, SYS_WRITE") != NULL);
check(context, strstr(buffer, "mov rsi, message") != NULL);
check(context, strstr(buffer, "mov rdx, message.len") != NULL);
check(context, strstr(buffer, "mov [rdi], rax") != NULL);
check(context, strstr(buffer, "loop:") != NULL);
check(context, strstr(buffer, "syscall") != NULL);
check(context, strstr(buffer, "jmp loop") != NULL);
free_program(&program);
}
void run_codegen_tests(struct TestContext* context)
{
test_generate_consts_and_data(context);
test_generate_text(context);
}
|