aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-11-04 11:58:53 +0100
committerBad Diode <bd@badd10de.dev>2021-11-04 11:58:53 +0100
commit7cbef14e8393475b1e569fdbfff2c46db859d43f (patch)
treec7a25a997fae700f5f7a952a9550d6ee74bea240
parent84c2bf292ddcb91543715951805ebc2335c46567 (diff)
downloadbdl-7cbef14e8393475b1e569fdbfff2c46db859d43f.tar.gz
bdl-7cbef14e8393475b1e569fdbfff2c46db859d43f.zip
Add `cons`, `car` and `cdr` primitives
-rw-r--r--src/compiler.h72
-rw-r--r--src/parser.c1
-rw-r--r--src/x86_64/postlude.asm4
-rw-r--r--src/x86_64/prelude.asm7
4 files changed, 76 insertions, 8 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
18void compile_object(Object *obj); 27void compile_object(Object *obj);
19void compile_fixnum(Object *obj); 28void compile_fixnum(Object *obj);
@@ -269,6 +278,49 @@ compile_arithmetic_list(OpType op, Object* args) {
269} 278}
270 279
271void 280void
281compile_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
301void
302compile_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
312void
313compile_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
323void
272compile_proc_call(Object *obj) { 324compile_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}
diff --git a/src/parser.c b/src/parser.c
index 9191aa2..5632e13 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -11,6 +11,7 @@ static char *builtins [] = {
11 "not", "and", "or", 11 "not", "and", "or",
12 "nil?", "zero?", "fixnum?", "bool?", 12 "nil?", "zero?", "fixnum?", "bool?",
13 "display", 13 "display",
14 "cons", "car", "cdr",
14}; 15};
15 16
16uint64_t 17uint64_t
diff --git a/src/x86_64/postlude.asm b/src/x86_64/postlude.asm
index 3355286..37f9df1 100644
--- a/src/x86_64/postlude.asm
+++ b/src/x86_64/postlude.asm
@@ -9,3 +9,7 @@ exit:
9 mov rax, 60 9 mov rax, 60
10 xor rdi, rdi 10 xor rdi, rdi
11 syscall 11 syscall
12
13section .bss
14bdl_heap:
15 resb HEAP_SIZE
diff --git a/src/x86_64/prelude.asm b/src/x86_64/prelude.asm
index 6bb6627..e57e820 100644
--- a/src/x86_64/prelude.asm
+++ b/src/x86_64/prelude.asm
@@ -1,3 +1,4 @@
1section .text
1printdln: 2printdln:
2 sar rdi, FIXNUM_SHIFT 3 sar rdi, FIXNUM_SHIFT
3 sub rsp, 40 4 sub rsp, 40
@@ -98,4 +99,8 @@ display_end:
98 99
99global _start 100global _start
100_start: 101_start:
101 push NIL_VAL 102 ;; point `rdi` to the start of the heap.
103 mov rsi, bdl_heap
104
105 ;; make sure the last element in the stack is the nil value.
106 push NIL_VAL