aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-11-02 16:55:17 +0100
committerBad Diode <bd@badd10de.dev>2021-11-02 16:55:17 +0100
commit58ffe8a7dbf57d5637e091083175028eb9614636 (patch)
tree7f636c32be8763ff244049819ca6678cff9fce7e
parentc1e253fbe7528038b00a6e7c17437846fc8cf568 (diff)
downloadbdl-58ffe8a7dbf57d5637e091083175028eb9614636.tar.gz
bdl-58ffe8a7dbf57d5637e091083175028eb9614636.zip
Add numerical comparison operations (binary only)
-rw-r--r--src/compiler.h68
1 files changed, 58 insertions, 10 deletions
diff --git a/src/compiler.h b/src/compiler.h
index a40fb1e..b703a99 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -79,7 +79,7 @@ typedef enum OpType {
79 OP_GREATER, 79 OP_GREATER,
80 OP_LESS, 80 OP_LESS,
81 OP_GREATER_EQ, 81 OP_GREATER_EQ,
82 OP_LESS_EQL, 82 OP_LESS_EQ,
83} OpType; 83} OpType;
84 84
85void 85void
@@ -112,10 +112,6 @@ compile_type_predicate(OpType op, Object* args) {
112 printf(" ;; <-- compile_type_predicate\n"); 112 printf(" ;; <-- compile_type_predicate\n");
113} 113}
114 114
115
116// TODO: Next -> numerical comparison operators
117// "=", "<", ">", "<=", ">=",
118
119void 115void
120compile_logic_list(OpType op, Object* args) { 116compile_logic_list(OpType op, Object* args) {
121 printf(" ;; --> compile_logic_list\n"); 117 printf(" ;; --> compile_logic_list\n");
@@ -163,6 +159,58 @@ compile_logic_list(OpType op, Object* args) {
163} 159}
164 160
165void 161void
162compile_cmp_list(OpType op, Object* args) {
163 printf(" ;; --> compile_cmp_list\n");
164 compile_object(args->head);
165
166 // TODO: Make sure to stop evaluating if the condition is not met.
167 // FIXME: Only working for two argument lists right now because we can't
168 // accumulate the bool and compare it with an int. We can fix it by passing
169 // two values on the stack (previous value and current result) or by only
170 // passing a previous value and having a conditional jump (need labels for
171 // that).
172 args = args->tail;
173 while (args != NULL) {
174 compile_object(args->head);
175 args = args->tail;
176
177 // Current value.
178 printf(" pop rcx\n");
179 printf(" sar rcx, %d\n", FIXNUM_SHIFT);
180
181 // Previous value.
182 printf(" pop rax\n");
183 printf(" sar rax, %d\n", FIXNUM_SHIFT);
184
185 printf(" cmp rax, rcx\n");
186 printf(" mov rax, 0\n");
187
188 switch (op) {
189 case OP_EQUAL: {
190 printf(" sete al\n");
191 } break;
192 case OP_GREATER: {
193 printf(" setg al\n");
194 } break;
195 case OP_LESS: {
196 printf(" setl al\n");
197 } break;
198 case OP_GREATER_EQ: {
199 printf(" setge al\n");
200 } break;
201 case OP_LESS_EQ: {
202 printf(" setle al\n");
203 } break;
204 default: break;
205 }
206 printf(" shl rax, %d\n", BOOL_SHIFT);
207 printf(" or rax, %d\n", BOOL_TAG);
208 printf(" push rax\n");
209 }
210 printf(" ;; <-- compile_cmp_list\n");
211}
212
213void
166compile_arithmetic_list(OpType op, Object* args) { 214compile_arithmetic_list(OpType op, Object* args) {
167 printf(" ;; --> compile_arithmetic\n"); 215 printf(" ;; --> compile_arithmetic\n");
168 compile_object(args->head); 216 compile_object(args->head);
@@ -236,15 +284,15 @@ compile_proc_call(Object *obj) {
236 } else if (sv_equal(&obj->head->text, &STRING("or"))) { 284 } else if (sv_equal(&obj->head->text, &STRING("or"))) {
237 compile_logic_list(OP_OR, obj->tail); 285 compile_logic_list(OP_OR, obj->tail);
238 } else if (sv_equal(&obj->head->text, &STRING("="))) { 286 } else if (sv_equal(&obj->head->text, &STRING("="))) {
239 compile_logic_list(OP_EQUAL, obj->tail); 287 compile_cmp_list(OP_EQUAL, obj->tail);
240 } else if (sv_equal(&obj->head->text, &STRING(">"))) { 288 } else if (sv_equal(&obj->head->text, &STRING(">"))) {
241 compile_logic_list(OP_GREATER, obj->tail); 289 compile_cmp_list(OP_GREATER, obj->tail);
242 } else if (sv_equal(&obj->head->text, &STRING("<"))) { 290 } else if (sv_equal(&obj->head->text, &STRING("<"))) {
243 compile_logic_list(OP_LESS, obj->tail); 291 compile_cmp_list(OP_LESS, obj->tail);
244 } else if (sv_equal(&obj->head->text, &STRING(">="))) { 292 } else if (sv_equal(&obj->head->text, &STRING(">="))) {
245 compile_logic_list(OP_GREATER_EQ, obj->tail); 293 compile_cmp_list(OP_GREATER_EQ, obj->tail);
246 } else if (sv_equal(&obj->head->text, &STRING("<="))) { 294 } else if (sv_equal(&obj->head->text, &STRING("<="))) {
247 compile_logic_list(OP_LESS_EQL, obj->tail); 295 compile_cmp_list(OP_LESS_EQ, obj->tail);
248 } else { 296 } else {
249 fprintf(stderr, "error: not implemented\n"); 297 fprintf(stderr, "error: not implemented\n");
250 exit(EXIT_FAILURE); 298 exit(EXIT_FAILURE);