aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-11-02 14:07:46 +0100
committerBad Diode <bd@badd10de.dev>2021-11-02 14:07:46 +0100
commitfedab6bac08333ca31e69f21add7b66c575ec87c (patch)
treeee40a85250e04a632ba674b29767bf5d270731d0
parent9866fad84ada32ef4f386e8be6ca09bd3711f034 (diff)
downloadbdl-fedab6bac08333ca31e69f21add7b66c575ec87c.tar.gz
bdl-fedab6bac08333ca31e69f21add7b66c575ec87c.zip
Add compilation of `display` primitive
-rw-r--r--src/compiler.h19
-rw-r--r--src/parser.c3
-rw-r--r--src/x86_64/postlude.asm24
-rw-r--r--src/x86_64/prelude.asm30
4 files changed, 44 insertions, 32 deletions
diff --git a/src/compiler.h b/src/compiler.h
index 76d6ccf..18e8a3e 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -139,6 +139,12 @@ compile_type_predicate(OpType op, Object* args) {
139 printf(" ;; <-- compile_type_predicate\n"); 139 printf(" ;; <-- compile_type_predicate\n");
140} 140}
141 141
142
143// TODO: Next -> numerical comparison operators =, <=, ...
144// "=", "<", ">", "<=", ">=",
145// "not", "and", "or",
146// NOTE: Make sure to stop evaluating if the condition is not met.
147
142void 148void
143compile_arithmetic_list(OpType op, Object* args) { 149compile_arithmetic_list(OpType op, Object* args) {
144 printf(" ;; --> compile_arithmetic_list\n"); 150 printf(" ;; --> compile_arithmetic_list\n");
@@ -183,6 +189,11 @@ compile_proc_call(Object *obj) {
183 if (sv_equal(&obj->head->text, &STRING("bool?"))) { 189 if (sv_equal(&obj->head->text, &STRING("bool?"))) {
184 compile_type_predicate(OP_IS_BOOL, obj->tail); 190 compile_type_predicate(OP_IS_BOOL, obj->tail);
185 } 191 }
192 if (sv_equal(&obj->head->text, &STRING("display"))) {
193 compile_object(obj->tail->head);
194 printf(" pop rdi\n");
195 printf(" call display\n");
196 }
186} 197}
187 198
188void 199void
@@ -199,6 +210,14 @@ compile_object(Object *obj) {
199 210
200void 211void
201compile(Root *roots) { 212compile(Root *roots) {
213 printf("%%define NIL_VAL %d\n", NIL_VAL);
214 printf("%%define BOOL_MASK %d\n", BOOL_MASK);
215 printf("%%define BOOL_TAG %d\n", BOOL_TAG);
216 printf("%%define BOOL_SHIFT %d\n", BOOL_SHIFT);
217 printf("%%define FIXNUM_MASK %d\n", FIXNUM_MASK);
218 printf("%%define FIXNUM_TAG %d\n", FIXNUM_TAG);
219 printf("%%define FIXNUM_SHIFT %d\n", FIXNUM_SHIFT);
220 printf("\n");
202 emit_file(PRELUDE_FILE); 221 emit_file(PRELUDE_FILE);
203 for (size_t i = 0; i < array_size(roots); i++) { 222 for (size_t i = 0; i < array_size(roots); i++) {
204 Object *root = roots[i]; 223 Object *root = roots[i];
diff --git a/src/parser.c b/src/parser.c
index 86cf713..9191aa2 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -10,6 +10,7 @@ static char *builtins [] = {
10 "=", "<", ">", "<=", ">=", 10 "=", "<", ">", "<=", ">=",
11 "not", "and", "or", 11 "not", "and", "or",
12 "nil?", "zero?", "fixnum?", "bool?", 12 "nil?", "zero?", "fixnum?", "bool?",
13 "display",
13}; 14};
14 15
15uint64_t 16uint64_t
@@ -597,6 +598,8 @@ parse(Token *tokens, Errors *errors) {
597 array_free(roots); 598 array_free(roots);
598 roots = final_roots; 599 roots = final_roots;
599 600
601 // TODO: Check if primitive procedures have been given the right number of
602 // arguments.
600 // TODO: Type check basic expressions (e.g. arithmetic/numeric comparisons). 603 // TODO: Type check basic expressions (e.g. arithmetic/numeric comparisons).
601 // We can't be sure when we have functions unless the return type is known. 604 // We can't be sure when we have functions unless the return type is known.
602 605
diff --git a/src/x86_64/postlude.asm b/src/x86_64/postlude.asm
index 5c8e56f..3355286 100644
--- a/src/x86_64/postlude.asm
+++ b/src/x86_64/postlude.asm
@@ -2,29 +2,7 @@
2_start_return: 2_start_return:
3 ;; return the last value in the stack 3 ;; return the last value in the stack
4 pop rdi 4 pop rdi
5 5 call display
6 ;; is nil?
7 mov rax, rdi
8 cmp rax, NIL_VAL
9 je exit
10
11 ;; is boolean?
12 mov rax, rdi
13 and rax, BOOL_MASK
14 cmp rax, BOOL_TAG
15 jne not_bool
16 call printbool
17 jmp exit
18not_bool:
19
20 ;; is fixnum?
21 mov rax, rdi
22 and rax, FIXNUM_MASK
23 cmp rax, FIXNUM_TAG
24 jne not_fixnum
25 call printdln
26 jmp exit
27not_fixnum:
28 6
29exit: 7exit:
30 ; exit syscall 8 ; exit syscall
diff --git a/src/x86_64/prelude.asm b/src/x86_64/prelude.asm
index c314ba4..6bb6627 100644
--- a/src/x86_64/prelude.asm
+++ b/src/x86_64/prelude.asm
@@ -1,12 +1,3 @@
1;; Value types.
2%define NIL_VAL 1
3%define BOOL_MASK 3
4%define BOOL_TAG 3
5%define BOOL_SHIFT 2
6%define FIXNUM_MASK 1
7%define FIXNUM_TAG 0
8%define FIXNUM_SHIFT 1
9
10printdln: 1printdln:
11 sar rdi, FIXNUM_SHIFT 2 sar rdi, FIXNUM_SHIFT
12 sub rsp, 40 3 sub rsp, 40
@@ -84,6 +75,27 @@ true_str:
84false_str: 75false_str:
85 db "false", 10 76 db "false", 10
86 77
78display:
79 ;; is nil?
80 mov rax, rdi
81 cmp rax, NIL_VAL
82 je display_end
83
84 ; ;; is boolean?
85 mov rax, rdi
86 and rax, BOOL_MASK
87 cmp rax, BOOL_TAG
88 jne not_bool
89 call printbool
90 ret
91not_bool:
92
93 ;; is fixnum?
94 mov rax, rdi
95 call printdln
96display_end:
97 ret
98
87global _start 99global _start
88_start: 100_start:
89 push NIL_VAL 101 push NIL_VAL