Files
mie/mie/dialect/cf/op/br.c

114 lines
2.6 KiB
C

#include <mie/dialect/dialect.h>
#include <mie/ir/block.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
fx_stream_write_char(printer->p_stream, ' ');
const struct mie_op_successor *successor = &op->op_successors.items[0];
mie_printer_print_op_successor(printer, successor, true);
return MIE_SUCCESS;
}
static bool parse_successor(struct mie_parser *ctx, struct mie_op_successor *out)
{
memset(out, 0x0, sizeof *out);
fx_string *str = mie_parser_get_tempstr(ctx);
bool result = false;
if (!mie_parser_parse_blockname(ctx, str, &out->s_name_span)) {
mie_parser_report_unexpected_token(
ctx, MIE_TOK_BLOCKNAME, "branch destination");
return false;
}
out->s_block_name = fx_string_steal(str);
if (mie_parser_peek_type(ctx) == MIE_TOK_LINEFEED) {
goto ok;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
struct mie_parser_item expected[] = {
MIE_PARSE_ITEM_TOKEN(MIE_TOK_LINEFEED),
MIE_PARSE_ITEM_TOKEN(MIE_SYM_LEFT_PAREN),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(
ctx, expected, "branch destination/arguments");
goto fail;
}
if (!mie_parser_parse_parameter_list(
ctx, true, MIE_VECTOR_REF(out->s_args),
"branch successor arguments")) {
goto fail;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
mie_parser_report_unexpected_token(
ctx, MIE_SYM_RIGHT_PAREN, "branch arguments");
goto fail;
}
ok:
return true;
fail:
if (out->s_block_name) {
free(out->s_block_name);
out->s_block_name = NULL;
}
if (MIE_VECTOR_MAX(out->s_args) > 0) {
mie_vector_destroy(out->s_args, NULL);
}
return false;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_op_successor *s
= mie_vector_emplace_back(out->op_successors, NULL);
if (!s) {
return MIE_ERR_NO_MEMORY;
}
if (!parse_successor(parser, s)) {
return MIE_ERR_BAD_SYNTAX;
}
return MIE_SUCCESS;
}
struct mie_op *mie_cf_br_put(
struct mie_emitter *e, struct mie_block *dest,
struct mie_register **dest_args, size_t nr_dest_args)
{
struct mie_op *op = mie_emitter_put_op(e, "cf", "br", NULL, 0);
if (!op) {
return NULL;
}
struct mie_op_successor *s
= mie_op_add_successor(op, dest, dest_args, nr_dest_args);
return op;
}
MIE_OP_DEFINITION_BEGIN(mie_cf_br, "br")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()