aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-12-23 13:40:23 +0100
committerBad Diode <bd@badd10de.dev>2021-12-23 13:40:23 +0100
commit4c2be0ee13ce16c0274741f77c0d07ea768a2f64 (patch)
tree5b115d4dc5c991cc704fe5d76611911158d5e3d8
parentd22ba5b4f2758e5700d7cc32e3d20a75f1f3c9df (diff)
downloadbdl-4c2be0ee13ce16c0274741f77c0d07ea768a2f64.tar.gz
bdl-4c2be0ee13ce16c0274741f77c0d07ea768a2f64.zip
Add `if` compilation for ir
-rw-r--r--src/ir.h28
1 files changed, 24 insertions, 4 deletions
diff --git a/src/ir.h b/src/ir.h
index 514a3ac..c87babe 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -10,6 +10,7 @@ typedef enum Op {
10 // Arithmetic ops. 10 // Arithmetic ops.
11 // - Binary operations. 11 // - Binary operations.
12 // - Arguments are passed via the stack. 12 // - Arguments are passed via the stack.
13 // - Consume two items in the stack.
13 OP_ADD, 14 OP_ADD,
14 OP_SUB, 15 OP_SUB,
15 OP_MUL, 16 OP_MUL,
@@ -18,7 +19,7 @@ typedef enum Op {
18 // Logic ops. 19 // Logic ops.
19 OP_NOT, 20 OP_NOT,
20 // Stack ops. 21 // Stack ops.
21 // - Requires an Object to push into the stack. 22 // - Requires a constant Object to push into the stack.
22 OP_PUSH, 23 OP_PUSH,
23 // - Discards the last value in the stack. 24 // - Discards the last value in the stack.
24 OP_DROP, 25 OP_DROP,
@@ -34,8 +35,9 @@ typedef enum Op {
34 OP_LABEL, 35 OP_LABEL,
35 // Jump/conditional ops. 36 // Jump/conditional ops.
36 // - Take a label as argument. 37 // - Take a label as argument.
37 // - For conditional jumps, the last value in the stack is used.
38 OP_JUMP, 38 OP_JUMP,
39 // - Consume one value in the stack.
40 // - All objects except `false` are considered `true`.
39 OP_JUMP_IF_TRUE, 41 OP_JUMP_IF_TRUE,
40 OP_JUMP_IF_FALSE, 42 OP_JUMP_IF_FALSE,
41 // - These require numerical objects on the stack. 43 // - These require numerical objects on the stack.
@@ -96,7 +98,7 @@ typedef struct Instruction {
96 98
97 // OP_LABEL 99 // OP_LABEL
98 // OP_JUMP 100 // OP_JUMP
99 // OP_JUMP_IF_FALSE 101 // OP_JUMP_IF_xxx
100 size_t label_id; 102 size_t label_id;
101 }; 103 };
102 104
@@ -316,6 +318,7 @@ compile_proc_call(ProgramIr *program, Procedure *proc, Object *obj) {
316 case BUILTIN_LE: { 318 case BUILTIN_LE: {
317 compile_numeric_cmp(program, proc, OP_JUMP_IF_GT, line, col, obj->tail); 319 compile_numeric_cmp(program, proc, OP_JUMP_IF_GT, line, col, obj->tail);
318 } break; 320 } break;
321 // TODO: cons, car, cdr, type checks (nil? zero? fixnum? bool? ...)
319 default: { 322 default: {
320 assert(false && "builtin not implemented"); 323 assert(false && "builtin not implemented");
321 } break; 324 } break;
@@ -326,6 +329,23 @@ compile_proc_call(ProgramIr *program, Procedure *proc, Object *obj) {
326} 329}
327 330
328void 331void
332compile_if(ProgramIr *program, Procedure *proc, Object *obj) {
333 size_t label_false = program->labels++;
334 compile_object(program, proc, obj->condition);
335 INST_ARG(proc, OP_JUMP_IF_FALSE, label_false, obj->line, obj->col);
336 compile_object(program, proc, obj->expr_true);
337 if (obj->expr_false != NULL) {
338 size_t label_exit = program->labels++;
339 INST_ARG(proc, OP_JUMP, label_exit, obj->line, obj->col);
340 INST_ARG(proc, OP_LABEL, label_false, obj->line, obj->col);
341 compile_object(program, proc, obj->expr_false);
342 INST_ARG(proc, OP_LABEL, label_exit, obj->line, obj->col);
343 } else {
344 INST_ARG(proc, OP_LABEL, label_false, obj->line, obj->col);
345 }
346}
347
348void
329compile_object(ProgramIr *program, Procedure *proc, Object *obj) { 349compile_object(ProgramIr *program, Procedure *proc, Object *obj) {
330 switch (obj->type) { 350 switch (obj->type) {
331 case OBJ_TYPE_NIL: 351 case OBJ_TYPE_NIL:
@@ -336,7 +356,7 @@ compile_object(ProgramIr *program, Procedure *proc, Object *obj) {
336 INST_ARG(proc, OP_PUSH, obj, obj->line, obj->col); 356 INST_ARG(proc, OP_PUSH, obj, obj->line, obj->col);
337 } break; 357 } break;
338 case OBJ_TYPE_PAIR: { compile_proc_call(program, proc, obj); } break; 358 case OBJ_TYPE_PAIR: { compile_proc_call(program, proc, obj); } break;
339 // case OBJ_TYPE_IF: { compile_if(obj); } break; 359 case OBJ_TYPE_IF: { compile_if(program, proc, obj); } break;
340 // case OBJ_TYPE_LAMBDA: { compile_lambda(obj); } break; 360 // case OBJ_TYPE_LAMBDA: { compile_lambda(obj); } break;
341 // case OBJ_TYPE_DEF: { compile_def(obj); } break; 361 // case OBJ_TYPE_DEF: { compile_def(obj); } break;
342 // case OBJ_TYPE_SYMBOL: { compile_symbol(obj); } break; 362 // case OBJ_TYPE_SYMBOL: { compile_symbol(obj); } break;