lang: codegen: implement message-send code generation and global var references
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user