diff options
-rw-r--r-- | src/compiler.h | 68 |
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 | ||
85 | void | 85 | void |
@@ -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 | |||
119 | void | 115 | void |
120 | compile_logic_list(OpType op, Object* args) { | 116 | compile_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 | ||
165 | void | 161 | void |
162 | compile_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 | |||
213 | void | ||
166 | compile_arithmetic_list(OpType op, Object* args) { | 214 | compile_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); |