diff options
author | Bad Diode <bd@badd10de.dev> | 2021-11-01 14:30:30 +0100 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-11-01 14:30:30 +0100 |
commit | 7418a5042471a3a7f05283d36e45b6b422d9785b (patch) | |
tree | 1a041c75f8c30c0ef9adf0d14bf046344b06dc60 /src/compiler.h | |
parent | e64cb7e315961d3f7772b42c2170acc2bd500a69 (diff) | |
download | bdl-7418a5042471a3a7f05283d36e45b6b422d9785b.tar.gz bdl-7418a5042471a3a7f05283d36e45b6b422d9785b.zip |
Add x86_64 compilation for arithmetic expressionsv0.10
Diffstat (limited to 'src/compiler.h')
-rw-r--r-- | src/compiler.h | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/compiler.h b/src/compiler.h new file mode 100644 index 0000000..3fed075 --- /dev/null +++ b/src/compiler.h | |||
@@ -0,0 +1,115 @@ | |||
1 | #ifndef BDL_COMPILER_H | ||
2 | #define BDL_COMPILER_H | ||
3 | |||
4 | |||
5 | #define PRELUDE_FILE "src/x86_64/prelude.asm" | ||
6 | #define POSTLUDE_FILE "src/x86_64/postlude.asm" | ||
7 | |||
8 | void compile_object(Object *obj); | ||
9 | void compile_fixnum(Object *obj); | ||
10 | void compile_proc_call(Object *obj); | ||
11 | void compile(Root *roots); | ||
12 | |||
13 | void | ||
14 | emit_file(char *file_name) { | ||
15 | FILE *file = fopen(file_name, "r"); | ||
16 | if (!file) { | ||
17 | fprintf(stderr, "error: couldn't open input file: %s\n", file_name); | ||
18 | exit(EXIT_FAILURE); | ||
19 | } | ||
20 | char buf[1024]; | ||
21 | size_t n = 0; | ||
22 | while ((n = fread(&buf, 1, 1024, file)) > 0) { | ||
23 | fwrite(buf, 1, n, stdout); | ||
24 | } | ||
25 | } | ||
26 | |||
27 | void | ||
28 | compile_fixnum(Object *obj) { | ||
29 | printf(" ;; -- compile_fixnum --\n"); | ||
30 | printf(" mov rax, %ld\n", obj->fixnum); | ||
31 | printf(" push rax\n"); | ||
32 | printf(" ;; --------------------\n"); | ||
33 | } | ||
34 | |||
35 | typedef enum OpType { | ||
36 | OP_ADD, | ||
37 | OP_SUB, | ||
38 | OP_MUL, | ||
39 | OP_DIV, | ||
40 | OP_MOD, | ||
41 | } OpType; | ||
42 | |||
43 | void | ||
44 | arithmetic_op(OpType type) { | ||
45 | printf(" ;; -- arithmetic_op --\n"); | ||
46 | printf(" pop rcx\n"); | ||
47 | printf(" pop rax\n"); | ||
48 | switch (type) { | ||
49 | case OP_ADD: { | ||
50 | printf(" add rax, rcx\n"); | ||
51 | } break; | ||
52 | case OP_SUB: { | ||
53 | printf(" sub rax, rcx\n"); | ||
54 | } break; | ||
55 | case OP_MUL: { | ||
56 | printf(" mul rcx\n"); | ||
57 | } break; | ||
58 | case OP_DIV: { | ||
59 | printf(" mov rdx, 0\n"); | ||
60 | printf(" div rcx\n"); | ||
61 | } break; | ||
62 | case OP_MOD: { | ||
63 | printf(" mov rdx, 0\n"); | ||
64 | printf(" div rcx\n"); | ||
65 | printf(" mov rax, rdx\n"); | ||
66 | } break; | ||
67 | } | ||
68 | printf(" push rax\n"); | ||
69 | printf(" ;; -------------------\n"); | ||
70 | } | ||
71 | |||
72 | void | ||
73 | compile_proc_call(Object *obj) { | ||
74 | printf(" ;; -- compile_proc_call --\n"); | ||
75 | OpType op; | ||
76 | if (sv_equal(&obj->head->text, &STRING("+"))) { op = OP_ADD;} | ||
77 | if (sv_equal(&obj->head->text, &STRING("-"))) { op = OP_SUB;} | ||
78 | if (sv_equal(&obj->head->text, &STRING("*"))) { op = OP_MUL;} | ||
79 | if (sv_equal(&obj->head->text, &STRING("/"))) { op = OP_DIV;} | ||
80 | if (sv_equal(&obj->head->text, &STRING("%"))) { op = OP_MOD;} | ||
81 | // TODO: Resolve function call. | ||
82 | Object *args = obj->tail; | ||
83 | // TODO: capture first operand in the accumulator. Number of arguments | ||
84 | // checking should have been handled in the parser. | ||
85 | compile_object(args->head); | ||
86 | args = args->tail; | ||
87 | while (args != NULL) { | ||
88 | compile_object(args->head); | ||
89 | args = args->tail; | ||
90 | arithmetic_op(op); | ||
91 | } | ||
92 | printf(" ;; -----------------------\n"); | ||
93 | } | ||
94 | |||
95 | void | ||
96 | compile_object(Object *obj) { | ||
97 | switch (obj->type) { | ||
98 | case OBJ_TYPE_FIXNUM: { compile_fixnum(obj); } break; | ||
99 | case OBJ_TYPE_PAIR: { compile_proc_call(obj); } break; | ||
100 | default: break; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | void | ||
105 | compile(Root *roots) { | ||
106 | emit_file(PRELUDE_FILE); | ||
107 | for (size_t i = 0; i < array_size(roots); i++) { | ||
108 | Object *root = roots[i]; | ||
109 | compile_object(root); | ||
110 | // OBJ_PRINT(root); | ||
111 | } | ||
112 | emit_file(POSTLUDE_FILE); | ||
113 | } | ||
114 | |||
115 | #endif // BDL_COMPILER_H | ||