bshell: re-organise build into three separate components
bshell: the front-end binary bshell.runtime: contains the parser, compiler, and classes needed to run bshell scripts bshell.core: contains the builtin commandlets and aliases
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
#include "compile-node.h"
|
||||
|
||||
enum bshell_status compile_if(
|
||||
struct compile_ctx *ctx,
|
||||
struct bshell_ast_node *src)
|
||||
{
|
||||
struct bshell_if_ast_node *if_group;
|
||||
if_group = (struct bshell_if_ast_node *)src;
|
||||
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) {
|
||||
struct bshell_if_branch_ast_node *branch;
|
||||
branch = fx_unbox(
|
||||
struct bshell_if_branch_ast_node,
|
||||
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,
|
||||
BSHELL_OPCODE_BR,
|
||||
0);
|
||||
break;
|
||||
}
|
||||
|
||||
compile_expression(ctx, branch->n_cond);
|
||||
compile_ref_label(ctx, label_ids[i++]);
|
||||
bshell_scriptblock_push_instruction(
|
||||
ctx->c_block,
|
||||
BSHELL_OPCODE_BR_TRUE,
|
||||
0);
|
||||
|
||||
cur = fx_queue_next(cur);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
cur = fx_queue_first(&if_group->n_branches);
|
||||
while (cur) {
|
||||
struct bshell_if_branch_ast_node *branch = fx_unbox(
|
||||
struct bshell_if_branch_ast_node,
|
||||
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,
|
||||
BSHELL_OPCODE_BR,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
compile_define_label(ctx, label_ids[nr_labels - 1]);
|
||||
free(label_ids);
|
||||
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user