314 lines
6.8 KiB
C
314 lines
6.8 KiB
C
#include <blue/object/string.h>
|
|
#include <mie/builder.h>
|
|
#include <mie/data.h>
|
|
#include <mie/module.h>
|
|
#include <mie/record.h>
|
|
#include <mie/type.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
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;
|
|
}
|