aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-11-03 14:51:42 +0100
committerBad Diode <bd@badd10de.dev>2021-11-03 14:51:42 +0100
commit889e34d0ca986f03de77dfa383c12f4980e746ee (patch)
tree2c070bdae851fedcefc1b748f48d4accce2ece50
parent4e59245e506055e4e355c419de638cdc8a485c42 (diff)
downloadbdl-889e34d0ca986f03de77dfa383c12f4980e746ee.tar.gz
bdl-889e34d0ca986f03de77dfa383c12f4980e746ee.zip
Fix behaviour of logic comparisons
-rw-r--r--src/compiler.h96
1 files changed, 55 insertions, 41 deletions
diff --git a/src/compiler.h b/src/compiler.h
index 441b665..e511b7c 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -26,10 +26,11 @@ generate_label(void) {
26 // for freeing the memory. 26 // for freeing the memory.
27 static size_t label_counter = 0; 27 static size_t label_counter = 0;
28 char buf[32]; 28 char buf[32];
29 memset(buf, 0, 32);
30 sprintf(buf, ".BDLL%ld", label_counter++); 29 sprintf(buf, ".BDLL%ld", label_counter++);
31 char * ret = malloc(strlen(buf)); 30 size_t len = strlen(buf);
32 memcpy(ret, buf, strlen(buf)); 31 char * ret = malloc(len + 1);
32 memcpy(ret, buf, len);
33 ret[len] = 0;
33 return ret; 34 return ret;
34} 35}
35 36
@@ -85,9 +86,6 @@ typedef enum OpType {
85 OP_IS_BOOL, 86 OP_IS_BOOL,
86 OP_IS_FIXNUM, 87 OP_IS_FIXNUM,
87 // Logic operations. 88 // Logic operations.
88 OP_NOT,
89 OP_AND,
90 OP_OR,
91 OP_EQUAL, 89 OP_EQUAL,
92 OP_GREATER, 90 OP_GREATER,
93 OP_LESS, 91 OP_LESS,
@@ -126,49 +124,65 @@ compile_type_predicate(OpType op, Object* args) {
126} 124}
127 125
128void 126void
129compile_logic_list(OpType op, Object* args) { 127compile_not(Object* args) {
130 printf(" ;; --> compile_logic_list\n"); 128 printf(" ;; --> compile_not\n");
131 compile_object(args->head); 129 compile_object(args->head);
132 if (op == OP_NOT) { 130 printf(" pop rax\n");
131 printf(" cmp rax, %d\n", FALSE_VAL);
132 printf(" mov rax, 0\n");
133 printf(" sete al\n");
134 printf(" shl rax, %d\n", BOOL_SHIFT);
135 printf(" or rax, %d\n", BOOL_TAG);
136 printf(" push rax\n");
137 printf(" ;; <-- compile_not\n");
138}
139
140void
141compile_and(Object *args) {
142 printf(" ;; --> compile_and\n");
143 char *lab_false = generate_label();
144 char *lab_exit = generate_label();
145 while (args != NULL) {
146 compile_object(args->head);
147 args = args->tail;
133 printf(" pop rax\n"); 148 printf(" pop rax\n");
134 printf(" cmp rax, %d\n", FALSE_VAL); 149 printf(" cmp rax, %d\n", FALSE_VAL);
135 printf(" mov rax, 0\n"); 150 printf(" je %s\n", lab_false);
136 printf(" sete al\n");
137 printf(" shl rax, %d\n", BOOL_SHIFT);
138 printf(" or rax, %d\n", BOOL_TAG);
139 printf(" push rax\n");
140 printf(" ;; <-- compile_logic_list\n");
141 return;
142 } 151 }
152 printf(" mov rax, %d\n", TRUE_VAL);
153 printf(" push rax\n");
154 printf(" jmp %s\n", lab_exit);
155 printf("%s:\n", lab_false);
156 printf(" mov rax, %d\n", FALSE_VAL);
157 printf(" push rax\n");
158 printf("%s:\n", lab_exit);
159 free(lab_false);
160 free(lab_exit);
161 printf(" ;; <-- compile_and\n");
162}
143 163
144 // TODO: Make sure to stop evaluating if the condition is not met. 164void
145 args = args->tail; 165compile_or(Object *args) {
166 printf(" ;; --> compile_or\n");
167 char *lab_true = generate_label();
168 char *lab_exit = generate_label();
146 while (args != NULL) { 169 while (args != NULL) {
147 compile_object(args->head); 170 compile_object(args->head);
148 args = args->tail; 171 args = args->tail;
149
150 // Current value.
151 printf(" pop rcx\n");
152 printf(" cmp rcx, %d\n", FALSE_VAL);
153 printf(" mov rcx, 0\n");
154 printf(" setne cl\n");
155
156 // Previous value.
157 printf(" pop rax\n"); 172 printf(" pop rax\n");
158 printf(" cmp rax, %d\n", FALSE_VAL); 173 printf(" cmp rax, %d\n", FALSE_VAL);
159 printf(" mov rax, 0\n"); 174 printf(" jne %s\n", lab_true);
160 printf(" setne al\n");
161
162 switch (op) {
163 case OP_AND: { printf(" and al, cl\n"); } break;
164 case OP_OR: { printf(" or al, cl\n"); } break;
165 default: break;
166 }
167 printf(" shl rax, %d\n", BOOL_SHIFT);
168 printf(" or rax, %d\n", BOOL_TAG);
169 printf(" push rax\n");
170 } 175 }
171 printf(" ;; <-- compile_logic_list\n"); 176 printf(" mov rax, %d\n", FALSE_VAL);
177 printf(" push rax\n");
178 printf(" jmp %s\n", lab_exit);
179 printf("%s:\n", lab_true);
180 printf(" mov rax, %d\n", TRUE_VAL);
181 printf(" push rax\n");
182 printf("%s:\n", lab_exit);
183 free(lab_true);
184 free(lab_exit);
185 printf(" ;; <-- compile_or\n");
172} 186}
173 187
174void 188void
@@ -291,11 +305,11 @@ compile_proc_call(Object *obj) {
291 printf(" pop rdi\n"); 305 printf(" pop rdi\n");
292 printf(" call display\n"); 306 printf(" call display\n");
293 } else if (sv_equal(&obj->head->text, &STRING("not"))) { 307 } else if (sv_equal(&obj->head->text, &STRING("not"))) {
294 compile_logic_list(OP_NOT, obj->tail); 308 compile_not(obj->tail);
295 } else if (sv_equal(&obj->head->text, &STRING("and"))) { 309 } else if (sv_equal(&obj->head->text, &STRING("and"))) {
296 compile_logic_list(OP_AND, obj->tail); 310 compile_and(obj->tail);
297 } else if (sv_equal(&obj->head->text, &STRING("or"))) { 311 } else if (sv_equal(&obj->head->text, &STRING("or"))) {
298 compile_logic_list(OP_OR, obj->tail); 312 compile_or(obj->tail);
299 } else if (sv_equal(&obj->head->text, &STRING("="))) { 313 } else if (sv_equal(&obj->head->text, &STRING("="))) {
300 compile_cmp_list(OP_EQUAL, obj->tail); 314 compile_cmp_list(OP_EQUAL, obj->tail);
301 } else if (sv_equal(&obj->head->text, &STRING(">"))) { 315 } else if (sv_equal(&obj->head->text, &STRING(">"))) {