From 2dca43bf255003acbe6c5e21700cf37f38d72165 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 13 Apr 2025 18:34:28 +0100 Subject: [PATCH] mie: start implementing ir memory->text conversion --- mie/convert/bitcode-read.c | 7 + mie/convert/bitcode-write.c | 7 + mie/convert/convert.c | 216 ++++++++++++++++ mie/convert/convert.h | 19 ++ mie/convert/lex.c | 0 mie/convert/lex.h | 0 mie/convert/parse.c | 0 mie/convert/parse.h | 0 mie/convert/text-read.c | 7 + mie/convert/text-write.c | 478 ++++++++++++++++++++++++++++++++++++ mie/include/mie/convert.h | 80 ++++++ 11 files changed, 814 insertions(+) create mode 100644 mie/convert/bitcode-read.c create mode 100644 mie/convert/bitcode-write.c create mode 100644 mie/convert/convert.c create mode 100644 mie/convert/convert.h create mode 100644 mie/convert/lex.c create mode 100644 mie/convert/lex.h create mode 100644 mie/convert/parse.c create mode 100644 mie/convert/parse.h create mode 100644 mie/convert/text-read.c create mode 100644 mie/convert/text-write.c create mode 100644 mie/include/mie/convert.h diff --git a/mie/convert/bitcode-read.c b/mie/convert/bitcode-read.c new file mode 100644 index 0000000..37c8087 --- /dev/null +++ b/mie/convert/bitcode-read.c @@ -0,0 +1,7 @@ +#include "convert.h" + +b_status read_value_from_bitcode( + struct mie_ir_converter *converter, struct mie_value **out) +{ + return B_ERR_NOT_SUPPORTED; +} diff --git a/mie/convert/bitcode-write.c b/mie/convert/bitcode-write.c new file mode 100644 index 0000000..00962d8 --- /dev/null +++ b/mie/convert/bitcode-write.c @@ -0,0 +1,7 @@ +#include "convert.h" + +b_status write_value_to_bitcode( + struct mie_ir_converter *converter, struct mie_value *value) +{ + return B_ERR_NOT_SUPPORTED; +} diff --git a/mie/convert/convert.c b/mie/convert/convert.c new file mode 100644 index 0000000..b622561 --- /dev/null +++ b/mie/convert/convert.c @@ -0,0 +1,216 @@ +#include "convert.h" + +#include +#include +#include +#include + +struct mie_ir_converter *mie_ir_converter_create( + enum mie_ir_format src, enum mie_ir_format dest) +{ + if (src == dest) { + return NULL; + } + + struct mie_ir_converter *out = malloc(sizeof *out); + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + + out->c_src_format = src; + out->c_dest_format = dest; + + return out; +} + +void mie_ir_converter_destroy(struct mie_ir_converter *converter) +{ + free(converter); +} + +b_status mie_ir_converter_set_src_value( + struct mie_ir_converter *converter, struct mie_value *value) +{ + if (converter->c_src_format != MIE_IR_MEM) { + return B_ERR_INVALID_ARGUMENT; + } + + converter->c_src_medium = MIE_IR_CONVERTER_MIE_VALUE; + converter->c_src.value = value; + + return B_SUCCESS; +} + +b_status mie_ir_converter_set_src_bitbuffer( + struct mie_ir_converter *converter, b_bitbuffer *bitbuffer) +{ + if (converter->c_src_format != MIE_IR_BITCODE) { + return B_ERR_INVALID_ARGUMENT; + } + + converter->c_src_medium = MIE_IR_CONVERTER_BITBUFFER; + converter->c_src.bitbuffer = bitbuffer; + + return B_SUCCESS; +} + +b_status mie_ir_converter_set_src_stringstream( + struct mie_ir_converter *converter, b_stringstream *stringstream) +{ + if (converter->c_src_format != MIE_IR_TEXT) { + return B_ERR_INVALID_ARGUMENT; + } + + converter->c_src_medium = MIE_IR_CONVERTER_STRINGSTREAM; + converter->c_src.stringstream = stringstream; + + return B_SUCCESS; +} + +b_status mie_ir_converter_set_src_string( + struct mie_ir_converter *converter, b_string *string) +{ + if (converter->c_src_format != MIE_IR_TEXT) { + return B_ERR_INVALID_ARGUMENT; + } + + converter->c_src_medium = MIE_IR_CONVERTER_STRING; + converter->c_src.string = string; + + return B_SUCCESS; +} + +b_status mie_ir_converter_set_src_file(struct mie_ir_converter *converter, FILE *file) +{ + if (converter->c_src_format != MIE_IR_TEXT) { + return B_ERR_INVALID_ARGUMENT; + } + + converter->c_src_medium = MIE_IR_CONVERTER_FILE; + converter->c_src.file = file; + + return B_SUCCESS; +} + +b_status mie_ir_converter_set_dest_value( + struct mie_ir_converter *converter, struct mie_value **value) +{ + if (converter->c_dest_format != MIE_IR_MEM) { + return B_ERR_INVALID_ARGUMENT; + } + + converter->c_dest_medium = MIE_IR_CONVERTER_MIE_VALUE; + converter->c_dest.value = value; + + return B_SUCCESS; +} + +b_status mie_ir_converter_set_dest_bitbuffer( + struct mie_ir_converter *converter, b_bitbuffer *bitbuffer) +{ + if (converter->c_dest_format != MIE_IR_BITCODE) { + return B_ERR_INVALID_ARGUMENT; + } + + converter->c_dest_medium = MIE_IR_CONVERTER_BITBUFFER; + converter->c_dest.bitbuffer = bitbuffer; + + return B_SUCCESS; +} + +b_status mie_ir_converter_set_dest_stringstream( + struct mie_ir_converter *converter, b_stringstream *stringstream) +{ + if (converter->c_dest_format != MIE_IR_TEXT) { + return B_ERR_INVALID_ARGUMENT; + } + + converter->c_dest_medium = MIE_IR_CONVERTER_STRINGSTREAM; + converter->c_dest.stringstream = stringstream; + + return B_SUCCESS; +} + +b_status mie_ir_converter_set_dest_string( + struct mie_ir_converter *converter, b_string *string) +{ + if (converter->c_dest_format != MIE_IR_TEXT) { + return B_ERR_INVALID_ARGUMENT; + } + + converter->c_dest_medium = MIE_IR_CONVERTER_STRING; + converter->c_dest.string = string; + + return B_SUCCESS; +} + +b_status mie_ir_converter_set_dest_file( + struct mie_ir_converter *converter, FILE *file) +{ + if (converter->c_dest_format != MIE_IR_TEXT) { + return B_ERR_INVALID_ARGUMENT; + } + + converter->c_dest_medium = MIE_IR_CONVERTER_FILE; + converter->c_dest.file = file; + + return B_SUCCESS; +} + +static b_status read_value_from_medium( + struct mie_ir_converter *converter, struct mie_value **value) +{ + switch (converter->c_src_format) { + case MIE_IR_MEM: + *value = converter->c_src.value; + return B_SUCCESS; + case MIE_IR_TEXT: + return read_value_from_text(converter, value); + case MIE_IR_BITCODE: + return read_value_from_bitcode(converter, value); + default: + return B_ERR_NOT_SUPPORTED; + } +} + +static b_status write_value_to_medium( + struct mie_ir_converter *converter, struct mie_value *value) +{ + switch (converter->c_dest_format) { + case MIE_IR_MEM: + *converter->c_dest.value = value; + return B_SUCCESS; + case MIE_IR_TEXT: + return write_value_to_text(converter, value); + case MIE_IR_BITCODE: + return write_value_to_bitcode(converter, value); + default: + return B_ERR_NOT_SUPPORTED; + } +} + +b_status mie_ir_converter_process(struct mie_ir_converter *converter) +{ + b_status status = B_SUCCESS; + struct mie_value *value = NULL; + + status = read_value_from_medium(converter, &value); + + if (!B_OK(status)) { + return status; + } + + if (!value) { + return B_ERR_BAD_FORMAT; + } + + status = write_value_to_medium(converter, value); + + if (converter->c_src_format != MIE_IR_MEM) { + mie_value_destroy(value); + } + + return status; +} diff --git a/mie/convert/convert.h b/mie/convert/convert.h new file mode 100644 index 0000000..4b618a0 --- /dev/null +++ b/mie/convert/convert.h @@ -0,0 +1,19 @@ +#ifndef _MIE_CONVERT_H_ +#define _MIE_CONVERT_H_ + +#include + +extern b_status write_char(struct mie_ir_converter *converter, char c); +extern b_status write_string(struct mie_ir_converter *converter, const char *s); + +extern b_status read_value_from_text( + struct mie_ir_converter *converter, struct mie_value **out); +extern b_status read_value_from_bitcode( + struct mie_ir_converter *converter, struct mie_value **out); + +extern b_status write_value_to_text( + struct mie_ir_converter *converter, struct mie_value *value); +extern b_status write_value_to_bitcode( + struct mie_ir_converter *converter, struct mie_value *value); + +#endif diff --git a/mie/convert/lex.c b/mie/convert/lex.c new file mode 100644 index 0000000..e69de29 diff --git a/mie/convert/lex.h b/mie/convert/lex.h new file mode 100644 index 0000000..e69de29 diff --git a/mie/convert/parse.c b/mie/convert/parse.c new file mode 100644 index 0000000..e69de29 diff --git a/mie/convert/parse.h b/mie/convert/parse.h new file mode 100644 index 0000000..e69de29 diff --git a/mie/convert/text-read.c b/mie/convert/text-read.c new file mode 100644 index 0000000..0804d9b --- /dev/null +++ b/mie/convert/text-read.c @@ -0,0 +1,7 @@ +#include "convert.h" + +b_status read_value_from_text( + struct mie_ir_converter *converter, struct mie_value **out) +{ + return B_ERR_NOT_SUPPORTED; +} diff --git a/mie/convert/text-write.c b/mie/convert/text-write.c new file mode 100644 index 0000000..93449d8 --- /dev/null +++ b/mie/convert/text-write.c @@ -0,0 +1,478 @@ +#include "convert.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define F_INCLUDE_TYPE 0x01u + +typedef b_status (*write_function)(struct mie_ir_converter *, struct mie_value *); + +static void mie_type_to_string(struct mie_type *type, char *out, size_t max) +{ + switch (type->t_id) { + case MIE_TYPE_PTR: + snprintf(out, max, "ptr"); + break; + case MIE_TYPE_VOID: + snprintf(out, max, "void"); + break; + case MIE_TYPE_INT: + snprintf(out, max, "i%u", type->t_width); + break; + case MIE_TYPE_ID: + snprintf(out, max, "id"); + break; + case MIE_TYPE_STR: + snprintf(out, max, "str"); + break; + case MIE_TYPE_ATOM: + snprintf(out, max, "atom"); + break; + case MIE_TYPE_LABEL: + snprintf(out, max, "label"); + break; + default: + snprintf(out, max, ""); + break; + } +} + +b_status write_char(struct mie_ir_converter *converter, char c) +{ + long result = 0; + char s[] = {c, '\0'}; + + switch (converter->c_dest_medium) { + case MIE_IR_CONVERTER_STRINGSTREAM: + return b_stringstream_add(converter->c_dest.stringstream, s); + case MIE_IR_CONVERTER_STRING: + b_string_append_cstr(converter->c_dest.string, s); + return B_SUCCESS; + case MIE_IR_CONVERTER_FILE: + result = fputc(c, converter->c_dest.file); + return result == EOF ? B_ERR_IO_FAILURE : B_SUCCESS; + default: + return B_ERR_NOT_SUPPORTED; + } + + return B_SUCCESS; +} + +b_status write_string(struct mie_ir_converter *converter, const char *s) +{ + long result = 0; + + switch (converter->c_dest_medium) { + case MIE_IR_CONVERTER_STRINGSTREAM: + return b_stringstream_add(converter->c_dest.stringstream, s); + case MIE_IR_CONVERTER_STRING: + b_string_append_cstr(converter->c_dest.string, s); + return B_SUCCESS; + case MIE_IR_CONVERTER_FILE: + result = fputs(s, converter->c_dest.file); + return result == EOF ? B_ERR_IO_FAILURE : B_SUCCESS; + default: + return B_ERR_NOT_SUPPORTED; + } + + return B_SUCCESS; +} + +b_status write_string_f(struct mie_ir_converter *converter, const char *format, ...) +{ + long result = 0; + + char buf[512]; + va_list arg; + va_start(arg, format); + + b_status status = B_SUCCESS; + + switch (converter->c_dest_medium) { + case MIE_IR_CONVERTER_STRINGSTREAM: + vsnprintf(buf, sizeof buf, format, arg); + status = b_stringstream_add(converter->c_dest.stringstream, buf); + break; + case MIE_IR_CONVERTER_STRING: + vsnprintf(buf, sizeof buf, format, arg); + b_string_append_cstr(converter->c_dest.string, buf); + status = B_SUCCESS; + break; + case MIE_IR_CONVERTER_FILE: + result = vfprintf(converter->c_dest.file, format, arg); + status = (result == EOF ? B_ERR_IO_FAILURE : B_SUCCESS); + break; + default: + status = B_ERR_NOT_SUPPORTED; + break; + } + + va_end(arg); + return status; +} + +static b_status write_operand_const( + struct mie_ir_converter *converter, struct mie_value *value, int flags) +{ + struct mie_const *c = MIE_CONST(value); + + if (flags & F_INCLUDE_TYPE) { + char type_name[64]; + mie_type_to_string(c->c_type, type_name, sizeof type_name); + write_string_f(converter, "%s ", type_name); + } + + switch (c->c_type->t_id) { + case MIE_TYPE_INT: + write_string_f(converter, "#%" PRId64, c->c_v.v_int); + break; + case MIE_TYPE_PTR: + case MIE_TYPE_ID: + write_string_f(converter, "%%%s", value->v_name.n_str); + break; + case MIE_TYPE_STR: + case MIE_TYPE_ATOM: + write_string(converter, c->c_v.v_str); + break; + case MIE_TYPE_CLASS: + write_string_f(converter, "@%s", value->v_name.n_str); + break; + default: + break; + } + + return B_SUCCESS; +} + +static b_status write_operand_instr( + struct mie_ir_converter *converter, struct mie_value *value, int flags) +{ + struct mie_instr *instr = MIE_INSTR(value); + + if (flags & F_INCLUDE_TYPE) { + char type_name[64]; + struct mie_type *type = mie_value_get_type(value); + mie_type_to_string(type, type_name, sizeof type_name); + write_string_f(converter, "%s ", type_name); + } + + write_string_f(converter, "%%%s", value->v_name.n_str); + return B_SUCCESS; +} + +static b_status write_operand_block( + struct mie_ir_converter *converter, struct mie_value *value, int flags) +{ + struct mie_block *block = MIE_BLOCK(value); + + if (flags & F_INCLUDE_TYPE) { + char type_name[64]; + struct mie_type *type = mie_value_get_type(value); + mie_type_to_string(type, type_name, sizeof type_name); + write_string_f(converter, "%s ", type_name); + } + + write_string_f(converter, "%%%s", value->v_name.n_str); + return B_SUCCESS; +} + +static b_status write_operand( + struct mie_ir_converter *converter, struct mie_value *value, int flags) +{ + switch (value->v_type->t_id) { + case MIE_VALUE_CONST: + return write_operand_const(converter, value, flags); + case MIE_VALUE_INSTR: + return write_operand_instr(converter, value, flags); + case MIE_VALUE_BLOCK: + return write_operand_block(converter, value, flags); + default: + return B_SUCCESS; + } +} + +static b_status write_module( + struct mie_ir_converter *converter, struct mie_value *value) +{ + struct mie_module *mod = MIE_MODULE(value); + b_status status = B_SUCCESS; + + b_queue_iterator it; + b_queue_foreach (&it, &mod->m_records) { + struct mie_value *record + = b_unbox(struct mie_value, it.entry, v_entry); + status = write_value_to_text(converter, record); + + if (!B_OK(status)) { + return status; + } + } + + b_queue_foreach (&it, &mod->m_types) { + struct mie_value *type + = b_unbox(struct mie_value, it.entry, v_entry); + status = write_value_to_text(converter, type); + + if (!B_OK(status)) { + return status; + } + } + + b_queue_foreach (&it, &mod->m_data) { + struct mie_value *data + = b_unbox(struct mie_value, it.entry, v_entry); + status = write_value_to_text(converter, data); + + if (!B_OK(status)) { + return status; + } + } + + b_queue_foreach (&it, &mod->m_func) { + struct mie_value *func + = b_unbox(struct mie_value, it.entry, v_entry); + status = write_value_to_text(converter, func); + + if (!B_OK(status)) { + return status; + } + } + + return B_SUCCESS; +} + +static b_status write_type_definition( + struct mie_ir_converter *converter, struct mie_value *value) +{ + return B_SUCCESS; +} + +static b_status write_record( + struct mie_ir_converter *converter, struct mie_value *value) +{ + return B_SUCCESS; +} + +static b_status write_func_definition( + struct mie_ir_converter *converter, struct mie_value *value) +{ + struct mie_func *func = MIE_FUNC(value); + + char type_name[32]; + mie_type_to_string(func->f_ret, type_name, sizeof type_name); + + write_string_f( + converter, "define %s @%s(", type_name, func->f_base.v_name.n_str); + + unsigned int i = 0; + b_queue_iterator it; + b_queue_foreach (&it, &func->f_args) { + struct mie_arg *arg = (struct mie_arg *)b_unbox( + struct mie_value, it.entry, v_entry); + + if (i > 0) { + puts(", "); + } + + mie_type_to_string(func->f_ret, type_name, sizeof type_name); + + write_string_f( + converter, "%s %%%s", type_name, + arg->arg_base.v_name.n_str); + } + + write_string_f(converter, ")"); + + switch (func->f_type) { + case MIE_FUNC_STATIC: + write_string_f(converter, " static"); + break; + case MIE_FUNC_INSTANCE: + write_string_f(converter, " instance"); + break; + case MIE_FUNC_LAMBDA: + write_string_f(converter, " lambda"); + break; + default: + break; + } + + write_string_f(converter, " {\n"); + + b_queue_foreach (&it, &func->f_blocks) { + struct mie_value *block + = b_unbox(struct mie_value, it.entry, v_entry); + write_value_to_text(converter, block); + } + + write_string_f(converter, "}\n"); + + return B_SUCCESS; +} + +static b_status write_block_definition( + struct mie_ir_converter *converter, struct mie_value *value) +{ + struct mie_block *block = MIE_BLOCK(value); + + write_string_f(converter, "%s:\n", block->b_base.v_name.n_str); + b_queue_iterator it; + b_queue_foreach (&it, &block->b_phi) { + struct mie_value *instr + = b_unbox(struct mie_value, it.entry, v_entry); + write_value_to_text(converter, instr); + } + + b_queue_foreach (&it, &block->b_instr) { + struct mie_value *instr + = b_unbox(struct mie_value, it.entry, v_entry); + write_value_to_text(converter, instr); + } + + if (block->b_terminator) { + write_value_to_text(converter, MIE_VALUE(block->b_terminator)); + } + + return B_SUCCESS; +} + +static b_status write_instr( + struct mie_ir_converter *converter, struct mie_value *value) +{ + struct mie_instr *instr = MIE_INSTR(value); + write_string_f(converter, "\t"); + + if (instr->i_base.v_name.n_str) { + write_string_f(converter, "%%%s = ", instr->i_base.v_name.n_str); + } + + char type[128]; + + switch (instr->i_type) { + case MIE_INSTR_RET: { + struct mie_ret *ret = (struct mie_ret *)instr; + write_string(converter, "ret "); + if (!ret->r_val) { + write_string(converter, "void"); + break; + } + + write_operand(converter, ret->r_val, F_INCLUDE_TYPE); + break; + } + + case MIE_INSTR_ADD: { + struct mie_binary_op *op = (struct mie_binary_op *)instr; + mie_type_to_string(op->op_type, type, sizeof type); + write_string_f(converter, "add %s ", type); + write_operand(converter, op->op_left, 0); + write_string(converter, ", "); + write_operand(converter, op->op_right, 0); + break; + } + case MIE_INSTR_SUB: + write_string(converter, "sub"); + break; + case MIE_INSTR_MUL: + write_string(converter, "mul"); + break; + case MIE_INSTR_DIV: + write_string(converter, "div"); + break; + case MIE_INSTR_LOAD: { + struct mie_load *load = (struct mie_load *)instr; + mie_type_to_string(load->l_type, type, sizeof type); + write_string_f(converter, "load %s, ", type); + write_operand(converter, load->l_src, F_INCLUDE_TYPE); + break; + } + case MIE_INSTR_STORE: { + struct mie_store *store = (struct mie_store *)instr; + write_string(converter, "store "); + write_operand(converter, store->s_val, F_INCLUDE_TYPE); + write_string(converter, ", "); + write_operand(converter, store->s_dest, F_INCLUDE_TYPE); + break; + } + case MIE_INSTR_ALLOCA: { + struct mie_alloca *alloca = (struct mie_alloca *)instr; + mie_type_to_string(alloca->a_type, type, sizeof type); + write_string_f(converter, "alloca %s", type); + break; + } + case MIE_INSTR_SWITCH: + write_string(converter, "switch"); + break; + case MIE_INSTR_BR: { + struct mie_branch *br = (struct mie_branch *)instr; + write_string(converter, "br "); + write_operand(converter, MIE_VALUE(br->b_dest), F_INCLUDE_TYPE); + break; + } + case MIE_INSTR_MSG: + write_string(converter, "msg"); + break; + case MIE_INSTR_CMP_EQ: + write_string(converter, "cmp eq"); + break; + case MIE_INSTR_CMP_LT: + write_string(converter, "cmp lt"); + break; + case MIE_INSTR_CMP_GT: + write_string(converter, "cmp gt"); + break; + case MIE_INSTR_CMP_LEQ: + write_string(converter, "cmp leq"); + break; + case MIE_INSTR_CMP_GEQ: + write_string(converter, "cmp geq"); + break; + case MIE_INSTR_GETELEMENTPTR: + write_string(converter, "getelementptr"); + break; + case MIE_INSTR_SETELEMENTPTR: + write_string(converter, "setelementptr"); + break; + case MIE_INSTR_PHI: + write_string(converter, "phi"); + break; + default: + write_string_f(converter, ""); + break; + } + + write_char(converter, '\n'); + return B_SUCCESS; +} + +static const write_function value_writers[] = { + [MIE_VALUE_MODULE] = write_module, + [MIE_VALUE_TYPE] = write_type_definition, + [MIE_VALUE_RECORD] = write_record, + [MIE_VALUE_FUNC] = write_func_definition, + [MIE_VALUE_ARG] = NULL, + [MIE_VALUE_BLOCK] = write_block_definition, + [MIE_VALUE_INSTR] = write_instr, + [MIE_VALUE_CONST] = NULL, +}; +static const size_t nr_value_printers + = sizeof value_writers / sizeof value_writers[0]; + +b_status write_value_to_text( + struct mie_ir_converter *converter, struct mie_value *value) +{ + write_function writer = value_writers[value->v_type->t_id]; + return writer(converter, value); +} diff --git a/mie/include/mie/convert.h b/mie/include/mie/convert.h new file mode 100644 index 0000000..75c1ead --- /dev/null +++ b/mie/include/mie/convert.h @@ -0,0 +1,80 @@ +#ifndef MIE_CONVERT_H_ +#define MIE_CONVERT_H_ + +#include +#include +#include +#include +#include + +struct mie_value; + +enum mie_ir_format { + MIE_IR_NONE = 0, + MIE_IR_MEM, + MIE_IR_BITCODE, + MIE_IR_TEXT, +}; + +enum mie_ir_converter_medium { + MIE_IR_CONVERTER_NONE = 0, + MIE_IR_CONVERTER_MIE_VALUE, + MIE_IR_CONVERTER_BITSTREAM, + MIE_IR_CONVERTER_BITBUFFER, + MIE_IR_CONVERTER_STRINGSTREAM, + MIE_IR_CONVERTER_STRING, + MIE_IR_CONVERTER_FILE, +}; + +struct mie_ir_converter { + enum mie_ir_format c_src_format, c_dest_format; + enum mie_ir_converter_medium c_src_medium, c_dest_medium; + + union { + /* TODO bitstream */ + struct mie_value *value; + b_bitbuffer *bitbuffer; + b_stringstream *stringstream; + b_string *string; + FILE *file; + } c_src; + + union { + /* TODO bitstream */ + struct mie_value **value; + b_bitbuffer *bitbuffer; + b_stringstream *stringstream; + b_string *string; + FILE *file; + } c_dest; +}; + +MIE_API struct mie_ir_converter *mie_ir_converter_create( + enum mie_ir_format src, enum mie_ir_format dest); +MIE_API void mie_ir_converter_destroy(struct mie_ir_converter *converter); + +MIE_API b_status mie_ir_converter_set_src_value( + struct mie_ir_converter *converter, struct mie_value *value); +MIE_API b_status mie_ir_converter_set_src_bitbuffer( + struct mie_ir_converter *converter, b_bitbuffer *bitbuffer); +MIE_API b_status mie_ir_converter_set_src_stringstream( + struct mie_ir_converter *converter, b_stringstream *stringstream); +MIE_API b_status mie_ir_converter_set_src_string( + struct mie_ir_converter *converter, b_string *string); +MIE_API b_status mie_ir_converter_set_src_file( + struct mie_ir_converter *converter, FILE *file); + +MIE_API b_status mie_ir_converter_set_dest_value( + struct mie_ir_converter *converter, struct mie_value **value); +MIE_API b_status mie_ir_converter_set_dest_bitbuffer( + struct mie_ir_converter *converter, b_bitbuffer *bitbuffer); +MIE_API b_status mie_ir_converter_set_dest_stringstream( + struct mie_ir_converter *converter, b_stringstream *stringstream); +MIE_API b_status mie_ir_converter_set_dest_string( + struct mie_ir_converter *converter, b_string *string); +MIE_API b_status mie_ir_converter_set_dest_file( + struct mie_ir_converter *converter, FILE *file); + +MIE_API b_status mie_ir_converter_process(struct mie_ir_converter *converter); + +#endif