From 377444ef59e9fbd29623bf9a378cfff3c60b8234 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Fri, 11 Apr 2025 13:40:54 +0100 Subject: [PATCH] mie: implement value type initialiser functions --- mie/builder.c | 313 ++++++++++++++++++++++++++++++++++++++ mie/const.c | 26 ++++ mie/include/mie/builder.h | 16 +- mie/include/mie/const.h | 7 +- mie/include/mie/func.h | 7 + mie/include/mie/instr.h | 7 + mie/include/mie/record.h | 4 +- mie/instr.c | 8 + mie/record.c | 19 +++ mie/value.c | 24 +++ 10 files changed, 424 insertions(+), 7 deletions(-) create mode 100644 mie/builder.c create mode 100644 mie/const.c create mode 100644 mie/instr.c create mode 100644 mie/record.c diff --git a/mie/builder.c b/mie/builder.c new file mode 100644 index 0000000..b56dd1f --- /dev/null +++ b/mie/builder.c @@ -0,0 +1,313 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct ctx_cached_int { + struct mie_int i_val; + b_btree_node i_node; +}; + +B_BTREE_DEFINE_SIMPLE_INSERT( + struct ctx_cached_int, i_node, i_val.i_value, put_cached_int) +B_BTREE_DEFINE_SIMPLE_GET( + struct ctx_cached_int, long long, i_node, i_val.i_value, get_cached_int) + +struct mie_ctx *mie_ctx_create(void) +{ + struct mie_ctx *out = malloc(sizeof *out); + + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + + out->ctx_true = mie_int_create(1, 1); + out->ctx_false = mie_int_create(0, 1); + + return out; +} + +void mie_ctx_destroy(struct mie_ctx *ctx) +{ + if (ctx->ctx_true) { + mie_value_release(MIE_VALUE(ctx->ctx_true)); + ctx->ctx_true = NULL; + } + + if (ctx->ctx_false) { + mie_value_release(MIE_VALUE(ctx->ctx_false)); + ctx->ctx_false = NULL; + } + + b_btree_iterator it = {}; + b_btree_iterator_begin(&ctx->ctx_ints, &it); + while (b_btree_iterator_is_valid(&it)) { + b_btree_node *node = it.node; + b_btree_iterator_erase(&it); + + struct ctx_cached_int *entry + = b_unbox(struct ctx_cached_int, node, i_node); + free(entry); + } + + free(ctx); +} + +struct mie_value *mie_ctx_get_bool(struct mie_ctx *ctx, bool val) +{ + return MIE_VALUE(val ? ctx->ctx_true : ctx->ctx_false); +} + +struct mie_value *mie_ctx_get_int(struct mie_ctx *ctx, long long val) +{ + struct ctx_cached_int *cache_entry = get_cached_int(&ctx->ctx_ints, val); + if (cache_entry) { + return MIE_VALUE(&cache_entry->i_val); + } + + cache_entry = malloc(sizeof *cache_entry); + if (!cache_entry) { + return NULL; + } + + memset(cache_entry, 0x0, sizeof *cache_entry); + + mie_int_init(&cache_entry->i_val, val, 32); + cache_entry->i_val.i_base.c_base.v_flags |= MIE_VALUE_F_STATIC; + + return MIE_VALUE(&cache_entry->i_val); +} + +struct mie_builder *mie_builder_create(struct mie_ctx *ctx, struct mie_module *mod) +{ + struct mie_builder *out = malloc(sizeof *out); + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + out->b_ctx = ctx; + out->b_module = mod; + + return out; +} + +void mie_builder_destroy(struct mie_builder *builder) +{ + free(builder); +} + +void mie_builder_put_record( + struct mie_builder *builder, struct mie_const *val, const char *name) +{ + if (!builder->b_module) { + return; + } + + b_queue_iterator it = {}; + b_queue_foreach (&it, &builder->b_module->m_records) { + struct mie_value *rec + = b_unbox(struct mie_value, it.entry, v_entry); + + if (!strcmp(rec->v_name.n_str, name)) { + return; + } + } + + struct mie_record *rec = mie_record_create(val); + rec->r_base.v_name.n_str = b_strdup(name); + b_queue_push_back(&builder->b_module->m_records, &rec->r_base.v_entry); +} + +void mie_builder_put_data(struct mie_builder *builder, struct mie_data *data) +{ + if (!builder->b_module) { + return; + } + + b_queue_iterator it = {}; + b_queue_foreach (&it, &builder->b_module->m_data) { + struct mie_value *cur + = b_unbox(struct mie_value, it.entry, v_entry); + + if (!strcmp(cur->v_name.n_str, data->d_base.v_name.n_str)) { + return; + } + } + + b_queue_push_back(&builder->b_module->m_data, &data->d_base.v_entry); +} + +void mie_builder_put_type(struct mie_builder *builder, struct mie_type *type) +{ + if (!builder->b_module) { + return; + } + + b_queue_iterator it = {}; + b_queue_foreach (&it, &builder->b_module->m_types) { + struct mie_value *cur + = b_unbox(struct mie_value, it.entry, v_entry); + + if (!strcmp(cur->v_name.n_str, type->t_base.v_name.n_str)) { + return; + } + } + + b_queue_push_back(&builder->b_module->m_data, &type->t_base.v_entry); +} + +void mie_builder_set_insert_point( + struct mie_builder *builder, struct mie_block *block) +{ + builder->b_current_block = block; +} + +struct mie_value *mie_builder_ret(struct mie_builder *builder, struct mie_value *val) +{ + struct mie_ret *ret = malloc(sizeof *ret); + if (!ret) { + return NULL; + } + + mie_instr_init(&ret->r_base, MIE_INSTR_RET); + ret->r_val = mie_value_retain(val); + + return NULL; +} + +struct mie_value *mie_builder_add( + struct mie_builder *builder, struct mie_value *left, + struct mie_value *right, const char *name) +{ + return NULL; +} + +struct mie_value *mie_builder_sub( + struct mie_builder *builder, struct mie_value *left, + struct mie_value *right, const char *name) +{ + return NULL; +} + +struct mie_value *mie_builder_mul( + struct mie_builder *builder, struct mie_value *left, + struct mie_value *right, const char *name) +{ + return NULL; +} + +struct mie_value *mie_builder_div( + struct mie_builder *builder, struct mie_value *left, + struct mie_value *right, const char *name) +{ + return NULL; +} + +struct mie_value *mie_builder_load( + struct mie_builder *builder, struct mie_value *type, + struct mie_value *src, const char *name) +{ + return NULL; +} + +struct mie_value *mie_builder_store( + struct mie_builder *builder, struct mie_value *val, struct mie_value *dest) +{ + return NULL; +} + +struct mie_value *mie_builder_alloca( + struct mie_builder *builder, struct mie_type *type, const char *name) +{ + return NULL; +} + +struct mie_value *mie_builder_switch( + struct mie_builder *builder, struct mie_value *cond, + struct mie_switch_branch *branches, size_t nr_branches, + struct mie_block *default_block) +{ + return NULL; +} + +struct mie_value *mie_builder_br(struct mie_builder *builder, struct mie_block *dest) +{ + return NULL; +} + +struct mie_value *mie_builder_br_if( + struct mie_builder *builder, struct mie_value *cond, + struct mie_block *if_true, struct mie_block *if_false) +{ + return NULL; +} + +struct mie_value *mie_builder_msg( + struct mie_builder *builder, struct mie_value *ret_type, + struct mie_value *dest, struct mie_value *src, const char *name) +{ + return NULL; +} + +struct mie_value *mie_builder_cmp_eq( + struct mie_builder *builder, struct mie_value *left, + struct mie_value *right, const char *name) +{ + return NULL; +} + +struct mie_value *mie_builder_cmp_lt( + struct mie_builder *builder, struct mie_value *left, + struct mie_value *right, const char *name) +{ + return NULL; +} + +struct mie_value *mie_builder_cmp_gt( + struct mie_builder *builder, struct mie_value *left, + struct mie_value *right, const char *name) +{ + return NULL; +} + +struct mie_value *mie_builder_cmp_leq( + struct mie_builder *builder, struct mie_value *left, + struct mie_value *right, const char *name) +{ + return NULL; +} + +struct mie_value *mie_builder_cmp_geq( + struct mie_builder *builder, struct mie_value *left, + struct mie_value *right, const char *name) +{ + return NULL; +} + +struct mie_value *mie_builder_getelementptr( + struct mie_builder *builder, struct mie_type *container_type, + struct mie_value *container, struct mie_value *index, const char *name) +{ + return NULL; +} + +struct mie_value *mie_builder_setelementptr( + struct mie_builder *builder, struct mie_type *container_type, + struct mie_value *container, struct mie_value *index) +{ + return NULL; +} + +struct mie_phi *mie_builder_phi( + struct mie_builder *builder, struct mie_type *type, + unsigned int nr_edges, const char *name) +{ + return NULL; +} diff --git a/mie/const.c b/mie/const.c new file mode 100644 index 0000000..b4b3409 --- /dev/null +++ b/mie/const.c @@ -0,0 +1,26 @@ +#include +#include +#include + +void mie_int_init(struct mie_int *out, long long val, unsigned int nr_bits) +{ + memset(out, 0x0, sizeof *out); + + mie_value_init(&out->i_base.c_base, MIE_VALUE_CONST); + + out->i_base.c_type = MIE_CONST_INT; + out->i_value = val; + out->i_width = nr_bits; +} + +struct mie_int *mie_int_create(long long val, unsigned int nr_bits) +{ + struct mie_int *out = malloc(sizeof *out); + + if (!out) { + return NULL; + } + + mie_int_init(out, val, nr_bits); + return out; +} diff --git a/mie/include/mie/builder.h b/mie/include/mie/builder.h index 9b31dc0..5d62c9b 100644 --- a/mie/include/mie/builder.h +++ b/mie/include/mie/builder.h @@ -1,20 +1,27 @@ #ifndef MIE_BUILDER_H_ #define MIE_BUILDER_H_ +#include +#include #include #include struct b_dict; struct mie_block; +struct mie_module; struct mie_data; struct mie_type; struct mie_phi; struct mie_ctx { + struct mie_int *ctx_true, *ctx_false; + b_btree ctx_ints; }; struct mie_builder { + struct mie_ctx *b_ctx; + struct mie_module *b_module; struct mie_instr *b_prev_instr; struct mie_block *b_current_block; }; @@ -22,14 +29,15 @@ struct mie_builder { extern struct mie_ctx *mie_ctx_create(void); extern void mie_ctx_destroy(struct mie_ctx *ctx); -extern struct mie_value mie_ctx_get_bool(struct mie_ctx, bool val); -extern struct mie_value mie_ctx_get_int(struct mie_ctx, long long val); +extern struct mie_value *mie_ctx_get_bool(struct mie_ctx *ctx, bool val); +extern struct mie_value *mie_ctx_get_int(struct mie_ctx *ctx, long long val); -extern struct mie_builder *mie_builder_create(void); +extern struct mie_builder *mie_builder_create( + struct mie_ctx *ctx, struct mie_module *mod); extern void mie_builder_destroy(struct mie_builder *builder); extern void mie_builder_put_record( - struct mie_builder *builder, const char *name, struct mie_value *val); + struct mie_builder *builder, struct mie_const *val, const char *name); extern void mie_builder_put_data(struct mie_builder *builder, struct mie_data *data); extern void mie_builder_put_type(struct mie_builder *builder, struct mie_type *type); extern void mie_builder_set_insert_point( diff --git a/mie/include/mie/const.h b/mie/include/mie/const.h index 4f1a453..b17c202 100644 --- a/mie/include/mie/const.h +++ b/mie/include/mie/const.h @@ -8,7 +8,7 @@ enum mie_const_type { MIE_CONST_INT, MIE_CONST_FLOAT, MIE_CONST_STRING, - MIE_CONST_SYMBOL, + MIE_CONST_ATOM, MIE_CONST_LABEL, MIE_CONST_ARRAY, }; @@ -34,7 +34,7 @@ struct mie_str { char *s_value; }; -struct mie_sym { +struct mie_atom { struct mie_const s_base; char *s_value; }; @@ -50,4 +50,7 @@ struct mie_array { struct mie_value **a_values; }; +extern void mie_int_init(struct mie_int *out, long long val, unsigned int nr_bits); +extern struct mie_int *mie_int_create(long long val, unsigned int nr_bits); + #endif diff --git a/mie/include/mie/func.h b/mie/include/mie/func.h index 64c878a..59e2d28 100644 --- a/mie/include/mie/func.h +++ b/mie/include/mie/func.h @@ -4,6 +4,7 @@ #include struct mie_type; +struct mie_arg; struct b_dict; enum mie_func_type { @@ -25,4 +26,10 @@ struct mie_func { b_queue f_blocks; }; +extern struct mie_func *mie_func_create( + const char *name, enum mie_func_type type, struct mie_type *ret_type, + struct mie_arg **args, unsigned int nr_args); +extern char *mie_func_generate_value_name( + struct mie_func *func, const char *name_hint); + #endif diff --git a/mie/include/mie/instr.h b/mie/include/mie/instr.h index 11ea515..fcb58ed 100644 --- a/mie/include/mie/instr.h +++ b/mie/include/mie/instr.h @@ -31,4 +31,11 @@ struct mie_instr { enum mie_instr_type i_type; }; +struct mie_ret { + struct mie_instr r_base; + struct mie_value *r_val; +}; + +extern void mie_instr_init(struct mie_instr *instr, enum mie_instr_type type); + #endif diff --git a/mie/include/mie/record.h b/mie/include/mie/record.h index 287eb23..aecdcdb 100644 --- a/mie/include/mie/record.h +++ b/mie/include/mie/record.h @@ -6,7 +6,9 @@ struct mie_record { struct mie_value r_base; - struct mie_const *r_value; + const struct mie_const *r_value; }; +extern struct mie_record *mie_record_create(const struct mie_const *val); + #endif diff --git a/mie/instr.c b/mie/instr.c new file mode 100644 index 0000000..78b160f --- /dev/null +++ b/mie/instr.c @@ -0,0 +1,8 @@ +#include + +void mie_instr_init(struct mie_instr *instr, enum mie_instr_type type) +{ + memset(instr, 0x0, sizeof *instr); + mie_value_init(&instr->i_base, MIE_VALUE_INSTR); + instr->i_type = type; +} diff --git a/mie/record.c b/mie/record.c new file mode 100644 index 0000000..efeff2f --- /dev/null +++ b/mie/record.c @@ -0,0 +1,19 @@ +#include +#include +#include + +struct mie_record *mie_record_create(const struct mie_const *val) +{ + struct mie_record *out = malloc(sizeof *out); + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + + mie_value_init(&out->r_base, MIE_VALUE_RECORD); + out->r_value = val; + mie_value_retain(MIE_VALUE(out->r_value)); + + return out; +} diff --git a/mie/value.c b/mie/value.c index c28ed3d..5367626 100644 --- a/mie/value.c +++ b/mie/value.c @@ -1 +1,25 @@ #include + +void mie_value_init(struct mie_value *val, enum mie_value_type type) +{ + memset(val, 0x0, sizeof *val); + + val->v_ref = 1; + val->v_type = type; +} + +struct mie_value *mie_value_retain(struct mie_value *val) +{ + val->v_ref++; + return val; +} + +void mie_value_release(struct mie_value *val) +{ + if (val->v_ref > 1) { + val->v_ref--; + return; + } + + /* TODO cleanup value */ +}