lang: codegen: replace codegen_value with a new system for passing different types of values between code generators
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user