diff options
author | Bad Diode <bd@badd10de.dev> | 2021-10-24 15:42:01 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-10-24 15:42:01 +0200 |
commit | dd5210368634e2b322435385eaaaccaa5125b5a9 (patch) | |
tree | 81c2bb47907281a82a198ed8cb28d9b7e34e7bf3 /src/bytecode/compiler.h | |
parent | d90b9f42a361bc3563b1f11bbd707c4288a65b40 (diff) | |
download | bdl-dd5210368634e2b322435385eaaaccaa5125b5a9.tar.gz bdl-dd5210368634e2b322435385eaaaccaa5125b5a9.zip |
Add initial IF implementation
Diffstat (limited to 'src/bytecode/compiler.h')
-rwxr-xr-x | src/bytecode/compiler.h | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h index b1cdfb9..559ad1c 100755 --- a/src/bytecode/compiler.h +++ b/src/bytecode/compiler.h | |||
@@ -232,6 +232,71 @@ compile_declare_op(Chunk *chunk, Visitor *vs, Token start, Ops op) { | |||
232 | } | 232 | } |
233 | 233 | ||
234 | void | 234 | void |
235 | compile_if_op(Chunk *chunk, Visitor *vs, Token start) { | ||
236 | Token tok = peek_token(vs); | ||
237 | if (tok.type == TOKEN_EOF) { | ||
238 | error_push((Error){ | ||
239 | .type = ERR_TYPE_COMPILER, | ||
240 | .value = ERR_UNBALANCED_PAREN, | ||
241 | .line = start.line, | ||
242 | .col = start.column, | ||
243 | }); | ||
244 | return; | ||
245 | } | ||
246 | if (tok.type == TOKEN_RPAREN) { | ||
247 | error_push((Error){ | ||
248 | .type = ERR_TYPE_COMPILER, | ||
249 | .value = ERR_NOT_ENOUGH_ARGS, | ||
250 | .line = start.line, | ||
251 | .col = start.column, | ||
252 | }); | ||
253 | return; | ||
254 | } | ||
255 | |||
256 | // Condition. | ||
257 | parse_tree(chunk, vs); | ||
258 | emit_constant(chunk, tok, FIXNUM_VAL(0xFF)); | ||
259 | size_t pos = array_size(chunk->code); | ||
260 | add_code(chunk, OP_JUMP_IF_FALSE, start.line, start.column); | ||
261 | |||
262 | // Block true. | ||
263 | parse_tree(chunk, vs); | ||
264 | |||
265 | // No else. | ||
266 | if (peek_token(vs).type == TOKEN_RPAREN) { | ||
267 | size_t false_block_start = array_size(chunk->code) - pos - 1; | ||
268 | size_t num_idx = add_constant(chunk, FIXNUM_VAL(false_block_start)); | ||
269 | chunk->code[pos - 1] = num_idx; | ||
270 | next_token(vs); | ||
271 | return; | ||
272 | } | ||
273 | |||
274 | // Else. | ||
275 | emit_constant(chunk, tok, FIXNUM_VAL(0xFF)); | ||
276 | size_t else_pos = array_size(chunk->code); | ||
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); | ||
283 | false_block_start = array_size(chunk->code) - else_pos - 1; | ||
284 | num_idx = add_constant(chunk, FIXNUM_VAL(false_block_start)); | ||
285 | chunk->code[else_pos - 1] = num_idx; | ||
286 | |||
287 | if (peek_token(vs).type != TOKEN_RPAREN) { | ||
288 | error_push((Error){ | ||
289 | .type = ERR_TYPE_COMPILER, | ||
290 | .value = ERR_TOO_MANY_ARGS, | ||
291 | .line = start.line, | ||
292 | .col = start.column, | ||
293 | }); | ||
294 | return; | ||
295 | } | ||
296 | next_token(vs); | ||
297 | } | ||
298 | |||
299 | void | ||
235 | parse_list(Chunk *chunk, Visitor *vs, Token start) { | 300 | parse_list(Chunk *chunk, Visitor *vs, Token start) { |
236 | if (!has_next_token(vs)) { | 301 | if (!has_next_token(vs)) { |
237 | error_push((Error){ | 302 | error_push((Error){ |
@@ -262,6 +327,7 @@ parse_list(Chunk *chunk, Visitor *vs, Token start) { | |||
262 | case TOKEN_NEWLINE: { compile_list_simple_op(chunk, vs, start, OP_NEWLINE); } break; | 327 | case TOKEN_NEWLINE: { compile_list_simple_op(chunk, vs, start, OP_NEWLINE); } break; |
263 | case TOKEN_DEF: { compile_declare_op(chunk, vs, start, OP_DEF); } break; | 328 | case TOKEN_DEF: { compile_declare_op(chunk, vs, start, OP_DEF); } break; |
264 | case TOKEN_SET: { compile_declare_op(chunk, vs, start, OP_SET); } break; | 329 | case TOKEN_SET: { compile_declare_op(chunk, vs, start, OP_SET); } break; |
330 | case TOKEN_IF: { compile_if_op(chunk, vs, start); } break; | ||
265 | default: { | 331 | default: { |
266 | error_push((Error){ | 332 | error_push((Error){ |
267 | .type = ERR_TYPE_COMPILER, | 333 | .type = ERR_TYPE_COMPILER, |