mie: start implementing ir memory->text conversion
This commit is contained in:
7
mie/convert/bitcode-read.c
Normal file
7
mie/convert/bitcode-read.c
Normal file
@@ -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;
|
||||||
|
}
|
||||||
7
mie/convert/bitcode-write.c
Normal file
7
mie/convert/bitcode-write.c
Normal file
@@ -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;
|
||||||
|
}
|
||||||
216
mie/convert/convert.c
Normal file
216
mie/convert/convert.c
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
#include "convert.h"
|
||||||
|
|
||||||
|
#include <mie/convert.h>
|
||||||
|
#include <mie/value.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
19
mie/convert/convert.h
Normal file
19
mie/convert/convert.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef _MIE_CONVERT_H_
|
||||||
|
#define _MIE_CONVERT_H_
|
||||||
|
|
||||||
|
#include <mie/convert.h>
|
||||||
|
|
||||||
|
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
|
||||||
0
mie/convert/lex.c
Normal file
0
mie/convert/lex.c
Normal file
0
mie/convert/lex.h
Normal file
0
mie/convert/lex.h
Normal file
0
mie/convert/parse.c
Normal file
0
mie/convert/parse.c
Normal file
0
mie/convert/parse.h
Normal file
0
mie/convert/parse.h
Normal file
7
mie/convert/text-read.c
Normal file
7
mie/convert/text-read.c
Normal file
@@ -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;
|
||||||
|
}
|
||||||
478
mie/convert/text-write.c
Normal file
478
mie/convert/text-write.c
Normal file
@@ -0,0 +1,478 @@
|
|||||||
|
#include "convert.h"
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <mie/alloca.h>
|
||||||
|
#include <mie/arg.h>
|
||||||
|
#include <mie/block.h>
|
||||||
|
#include <mie/branch.h>
|
||||||
|
#include <mie/const.h>
|
||||||
|
#include <mie/func.h>
|
||||||
|
#include <mie/instr.h>
|
||||||
|
#include <mie/module.h>
|
||||||
|
#include <mie/op.h>
|
||||||
|
#include <mie/ptr.h>
|
||||||
|
#include <mie/type.h>
|
||||||
|
#include <mie/value.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#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, "<unknown-type>");
|
||||||
|
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, "<unknown>");
|
||||||
|
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);
|
||||||
|
}
|
||||||
80
mie/include/mie/convert.h
Normal file
80
mie/include/mie/convert.h
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#ifndef MIE_CONVERT_H_
|
||||||
|
#define MIE_CONVERT_H_
|
||||||
|
|
||||||
|
#include <blue/core/stringstream.h>
|
||||||
|
#include <blue/object/bitbuffer.h>
|
||||||
|
#include <blue/object/string.h>
|
||||||
|
#include <mie/misc.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
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
|
||||||
Reference in New Issue
Block a user