aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-11-01 17:58:57 +0100
committerBad Diode <bd@badd10de.dev>2021-11-01 17:58:57 +0100
commit9866fad84ada32ef4f386e8be6ca09bd3711f034 (patch)
treecf25cef7fab9d1e8972c9272640aaccc2a8eb1a0
parent64f4b9192c231236ddeb10548e577ca1e3f40e9b (diff)
downloadbdl-9866fad84ada32ef4f386e8be6ca09bd3711f034.tar.gz
bdl-9866fad84ada32ef4f386e8be6ca09bd3711f034.zip
Add type predicate primitive procedures
Added: nil?, zero?, bool?, fixnum?
-rw-r--r--src/compiler.h110
-rw-r--r--src/parser.c1
2 files changed, 88 insertions, 23 deletions
diff --git a/src/compiler.h b/src/compiler.h
index 7d6fa6b..76d6ccf 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -58,11 +58,18 @@ compile_nil(void) {
58} 58}
59 59
60typedef enum OpType { 60typedef enum OpType {
61 // Arithmetic.
61 OP_ADD, 62 OP_ADD,
62 OP_SUB, 63 OP_SUB,
63 OP_MUL, 64 OP_MUL,
64 OP_DIV, 65 OP_DIV,
65 OP_MOD, 66 OP_MOD,
67 // Type predicates.
68 OP_IS_NIL,
69 OP_IS_ZERO,
70 OP_IS_BOOL,
71 OP_IS_FIXNUM,
72 // TODO: etc.
66} OpType; 73} OpType;
67 74
68void 75void
@@ -70,47 +77,71 @@ arithmetic_op(OpType type) {
70 printf(" ;; --> arithmetic_op\n"); 77 printf(" ;; --> arithmetic_op\n");
71 printf(" pop rcx\n"); 78 printf(" pop rcx\n");
72 printf(" pop rax\n"); 79 printf(" pop rax\n");
73 printf(" sar rax, %d\n", FIXNUM_SHIFT);
74 printf(" sar rcx, %d\n", FIXNUM_SHIFT);
75 switch (type) { 80 switch (type) {
76 case OP_ADD: { 81 case OP_ADD: { printf(" add rax, rcx\n"); } break;
77 printf(" add rax, rcx\n"); 82 case OP_SUB: { printf(" sub rax, rcx\n"); } break;
78 } break;
79 case OP_SUB: {
80 printf(" sub rax, rcx\n");
81 } break;
82 case OP_MUL: { 83 case OP_MUL: {
84 printf(" sar rax, %d\n", FIXNUM_SHIFT);
85 printf(" sar rcx, %d\n", FIXNUM_SHIFT);
83 printf(" mul rcx\n"); 86 printf(" mul rcx\n");
87 printf(" sal rax, %d\n", FIXNUM_SHIFT);
84 } break; 88 } break;
85 case OP_DIV: { 89 case OP_DIV: {
90 printf(" sar rax, %d\n", FIXNUM_SHIFT);
91 printf(" sar rcx, %d\n", FIXNUM_SHIFT);
86 printf(" mov rdx, 0\n"); 92 printf(" mov rdx, 0\n");
87 printf(" div rcx\n"); 93 printf(" div rcx\n");
94 printf(" sal rax, %d\n", FIXNUM_SHIFT);
88 } break; 95 } break;
89 case OP_MOD: { 96 case OP_MOD: {
97 printf(" sar rax, %d\n", FIXNUM_SHIFT);
98 printf(" sar rcx, %d\n", FIXNUM_SHIFT);
90 printf(" mov rdx, 0\n"); 99 printf(" mov rdx, 0\n");
91 printf(" div rcx\n"); 100 printf(" div rcx\n");
92 printf(" mov rax, rdx\n"); 101 printf(" mov rax, rdx\n");
102 printf(" sal rax, %d\n", FIXNUM_SHIFT);
93 } break; 103 } break;
104 default: break;
94 } 105 }
95 // No need to add the FIXNUM_TAG here, since it's zero.
96 printf(" sal rax, %d\n", FIXNUM_SHIFT);
97 printf(" push rax\n"); 106 printf(" push rax\n");
98 printf(" ;; <-- arithmetic_op\n"); 107 printf(" ;; <-- arithmetic_op\n");
99} 108}
100 109
110typedef void (CompileProc)(OpType, Object*);
111
101void 112void
102compile_proc_call(Object *obj) { 113compile_type_predicate(OpType op, Object* args) {
103 printf(" ;; --> compile_proc_call\n"); 114 printf(" ;; --> compile_type_predicate\n");
104 OpType op; 115 compile_object(args->head);
105 if (sv_equal(&obj->head->text, &STRING("+"))) { op = OP_ADD;} 116 printf(" pop rax\n");
106 if (sv_equal(&obj->head->text, &STRING("-"))) { op = OP_SUB;} 117 switch (op) {
107 if (sv_equal(&obj->head->text, &STRING("*"))) { op = OP_MUL;} 118 case OP_IS_NIL: {
108 if (sv_equal(&obj->head->text, &STRING("/"))) { op = OP_DIV;} 119 printf(" cmp rax, %d\n", NIL_VAL);
109 if (sv_equal(&obj->head->text, &STRING("%"))) { op = OP_MOD;} 120 } break;
110 // TODO: Resolve function call. 121 case OP_IS_ZERO: {
111 Object *args = obj->tail; 122 printf(" cmp rax, 0\n");
112 // TODO: capture first operand in the accumulator. Number of arguments 123 } break;
113 // checking should have been handled in the parser. 124 case OP_IS_BOOL: {
125 printf(" and rax, %d\n", BOOL_MASK);
126 printf(" cmp rax, %d\n", BOOL_TAG);
127 } break;
128 case OP_IS_FIXNUM: {
129 printf(" and rax, %d\n", FIXNUM_MASK);
130 printf(" cmp rax, %d\n", FIXNUM_TAG);
131 } break;
132 default: break;
133 }
134 printf(" mov rax, 0\n");
135 printf(" sete al\n");
136 printf(" sal rax, %d\n", BOOL_SHIFT);
137 printf(" or rax, %d\n", BOOL_TAG);
138 printf(" push rax\n");
139 printf(" ;; <-- compile_type_predicate\n");
140}
141
142void
143compile_arithmetic_list(OpType op, Object* args) {
144 printf(" ;; --> compile_arithmetic_list\n");
114 compile_object(args->head); 145 compile_object(args->head);
115 args = args->tail; 146 args = args->tail;
116 while (args != NULL) { 147 while (args != NULL) {
@@ -118,7 +149,40 @@ compile_proc_call(Object *obj) {
118 args = args->tail; 149 args = args->tail;
119 arithmetic_op(op); 150 arithmetic_op(op);
120 } 151 }
121 printf(" ;; <-- compile_proc_call\n"); 152 printf(" ;; <-- compile_arithmetic_list\n");
153}
154
155void
156compile_proc_call(Object *obj) {
157 // TODO: Probably we want to use a hash table for these lookups that is
158 // initialized at the start of the compilation procedure.
159 if (sv_equal(&obj->head->text, &STRING("+"))) {
160 compile_arithmetic_list(OP_ADD, obj->tail);
161 }
162 if (sv_equal(&obj->head->text, &STRING("-"))) {
163 compile_arithmetic_list(OP_SUB, obj->tail);
164 }
165 if (sv_equal(&obj->head->text, &STRING("*"))) {
166 compile_arithmetic_list(OP_MUL, obj->tail);
167 }
168 if (sv_equal(&obj->head->text, &STRING("/"))) {
169 compile_arithmetic_list(OP_DIV, obj->tail);
170 }
171 if (sv_equal(&obj->head->text, &STRING("%"))) {
172 compile_arithmetic_list(OP_MOD, obj->tail);
173 }
174 if (sv_equal(&obj->head->text, &STRING("nil?"))) {
175 compile_type_predicate(OP_IS_NIL, obj->tail);
176 }
177 if (sv_equal(&obj->head->text, &STRING("zero?"))) {
178 compile_type_predicate(OP_IS_ZERO, obj->tail);
179 }
180 if (sv_equal(&obj->head->text, &STRING("fixnum?"))) {
181 compile_type_predicate(OP_IS_FIXNUM, obj->tail);
182 }
183 if (sv_equal(&obj->head->text, &STRING("bool?"))) {
184 compile_type_predicate(OP_IS_BOOL, obj->tail);
185 }
122} 186}
123 187
124void 188void
diff --git a/src/parser.c b/src/parser.c
index 57efd96..86cf713 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -9,6 +9,7 @@ static char *builtins [] = {
9 "+", "-", "*", "/", "%", 9 "+", "-", "*", "/", "%",
10 "=", "<", ">", "<=", ">=", 10 "=", "<", ">", "<=", ">=",
11 "not", "and", "or", 11 "not", "and", "or",
12 "nil?", "zero?", "fixnum?", "bool?",
12}; 13};
13 14
14uint64_t 15uint64_t