lang: codegen: implement cond-group code generation

This commit is contained in:
2025-04-28 15:44:44 +01:00
parent 6af9b62b88
commit 64d1015a3c
8 changed files with 327 additions and 22 deletions

View File

@@ -9,6 +9,10 @@
#include <mie/record.h>
#include <stdlib.h>
enum {
ENSURE_OPEN_BLOCK = 0x01u,
};
struct unit_codegen_state {
struct code_generator_state s_base;
struct code_generator_scope *s_scope;
@@ -19,7 +23,7 @@ struct unit_codegen_state {
};
static enum ivy_status switch_to_immediate_func(
struct ivy_codegen *gen, struct unit_codegen_state *unit)
struct ivy_codegen *gen, struct unit_codegen_state *unit, long flags)
{
if (!unit->s_immediate) {
struct mie_type *ret_type
@@ -46,7 +50,7 @@ static enum ivy_status switch_to_immediate_func(
mie_func_insert_block(unit->s_immediate, block, NULL);
}
if (mie_block_is_terminated(block)) {
if (mie_block_is_terminated(block) && (flags & ENSURE_OPEN_BLOCK)) {
block = mie_func_create_block(unit->s_immediate, NULL);
mie_func_insert_block(unit->s_immediate, block, NULL);
}
@@ -82,7 +86,7 @@ static struct code_generator_result gen_expr(
enum ivy_status status = IVY_OK;
if (!current || current != unit->s_immediate) {
status = switch_to_immediate_func(gen, unit);
status = switch_to_immediate_func(gen, unit, ENSURE_OPEN_BLOCK);
}
if (status != IVY_OK) {
@@ -172,7 +176,7 @@ static struct code_generator_result gen_var_declaration(
enum ivy_status status = IVY_OK;
if (!current || current != unit->s_immediate) {
status = switch_to_immediate_func(gen, unit);
status = switch_to_immediate_func(gen, unit, ENSURE_OPEN_BLOCK);
}
if (status != IVY_OK) {
@@ -193,7 +197,7 @@ static struct code_generator_result gen_return(
enum ivy_status status = IVY_OK;
if (!current || current != unit->s_immediate) {
status = switch_to_immediate_func(gen, unit);
status = switch_to_immediate_func(gen, unit, ENSURE_OPEN_BLOCK);
}
if (status != IVY_OK) {
@@ -258,6 +262,18 @@ static enum ivy_status state_fini(
struct unit_codegen_state *unit = (struct unit_codegen_state *)state;
codegen_var_map_fini(&unit->s_vars);
struct mie_func *current = mie_builder_get_current_func(gen->c_builder);
enum ivy_status status = IVY_OK;
if (!current || current != unit->s_immediate) {
status = switch_to_immediate_func(gen, unit, 0);
}
struct mie_block *block = mie_builder_get_current_block(gen->c_builder);
if (!block->b_terminator) {
mie_builder_ret(gen->c_builder, NULL);
}
return IVY_OK;
}