114 lines
2.6 KiB
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()
|