aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-12-23 12:12:48 +0100
committerBad Diode <bd@badd10de.dev>2021-12-23 12:12:48 +0100
commitb2afd9e4a0389d824421b7dfe6b4db522b7a722b (patch)
treefd673484fcc6cacfaa66054a4f0f015a7feff7eb
parent64d282b77633338ac3ff9fe924fe86bfab1012e6 (diff)
downloadbdl-b2afd9e4a0389d824421b7dfe6b4db522b7a722b.tar.gz
bdl-b2afd9e4a0389d824421b7dfe6b4db522b7a722b.zip
Add compilation of `or` builtin for the ir
-rw-r--r--src/ir.h16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/ir.h b/src/ir.h
index bb15596..c1cdae4 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -29,6 +29,7 @@ typedef enum Op {
29 // - Take a label as argument. 29 // - Take a label as argument.
30 // - For conditional jumps, the last value in the stack is used. 30 // - For conditional jumps, the last value in the stack is used.
31 OP_JUMP, 31 OP_JUMP,
32 OP_JUMP_IF_TRUE,
32 OP_JUMP_IF_FALSE, 33 OP_JUMP_IF_FALSE,
33 // Primitive complex commands. 34 // Primitive complex commands.
34 // - Prints the last object in the stack. 35 // - Prints the last object in the stack.
@@ -53,6 +54,7 @@ static const char* ops_str[] = {
53 [OP_DROP] = "OP_DROP", 54 [OP_DROP] = "OP_DROP",
54 [OP_LABEL] = "OP_LABEL", 55 [OP_LABEL] = "OP_LABEL",
55 [OP_JUMP] = "OP_JUMP", 56 [OP_JUMP] = "OP_JUMP",
57 [OP_JUMP_IF_TRUE] = "OP_JUMP_IF_TRUE",
56 [OP_JUMP_IF_FALSE] = "OP_JUMP_IF_FALSE", 58 [OP_JUMP_IF_FALSE] = "OP_JUMP_IF_FALSE",
57 [OP_PRINT] = "OP_PRINT", 59 [OP_PRINT] = "OP_PRINT",
58 [OP_CALL] = "OP_CALL", 60 [OP_CALL] = "OP_CALL",
@@ -117,6 +119,7 @@ print_instruction(Instruction *instruction) {
117 OBJ_PRINT(instruction->argument); 119 OBJ_PRINT(instruction->argument);
118 } break; 120 } break;
119 case OP_JUMP: 121 case OP_JUMP:
122 case OP_JUMP_IF_TRUE:
120 case OP_JUMP_IF_FALSE: 123 case OP_JUMP_IF_FALSE:
121 case OP_LABEL: { 124 case OP_LABEL: {
122 printf("%-16s -> %zu\n", ops_str[op], instruction->label_id); 125 printf("%-16s -> %zu\n", ops_str[op], instruction->label_id);
@@ -180,7 +183,6 @@ compile_not(ProgramIr *program, Procedure *proc,
180void 183void
181compile_and(ProgramIr *program, Procedure *proc, 184compile_and(ProgramIr *program, Procedure *proc,
182 size_t line, size_t col, Object *args) { 185 size_t line, size_t col, Object *args) {
183 // Generate labels.
184 size_t label_false = program->labels++; 186 size_t label_false = program->labels++;
185 size_t label_exit = program->labels++; 187 size_t label_exit = program->labels++;
186 while (args != NULL) { 188 while (args != NULL) {
@@ -198,6 +200,18 @@ compile_and(ProgramIr *program, Procedure *proc,
198void 200void
199compile_or(ProgramIr *program, Procedure *proc, 201compile_or(ProgramIr *program, Procedure *proc,
200 size_t line, size_t col, Object *args) { 202 size_t line, size_t col, Object *args) {
203 size_t label_true = program->labels++;
204 size_t label_exit = program->labels++;
205 while (args != NULL) {
206 compile_object(program, proc, args->head);
207 args = args->tail;
208 INST_ARG(proc, OP_JUMP_IF_TRUE, label_true, line, col);
209 }
210 INST_ARG(proc, OP_PUSH, &obj_false, line, col);
211 INST_ARG(proc, OP_JUMP, label_exit, line, col);
212 INST_ARG(proc, OP_LABEL, label_true, line, col);
213 INST_ARG(proc, OP_PUSH, &obj_true, line, col);
214 INST_ARG(proc, OP_LABEL, label_exit, line, col);
201} 215}
202 216
203void 217void