aboutsummaryrefslogtreecommitdiffstats
path: root/src/compiler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler.c')
-rw-r--r--src/compiler.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/src/compiler.c b/src/compiler.c
index 5bddcb6..f46d00d 100644
--- a/src/compiler.c
+++ b/src/compiler.c
@@ -504,34 +504,49 @@ compile_if(Chunk *chunk, Node *node) {
504 } 504 }
505 } 505 }
506 506
507 // Jump to the end of the expression. 507 if (node->cond_else) {
508 sz jump_b = array_size(chunk->code); 508 // Jump to the end of the expression.
509 EMIT_OP(OP_JMPI, 0xff, 0, 0, node->cond_if, chunk); 509 sz jump_b = array_size(chunk->code);
510 510 EMIT_OP(OP_JMPI, 0xff, 0, 0, node->cond_else, chunk);
511 // Else expression. 511
512 CompResult else_expr = compile_expr(chunk, node->cond_else); 512 // Else expression.
513 if (has_value) { 513 CompResult else_expr = compile_expr(chunk, node->cond_else);
514 switch (else_expr.type) { 514 if (has_value) {
515 case COMP_CONST: { 515 switch (else_expr.type) {
516 EMIT_OP(OP_LD64K, reg_dst, else_expr.idx, 0, node->cond_if, 516 case COMP_CONST: {
517 chunk); 517 EMIT_OP(OP_LD64K, reg_dst, else_expr.idx, 0,
518 } break; 518 node->cond_else, chunk);
519 case COMP_REG: { 519 } break;
520 EMIT_OP(OP_MOV64, reg_dst, else_expr.idx, 0, node->cond_if, 520 case COMP_REG: {
521 chunk); 521 EMIT_OP(OP_MOV64, reg_dst, else_expr.idx, 0,
522 } break; 522 node->cond_else, chunk);
523 default: { 523 } break;
524 return (CompResult){.type = COMP_ERR}; 524 default: {
525 } break; 525 return (CompResult){.type = COMP_ERR};
526 } break;
527 }
528 }
529 sz end_expr = array_size(chunk->code);
530
531 // Backpatch jumps.
532 sz const_a = add_constant(chunk, jump_b + 1 - jump_a);
533 sz const_b = add_constant(chunk, end_expr - jump_b);
534 chunk->code[jump_a].a = const_a;
535 chunk->code[jump_b].dst = const_b;
536 } else {
537 sz end_expr = array_size(chunk->code);
538 if (has_value) {
539 sz const_a = add_constant(chunk, end_expr + 1 - jump_a);
540 chunk->code[jump_a].a = const_a;
541 sz zero = add_constant(chunk, 0);
542 sz end = add_constant(chunk, 2);
543 EMIT_OP(OP_JMPI, end, 0, 0, node, chunk);
544 EMIT_OP(OP_LD64K, reg_dst, zero, 0, node, chunk);
545 } else {
546 sz const_a = add_constant(chunk, end_expr - jump_a);
547 chunk->code[jump_a].a = const_a;
526 } 548 }
527 } 549 }
528 sz end_expr = array_size(chunk->code);
529
530 // Backpatch jumps.
531 sz const_a = add_constant(chunk, jump_b + 1 - jump_a);
532 sz const_b = add_constant(chunk, end_expr - jump_b);
533 chunk->code[jump_a].a = const_a;
534 chunk->code[jump_b].dst = const_b;
535 // TODO: does it has an else or not? Moreover, should we enforce on the 550 // TODO: does it has an else or not? Moreover, should we enforce on the
536 // semantic level that if the `if` expression returns a value we must add an 551 // semantic level that if the `if` expression returns a value we must add an
537 // else? 552 // else?