#include "../debug.h" #include "codegen.h" #include #include #include #if 0 struct var_codegen_state { struct code_generator_state s_base; unsigned int s_prev_node; /* TODO support multiple idents (for tuples) */ struct ivy_ast_ident_node *s_var_ident; struct mie_value *s_var_ptr; struct mie_value *s_value; }; static struct code_generator_result gen_var( struct ivy_codegen *gen, struct code_generator_state *state, struct ivy_ast_node *node, size_t depth) { struct var_codegen_state *var = (struct var_codegen_state *)state; if (var->s_prev_node != 0) { return CODEGEN_RESULT_ERR(IVY_ERR_BAD_SYNTAX); } var->s_prev_node = IVY_AST_VAR; 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 var_codegen_state *var = (struct var_codegen_state *)state; if (var->s_prev_node != IVY_AST_IDENT && var->s_prev_node != IVY_AST_TUPLE) { 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 struct code_generator_result gen_ident( struct ivy_codegen *gen, struct code_generator_state *state, struct ivy_ast_node *node, size_t depth) { struct var_codegen_state *var = (struct var_codegen_state *)state; if (var->s_prev_node != IVY_AST_VAR) { return gen_value_expr(gen, state, node, depth); } struct ivy_ast_ident_node *ident = (struct ivy_ast_ident_node *)node; const char *var_name = ident->n_content->t_str; /* TODO get type from expression */ struct mie_type *id = mie_ctx_get_type(gen->c_ctx, MIE_TYPE_ID); struct mie_value *var_ptr = mie_builder_alloca(gen->c_builder, id, var_name); var->s_var_ident = (struct ivy_ast_ident_node *)node; var->s_var_ptr = var_ptr; var->s_prev_node = IVY_AST_IDENT; return CODEGEN_RESULT_OK(0); } #if 0 static struct code_generator_result gen_var_ref( struct ivy_codegen *gen, struct code_generator_state *state, struct ivy_ast_node *node) { struct ivy_ast_ident_node *ident = (struct ivy_ast_ident_node *)node; struct codegen_var *var = codegen_resolve_variable(gen, ident->n_content->t_str); if (var) { /* this variable has been defined previously, and we have a * mie_value representing its location on the stack */ struct codegen_value *var_value = codegen_value_create(node, var->v_ptr); codegen_push_value(gen, var_value); return CODEGEN_RESULT_OK(0); } /* this variable either doesn't exist, or is a global variable */ struct codegen_value *var_value = codegen_value_create(node, NULL); codegen_push_value(gen, var_value); return CODEGEN_RESULT_OK(0); } #endif 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 var decl\n"); return IVY_OK; } static enum ivy_status state_fini( struct ivy_codegen *gen, struct code_generator_state *state, struct mie_value **result) { debug_printf("codegen: end of var decl\n"); struct var_codegen_state *var = (struct var_codegen_state *)state; const char *ident = var->s_var_ident->n_content->t_str; struct mie_type *type = NULL; if (var->s_value) { type = mie_value_get_type(var->s_value, gen->c_ctx); } else { type = mie_ctx_get_type(gen->c_ctx, MIE_TYPE_ID); } struct codegen_var var_info = { .v_node = (struct ivy_ast_node *)var->s_var_ident, .v_type = type, .v_flags = CODEGEN_VAR_F_PTR, .v_value = var->s_var_ptr, }; codegen_define_variable(gen, ident, &var_info); // struct code_generator_scope *scope = codegen_get_current_scope(gen); // code_generator_scope_put_variable(scope, var->s_var_ident, var->s_var_ptr); if (var->s_value) { mie_builder_store(gen->c_builder, var->s_value, var->s_var_ptr); } return IVY_OK; } static struct code_generator_result value_received( struct ivy_codegen *gen, struct code_generator_state *state, struct mie_value *value) { debug_printf("codegen: var decl value received\n"); struct var_codegen_state *var = (struct var_codegen_state *)state; if (!var->s_var_ptr) { return CODEGEN_RESULT_ERR(IVY_ERR_BAD_SYNTAX); } var->s_value = value; return CODEGEN_RESULT_OK(CODEGEN_R_POP_GENERATOR); } struct code_generator var_generator = { .g_type = CODE_GENERATOR_VAR, .g_state_size = sizeof(struct var_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_IDENT] = gen_ident, }, }; #endif