diff options
author | Bad Diode <bd@badd10de.dev> | 2021-10-24 16:47:15 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-10-24 16:47:15 +0200 |
commit | abdcae0f839d0bd772c5f7211cb1cb2034355b62 (patch) | |
tree | ee3b8c8811a1383cfb453b5638acc20997876a4c /src/bytecode/compiler.h | |
parent | dd5210368634e2b322435385eaaaccaa5125b5a9 (diff) | |
download | bdl-abdcae0f839d0bd772c5f7211cb1cb2034355b62.tar.gz bdl-abdcae0f839d0bd772c5f7211cb1cb2034355b62.zip |
Cleanup IF jump code in compiler
Diffstat (limited to 'src/bytecode/compiler.h')
-rwxr-xr-x | src/bytecode/compiler.h | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h index 559ad1c..c01f745 100755 --- a/src/bytecode/compiler.h +++ b/src/bytecode/compiler.h | |||
@@ -45,6 +45,22 @@ emit_constant(Chunk *chunk, Token tok, Object obj) { | |||
45 | } | 45 | } |
46 | } | 46 | } |
47 | 47 | ||
48 | size_t | ||
49 | emit_jump(Chunk *chunk, Token tok, Ops op) { | ||
50 | add_code(chunk, op, tok.line, tok.column); | ||
51 | add_code(chunk, 0xFF, tok.line, tok.column); | ||
52 | add_code(chunk, 0xFF, tok.line, tok.column); | ||
53 | return array_size(chunk->code) - 2; | ||
54 | } | ||
55 | |||
56 | void | ||
57 | patch_jump(Chunk *chunk, size_t offset) { | ||
58 | size_t jump = array_size(chunk->code) - offset - 2; | ||
59 | assert(jump <= UINT16_MAX && "error: jump is too long"); | ||
60 | chunk->code[offset] = (jump >> 8) & 0xFF; | ||
61 | chunk->code[offset + 1] = (jump) & 0xFF; | ||
62 | } | ||
63 | |||
48 | void | 64 | void |
49 | parse_fixnum(Chunk *chunk, Token tok) { | 65 | parse_fixnum(Chunk *chunk, Token tok) { |
50 | ssize_t num = 0; | 66 | ssize_t num = 0; |
@@ -255,34 +271,23 @@ compile_if_op(Chunk *chunk, Visitor *vs, Token start) { | |||
255 | 271 | ||
256 | // Condition. | 272 | // Condition. |
257 | parse_tree(chunk, vs); | 273 | parse_tree(chunk, vs); |
258 | emit_constant(chunk, tok, FIXNUM_VAL(0xFF)); | 274 | size_t jmp_false = emit_jump(chunk, start, OP_JUMP_IF_FALSE); |
259 | size_t pos = array_size(chunk->code); | ||
260 | add_code(chunk, OP_JUMP_IF_FALSE, start.line, start.column); | ||
261 | 275 | ||
262 | // Block true. | 276 | // True expression. |
263 | parse_tree(chunk, vs); | 277 | parse_tree(chunk, vs); |
264 | 278 | ||
265 | // No else. | 279 | // No second expression. |
266 | if (peek_token(vs).type == TOKEN_RPAREN) { | 280 | if (peek_token(vs).type == TOKEN_RPAREN) { |
267 | size_t false_block_start = array_size(chunk->code) - pos - 1; | 281 | patch_jump(chunk, jmp_false); |
268 | size_t num_idx = add_constant(chunk, FIXNUM_VAL(false_block_start)); | ||
269 | chunk->code[pos - 1] = num_idx; | ||
270 | next_token(vs); | 282 | next_token(vs); |
271 | return; | 283 | return; |
272 | } | 284 | } |
273 | 285 | ||
274 | // Else. | 286 | // False expression. |
275 | emit_constant(chunk, tok, FIXNUM_VAL(0xFF)); | 287 | size_t jmp_end = emit_jump(chunk, start, OP_JUMP); |
276 | size_t else_pos = array_size(chunk->code); | 288 | patch_jump(chunk, jmp_false); |
277 | add_code(chunk, OP_JUMP, start.line, start.column); | ||
278 | |||
279 | size_t false_block_start = array_size(chunk->code) - pos - 1; | ||
280 | size_t num_idx = add_constant(chunk, FIXNUM_VAL(false_block_start)); | ||
281 | chunk->code[pos - 1] = num_idx; | ||
282 | parse_tree(chunk, vs); | 289 | parse_tree(chunk, vs); |
283 | false_block_start = array_size(chunk->code) - else_pos - 1; | 290 | patch_jump(chunk, jmp_end); |
284 | num_idx = add_constant(chunk, FIXNUM_VAL(false_block_start)); | ||
285 | chunk->code[else_pos - 1] = num_idx; | ||
286 | 291 | ||
287 | if (peek_token(vs).type != TOKEN_RPAREN) { | 292 | if (peek_token(vs).type != TOKEN_RPAREN) { |
288 | error_push((Error){ | 293 | error_push((Error){ |