scf: implement print/parse for for, if, yield
This commit is contained in:
@@ -1,14 +1,281 @@
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/block.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/ir/region.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/parse/parser.h>
|
||||
#include <mie/print/printer.h>
|
||||
#include <mie/type/function.h>
|
||||
#include <mie/type/storage.h>
|
||||
|
||||
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
|
||||
{
|
||||
struct mie_region *body = mie_op_get_first_region(op);
|
||||
struct mie_block *entry = NULL;
|
||||
struct mie_register *iv = NULL;
|
||||
struct mie_op_arg *lb = NULL, *ub = NULL, *step = NULL;
|
||||
|
||||
if (!body) {
|
||||
return MIE_ERR_BAD_STATE;
|
||||
}
|
||||
|
||||
entry = mie_region_get_first_block(body);
|
||||
if (!entry) {
|
||||
return MIE_ERR_BAD_STATE;
|
||||
}
|
||||
|
||||
if (MIE_VECTOR_COUNT(op->op_args) < 3) {
|
||||
return MIE_ERR_BAD_STATE;
|
||||
}
|
||||
|
||||
if (MIE_VECTOR_COUNT(entry->b_params) < 1) {
|
||||
return MIE_ERR_BAD_STATE;
|
||||
}
|
||||
|
||||
iv = &entry->b_params.items[0];
|
||||
lb = &op->op_args.items[0];
|
||||
ub = &op->op_args.items[1];
|
||||
step = &op->op_args.items[2];
|
||||
|
||||
b_stream_write_char(printer->p_stream, ' ');
|
||||
mie_printer_print_register(printer, iv, 0);
|
||||
b_stream_write_string(printer->p_stream, " = ", NULL);
|
||||
mie_printer_print_op_arg(printer, lb, 0);
|
||||
b_stream_write_string(printer->p_stream, " to ", NULL);
|
||||
mie_printer_print_op_arg(printer, ub, 0);
|
||||
b_stream_write_string(printer->p_stream, " step ", NULL);
|
||||
mie_printer_print_op_arg(printer, step, 0);
|
||||
|
||||
if (MIE_VECTOR_COUNT(entry->b_params) > 1) {
|
||||
b_stream_write_string(printer->p_stream, " iter-args(", NULL);
|
||||
for (size_t i = 1; i < MIE_VECTOR_COUNT(entry->b_params); i++) {
|
||||
if (i > 1) {
|
||||
b_stream_write_string(printer->p_stream, ", ", NULL);
|
||||
}
|
||||
|
||||
mie_printer_print_register(
|
||||
printer, &entry->b_params.items[i], 0);
|
||||
b_stream_write_string(printer->p_stream, " = ", NULL);
|
||||
mie_printer_print_op_arg(
|
||||
printer, &op->op_args.items[i + 2], false);
|
||||
}
|
||||
b_stream_write_char(printer->p_stream, ')');
|
||||
}
|
||||
|
||||
if (MIE_VECTOR_COUNT(op->op_result) > 0) {
|
||||
b_stream_write_string(printer->p_stream, " -> ", NULL);
|
||||
if (MIE_VECTOR_COUNT(op->op_result) > 1) {
|
||||
b_stream_write_char(printer->p_stream, '(');
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
|
||||
mie_printer_print_type(
|
||||
printer, op->op_result.items[i].reg_type);
|
||||
}
|
||||
|
||||
if (MIE_VECTOR_COUNT(op->op_result) > 1) {
|
||||
b_stream_write_char(printer->p_stream, ')');
|
||||
}
|
||||
}
|
||||
|
||||
b_stream_write_char(printer->p_stream, ' ');
|
||||
mie_printer_print_region(
|
||||
printer, body, MIE_PRINT_F_EXCLUDE_FIRST_BLOCK_HEADER);
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
static bool parse_result_type(
|
||||
struct mie_parser *parser, struct mie_parser_scope *scope,
|
||||
struct mie_op *out, struct mie_block *entry)
|
||||
{
|
||||
const struct mie_type *type = NULL;
|
||||
struct mie_file_span span;
|
||||
if (!mie_parser_parse_type(parser, "loop result type", &type, &span)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct mie_type **types;
|
||||
size_t nr_types;
|
||||
|
||||
if (mie_type_is_storage(type)) {
|
||||
const struct mie_storage_type *storage
|
||||
= (const struct mie_storage_type *)type;
|
||||
|
||||
types = storage->st_parts.items;
|
||||
nr_types = storage->st_parts.count;
|
||||
} else if (!mie_type_is_function(type)) {
|
||||
types = &type;
|
||||
nr_types = 1;
|
||||
} else {
|
||||
mie_parser_report_error_simple(
|
||||
parser, "builtin", MIE_BUILTIN_E_INVALID_TYPE,
|
||||
MIE_BUILTIN_MSG_CANNOT_USE_FUNCTION_TYPE_HERE, &span);
|
||||
}
|
||||
|
||||
if (MIE_VECTOR_COUNT(out->op_result) != nr_types) {
|
||||
mie_parser_report_error_simple(
|
||||
parser, "builtin", MIE_BUILTIN_E_INCORRECT_NUMBER_OF_TYPES,
|
||||
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_RESULTS,
|
||||
&span);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nr_types; i++) {
|
||||
out->op_result.items[i].reg_type = types[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_iter_arg(
|
||||
struct mie_parser *parser, struct mie_parser_scope *scope,
|
||||
struct mie_op *out, struct mie_block *entry)
|
||||
{
|
||||
struct mie_register *reg = mie_block_add_param(entry);
|
||||
struct mie_op_arg *arg = mie_op_add_arg(out);
|
||||
|
||||
if (!mie_parser_parse_register(
|
||||
parser, scope, "iterator parameter name", reg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(parser, MIE_SYM_EQUAL)) {
|
||||
mie_parser_report_unexpected_token(
|
||||
parser, MIE_SYM_EQUAL, "iterator parameter");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_parameter(
|
||||
parser, false, arg, "iterator parameter value")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct mie_register *value = mie_parser_scope_find_value(
|
||||
scope, arg->arg_unresolved.reg_name);
|
||||
if (value) {
|
||||
reg->reg_type = value->reg_type;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_iter_args(
|
||||
struct mie_parser *parser, struct mie_parser_scope *scope,
|
||||
struct mie_op *out, struct mie_block *entry)
|
||||
{
|
||||
if (!mie_parser_parse_keyword(parser, "iter-args", NULL)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(parser, MIE_SYM_LEFT_PAREN)) {
|
||||
mie_parser_report_unexpected_token(
|
||||
parser, MIE_SYM_LEFT_PAREN, "iterator parameter list");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parse_iter_arg(parser, scope, out, entry)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (mie_parser_parse_symbol(parser, MIE_SYM_RIGHT_PAREN)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
|
||||
struct mie_parser_item expected[] = {
|
||||
MIE_PARSE_ITEM_TOKEN(MIE_SYM_COMMA),
|
||||
MIE_PARSE_ITEM_TOKEN(MIE_SYM_RIGHT_PAREN),
|
||||
MIE_PARSE_ITEM_NONE,
|
||||
};
|
||||
mie_parser_report_unexpected_token_v(
|
||||
parser, expected, "iterator parameter list");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parse_iter_arg(parser, scope, out, entry)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
struct mie_parser *parser, struct mie_parser_scope *scope,
|
||||
struct mie_op *out)
|
||||
{
|
||||
struct mie_region *body = mie_op_add_region(out);
|
||||
struct mie_block *entry = mie_region_add_block(body);
|
||||
struct mie_register *iv = mie_block_add_param(entry);
|
||||
|
||||
mie_parser_scope_put_name(scope, &entry->b_name, "for.entry", 0);
|
||||
|
||||
if (!mie_parser_parse_register(parser, scope, "induction variable", iv)) {
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
iv->reg_type = mie_ctx_get_type(
|
||||
mie_parser_get_mie_ctx(parser), "builtin", "index");
|
||||
|
||||
if (!mie_parser_parse_symbol(parser, MIE_SYM_EQUAL)) {
|
||||
mie_parser_report_unexpected_token(
|
||||
parser, MIE_SYM_EQUAL, "for-loop");
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
struct mie_op_arg *lb = mie_op_add_arg(out);
|
||||
if (!mie_parser_parse_parameter(parser, false, lb, "lower bound")) {
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_keyword(parser, "to", NULL)) {
|
||||
mie_parser_report_unexpected_token_s(parser, "to", "for-loop");
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
struct mie_op_arg *ub = mie_op_add_arg(out);
|
||||
if (!mie_parser_parse_parameter(parser, false, ub, "upper bound")) {
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_keyword(parser, "step", NULL)) {
|
||||
mie_parser_report_unexpected_token_s(parser, "step", "for-loop");
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
struct mie_op_arg *step = mie_op_add_arg(out);
|
||||
if (!mie_parser_parse_parameter(parser, false, step, "step")) {
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
if (!parse_iter_args(parser, scope, out, entry)) {
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
if (mie_parser_parse_symbol(parser, MIE_SYM_HYPHEN_RIGHT_ANGLE)) {
|
||||
if (!parse_result_type(parser, scope, out, entry)) {
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
} else if (MIE_VECTOR_COUNT(out->op_result) > 0) {
|
||||
struct mie_file_span span;
|
||||
mie_op_get_results_span(out, &span);
|
||||
mie_parser_report_error_simple(
|
||||
parser, "builtin",
|
||||
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
|
||||
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_RESULTS,
|
||||
&span);
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_region(parser, out, body, entry)) {
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,9 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
static enum mie_status parse(
|
||||
struct mie_parser *parser, struct mie_parser_scope *names,
|
||||
struct mie_op *out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.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)
|
||||
@@ -30,8 +32,81 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
static enum mie_status parse(
|
||||
struct mie_parser *parser, struct mie_parser_scope *scope,
|
||||
struct mie_op *out)
|
||||
{
|
||||
if (!mie_parser_parse_parameter_list(
|
||||
parser, false, MIE_VECTOR_REF(out->op_args),
|
||||
"yield value(s)")) {
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
|
||||
mie_parser_report_unexpected_token(
|
||||
parser, MIE_SYM_COLON, "yield value type(s)");
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
MIE_VECTOR_DEFINE(const struct mie_type *, types);
|
||||
const struct mie_type *tmp = NULL;
|
||||
struct mie_file_span first_span, last_span;
|
||||
|
||||
if (!mie_parser_parse_type(
|
||||
parser, "yield value type(s)", &tmp, &first_span)) {
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
mie_vector_push_back(types, &tmp, NULL);
|
||||
bool ok = true;
|
||||
|
||||
while (1) {
|
||||
if (mie_parser_peek_type(parser) == MIE_TOK_LINEFEED) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
|
||||
struct mie_parser_item expected[] = {
|
||||
MIE_PARSE_ITEM_TOKEN(MIE_SYM_COMMA),
|
||||
MIE_PARSE_ITEM_TOKEN(MIE_TOK_LINEFEED),
|
||||
MIE_PARSE_ITEM_NONE,
|
||||
};
|
||||
|
||||
mie_parser_report_unexpected_token_v(
|
||||
parser, expected, "yield value type list");
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_type(
|
||||
parser, "yield value type", &tmp, &last_span)) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
mie_vector_push_back(types, &tmp, NULL);
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
mie_vector_destroy(types, NULL);
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
if (MIE_VECTOR_COUNT(types) != MIE_VECTOR_COUNT(out->op_args)) {
|
||||
struct mie_file_span span = {
|
||||
.s_start = first_span.s_start,
|
||||
.s_end = last_span.s_end,
|
||||
};
|
||||
mie_parser_report_error_simple(
|
||||
parser, "builtin", MIE_BUILTIN_E_INCORRECT_NUMBER_OF_TYPES,
|
||||
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_ARGS, &span);
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(types); i++) {
|
||||
out->op_args.items[i].arg_unresolved.reg_type = types.items[i];
|
||||
}
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user