2026-05-17 15:33:44 +01:00
|
|
|
#include "compile-node.h"
|
|
|
|
|
|
2026-05-25 10:33:29 +01:00
|
|
|
enum bshell_status compile_if(
|
|
|
|
|
struct compile_ctx *ctx,
|
|
|
|
|
struct bshell_ast_node *src)
|
2026-05-17 15:33:44 +01:00
|
|
|
{
|
2026-05-25 10:33:29 +01:00
|
|
|
struct bshell_if_ast_node *if_group;
|
|
|
|
|
if_group = (struct bshell_if_ast_node *)src;
|
2026-05-17 15:33:44 +01:00
|
|
|
size_t nr_labels = fx_queue_length(&if_group->n_branches);
|
|
|
|
|
// add one extra label for the end of the if group
|
|
|
|
|
nr_labels++;
|
|
|
|
|
|
|
|
|
|
size_t *label_ids = calloc(nr_labels, sizeof *label_ids);
|
|
|
|
|
if (!label_ids) {
|
|
|
|
|
return BSHELL_ERR_NO_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t i;
|
|
|
|
|
for (i = 0; i < nr_labels; i++) {
|
|
|
|
|
label_ids[i] = compile_declare_label(ctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
fx_queue_entry *cur = fx_queue_first(&if_group->n_branches);
|
|
|
|
|
while (cur) {
|
2026-05-25 10:33:29 +01:00
|
|
|
struct bshell_if_branch_ast_node *branch;
|
|
|
|
|
branch = fx_unbox(
|
|
|
|
|
struct bshell_if_branch_ast_node,
|
2026-05-17 15:33:44 +01:00
|
|
|
cur,
|
|
|
|
|
n_base.n_entry);
|
|
|
|
|
if (!branch->n_cond) {
|
|
|
|
|
compile_block_immediate(ctx, branch->n_body);
|
|
|
|
|
compile_ref_label(ctx, label_ids[nr_labels - 1]);
|
|
|
|
|
bshell_scriptblock_push_instruction(
|
|
|
|
|
ctx->c_block,
|
2026-05-25 10:33:29 +01:00
|
|
|
BSHELL_OPCODE_BR,
|
2026-05-17 15:33:44 +01:00
|
|
|
0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
compile_expression(ctx, branch->n_cond);
|
|
|
|
|
compile_ref_label(ctx, label_ids[i++]);
|
|
|
|
|
bshell_scriptblock_push_instruction(
|
|
|
|
|
ctx->c_block,
|
2026-05-25 10:33:29 +01:00
|
|
|
BSHELL_OPCODE_BR_TRUE,
|
2026-05-17 15:33:44 +01:00
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
cur = fx_queue_next(cur);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
cur = fx_queue_first(&if_group->n_branches);
|
|
|
|
|
while (cur) {
|
2026-05-25 10:33:29 +01:00
|
|
|
struct bshell_if_branch_ast_node *branch = fx_unbox(
|
|
|
|
|
struct bshell_if_branch_ast_node,
|
2026-05-17 15:33:44 +01:00
|
|
|
cur,
|
|
|
|
|
n_base.n_entry);
|
|
|
|
|
if (!branch->n_cond) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
compile_define_label(ctx, label_ids[i++]);
|
|
|
|
|
compile_block_immediate(ctx, branch->n_body);
|
|
|
|
|
cur = fx_queue_next(cur);
|
|
|
|
|
|
|
|
|
|
if (i < nr_labels - 2) {
|
|
|
|
|
compile_ref_label(ctx, label_ids[nr_labels - 1]);
|
|
|
|
|
bshell_scriptblock_push_instruction(
|
|
|
|
|
ctx->c_block,
|
2026-05-25 10:33:29 +01:00
|
|
|
BSHELL_OPCODE_BR,
|
2026-05-17 15:33:44 +01:00
|
|
|
0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
compile_define_label(ctx, label_ids[nr_labels - 1]);
|
|
|
|
|
free(label_ids);
|
|
|
|
|
|
|
|
|
|
return BSHELL_SUCCESS;
|
|
|
|
|
}
|