diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-28 14:20:53 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-28 14:20:53 +0200 |
commit | a723c431f7674de916997df5ed4ce4026a244e07 (patch) | |
tree | 0b84b15226a225810cbeee3f14f224e590da8b1f | |
parent | 821eeb930dc29d4012feb1f65256835430add6e6 (diff) | |
download | bdl-a723c431f7674de916997df5ed4ce4026a244e07.tar.gz bdl-a723c431f7674de916997df5ed4ce4026a244e07.zip |
Generalize binary compilation expression
-rw-r--r-- | src/compiler.c | 78 | ||||
-rw-r--r-- | src/vm.c | 3 | ||||
-rw-r--r-- | tests/compilation.bad | 11 |
3 files changed, 67 insertions, 25 deletions
diff --git a/src/compiler.c b/src/compiler.c index d1e8a74..bc875fd 100644 --- a/src/compiler.c +++ b/src/compiler.c | |||
@@ -45,7 +45,7 @@ typedef enum OpCode { | |||
45 | // OP DST A B | 45 | // OP DST A B |
46 | // --------------------------------------------------------------- | 46 | // --------------------------------------------------------------- |
47 | // VM/high level instructions. | 47 | // VM/high level instructions. |
48 | OP_HALT, // halt | 48 | OP_HALT, // halt |
49 | // Load/Store instructions. | 49 | // Load/Store instructions. |
50 | OP_LD8K, // ld8k rx, ca -> u8 rx = ca | 50 | OP_LD8K, // ld8k rx, ca -> u8 rx = ca |
51 | OP_LD16K, // ld16k rx, ca -> u16 rx = ca | 51 | OP_LD16K, // ld16k rx, ca -> u16 rx = ca |
@@ -68,16 +68,16 @@ typedef enum OpCode { | |||
68 | OP_ST32, // st32 rx, ra, rb -> u32 *p; p[ra + rb] = rx | 68 | OP_ST32, // st32 rx, ra, rb -> u32 *p; p[ra + rb] = rx |
69 | OP_ST64, // st64 rx, ra, rb -> u64 *p; p[ra + rb] = rx | 69 | OP_ST64, // st64 rx, ra, rb -> u64 *p; p[ra + rb] = rx |
70 | // Integer arithmetic (only int/s64 for now). | 70 | // Integer arithmetic (only int/s64 for now). |
71 | OP_ADDI, // addk rx, ra, cb | 71 | OP_ADDI, // addk rx, ra, cb |
72 | OP_SUBI, // subk rx, ra, cb | 72 | OP_SUBI, // subk rx, ra, cb |
73 | OP_MULI, // mulk rx, ra, cb | 73 | OP_MULI, // mulk rx, ra, cb |
74 | OP_DIVI, // divk rx, ra, cb | 74 | OP_DIVI, // divk rx, ra, cb |
75 | OP_MODI, // modk rx, ra, cb | 75 | OP_MODI, // modk rx, ra, cb |
76 | OP_ADD, // add rx, ra, rb | 76 | OP_ADD, // add rx, ra, rb |
77 | OP_SUB, // sub rx, ra, rb | 77 | OP_SUB, // sub rx, ra, rb |
78 | OP_MUL, // mul rx, ra, rb | 78 | OP_MUL, // mul rx, ra, rb |
79 | OP_DIV, // div rx, ra, rb | 79 | OP_DIV, // div rx, ra, rb |
80 | OP_MOD, // mod rx, ra, rb | 80 | OP_MOD, // mod rx, ra, rb |
81 | // Floating point arithmetic (only f64 for now). | 81 | // Floating point arithmetic (only f64 for now). |
82 | OP_ADDFI, // addfk rx, ra, cb | 82 | OP_ADDFI, // addfk rx, ra, cb |
83 | OP_SUBFI, // subfk rx, ra, cb | 83 | OP_SUBFI, // subfk rx, ra, cb |
@@ -174,7 +174,47 @@ CompResult compile_expr(Chunk *chunk, Node *node); | |||
174 | } while (0) | 174 | } while (0) |
175 | 175 | ||
176 | CompResult | 176 | CompResult |
177 | compile_binary(OpCode op, Chunk *chunk, Node *node) { | 177 | compile_binary(Chunk *chunk, Node *node) { |
178 | OpCode op = OP_HALT; | ||
179 | OpCode ldop = OP_LD64K; | ||
180 | switch (node->kind) { | ||
181 | case NODE_ADD: { | ||
182 | if (str_eq(node->type, cstr("int"))) { | ||
183 | op = OP_ADD; | ||
184 | } else if (str_eq(node->type, cstr("f64"))) { | ||
185 | op = OP_ADDF; | ||
186 | } | ||
187 | } break; | ||
188 | case NODE_SUB: { | ||
189 | if (str_eq(node->type, cstr("int"))) { | ||
190 | op = OP_SUB; | ||
191 | } else if (str_eq(node->type, cstr("f64"))) { | ||
192 | op = OP_SUBF; | ||
193 | } | ||
194 | } break; | ||
195 | case NODE_MUL: { | ||
196 | if (str_eq(node->type, cstr("int"))) { | ||
197 | op = OP_MUL; | ||
198 | } else if (str_eq(node->type, cstr("f64"))) { | ||
199 | op = OP_MULF; | ||
200 | } | ||
201 | } break; | ||
202 | case NODE_DIV: { | ||
203 | if (str_eq(node->type, cstr("int"))) { | ||
204 | op = OP_DIV; | ||
205 | } else if (str_eq(node->type, cstr("f64"))) { | ||
206 | op = OP_DIVF; | ||
207 | } | ||
208 | } break; | ||
209 | case NODE_MOD: { | ||
210 | if (str_eq(node->type, cstr("int"))) { | ||
211 | op = OP_MOD; | ||
212 | } else if (str_eq(node->type, cstr("f64"))) { | ||
213 | op = OP_MODF; | ||
214 | } | ||
215 | } break; | ||
216 | default: break; | ||
217 | } | ||
178 | CompResult comp_a = compile_expr(chunk, node->left); | 218 | CompResult comp_a = compile_expr(chunk, node->left); |
179 | CompResult comp_b = compile_expr(chunk, node->right); | 219 | CompResult comp_b = compile_expr(chunk, node->right); |
180 | sz reg_a; | 220 | sz reg_a; |
@@ -182,7 +222,7 @@ compile_binary(OpCode op, Chunk *chunk, Node *node) { | |||
182 | switch (comp_a.type) { | 222 | switch (comp_a.type) { |
183 | case COMP_CONST: { | 223 | case COMP_CONST: { |
184 | reg_a = chunk->reg_idx++; | 224 | reg_a = chunk->reg_idx++; |
185 | EMIT_OP(OP_LD64K, reg_a, comp_a.idx, 0, node, chunk); | 225 | EMIT_OP(ldop, reg_a, comp_a.idx, 0, node, chunk); |
186 | } break; | 226 | } break; |
187 | case COMP_REG: { | 227 | case COMP_REG: { |
188 | reg_a = comp_a.idx; | 228 | reg_a = comp_a.idx; |
@@ -194,7 +234,7 @@ compile_binary(OpCode op, Chunk *chunk, Node *node) { | |||
194 | switch (comp_b.type) { | 234 | switch (comp_b.type) { |
195 | case COMP_CONST: { | 235 | case COMP_CONST: { |
196 | reg_b = chunk->reg_idx++; | 236 | reg_b = chunk->reg_idx++; |
197 | EMIT_OP(OP_LD64K, reg_b, comp_b.idx, 0, node, chunk); | 237 | EMIT_OP(ldop, reg_b, comp_b.idx, 0, node, chunk); |
198 | } break; | 238 | } break; |
199 | case COMP_REG: { | 239 | case COMP_REG: { |
200 | reg_b = comp_b.idx; | 240 | reg_b = comp_b.idx; |
@@ -212,11 +252,11 @@ compile_binary(OpCode op, Chunk *chunk, Node *node) { | |||
212 | CompResult | 252 | CompResult |
213 | compile_expr(Chunk *chunk, Node *node) { | 253 | compile_expr(Chunk *chunk, Node *node) { |
214 | switch (node->kind) { | 254 | switch (node->kind) { |
215 | case NODE_ADD: return compile_binary(OP_ADD, chunk, node); break; | 255 | case NODE_ADD: |
216 | case NODE_SUB: return compile_binary(OP_SUB, chunk, node); break; | 256 | case NODE_SUB: |
217 | case NODE_MUL: return compile_binary(OP_MUL, chunk, node); break; | 257 | case NODE_MUL: |
218 | case NODE_DIV: return compile_binary(OP_DIV, chunk, node); break; | 258 | case NODE_DIV: |
219 | case NODE_MOD: return compile_binary(OP_MOD, chunk, node); break; | 259 | case NODE_MOD: return compile_binary(chunk, node); break; |
220 | case NODE_TRUE: | 260 | case NODE_TRUE: |
221 | case NODE_FALSE: | 261 | case NODE_FALSE: |
222 | case NODE_NUM_FLOAT: | 262 | case NODE_NUM_FLOAT: |
@@ -161,7 +161,8 @@ vm_run(VM *vm) { | |||
161 | fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f); | 161 | fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f); |
162 | } break; | 162 | } break; |
163 | case OP_HALT: { | 163 | case OP_HALT: { |
164 | println("VM HALT -> %d", vm->regs[instruction.dst]); | 164 | println("VM HALT (int) -> %d", vm->regs[instruction.dst]); |
165 | println("VM HALT (float) -> %f", vm->regs[instruction.dst]); | ||
165 | return; | 166 | return; |
166 | } | 167 | } |
167 | 168 | ||
diff --git a/tests/compilation.bad b/tests/compilation.bad index 782e75f..6fc5662 100644 --- a/tests/compilation.bad +++ b/tests/compilation.bad | |||
@@ -1,9 +1,10 @@ | |||
1 | 1 + 2 * 3 | 1 | 1 + 2 * 3 |
2 | true | 2 | 1.0 + 2.0 * 3.0 |
3 | false | 3 | ; true |
4 | 0 1 | 4 | ; false |
5 | "hello" | 5 | ; 0 1 |
6 | "world" | 6 | ; "hello" |
7 | ; "world" | ||
7 | ; fun foo(): int { | 8 | ; fun foo(): int { |
8 | ; 32 | 9 | ; 32 |
9 | ; } | 10 | ; } |