aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-28 14:20:53 +0200
committerBad Diode <bd@badd10de.dev>2024-06-28 14:20:53 +0200
commita723c431f7674de916997df5ed4ce4026a244e07 (patch)
tree0b84b15226a225810cbeee3f14f224e590da8b1f
parent821eeb930dc29d4012feb1f65256835430add6e6 (diff)
downloadbdl-a723c431f7674de916997df5ed4ce4026a244e07.tar.gz
bdl-a723c431f7674de916997df5ed4ce4026a244e07.zip
Generalize binary compilation expression
-rw-r--r--src/compiler.c78
-rw-r--r--src/vm.c3
-rw-r--r--tests/compilation.bad11
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
176CompResult 176CompResult
177compile_binary(OpCode op, Chunk *chunk, Node *node) { 177compile_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) {
212CompResult 252CompResult
213compile_expr(Chunk *chunk, Node *node) { 253compile_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:
diff --git a/src/vm.c b/src/vm.c
index 8d4e67e..3400d7a 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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 @@
11 + 2 * 3 11 + 2 * 3
2true 21.0 + 2.0 * 3.0
3false 3; true
40 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; }