cf: implement print/parse for br, br-cond

This commit is contained in:
2026-03-16 12:01:50 +00:00
parent 639652b083
commit ef4349b732
2 changed files with 171 additions and 2 deletions

View File

@@ -1,8 +1,10 @@
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h> #include <mie/dialect/dialect.h>
#include <mie/ir/emit.h> #include <mie/ir/emit.h>
#include <mie/ir/op-definition.h> #include <mie/ir/op-definition.h>
#include <mie/ir/op.h> #include <mie/ir/op.h>
#include <mie/macros.h> #include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h> #include <mie/print/printer.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op) static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
@@ -29,8 +31,104 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS; return MIE_SUCCESS;
} }
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out) static bool parse_successor(struct mie_parser *ctx, struct mie_op_successor *out)
{ {
memset(out, 0x0, sizeof *out);
b_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 = b_string_steal(str);
if (mie_parser_peek_type(ctx) == MIE_TOK_LINEFEED
|| mie_parser_peek_symbol(ctx) == MIE_SYM_COMMA) {
goto ok;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
struct mie_parser_item expected[] = {
MIE_PARSE_ITEM_TOKEN(MIE_SYM_COMMA),
MIE_PARSE_ITEM_TOKEN(MIE_SYM_LEFT_PAREN),
MIE_PARSE_ITEM_TOKEN(MIE_TOK_LINEFEED),
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_arg *cond = mie_op_add_arg(out);
struct mie_file_span span;
if (!mie_parser_parse_parameter(
parser, false, cond, "branch condition")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COMMA, "branch destination list");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_op_successor *true_branch
= mie_vector_emplace_back(out->op_successors, NULL);
if (!parse_successor(parser, true_branch)) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COMMA, "branch destination list");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_op_successor *false_branch
= mie_vector_emplace_back(out->op_successors, NULL);
if (!parse_successor(parser, false_branch)) {
return MIE_ERR_BAD_SYNTAX;
}
cond->arg_unresolved.reg_type
= mie_ctx_get_int_type(mie_parser_get_mie_ctx(parser), 1);
return MIE_SUCCESS; return MIE_SUCCESS;
} }

View File

@@ -4,6 +4,7 @@
#include <mie/ir/op-definition.h> #include <mie/ir/op-definition.h>
#include <mie/ir/op.h> #include <mie/ir/op.h>
#include <mie/macros.h> #include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h> #include <mie/print/printer.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op) static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
@@ -16,8 +17,78 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS; return MIE_SUCCESS;
} }
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out) static bool parse_successor(struct mie_parser *ctx, struct mie_op_successor *out)
{ {
memset(out, 0x0, sizeof *out);
b_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 = b_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; return MIE_SUCCESS;
} }