2025-04-16 21:58:52 +01:00
|
|
|
#include "../debug.h"
|
|
|
|
|
#include "codegen.h"
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-17 21:44:38 +01:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-16 21:58:52 +01:00
|
|
|
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) {
|
2025-04-17 21:44:38 +01:00
|
|
|
return gen_value_expr(gen, state, node, depth);
|
2025-04-16 21:58:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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(
|
2025-04-17 21:44:38 +01:00
|
|
|
struct ivy_codegen *gen, struct code_generator_state *state,
|
|
|
|
|
uintptr_t argv, void *argp)
|
2025-04-16 21:58:52 +01:00
|
|
|
{
|
2025-04-17 21:44:38 +01:00
|
|
|
debug_printf("codegen: start of var decl\n");
|
2025-04-16 21:58:52 +01:00
|
|
|
return IVY_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static enum ivy_status state_fini(
|
|
|
|
|
struct ivy_codegen *gen, struct code_generator_state *state,
|
|
|
|
|
struct mie_value **result)
|
|
|
|
|
{
|
2025-04-17 21:44:38 +01:00
|
|
|
debug_printf("codegen: end of var decl\n");
|
2025-04-16 21:58:52 +01:00
|
|
|
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);
|
|
|
|
|
}
|
2025-04-17 21:44:38 +01:00
|
|
|
|
2025-04-16 21:58:52 +01:00
|
|
|
return IVY_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct code_generator_result value_received(
|
|
|
|
|
struct ivy_codegen *gen, struct code_generator_state *state,
|
|
|
|
|
struct mie_value *value)
|
|
|
|
|
{
|
2025-04-17 21:44:38 +01:00
|
|
|
debug_printf("codegen: var decl value received\n");
|
2025-04-16 21:58:52 +01:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
2025-04-17 21:44:38 +01:00
|
|
|
return CODEGEN_RESULT_OK(CODEGEN_R_POP_GENERATOR);
|
2025-04-16 21:58:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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,
|
2025-04-17 21:44:38 +01:00
|
|
|
.g_expr_generator = gen_value_expr,
|
2025-04-16 21:58:52 +01:00
|
|
|
.g_node_generators = {
|
|
|
|
|
[IVY_AST_VAR] = gen_var,
|
|
|
|
|
[IVY_AST_IDENT] = gen_ident,
|
|
|
|
|
},
|
|
|
|
|
};
|