156 lines
4.9 KiB
C
156 lines
4.9 KiB
C
#ifndef _LANG_CODEGEN_H_
|
|
#define _LANG_CODEGEN_H_
|
|
|
|
#include "var-map.h"
|
|
|
|
#include <blue/core/queue.h>
|
|
#include <ivy/lang/ast.h>
|
|
#include <ivy/lang/lex.h>
|
|
#include <mie/ctx.h>
|
|
#include <mie/ir/builder.h>
|
|
|
|
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_GLOBAL,
|
|
CODE_GENERATOR_MSG,
|
|
CODE_GENERATOR_FSTRING,
|
|
CODE_GENERATOR_LAMBDA,
|
|
CODE_GENERATOR_RETURN,
|
|
CODE_GENERATOR_COND_GROUP,
|
|
CODE_GENERATOR_COND,
|
|
CODE_GENERATOR_FOR_LOOP,
|
|
};
|
|
|
|
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
|