cf: implement print/parse for br, br-cond
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user