From 6844f498c522f1448ce287bc97220579012baf0a Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 8 Sep 2025 16:17:29 +0100 Subject: [PATCH] lang: codegen: replace codegen_value with a new system for passing different types of values between code generators --- lang/codegen/block.c | 2 +- lang/codegen/codegen.c | 98 +++++++++++++++++++++------------------ lang/codegen/codegen.h | 43 +++++++++++------ lang/codegen/cond-group.c | 4 +- lang/codegen/cond.c | 2 +- lang/codegen/expr.c | 14 ++++-- lang/codegen/for-loop.c | 4 +- lang/codegen/fstring.c | 8 ++-- lang/codegen/lambda.c | 13 ++---- lang/codegen/msg.c | 11 +++-- lang/codegen/return.c | 4 +- lang/codegen/unit.c | 2 +- 12 files changed, 114 insertions(+), 91 deletions(-) diff --git a/lang/codegen/block.c b/lang/codegen/block.c index 2820c7f..7f6607e 100644 --- a/lang/codegen/block.c +++ b/lang/codegen/block.c @@ -68,7 +68,7 @@ static enum ivy_status state_init( static enum ivy_status state_fini( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value **result) + struct code_generator_value *result) { return IVY_OK; } diff --git a/lang/codegen/codegen.c b/lang/codegen/codegen.c index 72c3b15..79fa06d 100644 --- a/lang/codegen/codegen.c +++ b/lang/codegen/codegen.c @@ -57,7 +57,7 @@ enum ivy_status codegen_push_generator( } enum ivy_status codegen_pop_generator( - struct ivy_codegen *gen, struct mie_value **result) + struct ivy_codegen *gen, struct code_generator_value *result) { b_queue_entry *entry = b_queue_pop_back(&gen->c_state); if (!entry) { @@ -81,42 +81,6 @@ enum ivy_status codegen_pop_generator( return IVY_OK; } -struct codegen_value *codegen_value_create( - struct ivy_ast_node *node, struct mie_value *val) -{ - struct codegen_value *out = malloc(sizeof *out); - if (!out) { - return NULL; - } - - memset(out, 0x0, sizeof *out); - - out->v_node = node; - out->v_value = val; - - return out; -} - -void codegen_value_destroy(struct codegen_value *val) -{ - free(val); -} - -void codegen_push_value(struct ivy_codegen *gen, struct codegen_value *value) -{ - b_queue_push_back(&gen->c_values, &value->v_entry); -} - -struct codegen_value *codegen_pop_value(struct ivy_codegen *gen) -{ - b_queue_entry *entry = b_queue_pop_back(&gen->c_values); - if (!entry) { - return NULL; - } - - return b_unbox(struct codegen_value, entry, v_entry); -} - enum ivy_status codegen_define_variable( struct ivy_codegen *gen, const char *ident, const struct codegen_var *var) { @@ -305,9 +269,15 @@ struct mie_module *ivy_codegen_get_current_module(struct ivy_codegen *gen) static enum ivy_status pop_generator_recurse( struct ivy_codegen *gen, size_t node_depth) { + enum ivy_status status; + while (1) { - struct mie_value *value = NULL; - codegen_pop_generator(gen, &value); + struct code_generator_value value = {0}; + status = codegen_pop_generator(gen, &value); + if (status != IVY_OK) { + return status; + } + struct code_generator_state *state = get_current_generator_state(gen); @@ -320,7 +290,7 @@ static enum ivy_status pop_generator_recurse( }; if (state->s_gen->g_value_received) { - state->s_gen->g_value_received(gen, state, value); + state->s_gen->g_value_received(gen, state, &value); } bool should_pop = ((result.r_flags & CODEGEN_R_POP_GENERATOR) != 0) @@ -431,11 +401,18 @@ enum ivy_status ivy_codegen_push_node( enum ivy_status ivy_codegen_push_eof(struct ivy_codegen *gen) { - struct code_generator_result result; + enum ivy_status status = IVY_OK; + struct code_generator_result result = { + .r_status = IVY_OK, + }; while (!b_queue_empty(&gen->c_state)) { - struct mie_value *value = NULL; - codegen_pop_generator(gen, &value); + struct code_generator_value value = {0}; + status = codegen_pop_generator(gen, &value); + if (status != IVY_OK) { + return status; + } + struct code_generator_state *state = get_current_generator_state(gen); @@ -443,7 +420,7 @@ enum ivy_status ivy_codegen_push_eof(struct ivy_codegen *gen) continue; } - result = state->s_gen->g_value_received(gen, state, value); + result = state->s_gen->g_value_received(gen, state, &value); if (result.r_status != IVY_OK) { break; @@ -452,3 +429,36 @@ enum ivy_status ivy_codegen_push_eof(struct ivy_codegen *gen) return result.r_status; } + +struct mie_value *code_generator_value_get_mie_value(struct code_generator_value *vp) +{ + if (vp->v_type != CODE_GENERATOR_VALUE_MIE_VALUE) { + return NULL; + } + + return vp->v_value.mie_value; +} + +void code_generator_value_set_mie_value( + struct code_generator_value *vp, struct mie_value *value) +{ + vp->v_type = CODE_GENERATOR_VALUE_MIE_VALUE; + vp->v_value.mie_value = value; +} + +extern struct mie_phi_edge *code_generator_value_get_phi_edge( + struct code_generator_value *vp) +{ + if (vp->v_type != CODE_GENERATOR_VALUE_PHI_EDGE) { + return NULL; + } + + return vp->v_value.phi_edge; +} + +void code_generator_value_set_phi_edge( + struct code_generator_value *vp, struct mie_phi_edge *edge) +{ + vp->v_type = CODE_GENERATOR_VALUE_PHI_EDGE; + vp->v_value.phi_edge = edge; +} diff --git a/lang/codegen/codegen.h b/lang/codegen/codegen.h index fe8e6c8..be837b5 100644 --- a/lang/codegen/codegen.h +++ b/lang/codegen/codegen.h @@ -57,6 +57,12 @@ enum code_generator_scope_type { CODE_GENERATOR_SCOPE_BLOCK, }; +enum code_generator_value_type { + CODE_GENERATOR_VALUE_NONE = 0, + CODE_GENERATOR_VALUE_MIE_VALUE, + CODE_GENERATOR_VALUE_PHI_EDGE, +}; + struct code_generator_result { enum ivy_status r_status; @@ -66,10 +72,13 @@ struct code_generator_result { } r_flags; }; -struct codegen_value { - b_queue_entry v_entry; - struct ivy_ast_node *v_node; - struct mie_value *v_value; +struct code_generator_value { + enum code_generator_value_type v_type; + + union { + struct mie_value *mie_value; + struct mie_phi_edge *phi_edge; + } v_value; }; struct code_generator_state; @@ -77,14 +86,16 @@ struct code_generator_state; typedef enum ivy_status (*code_generator_state_init_callback)( struct ivy_codegen *, struct code_generator_state *, uintptr_t, void *); typedef enum ivy_status (*code_generator_state_fini_callback)( - struct ivy_codegen *, struct code_generator_state *, struct mie_value **); + struct ivy_codegen *, struct code_generator_state *, + struct code_generator_value *); typedef struct code_generator_result (*code_generator_callback)( struct ivy_codegen *); typedef struct code_generator_result (*code_generator_node_callback)( struct ivy_codegen *, struct code_generator_state *, struct ivy_ast_node *, size_t); typedef struct code_generator_result (*code_generator_value_received_callback)( - struct ivy_codegen *, struct code_generator_state *, struct mie_value *); + struct ivy_codegen *, struct code_generator_state *, + struct code_generator_value *); typedef enum ivy_status (*code_generator_define_variable_callback)( struct ivy_codegen *, struct code_generator_state *, const char *, const struct codegen_var *); @@ -136,14 +147,7 @@ extern enum ivy_status codegen_push_generator( struct ivy_codegen *gen, enum code_generator_type gen_type, uintptr_t argv, void *argp); extern enum ivy_status codegen_pop_generator( - struct ivy_codegen *gen, struct mie_value **result); - -extern struct codegen_value *codegen_value_create( - struct ivy_ast_node *node, struct mie_value *val); -extern void codegen_value_destroy(struct codegen_value *val); - -extern void codegen_push_value(struct ivy_codegen *gen, struct codegen_value *val); -extern struct codegen_value *codegen_pop_value(struct ivy_codegen *gen); + struct ivy_codegen *gen, struct code_generator_value *result); extern enum ivy_status codegen_define_variable( struct ivy_codegen *gen, const char *ident, const struct codegen_var *var); @@ -151,5 +155,16 @@ extern enum ivy_status codegen_resolve_variable( struct ivy_codegen *gen, const char *ident, struct codegen_var *out); extern struct mie_value *codegen_load_variable( struct ivy_codegen *gen, struct codegen_var *var); +extern void codegen_store_variable( + struct ivy_codegen *gen, struct codegen_var *var, struct mie_value *val); + +extern struct mie_value *code_generator_value_get_mie_value( + struct code_generator_value *vp); +extern void code_generator_value_set_mie_value( + struct code_generator_value *vp, struct mie_value *value); +extern struct mie_phi_edge *code_generator_value_get_phi_edge( + struct code_generator_value *vp); +extern void code_generator_value_set_phi_edge( + struct code_generator_value *vp, struct mie_phi_edge *edge); #endif diff --git a/lang/codegen/cond-group.c b/lang/codegen/cond-group.c index 11ee2e8..13ef730 100644 --- a/lang/codegen/cond-group.c +++ b/lang/codegen/cond-group.c @@ -48,7 +48,7 @@ static enum ivy_status state_init( static enum ivy_status state_fini( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value **result) + struct code_generator_value *result) { debug_printf("codegen: end of cond group\n"); struct cond_group_codegen_state *group @@ -68,7 +68,7 @@ static enum ivy_status state_fini( static struct code_generator_result value_received( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value *value) + struct code_generator_value *value) { struct cond_group_codegen_state *cond = (struct cond_group_codegen_state *)state; diff --git a/lang/codegen/cond.c b/lang/codegen/cond.c index 9d0395c..30b95bf 100644 --- a/lang/codegen/cond.c +++ b/lang/codegen/cond.c @@ -79,7 +79,7 @@ static enum ivy_status state_init( static enum ivy_status state_fini( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value **result) + struct code_generator_value *result) { debug_printf("codegen: end of cond\n"); struct cond_codegen_state *cond = (struct cond_codegen_state *)state; diff --git a/lang/codegen/expr.c b/lang/codegen/expr.c index 26538fd..76d4ded 100644 --- a/lang/codegen/expr.c +++ b/lang/codegen/expr.c @@ -363,7 +363,7 @@ static enum ivy_status state_init( static enum ivy_status state_fini( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value **result) + struct code_generator_value *result) { debug_printf("codegen: end of expression\n"); @@ -472,19 +472,23 @@ static enum ivy_status state_fini( } struct expr_item *result_item = b_unbox(struct expr_item, cur, i_entry); + struct mie_value *result_value; if (result_item->i_operand_type == EXPR_OPERAND_VAR) { - *result = codegen_load_variable(gen, &result_item->i_var); + result_value = load_variable(gen, &result_item->i_var); } else { - *result = result_item->i_value; + result_value = result_item->i_value; } free(result_item); - return IVY_OK; + result->v_type = CODE_GENERATOR_VALUE_MIE_VALUE; + result->v_value.mie_value = result_value; + + return status; } static struct code_generator_result value_received( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value *value) + struct code_generator_value *value) { struct expr_codegen_state *expr = (struct expr_codegen_state *)state; diff --git a/lang/codegen/for-loop.c b/lang/codegen/for-loop.c index 2699846..4729079 100644 --- a/lang/codegen/for-loop.c +++ b/lang/codegen/for-loop.c @@ -37,14 +37,14 @@ static enum ivy_status state_init( static enum ivy_status state_fini( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value **result) + struct code_generator_value *result) { return IVY_OK; } static struct code_generator_result value_received( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value *value) + struct code_generator_value *value) { struct for_codegen_state *for_loop = (struct for_codegen_state *)state; diff --git a/lang/codegen/fstring.c b/lang/codegen/fstring.c index fd963a4..94d15c5 100644 --- a/lang/codegen/fstring.c +++ b/lang/codegen/fstring.c @@ -49,7 +49,7 @@ static enum ivy_status state_init( static enum ivy_status state_fini( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value **result) + struct code_generator_value *result) { debug_printf("codegen: end of fstring\n"); struct fstring_codegen_state *fstring @@ -62,13 +62,13 @@ static enum ivy_status state_fini( gen->c_builder, id, fstring->s_stringbuilder, sel, NULL, 0, 0, NULL); - *result = str; + code_generator_value_set_mie_value(result, str); return IVY_OK; } static struct code_generator_result value_received( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value *value) + struct code_generator_value *value) { struct fstring_codegen_state *fstring = (struct fstring_codegen_state *)state; @@ -78,7 +78,7 @@ static struct code_generator_result value_received( mie_builder_msg( gen->c_builder, void_type, fstring->s_stringbuilder, sel, - &value, 1, MIE_BUILDER_IGNORE_RESULT, NULL); + &value->v_value.mie_value, 1, MIE_BUILDER_IGNORE_RESULT, NULL); return CODEGEN_RESULT_OK(0); } diff --git a/lang/codegen/lambda.c b/lang/codegen/lambda.c index a40dfb7..c1a2ea1 100644 --- a/lang/codegen/lambda.c +++ b/lang/codegen/lambda.c @@ -147,13 +147,14 @@ static enum ivy_status state_init( static enum ivy_status state_fini( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value **result) + struct code_generator_value *result) { struct lambda_codegen_state *lambda = (struct lambda_codegen_state *)state; switch_to_outer_block(gen, lambda); mie_module_add_function(gen->c_module, lambda->s_func, ".anon"); - *result = MIE_VALUE(lambda->s_ctx_external); + result->v_type = CODE_GENERATOR_VALUE_MIE_VALUE; + result->v_value.mie_value = MIE_VALUE(lambda->s_ctx_external); codegen_var_map_fini(&lambda->s_args); codegen_var_map_fini(&lambda->s_captured_vars); @@ -244,19 +245,11 @@ static enum ivy_status capture_var( return IVY_OK; } -static struct code_generator_result value_received( - struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value *value) -{ - return CODEGEN_RESULT_OK(0); -} - struct code_generator lambda_generator = { .g_type = CODE_GENERATOR_LAMBDA, .g_state_size = sizeof(struct lambda_codegen_state), .g_state_init = state_init, .g_state_fini = state_fini, - .g_value_received = value_received, .g_resolve_var = resolve_var, .g_capture_var = capture_var, .g_node_generators = { diff --git a/lang/codegen/msg.c b/lang/codegen/msg.c index e1a63cb..bc14e97 100644 --- a/lang/codegen/msg.c +++ b/lang/codegen/msg.c @@ -142,7 +142,7 @@ static void serialise_selector( static enum ivy_status state_fini( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value **result) + struct code_generator_value *result) { debug_printf("codegen: end of msg\n"); @@ -179,19 +179,20 @@ static enum ivy_status state_fini( free(msg->s_args); } - *result = msg_send; + result->v_type = CODE_GENERATOR_VALUE_MIE_VALUE; + result->v_value.mie_value = msg_send; return IVY_OK; } static struct code_generator_result value_received( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value *value) + struct code_generator_value *value) { struct msg_codegen_state *msg = (struct msg_codegen_state *)state; switch (msg->s_prev_part) { case MSG_START: - msg->s_recipient = value; + msg->s_recipient = value->v_value.mie_value; msg->s_prev_part = MSG_RECIPIENT; break; case MSG_RECIPIENT: @@ -204,7 +205,7 @@ static struct code_generator_result value_received( return CODEGEN_RESULT_ERR(IVY_ERR_BAD_SYNTAX); } - msg->s_args[msg->s_nr_args++] = value; + msg->s_args[msg->s_nr_args++] = value->v_value.mie_value; break; default: break; diff --git a/lang/codegen/return.c b/lang/codegen/return.c index bee3c8c..71de987 100644 --- a/lang/codegen/return.c +++ b/lang/codegen/return.c @@ -48,7 +48,7 @@ static enum ivy_status state_init( static enum ivy_status state_fini( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value **result) + struct code_generator_value *result) { debug_printf("codegen: end of return\n"); struct return_codegen_state *ret = (struct return_codegen_state *)state; @@ -60,7 +60,7 @@ static enum ivy_status state_fini( static struct code_generator_result value_received( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value *value) + struct code_generator_value *value) { debug_printf("codegen: return value received\n"); diff --git a/lang/codegen/unit.c b/lang/codegen/unit.c index 8c6214c..c1f90ba 100644 --- a/lang/codegen/unit.c +++ b/lang/codegen/unit.c @@ -199,7 +199,7 @@ static enum ivy_status state_init( static enum ivy_status state_fini( struct ivy_codegen *gen, struct code_generator_state *state, - struct mie_value **result) + struct code_generator_value *result) { struct unit_codegen_state *unit = (struct unit_codegen_state *)state; codegen_var_map_fini(&unit->s_vars);