#include "../debug.h" #include "codegen.h" #include #include #include struct return_codegen_state { struct code_generator_state s_base; unsigned int s_prev_node; struct mie_value *s_value; }; 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 return_codegen_state *ret = (struct return_codegen_state *)state; if (ret->s_prev_node != 0) { return CODEGEN_RESULT_ERR(IVY_ERR_BAD_SYNTAX); } ret->s_prev_node = IVY_AST_RETURN; return CODEGEN_RESULT_OK(0); } static struct code_generator_result gen_value_expr( struct ivy_codegen *gen, struct code_generator_state *state, struct ivy_ast_node *node, size_t depth) { struct return_codegen_state *ret = (struct return_codegen_state *)state; if (ret->s_prev_node != IVY_AST_RETURN) { return CODEGEN_RESULT_ERR(IVY_ERR_BAD_SYNTAX); } codegen_push_generator(gen, CODE_GENERATOR_EXPR, 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) { debug_printf("codegen: start of return\n"); return IVY_OK; } static enum ivy_status state_fini( struct ivy_codegen *gen, struct code_generator_state *state, struct code_generator_value *result) { debug_printf("codegen: end of return\n"); struct return_codegen_state *ret = (struct return_codegen_state *)state; mie_builder_ret(gen->c_builder, ret->s_value); return IVY_OK; } static struct code_generator_result value_received( struct ivy_codegen *gen, struct code_generator_state *state, struct code_generator_value *value) { debug_printf("codegen: return value received\n"); struct return_codegen_state *ret = (struct return_codegen_state *)state; if (ret->s_value || ret->s_prev_node != IVY_AST_RETURN) { return CODEGEN_RESULT_ERR(IVY_ERR_BAD_SYNTAX); } ret->s_value = value->v_value.mie_value; ret->s_prev_node = IVY_AST_EXPR; return CODEGEN_RESULT_OK(CODEGEN_R_POP_GENERATOR); } struct code_generator return_generator = { .g_type = CODE_GENERATOR_RETURN, .g_state_size = sizeof(struct return_codegen_state), .g_state_init = state_init, .g_state_fini = state_fini, .g_value_received = value_received, .g_expr_generator = gen_value_expr, .g_node_generators = { [IVY_AST_RETURN] = gen_return, }, };