#include #include #include #include #include #include #include #include struct mie_func *mie_func_create(enum mie_func_type type, struct mie_type *ret_type) { 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_type = type; out->f_ret = ret_type; out->f_names = mie_name_map_create(); return out; } struct mie_value *mie_func_add_arg( struct mie_func *func, struct mie_type *type, const char *name) { struct mie_arg *arg = mie_arg_create(type); if (!arg) { return NULL; } struct mie_value *v = mie_func_generate_value_name(func, MIE_VALUE(arg), name); if (!v) { mie_value_destroy(MIE_VALUE(arg)); return NULL; } b_queue_push_back(&func->f_args, &v->v_entry); return v; } 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, 0); return b_unbox(struct mie_value, name, v_name); } struct mie_block *mie_func_get_first_block(struct mie_func *func) { b_queue_entry *entry = b_queue_first(&func->f_blocks); if (!entry) { return NULL; } return (struct mie_block *)b_unbox(struct mie_value, entry, v_entry); } struct mie_block *mie_func_get_last_block(struct mie_func *func) { b_queue_entry *entry = b_queue_last(&func->f_blocks); if (!entry) { return NULL; } return (struct mie_block *)b_unbox(struct mie_value, entry, v_entry); } 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, };