#include "codegen.h" #include #include #include struct block_codegen_state { struct code_generator_state s_base; struct code_generator_scope *s_scope; struct codegen_var_map s_vars; }; static struct code_generator_result gen_expr( struct ivy_codegen *gen, struct code_generator_state *state, struct ivy_ast_node *node, size_t depth) { struct block_codegen_state *block = (struct block_codegen_state *)state; struct mie_builder *builder = gen->c_builder; struct mie_func *current = mie_builder_get_current_func(builder); codegen_push_generator( gen, CODE_GENERATOR_EXPR, CODEGEN_F_IGNORE_RESULT, NULL); return CODEGEN_RESULT_OK(CODEGEN_R_REPEAT_NODE); } static struct code_generator_result gen_var_declaration( struct ivy_codegen *gen, struct code_generator_state *state, struct ivy_ast_node *node, size_t depth) { struct block_codegen_state *block = (struct block_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 (status != IVY_OK) { return CODEGEN_RESULT_ERR(status); } codegen_push_generator(gen, CODE_GENERATOR_VAR, 0, NULL); return CODEGEN_RESULT_OK(CODEGEN_R_REPEAT_NODE); } static struct code_generator_result gen_return( struct ivy_codegen *gen, struct code_generator_state *state, struct ivy_ast_node *node, size_t depth) { struct block_codegen_state *block = (struct block_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 (status != IVY_OK) { return CODEGEN_RESULT_ERR(status); } codegen_push_generator(gen, CODE_GENERATOR_RETURN, 0, NULL); return CODEGEN_RESULT_OK(CODEGEN_R_REPEAT_NODE); } static enum ivy_status state_init( struct ivy_codegen *gen, struct code_generator_state *state, uintptr_t argv, void *argp) { struct block_codegen_state *block = (struct block_codegen_state *)state; codegen_var_map_init(&block->s_vars); return IVY_OK; } static enum ivy_status state_fini( struct ivy_codegen *gen, struct code_generator_state *state, struct code_generator_value *result) { return IVY_OK; } static enum ivy_status define_var( struct ivy_codegen *gen, struct code_generator_state *state, const char *ident, const struct codegen_var *var) { struct block_codegen_state *block = (struct block_codegen_state *)state; return codegen_var_map_put(&block->s_vars, ident, var); } static enum ivy_status resolve_var( struct ivy_codegen *gen, struct code_generator_state *state, const char *ident, struct codegen_var *var) { struct block_codegen_state *block = (struct block_codegen_state *)state; struct codegen_var *result = NULL; enum ivy_status status = codegen_var_map_get(&block->s_vars, ident, &result); if (status != IVY_OK) { return status; } memcpy(var, result, sizeof *var); return IVY_OK; } struct code_generator block_generator = { .g_type = CODE_GENERATOR_BLOCK, .g_state_size = sizeof(struct block_codegen_state), .g_state_init = state_init, .g_state_fini = state_fini, .g_node_generators = { NODE_CODEGEN(RETURN, gen_return), }, .g_expr_generator = gen_expr, .g_define_var = define_var, .g_resolve_var = resolve_var, };