aboutsummaryrefslogtreecommitdiffstats
path: root/src/compiler.h
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-11-01 14:30:30 +0100
committerBad Diode <bd@badd10de.dev>2021-11-01 14:30:30 +0100
commit7418a5042471a3a7f05283d36e45b6b422d9785b (patch)
tree1a041c75f8c30c0ef9adf0d14bf046344b06dc60 /src/compiler.h
parente64cb7e315961d3f7772b42c2170acc2bd500a69 (diff)
downloadbdl-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.h115
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
8void compile_object(Object *obj);
9void compile_fixnum(Object *obj);
10void compile_proc_call(Object *obj);
11void compile(Root *roots);
12
13void
14emit_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
27void
28compile_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
35typedef enum OpType {
36 OP_ADD,
37 OP_SUB,
38 OP_MUL,
39 OP_DIV,
40 OP_MOD,
41} OpType;
42
43void
44arithmetic_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
72void
73compile_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
95void
96compile_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
104void
105compile(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