#include #include #include #include #include #include #include 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) { struct mie_func *out = malloc(sizeof *out); if (!out) { return NULL; } memset(out, 0x0, sizeof *out); mie_value_init(&out->f_base, MIE_VALUE_FUNC); out->f_base.v_name.n_str = b_strdup(name); out->f_base.v_name.n_base.e_hash = b_hash_string(name); out->f_type = type; out->f_ret = ret_type; out->f_names = mie_name_map_create(); for (size_t i = 0; i < nr_args; i++) { if (args[i]) { struct mie_value *arg_value = MIE_VALUE(args[i]); b_queue_push_back(&out->f_args, &arg_value->v_entry); } } return out; } struct mie_block *mie_func_create_block(struct mie_func *func, const char *name) { struct mie_block *out = malloc(sizeof *out); if (!out) { return NULL; } memset(out, 0x0, sizeof *out); mie_value_init(&out->b_base, MIE_VALUE_BLOCK); struct mie_value *block = MIE_VALUE(out); block = mie_func_generate_value_name(func, block, name); if (!block) { free(out); return NULL; } out->b_parent = func; return out; } void mie_func_insert_block( struct mie_func *func, struct mie_block *block, struct mie_block *after) { if (after) { b_queue_insert_after( &func->f_blocks, &block->b_base.v_entry, &after->b_base.v_entry); } else { b_queue_push_back(&func->f_blocks, &block->b_base.v_entry); } } struct mie_value *mie_func_generate_value_name( struct mie_func *func, struct mie_value *val, const char *hint) { struct mie_name *name = mie_name_map_put(func->f_names, &val->v_name, hint); return b_unbox(struct mie_value, name, v_name); } static struct mie_type *get_type(struct mie_value *v) { struct mie_func *f = MIE_FUNC(v); return f->f_ret; } static void cleanup(struct mie_value *value) { struct mie_func *func = MIE_FUNC(value); b_queue_iterator it; b_queue_iterator_begin(&func->f_args, &it); while (b_queue_iterator_is_valid(&it)) { struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry); b_queue_iterator_erase(&it); mie_value_destroy(v); } b_queue_iterator_begin(&func->f_blocks, &it); while (b_queue_iterator_is_valid(&it)) { struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry); b_queue_iterator_erase(&it); mie_value_destroy(v); } mie_name_map_destroy(func->f_names); } const struct mie_value_type func_value_type = { .t_id = MIE_VALUE_FUNC, .t_get_type = get_type, .t_cleanup = cleanup, };