func: implement print/parse for func, return
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include <mie/attribute/attribute-map.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/diag/diag.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/func.h>
|
||||
@@ -11,6 +12,7 @@
|
||||
#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>
|
||||
|
||||
@@ -69,8 +71,126 @@ 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_return_type(
|
||||
struct mie_parser *parser,
|
||||
MIE_VECTOR_REF_PARAM(const struct mie_type *, out))
|
||||
{
|
||||
bool ok = true;
|
||||
if (mie_parser_peek_symbol(parser) == MIE_SYM_LEFT_PAREN) {
|
||||
ok = mie_parser_parse_type_list(
|
||||
parser, "function return type", MIE_VECTOR_REF2(out), NULL);
|
||||
} else {
|
||||
const struct mie_type *tmp;
|
||||
ok = mie_parser_parse_type(
|
||||
parser, "function return type", &tmp, NULL);
|
||||
|
||||
if (ok) {
|
||||
mie_vector_ref_push_back(out, &tmp, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return ok ? MIE_SUCCESS : MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
struct mie_parser *parser, struct mie_parser_scope *scope,
|
||||
struct mie_op *out)
|
||||
{
|
||||
if (!scope) {
|
||||
struct mie_diag *diag = mie_parser_report_error_simple(
|
||||
parser, "builtin", MIE_BUILTIN_E_OP_REQUIRES_PARENT_SCOPE,
|
||||
MIE_BUILTIN_MSG_OP_REQUIRES_PARENT_SCOPE,
|
||||
&out->op_name_span);
|
||||
mie_diag_push_msg(
|
||||
diag, mie_parser_get_mie_ctx(parser), "builtin",
|
||||
MIE_BUILTIN_MSG_OP_PARENT_SCOPE_EXAMPLE);
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
b_string *temp = mie_parser_get_tempstr(parser);
|
||||
if (!mie_parser_parse_symname(parser, temp, NULL)) {
|
||||
mie_parser_report_unexpected_token(
|
||||
parser, MIE_TOK_SYMNAME, "function signature");
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
struct mie_attribute *sym_name = mie_ctx_get_string(
|
||||
mie_parser_get_mie_ctx(parser), b_string_ptr(temp));
|
||||
|
||||
if (!mie_parser_parse_symbol(parser, MIE_SYM_LEFT_PAREN)) {
|
||||
mie_parser_report_unexpected_token(
|
||||
parser, MIE_SYM_LEFT_PAREN, "function parameter list");
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
MIE_VECTOR_DEFINE(struct mie_op_arg, block_params);
|
||||
MIE_VECTOR_DEFINE(const struct mie_type *, in_types);
|
||||
MIE_VECTOR_DEFINE(const struct mie_type *, out_types);
|
||||
|
||||
if (!mie_parser_parse_parameter_list(
|
||||
parser, true, MIE_VECTOR_REF(block_params),
|
||||
"function parameter list")) {
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(parser, MIE_SYM_RIGHT_PAREN)) {
|
||||
mie_parser_report_unexpected_token(
|
||||
parser, MIE_SYM_LEFT_PAREN, "function parameter list");
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
struct mie_region *body = mie_op_add_region(out);
|
||||
struct mie_block *entry = mie_region_add_block(body);
|
||||
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(block_params); i++) {
|
||||
struct mie_register *param_reg = mie_vector_emplace_back(
|
||||
entry->b_params, &mie_register_vector_ops);
|
||||
|
||||
param_reg->reg_flags = block_params.items[i].arg_unresolved.reg_flags
|
||||
| MIE_REGISTER_F_BLOCK_PARAM;
|
||||
param_reg->reg_type = block_params.items[i].arg_unresolved.reg_type;
|
||||
param_reg->reg_block = entry;
|
||||
if (!mie_parser_scope_put_name(
|
||||
scope, ¶m_reg->reg_name,
|
||||
block_params.items[i].arg_unresolved.reg_name,
|
||||
MIE_NAME_MAP_F_STRICT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mie_vector_push_back(in_types, ¶m_reg->reg_type, NULL);
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(parser, MIE_SYM_HYPHEN_RIGHT_ANGLE)) {
|
||||
mie_parser_report_unexpected_token(
|
||||
parser, MIE_SYM_HYPHEN_RIGHT_ANGLE,
|
||||
"function signature");
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
if (parse_return_type(parser, MIE_VECTOR_REF(out_types)) != MIE_SUCCESS) {
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
const struct mie_type *func_type = mie_ctx_get_function_type(
|
||||
mie_parser_get_mie_ctx(parser), in_types.items, in_types.count,
|
||||
out_types.items, out_types.count);
|
||||
|
||||
mie_vector_destroy(in_types, NULL);
|
||||
mie_vector_destroy(out_types, NULL);
|
||||
|
||||
struct mie_attribute *function_type
|
||||
= mie_type_attr_create(mie_parser_get_mie_ctx(parser), func_type);
|
||||
|
||||
mie_attribute_map_put(
|
||||
&out->op_attrib, "sym_name", sym_name, MIE_ATTRMAP_F_REPLACE);
|
||||
mie_attribute_map_put(
|
||||
&out->op_attrib, "function_type", function_type,
|
||||
MIE_ATTRMAP_F_REPLACE);
|
||||
|
||||
if (!mie_parser_parse_region(parser, out, body, entry)) {
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#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>
|
||||
|
||||
@@ -38,8 +39,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),
|
||||
"function return values")) {
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
|
||||
mie_parser_report_unexpected_token(
|
||||
parser, MIE_SYM_COLON, "function return type");
|
||||
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, "function return type", &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, "function return type list");
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_type(
|
||||
parser, "function return 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