mie: refactor ir api into a separate sub-directory
This commit is contained in:
148
mie/ir/module.c
Normal file
148
mie/ir/module.c
Normal file
@@ -0,0 +1,148 @@
|
||||
#include <blue/object/hashmap.h>
|
||||
#include <mie/ir/const.h>
|
||||
#include <mie/ir/data.h>
|
||||
#include <mie/ir/func.h>
|
||||
#include <mie/ir/module.h>
|
||||
#include <mie/ir/type.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct mie_module *mie_module_create(void)
|
||||
{
|
||||
struct mie_module *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
mie_value_init(&out->m_base, MIE_VALUE_MODULE);
|
||||
|
||||
out->m_names = mie_name_map_create();
|
||||
out->m_data = b_hashmap_create(NULL, NULL);
|
||||
out->m_data_strings = b_hashmap_create(NULL, NULL);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void mie_module_add_function(
|
||||
struct mie_module *mod, struct mie_func *func, const char *name)
|
||||
{
|
||||
struct mie_value *v
|
||||
= mie_module_generate_value_name(mod, MIE_VALUE(func), name);
|
||||
if (!v) {
|
||||
return;
|
||||
}
|
||||
|
||||
b_queue_push_back(&mod->m_func, &v->v_entry);
|
||||
}
|
||||
|
||||
struct mie_data *mie_module_get_string_ptr(struct mie_module *mod, const char *s)
|
||||
{
|
||||
b_hashmap_key key = {
|
||||
.key_data = s,
|
||||
.key_size = strlen(s),
|
||||
};
|
||||
|
||||
const b_hashmap_value *entry = b_hashmap_get(mod->m_data_strings, &key);
|
||||
if (entry) {
|
||||
return entry->value_data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mie_data *mie_module_get_data(struct mie_module *mod, const char *name)
|
||||
{
|
||||
b_hashmap_key key = {
|
||||
.key_data = name,
|
||||
.key_size = strlen(name),
|
||||
};
|
||||
|
||||
const b_hashmap_value *entry = b_hashmap_get(mod->m_data, &key);
|
||||
if (entry) {
|
||||
return entry->value_data;
|
||||
}
|
||||
|
||||
/* don't search m_data_strings, as it is keyed by the string contents
|
||||
* rather than the data entry name, and its entries are duplicated in
|
||||
* m_data anyway */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
enum b_status mie_module_put_data(
|
||||
struct mie_module *mod, struct mie_data *data, const char *name)
|
||||
{
|
||||
struct mie_value *v
|
||||
= mie_module_generate_value_name(mod, MIE_VALUE(data), name);
|
||||
|
||||
b_hashmap_key key = {
|
||||
.key_data = v->v_name.n_str,
|
||||
.key_size = strlen(name),
|
||||
};
|
||||
|
||||
b_hashmap_value value = {
|
||||
.value_data = data,
|
||||
.value_size = sizeof *data,
|
||||
};
|
||||
|
||||
b_hashmap_put(mod->m_data, &key, &value);
|
||||
|
||||
if (data->d_type != MIE_DATA_CONST) {
|
||||
return B_SUCCESS;
|
||||
}
|
||||
|
||||
struct mie_const *const_data = data->d_const.c_value;
|
||||
if (const_data->c_type->t_id == MIE_TYPE_STR) {
|
||||
struct mie_string *s = MIE_STRING(const_data);
|
||||
key.key_data = s->s_value;
|
||||
key.key_size = strlen(key.key_data);
|
||||
b_hashmap_put(mod->m_data_strings, &key, &value);
|
||||
}
|
||||
|
||||
return B_SUCCESS;
|
||||
}
|
||||
|
||||
struct mie_value *mie_module_generate_value_name(
|
||||
struct mie_module *mod, struct mie_value *val, const char *hint)
|
||||
{
|
||||
struct mie_name *name
|
||||
= mie_name_map_put(mod->m_names, &val->v_name, hint, 0);
|
||||
return b_unbox(struct mie_value, name, v_name);
|
||||
}
|
||||
|
||||
static void cleanup(struct mie_value *value)
|
||||
{
|
||||
struct mie_module *module = MIE_MODULE(value);
|
||||
|
||||
b_queue_iterator it;
|
||||
b_queue_iterator_begin(&module->m_records, &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(&module->m_types, &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(&module->m_func, &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_hashmap_release(module->m_data_strings);
|
||||
b_hashmap_release(module->m_data);
|
||||
}
|
||||
|
||||
const struct mie_value_type module_value_type = {
|
||||
.t_id = MIE_VALUE_MODULE,
|
||||
.t_cleanup = cleanup,
|
||||
};
|
||||
Reference in New Issue
Block a user