aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-11-02 15:56:32 +0100
committerBad Diode <bd@badd10de.dev>2021-11-02 15:56:32 +0100
commitdca96d579fdf7eb747294fc786e89a08031fe003 (patch)
treec5da381075147ab88bdfb17497b6ad078bb1165e
parentfedab6bac08333ca31e69f21add7b66c575ec87c (diff)
downloadbdl-dca96d579fdf7eb747294fc786e89a08031fe003.tar.gz
bdl-dca96d579fdf7eb747294fc786e89a08031fe003.zip
Add `not` primitive procedure
-rw-r--r--src/compiler.h153
1 files changed, 93 insertions, 60 deletions
diff --git a/src/compiler.h b/src/compiler.h
index 18e8a3e..76aec85 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -9,6 +9,8 @@
9#define BOOL_MASK 3 9#define BOOL_MASK 3
10#define BOOL_TAG 3 10#define BOOL_TAG 3
11#define BOOL_SHIFT 2 11#define BOOL_SHIFT 2
12#define TRUE_VAL ((1 << BOOL_SHIFT) | BOOL_TAG)
13#define FALSE_VAL ((0 << BOOL_SHIFT) | BOOL_TAG)
12#define FIXNUM_MASK 1 14#define FIXNUM_MASK 1
13#define FIXNUM_TAG 0 15#define FIXNUM_TAG 0
14#define FIXNUM_SHIFT 1 16#define FIXNUM_SHIFT 1
@@ -69,47 +71,18 @@ typedef enum OpType {
69 OP_IS_ZERO, 71 OP_IS_ZERO,
70 OP_IS_BOOL, 72 OP_IS_BOOL,
71 OP_IS_FIXNUM, 73 OP_IS_FIXNUM,
72 // TODO: etc. 74 // Logic operations.
75 OP_NOT,
76 OP_AND,
77 OP_OR,
78 OP_EQUAL,
79 OP_GREATER,
80 OP_LESS,
81 OP_GREATER_EQ,
82 OP_LESS_EQL,
73} OpType; 83} OpType;
74 84
75void 85void
76arithmetic_op(OpType type) {
77 printf(" ;; --> arithmetic_op\n");
78 printf(" pop rcx\n");
79 printf(" pop rax\n");
80 switch (type) {
81 case OP_ADD: { printf(" add rax, rcx\n"); } break;
82 case OP_SUB: { printf(" sub rax, rcx\n"); } break;
83 case OP_MUL: {
84 printf(" sar rax, %d\n", FIXNUM_SHIFT);
85 printf(" sar rcx, %d\n", FIXNUM_SHIFT);
86 printf(" mul rcx\n");
87 printf(" sal rax, %d\n", FIXNUM_SHIFT);
88 } break;
89 case OP_DIV: {
90 printf(" sar rax, %d\n", FIXNUM_SHIFT);
91 printf(" sar rcx, %d\n", FIXNUM_SHIFT);
92 printf(" mov rdx, 0\n");
93 printf(" div rcx\n");
94 printf(" sal rax, %d\n", FIXNUM_SHIFT);
95 } break;
96 case OP_MOD: {
97 printf(" sar rax, %d\n", FIXNUM_SHIFT);
98 printf(" sar rcx, %d\n", FIXNUM_SHIFT);
99 printf(" mov rdx, 0\n");
100 printf(" div rcx\n");
101 printf(" mov rax, rdx\n");
102 printf(" sal rax, %d\n", FIXNUM_SHIFT);
103 } break;
104 default: break;
105 }
106 printf(" push rax\n");
107 printf(" ;; <-- arithmetic_op\n");
108}
109
110typedef void (CompileProc)(OpType, Object*);
111
112void
113compile_type_predicate(OpType op, Object* args) { 86compile_type_predicate(OpType op, Object* args) {
114 printf(" ;; --> compile_type_predicate\n"); 87 printf(" ;; --> compile_type_predicate\n");
115 compile_object(args->head); 88 compile_object(args->head);
@@ -143,19 +116,69 @@ compile_type_predicate(OpType op, Object* args) {
143// TODO: Next -> numerical comparison operators =, <=, ... 116// TODO: Next -> numerical comparison operators =, <=, ...
144// "=", "<", ">", "<=", ">=", 117// "=", "<", ">", "<=", ">=",
145// "not", "and", "or", 118// "not", "and", "or",
146// NOTE: Make sure to stop evaluating if the condition is not met. 119
120void
121compile_logic_list(OpType op, Object* args) {
122 printf(" ;; --> compile_logic_list\n");
123 compile_object(args->head);
124 do {
125 // TODO: Make sure to stop evaluating if the condition is not met.
126 args = args->tail;
127 printf(" pop rax\n");
128 switch (op) {
129 case OP_NOT: {
130 printf(" cmp rax, %d\n", FALSE_VAL);
131 printf(" mov rax, 0\n");
132 } break;
133 default: break;
134 }
135 printf(" sete al\n");
136 printf(" sal rax, %d\n", BOOL_SHIFT);
137 printf(" or rax, %d\n", BOOL_TAG);
138 printf(" push rax\n");
139 } while (args != NULL);
140 printf(" ;; <-- compile_logic_list\n");
141}
147 142
148void 143void
149compile_arithmetic_list(OpType op, Object* args) { 144compile_arithmetic_list(OpType op, Object* args) {
150 printf(" ;; --> compile_arithmetic_list\n"); 145 printf(" ;; --> compile_arithmetic\n");
151 compile_object(args->head); 146 compile_object(args->head);
152 args = args->tail; 147 args = args->tail;
153 while (args != NULL) { 148 while (args != NULL) {
154 compile_object(args->head); 149 compile_object(args->head);
155 args = args->tail; 150 args = args->tail;
156 arithmetic_op(op); 151 printf(" pop rcx\n");
152 printf(" pop rax\n");
153 switch (op) {
154 case OP_ADD: { printf(" add rax, rcx\n"); } break;
155 case OP_SUB: { printf(" sub rax, rcx\n"); } break;
156 case OP_MUL: {
157 printf(" sar rax, %d\n", FIXNUM_SHIFT);
158 printf(" sar rcx, %d\n", FIXNUM_SHIFT);
159 printf(" mul rcx\n");
160 printf(" sal rax, %d\n", FIXNUM_SHIFT);
161 } break;
162 case OP_DIV: {
163 printf(" sar rax, %d\n", FIXNUM_SHIFT);
164 printf(" sar rcx, %d\n", FIXNUM_SHIFT);
165 printf(" mov rdx, 0\n");
166 printf(" div rcx\n");
167 printf(" sal rax, %d\n", FIXNUM_SHIFT);
168 } break;
169 case OP_MOD: {
170 printf(" sar rax, %d\n", FIXNUM_SHIFT);
171 printf(" sar rcx, %d\n", FIXNUM_SHIFT);
172 printf(" mov rdx, 0\n");
173 printf(" div rcx\n");
174 printf(" mov rax, rdx\n");
175 printf(" sal rax, %d\n", FIXNUM_SHIFT);
176 } break;
177 default: break;
178 }
179 printf(" push rax\n");
157 } 180 }
158 printf(" ;; <-- compile_arithmetic_list\n"); 181 printf(" ;; <-- compile_arithmetic\n");
159} 182}
160 183
161void 184void
@@ -164,35 +187,45 @@ compile_proc_call(Object *obj) {
164 // initialized at the start of the compilation procedure. 187 // initialized at the start of the compilation procedure.
165 if (sv_equal(&obj->head->text, &STRING("+"))) { 188 if (sv_equal(&obj->head->text, &STRING("+"))) {
166 compile_arithmetic_list(OP_ADD, obj->tail); 189 compile_arithmetic_list(OP_ADD, obj->tail);
167 } 190 } else if (sv_equal(&obj->head->text, &STRING("-"))) {
168 if (sv_equal(&obj->head->text, &STRING("-"))) {
169 compile_arithmetic_list(OP_SUB, obj->tail); 191 compile_arithmetic_list(OP_SUB, obj->tail);
170 } 192 } else if (sv_equal(&obj->head->text, &STRING("*"))) {
171 if (sv_equal(&obj->head->text, &STRING("*"))) {
172 compile_arithmetic_list(OP_MUL, obj->tail); 193 compile_arithmetic_list(OP_MUL, obj->tail);
173 } 194 } else if (sv_equal(&obj->head->text, &STRING("/"))) {
174 if (sv_equal(&obj->head->text, &STRING("/"))) {
175 compile_arithmetic_list(OP_DIV, obj->tail); 195 compile_arithmetic_list(OP_DIV, obj->tail);
176 } 196 } else if (sv_equal(&obj->head->text, &STRING("%"))) {
177 if (sv_equal(&obj->head->text, &STRING("%"))) {
178 compile_arithmetic_list(OP_MOD, obj->tail); 197 compile_arithmetic_list(OP_MOD, obj->tail);
179 } 198 } else if (sv_equal(&obj->head->text, &STRING("nil?"))) {
180 if (sv_equal(&obj->head->text, &STRING("nil?"))) {
181 compile_type_predicate(OP_IS_NIL, obj->tail); 199 compile_type_predicate(OP_IS_NIL, obj->tail);
182 } 200 } else if (sv_equal(&obj->head->text, &STRING("zero?"))) {
183 if (sv_equal(&obj->head->text, &STRING("zero?"))) {
184 compile_type_predicate(OP_IS_ZERO, obj->tail); 201 compile_type_predicate(OP_IS_ZERO, obj->tail);
185 } 202 } else if (sv_equal(&obj->head->text, &STRING("fixnum?"))) {
186 if (sv_equal(&obj->head->text, &STRING("fixnum?"))) {
187 compile_type_predicate(OP_IS_FIXNUM, obj->tail); 203 compile_type_predicate(OP_IS_FIXNUM, obj->tail);
188 } 204 } else if (sv_equal(&obj->head->text, &STRING("bool?"))) {
189 if (sv_equal(&obj->head->text, &STRING("bool?"))) {
190 compile_type_predicate(OP_IS_BOOL, obj->tail); 205 compile_type_predicate(OP_IS_BOOL, obj->tail);
191 } 206 } else if (sv_equal(&obj->head->text, &STRING("display"))) {
192 if (sv_equal(&obj->head->text, &STRING("display"))) {
193 compile_object(obj->tail->head); 207 compile_object(obj->tail->head);
194 printf(" pop rdi\n"); 208 printf(" pop rdi\n");
195 printf(" call display\n"); 209 printf(" call display\n");
210 } else if (sv_equal(&obj->head->text, &STRING("not"))) {
211 compile_logic_list(OP_NOT, obj->tail);
212 } else if (sv_equal(&obj->head->text, &STRING("and"))) {
213 compile_logic_list(OP_AND, obj->tail);
214 } else if (sv_equal(&obj->head->text, &STRING("or"))) {
215 compile_logic_list(OP_OR, obj->tail);
216 } else if (sv_equal(&obj->head->text, &STRING("="))) {
217 compile_logic_list(OP_EQUAL, obj->tail);
218 } else if (sv_equal(&obj->head->text, &STRING(">"))) {
219 compile_logic_list(OP_GREATER, obj->tail);
220 } else if (sv_equal(&obj->head->text, &STRING("<"))) {
221 compile_logic_list(OP_LESS, obj->tail);
222 } else if (sv_equal(&obj->head->text, &STRING(">="))) {
223 compile_logic_list(OP_GREATER_EQ, obj->tail);
224 } else if (sv_equal(&obj->head->text, &STRING("<="))) {
225 compile_logic_list(OP_LESS_EQL, obj->tail);
226 } else {
227 fprintf(stderr, "error: not implemented\n");
228 exit(EXIT_FAILURE);
196 } 229 }
197} 230}
198 231