#include "../debug.h" #include "codegen.h" #include #include #include 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_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) { /* TODO support tuple assignment */ return CODEGEN_RESULT_ERR(IVY_ERR_BAD_SYNTAX); } 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); } 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); return CODEGEN_RESULT_OK(CODEGEN_REPEAT_NODE); } #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) { 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) { printf("codegen: end of var decl\n"); struct var_codegen_state *var = (struct var_codegen_state *)state; 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) { 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_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_node_generators = { [IVY_AST_VAR] = gen_var, [IVY_AST_IDENT] = gen_ident, [IVY_AST_INT] = gen_value_expr, [IVY_AST_OP] = gen_value_expr, }, };