diff options
author | Bad Diode <bd@badd10de.dev> | 2021-11-04 11:58:53 +0100 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-11-04 11:58:53 +0100 |
commit | 7cbef14e8393475b1e569fdbfff2c46db859d43f (patch) | |
tree | c7a25a997fae700f5f7a952a9550d6ee74bea240 /src/compiler.h | |
parent | 84c2bf292ddcb91543715951805ebc2335c46567 (diff) | |
download | bdl-7cbef14e8393475b1e569fdbfff2c46db859d43f.tar.gz bdl-7cbef14e8393475b1e569fdbfff2c46db859d43f.zip |
Add `cons`, `car` and `cdr` primitives
Diffstat (limited to 'src/compiler.h')
-rw-r--r-- | src/compiler.h | 72 |
1 files changed, 65 insertions, 7 deletions
diff --git a/src/compiler.h b/src/compiler.h index 7323f4d..070f24a 100644 --- a/src/compiler.h +++ b/src/compiler.h | |||
@@ -5,15 +5,24 @@ | |||
5 | #define PRELUDE_FILE "src/x86_64/prelude.asm" | 5 | #define PRELUDE_FILE "src/x86_64/prelude.asm" |
6 | #define POSTLUDE_FILE "src/x86_64/postlude.asm" | 6 | #define POSTLUDE_FILE "src/x86_64/postlude.asm" |
7 | 7 | ||
8 | #define NIL_VAL 1 | 8 | #define HEAP_SIZE MB(32) |
9 | #define BOOL_MASK 3 | 9 | |
10 | #define BOOL_TAG 3 | 10 | // Immediate constants. |
11 | #define BOOL_SHIFT 2 | 11 | #define NIL_VAL 47 |
12 | #define BOOL_MASK 127 | ||
13 | #define BOOL_TAG 31 | ||
14 | #define BOOL_SHIFT 7 | ||
12 | #define TRUE_VAL ((1 << BOOL_SHIFT) | BOOL_TAG) | 15 | #define TRUE_VAL ((1 << BOOL_SHIFT) | BOOL_TAG) |
13 | #define FALSE_VAL ((0 << BOOL_SHIFT) | BOOL_TAG) | 16 | #define FALSE_VAL ((0 << BOOL_SHIFT) | BOOL_TAG) |
14 | #define FIXNUM_MASK 1 | 17 | #define FIXNUM_MASK 3 |
15 | #define FIXNUM_TAG 0 | 18 | #define FIXNUM_TAG 0 |
16 | #define FIXNUM_SHIFT 1 | 19 | #define FIXNUM_SHIFT 2 |
20 | |||
21 | // Heap allocated objects. | ||
22 | #define STRING_MASK 7 | ||
23 | #define STRING_TAG 3 | ||
24 | #define PAIR_MASK 7 | ||
25 | #define PAIR_TAG 1 | ||
17 | 26 | ||
18 | void compile_object(Object *obj); | 27 | void compile_object(Object *obj); |
19 | void compile_fixnum(Object *obj); | 28 | void compile_fixnum(Object *obj); |
@@ -269,6 +278,49 @@ compile_arithmetic_list(OpType op, Object* args) { | |||
269 | } | 278 | } |
270 | 279 | ||
271 | void | 280 | void |
281 | compile_cons(Object *obj) { | ||
282 | printf(" ;; --> compile_cons\n"); | ||
283 | // Store objects into the car and cdr. | ||
284 | compile_object(obj->head); | ||
285 | compile_object(obj->tail->head); | ||
286 | printf(" pop rdx\n"); | ||
287 | printf(" pop rax\n"); | ||
288 | printf(" mov [rsi], rax\n"); | ||
289 | printf(" mov [rsi + 8], rdx\n"); | ||
290 | |||
291 | // Push memory address of cons cell. | ||
292 | printf(" mov rax, rsi\n"); | ||
293 | printf(" or rax, %ld\n", PAIR_TAG); | ||
294 | printf(" push rax\n"); | ||
295 | |||
296 | // Bump allocation register. | ||
297 | printf(" add rsi, 16\n"); | ||
298 | printf(" ;; <-- compile_cons\n"); | ||
299 | } | ||
300 | |||
301 | void | ||
302 | compile_car(Object *obj) { | ||
303 | printf(" ;; <-- compile_car\n"); | ||
304 | compile_object(obj->head); | ||
305 | printf(" pop rax\n"); | ||
306 | printf(" and eax, %ld\n", ~PAIR_MASK); | ||
307 | printf(" mov rdx, [rax]\n"); | ||
308 | printf(" push rdx\n"); | ||
309 | printf(" ;; <-- compile_car\n"); | ||
310 | } | ||
311 | |||
312 | void | ||
313 | compile_cdr(Object *obj) { | ||
314 | printf(" ;; <-- compile_cdr\n"); | ||
315 | compile_object(obj->head); | ||
316 | printf(" pop rax\n"); | ||
317 | printf(" and eax, %ld\n", ~PAIR_MASK); | ||
318 | printf(" mov rdx, [rax + 8]\n"); | ||
319 | printf(" push rdx\n"); | ||
320 | printf(" ;; <-- compile_cdr\n"); | ||
321 | } | ||
322 | |||
323 | void | ||
272 | compile_proc_call(Object *obj) { | 324 | compile_proc_call(Object *obj) { |
273 | // TODO: Probably we want to use a hash table for these lookups that is | 325 | // TODO: Probably we want to use a hash table for these lookups that is |
274 | // initialized at the start of the compilation procedure. | 326 | // initialized at the start of the compilation procedure. |
@@ -310,6 +362,12 @@ compile_proc_call(Object *obj) { | |||
310 | compile_cmp_list(OP_GREATER_EQ, obj->tail); | 362 | compile_cmp_list(OP_GREATER_EQ, obj->tail); |
311 | } else if (sv_equal(&obj->head->text, &STRING("<="))) { | 363 | } else if (sv_equal(&obj->head->text, &STRING("<="))) { |
312 | compile_cmp_list(OP_LESS_EQ, obj->tail); | 364 | compile_cmp_list(OP_LESS_EQ, obj->tail); |
365 | } else if (sv_equal(&obj->head->text, &STRING("cons"))) { | ||
366 | compile_cons(obj->tail); | ||
367 | } else if (sv_equal(&obj->head->text, &STRING("car"))) { | ||
368 | compile_car(obj->tail); | ||
369 | } else if (sv_equal(&obj->head->text, &STRING("cdr"))) { | ||
370 | compile_cdr(obj->tail); | ||
313 | } else { | 371 | } else { |
314 | fprintf(stderr, "error: not implemented\n"); | 372 | fprintf(stderr, "error: not implemented\n"); |
315 | exit(EXIT_FAILURE); | 373 | exit(EXIT_FAILURE); |
@@ -359,12 +417,12 @@ compile(Root *roots) { | |||
359 | printf("%%define FIXNUM_MASK %d\n", FIXNUM_MASK); | 417 | printf("%%define FIXNUM_MASK %d\n", FIXNUM_MASK); |
360 | printf("%%define FIXNUM_TAG %d\n", FIXNUM_TAG); | 418 | printf("%%define FIXNUM_TAG %d\n", FIXNUM_TAG); |
361 | printf("%%define FIXNUM_SHIFT %d\n", FIXNUM_SHIFT); | 419 | printf("%%define FIXNUM_SHIFT %d\n", FIXNUM_SHIFT); |
420 | printf("%%define HEAP_SIZE %ld\n", HEAP_SIZE); | ||
362 | printf("\n"); | 421 | printf("\n"); |
363 | emit_file(PRELUDE_FILE); | 422 | emit_file(PRELUDE_FILE); |
364 | for (size_t i = 0; i < array_size(roots); i++) { | 423 | for (size_t i = 0; i < array_size(roots); i++) { |
365 | Object *root = roots[i]; | 424 | Object *root = roots[i]; |
366 | compile_object(root); | 425 | compile_object(root); |
367 | // OBJ_PRINT(root); | ||
368 | } | 426 | } |
369 | emit_file(POSTLUDE_FILE); | 427 | emit_file(POSTLUDE_FILE); |
370 | } | 428 | } |