diff options
author | Bad Diode <bd@badd10de.dev> | 2021-11-01 16:59:01 +0100 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-11-01 16:59:01 +0100 |
commit | 64f4b9192c231236ddeb10548e577ca1e3f40e9b (patch) | |
tree | a02912deccb28307b000e9a6e2a98413395979ef /src/compiler.h | |
parent | 7418a5042471a3a7f05283d36e45b6b422d9785b (diff) | |
download | bdl-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.h | 46 |
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 | |||
8 | void compile_object(Object *obj); | 16 | void compile_object(Object *obj); |
9 | void compile_fixnum(Object *obj); | 17 | void compile_fixnum(Object *obj); |
10 | void compile_proc_call(Object *obj); | 18 | void compile_proc_call(Object *obj); |
@@ -26,10 +34,27 @@ emit_file(char *file_name) { | |||
26 | 34 | ||
27 | void | 35 | void |
28 | compile_fixnum(Object *obj) { | 36 | compile_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 | |||
43 | void | ||
44 | compile_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 | |||
52 | void | ||
53 | compile_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 | ||
35 | typedef enum OpType { | 60 | typedef enum OpType { |
@@ -42,9 +67,11 @@ typedef enum OpType { | |||
42 | 67 | ||
43 | void | 68 | void |
44 | arithmetic_op(OpType type) { | 69 | arithmetic_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 | ||
72 | void | 101 | void |
73 | compile_proc_call(Object *obj) { | 102 | compile_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 | ||
95 | void | 124 | void |
96 | compile_object(Object *obj) { | 125 | compile_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; |