diff options
author | Bad Diode <bd@badd10de.dev> | 2021-12-23 12:12:48 +0100 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-12-23 12:12:48 +0100 |
commit | b2afd9e4a0389d824421b7dfe6b4db522b7a722b (patch) | |
tree | fd673484fcc6cacfaa66054a4f0f015a7feff7eb | |
parent | 64d282b77633338ac3ff9fe924fe86bfab1012e6 (diff) | |
download | bdl-b2afd9e4a0389d824421b7dfe6b4db522b7a722b.tar.gz bdl-b2afd9e4a0389d824421b7dfe6b4db522b7a722b.zip |
Add compilation of `or` builtin for the ir
-rw-r--r-- | src/ir.h | 16 |
1 files changed, 15 insertions, 1 deletions
@@ -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, | |||
180 | void | 183 | void |
181 | compile_and(ProgramIr *program, Procedure *proc, | 184 | compile_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, | |||
198 | void | 200 | void |
199 | compile_or(ProgramIr *program, Procedure *proc, | 201 | compile_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 | ||
203 | void | 217 | void |