#ifndef _LANG_CODEGEN_H_ #define _LANG_CODEGEN_H_ #include "var-map.h" #include #include #include #include #include struct ivy_codegen; struct ivy_ast_node; struct mie_value; struct mie_func; struct codegen_var; #define CODEGEN_RESULT_OK(flags) \ (struct code_generator_result) \ { \ .r_status = (IVY_OK), .r_flags = (flags) \ } #define CODEGEN_RESULT_ERR(status) \ (struct code_generator_result) \ { \ .r_status = (status), .r_flags = (0) \ } #define __AST_INDEX(type) IVY_AST_##type #define NODE_CODEGEN(type, func) [__AST_INDEX(type)] = func enum code_generator_flags { CODEGEN_F_IGNORE_RESULT = 0x01u, }; enum code_generator_type { CODE_GENERATOR_NONE = 0, CODE_GENERATOR_UNIT, CODE_GENERATOR_BLOCK, CODE_GENERATOR_EXPR, CODE_GENERATOR_VAR, CODE_GENERATOR_MSG, CODE_GENERATOR_FSTRING, CODE_GENERATOR_LAMBDA, CODE_GENERATOR_RETURN, }; enum code_generator_scope_type { CODE_GENERATOR_SCOPE_NONE = 0, CODE_GENERATOR_SCOPE_UNIT, CODE_GENERATOR_SCOPE_FUNC, CODE_GENERATOR_SCOPE_BLOCK, }; struct code_generator_result { enum ivy_status r_status; enum code_generator_result_flags { CODEGEN_R_REPEAT_NODE = 0x01u, CODEGEN_R_POP_GENERATOR = 0x02u, } r_flags; }; struct codegen_value { b_queue_entry v_entry; struct ivy_ast_node *v_node; struct mie_value *v_value; }; struct code_generator_state; typedef enum ivy_status (*code_generator_state_init_callback)( struct ivy_codegen *, struct code_generator_state *, uintptr_t, void *); typedef enum ivy_status (*code_generator_state_fini_callback)( struct ivy_codegen *, struct code_generator_state *, struct mie_value **); typedef struct code_generator_result (*code_generator_callback)( struct ivy_codegen *); typedef struct code_generator_result (*code_generator_node_callback)( struct ivy_codegen *, struct code_generator_state *, struct ivy_ast_node *, size_t); typedef struct code_generator_result (*code_generator_value_received_callback)( struct ivy_codegen *, struct code_generator_state *, struct mie_value *); typedef enum ivy_status (*code_generator_define_variable_callback)( struct ivy_codegen *, struct code_generator_state *, const char *, const struct codegen_var *); typedef enum ivy_status (*code_generator_resolve_variable_callback)( struct ivy_codegen *, struct code_generator_state *, const char *, struct codegen_var *); typedef enum ivy_status (*code_generator_capture_variable_callback)( struct ivy_codegen *, struct code_generator_state *, const char *, struct codegen_var *); struct code_generator { enum code_generator_type g_type; size_t g_state_size; code_generator_state_init_callback g_state_init; code_generator_state_fini_callback g_state_fini; code_generator_node_callback g_node_generators[IVY_AST_TYPE_COUNT]; code_generator_node_callback g_expr_generator; code_generator_value_received_callback g_value_received; code_generator_define_variable_callback g_define_var; code_generator_resolve_variable_callback g_resolve_var; code_generator_capture_variable_callback g_capture_var; }; struct code_generator_state { b_queue_entry s_entry; uintptr_t s_argv; void *s_argp; const struct code_generator *s_gen; struct ivy_ast_node *s_root; size_t s_depth; }; struct ivy_codegen { b_queue c_values; b_queue c_state; b_queue c_scope; struct mie_builder *c_builder; struct mie_ctx *c_ctx; struct mie_module *c_module; }; extern const struct code_generator *get_code_generator( enum code_generator_type type); extern const struct code_generator *get_root_code_generator( enum ivy_ast_node_type type); extern enum ivy_status codegen_push_generator( struct ivy_codegen *gen, enum code_generator_type gen_type, uintptr_t argv, void *argp); extern enum ivy_status codegen_pop_generator( struct ivy_codegen *gen, struct mie_value **result); extern struct codegen_value *codegen_value_create( struct ivy_ast_node *node, struct mie_value *val); extern void codegen_value_destroy(struct codegen_value *val); extern void codegen_push_value(struct ivy_codegen *gen, struct codegen_value *val); extern struct codegen_value *codegen_pop_value(struct ivy_codegen *gen); extern enum ivy_status codegen_define_variable( struct ivy_codegen *gen, const char *ident, const struct codegen_var *var); extern enum ivy_status codegen_resolve_variable( struct ivy_codegen *gen, const char *ident, struct codegen_var *out); extern struct mie_value *codegen_load_variable( struct ivy_codegen *gen, struct codegen_var *var); #endif