aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode/compiler.h
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-24 15:42:01 +0200
committerBad Diode <bd@badd10de.dev>2021-10-24 15:42:01 +0200
commitdd5210368634e2b322435385eaaaccaa5125b5a9 (patch)
tree81c2bb47907281a82a198ed8cb28d9b7e34e7bf3 /src/bytecode/compiler.h
parentd90b9f42a361bc3563b1f11bbd707c4288a65b40 (diff)
downloadbdl-dd5210368634e2b322435385eaaaccaa5125b5a9.tar.gz
bdl-dd5210368634e2b322435385eaaaccaa5125b5a9.zip
Add initial IF implementation
Diffstat (limited to 'src/bytecode/compiler.h')
-rwxr-xr-xsrc/bytecode/compiler.h66
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
234void 234void
235compile_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
299void
235parse_list(Chunk *chunk, Visitor *vs, Token start) { 300parse_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,