From a27375ac2e7cddaade79c23ea18cbd3a0352d5e0 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 16 Mar 2026 12:02:19 +0000 Subject: [PATCH] func: implement print/parse for func, return --- mie/dialect/func/op/func.c | 122 ++++++++++++++++++++++++++++++++++- mie/dialect/func/op/return.c | 76 +++++++++++++++++++++- 2 files changed, 196 insertions(+), 2 deletions(-) diff --git a/mie/dialect/func/op/func.c b/mie/dialect/func/op/func.c index 985acf8..4a4531d 100644 --- a/mie/dialect/func/op/func.c +++ b/mie/dialect/func/op/func.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -11,6 +12,7 @@ #include #include #include +#include #include #include @@ -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; } diff --git a/mie/dialect/func/op/return.c b/mie/dialect/func/op/return.c index 2599635..6933dd8 100644 --- a/mie/dialect/func/op/return.c +++ b/mie/dialect/func/op/return.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -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; }