lang: codegen: implement message-send code generation and global var references

This commit is contained in:
2025-04-17 21:44:38 +01:00
parent a4504c0507
commit 7b8d77a264
7 changed files with 359 additions and 55 deletions

View File

@@ -19,7 +19,8 @@
*/
enum ivy_status codegen_push_generator(
struct ivy_codegen *gen, enum code_generator_type gen_type, void *arg)
struct ivy_codegen *gen, enum code_generator_type gen_type,
uintptr_t argv, void *argp)
{
const struct code_generator *generator = get_code_generator(gen_type);
if (!generator) {
@@ -38,12 +39,11 @@ enum ivy_status codegen_push_generator(
memset(state, 0x0, generator->g_state_size);
state->s_gen = generator;
state->s_arg = arg;
enum ivy_status status = IVY_OK;
if (generator->g_state_init) {
status = generator->g_state_init(gen, state);
status = generator->g_state_init(gen, state, argv, argp);
}
if (status != IVY_OK) {
@@ -201,6 +201,8 @@ struct codegen_var *codegen_resolve_variable(
if (code_generator_scope_is_top_level(scope)) {
break;
}
cur = b_queue_prev(cur);
}
return NULL;
@@ -303,7 +305,8 @@ struct mie_module *ivy_codegen_get_current_module(struct ivy_codegen *gen)
return gen->c_module;
}
static enum ivy_status pop_generator_recurse(struct ivy_codegen *gen)
static enum ivy_status pop_generator_recurse(
struct ivy_codegen *gen, size_t node_depth)
{
while (1) {
struct mie_value *value = NULL;
@@ -318,14 +321,46 @@ static enum ivy_status pop_generator_recurse(struct ivy_codegen *gen)
struct code_generator_result result
= state->s_gen->g_value_received(gen, state, value);
if (!(result.r_flags & CODEGEN_POP_GENERATOR)) {
bool should_pop = ((result.r_flags & CODEGEN_R_POP_GENERATOR) != 0)
|| node_depth <= state->s_depth;
if (result.r_status != IVY_OK) {
return result.r_status;
}
if (!should_pop) {
return IVY_OK;
}
}
return IVY_OK;
}
static bool node_is_expr(struct ivy_ast_node *node)
{
switch (node->n_type) {
case IVY_AST_OP:
case IVY_AST_MSG:
case IVY_AST_LAMBDA:
case IVY_AST_DISCARD:
case IVY_AST_INT:
case IVY_AST_DOUBLE:
case IVY_AST_STRING:
case IVY_AST_FSTRING:
case IVY_AST_ATOM:
case IVY_AST_IDENT:
case IVY_AST_CASCADE:
case IVY_AST_MATCH:
case IVY_AST_COND_GROUP:
case IVY_AST_TUPLE:
case IVY_AST_PKG_STATIC:
case IVY_AST_PKG_DYNAMIC:
return true;
default:
return false;
}
}
enum ivy_status ivy_codegen_push_node(
struct ivy_codegen *gen, struct ivy_ast_node *node, size_t node_depth)
{
@@ -340,7 +375,7 @@ enum ivy_status ivy_codegen_push_node(
return IVY_ERR_BAD_SYNTAX;
}
codegen_push_generator(gen, generator->g_type, 0);
codegen_push_generator(gen, generator->g_type, 0, NULL);
}
while (true) {
@@ -358,7 +393,7 @@ enum ivy_status ivy_codegen_push_node(
state->s_root = node;
state->s_depth = node_depth;
} else if (node_depth <= state->s_depth) {
status = pop_generator_recurse(gen);
status = pop_generator_recurse(gen, node_depth);
}
if (status != IVY_OK) {
@@ -368,16 +403,21 @@ enum ivy_status ivy_codegen_push_node(
state = get_current_generator_state(gen);
const struct code_generator *generator = state->s_gen;
bool is_expr = node_is_expr(node);
code_generator_node_callback func
= generator->g_node_generators[node->n_type];
if (!func && is_expr) {
func = generator->g_expr_generator;
}
if (!func) {
return IVY_OK;
}
result = func(gen, state, node, node_depth);
if (result.r_flags & CODEGEN_REPEAT_NODE) {
if (result.r_flags & CODEGEN_R_REPEAT_NODE) {
continue;
}