aboutsummaryrefslogtreecommitdiffstats
path: root/src/compiler.h
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-11-01 16:59:01 +0100
committerBad Diode <bd@badd10de.dev>2021-11-01 16:59:01 +0100
commit64f4b9192c231236ddeb10548e577ca1e3f40e9b (patch)
treea02912deccb28307b000e9a6e2a98413395979ef /src/compiler.h
parent7418a5042471a3a7f05283d36e45b6b422d9785b (diff)
downloadbdl-64f4b9192c231236ddeb10548e577ca1e3f40e9b.tar.gz
bdl-64f4b9192c231236ddeb10548e577ca1e3f40e9b.zip
Add support for immediate constants
- Fixnums are tagged with a zero on the LSB. - The nil value is equal to exactly 1. - Boolean values have a 11 tag. A value of 111 is true and 011 false.
Diffstat (limited to 'src/compiler.h')
-rw-r--r--src/compiler.h46
1 files changed, 39 insertions, 7 deletions
diff --git a/src/compiler.h b/src/compiler.h
index 3fed075..7d6fa6b 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -5,6 +5,14 @@
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
9#define BOOL_MASK 3
10#define BOOL_TAG 3
11#define BOOL_SHIFT 2
12#define FIXNUM_MASK 1
13#define FIXNUM_TAG 0
14#define FIXNUM_SHIFT 1
15
8void compile_object(Object *obj); 16void compile_object(Object *obj);
9void compile_fixnum(Object *obj); 17void compile_fixnum(Object *obj);
10void compile_proc_call(Object *obj); 18void compile_proc_call(Object *obj);
@@ -26,10 +34,27 @@ emit_file(char *file_name) {
26 34
27void 35void
28compile_fixnum(Object *obj) { 36compile_fixnum(Object *obj) {
29 printf(" ;; -- compile_fixnum --\n"); 37 printf(" ;; --> compile_fixnum\n");
30 printf(" mov rax, %ld\n", obj->fixnum); 38 printf(" mov rax, %ld\n", (obj->fixnum << FIXNUM_SHIFT) | FIXNUM_TAG);
39 printf(" push rax\n");
40 printf(" ;; <-- compile_fixnum\n");
41}
42
43void
44compile_boolean(Object *obj) {
45 printf(" ;; --> compile_boolean\n");
46 int is_true = obj->type == OBJ_TYPE_TRUE;
47 printf(" mov rax, %d\n", (is_true << BOOL_SHIFT) | BOOL_TAG);
48 printf(" push rax\n");
49 printf(" ;; <-- compile_boolean\n");
50}
51
52void
53compile_nil(void) {
54 printf(" ;; --> compile_nil\n");
55 printf(" mov rax, %d\n", NIL_VAL);
31 printf(" push rax\n"); 56 printf(" push rax\n");
32 printf(" ;; --------------------\n"); 57 printf(" ;; <-- compile_nil\n");
33} 58}
34 59
35typedef enum OpType { 60typedef enum OpType {
@@ -42,9 +67,11 @@ typedef enum OpType {
42 67
43void 68void
44arithmetic_op(OpType type) { 69arithmetic_op(OpType type) {
45 printf(" ;; -- arithmetic_op --\n"); 70 printf(" ;; --> arithmetic_op\n");
46 printf(" pop rcx\n"); 71 printf(" pop rcx\n");
47 printf(" pop rax\n"); 72 printf(" pop rax\n");
73 printf(" sar rax, %d\n", FIXNUM_SHIFT);
74 printf(" sar rcx, %d\n", FIXNUM_SHIFT);
48 switch (type) { 75 switch (type) {
49 case OP_ADD: { 76 case OP_ADD: {
50 printf(" add rax, rcx\n"); 77 printf(" add rax, rcx\n");
@@ -65,13 +92,15 @@ arithmetic_op(OpType type) {
65 printf(" mov rax, rdx\n"); 92 printf(" mov rax, rdx\n");
66 } break; 93 } break;
67 } 94 }
95 // No need to add the FIXNUM_TAG here, since it's zero.
96 printf(" sal rax, %d\n", FIXNUM_SHIFT);
68 printf(" push rax\n"); 97 printf(" push rax\n");
69 printf(" ;; -------------------\n"); 98 printf(" ;; <-- arithmetic_op\n");
70} 99}
71 100
72void 101void
73compile_proc_call(Object *obj) { 102compile_proc_call(Object *obj) {
74 printf(" ;; -- compile_proc_call --\n"); 103 printf(" ;; --> compile_proc_call\n");
75 OpType op; 104 OpType op;
76 if (sv_equal(&obj->head->text, &STRING("+"))) { op = OP_ADD;} 105 if (sv_equal(&obj->head->text, &STRING("+"))) { op = OP_ADD;}
77 if (sv_equal(&obj->head->text, &STRING("-"))) { op = OP_SUB;} 106 if (sv_equal(&obj->head->text, &STRING("-"))) { op = OP_SUB;}
@@ -89,12 +118,15 @@ compile_proc_call(Object *obj) {
89 args = args->tail; 118 args = args->tail;
90 arithmetic_op(op); 119 arithmetic_op(op);
91 } 120 }
92 printf(" ;; -----------------------\n"); 121 printf(" ;; <-- compile_proc_call\n");
93} 122}
94 123
95void 124void
96compile_object(Object *obj) { 125compile_object(Object *obj) {
97 switch (obj->type) { 126 switch (obj->type) {
127 case OBJ_TYPE_NIL: { compile_nil(); } break;
128 case OBJ_TYPE_TRUE:
129 case OBJ_TYPE_FALSE: { compile_boolean(obj); } break;
98 case OBJ_TYPE_FIXNUM: { compile_fixnum(obj); } break; 130 case OBJ_TYPE_FIXNUM: { compile_fixnum(obj); } break;
99 case OBJ_TYPE_PAIR: { compile_proc_call(obj); } break; 131 case OBJ_TYPE_PAIR: { compile_proc_call(obj); } break;
100 default: break; 132 default: break;