#include "codegen.h" #include #include #include struct unit_codegen_state { struct code_generator_state s_base; /* function for top-level statements */ struct mie_func *s_immediate; }; static enum ivy_status switch_to_immediate_func( struct ivy_codegen *gen, struct unit_codegen_state *unit) { if (!unit->s_immediate) { struct mie_type *ret_type = mie_ctx_get_type(gen->c_ctx, MIE_TYPE_VOID); unit->s_immediate = mie_func_create( "init", MIE_FUNC_STATIC, ret_type, NULL, 0); if (!unit->s_immediate) { return IVY_ERR_NO_MEMORY; } mie_module_add_function(gen->c_module, unit->s_immediate); } struct mie_block *block = mie_func_get_last_block(unit->s_immediate); if (!block || mie_block_is_terminated(block)) { block = mie_func_create_block(unit->s_immediate, NULL); mie_func_insert_block(unit->s_immediate, block, NULL); } mie_builder_set_insert_point(gen->c_builder, block); return IVY_OK; } static struct code_generator_result gen_expr( struct ivy_codegen *gen, struct code_generator_state *state, struct ivy_ast_node *node) { struct unit_codegen_state *unit = (struct unit_codegen_state *)state; struct mie_builder *builder = gen->c_builder; struct mie_func *current = mie_builder_get_current_func(builder); enum ivy_status status = IVY_OK; if (!current || current != unit->s_immediate) { status = switch_to_immediate_func(gen, unit); } if (status != IVY_OK) { return CODEGEN_RESULT_ERR(status); } codegen_push_generator(gen, CODE_GENERATOR_EXPR, NULL); return CODEGEN_RESULT_OK(CODEGEN_REPEAT_NODE); } struct code_generator unit_generator = { .g_type = CODE_GENERATOR_UNIT, .g_state_size = sizeof(struct unit_codegen_state), .g_node_generators_pre = { [IVY_AST_INT] = gen_expr, [IVY_AST_OP] = gen_expr, }, };