2026-01-08 19:19:45 +00:00
|
|
|
#include <mie/ctx.h>
|
|
|
|
|
#include <mie/dialect/arith.h>
|
|
|
|
|
#include <mie/dialect/dialect.h>
|
2026-01-11 14:26:54 +00:00
|
|
|
#include <mie/ir/block.h>
|
2026-01-04 14:08:57 +00:00
|
|
|
#include <mie/ir/module.h>
|
|
|
|
|
#include <mie/ir/op.h>
|
|
|
|
|
#include <mie/ir/region.h>
|
|
|
|
|
#include <mie/ir/register.h>
|
|
|
|
|
#include <mie/parse/lex.h>
|
|
|
|
|
#include <mie/parse/parse.h>
|
|
|
|
|
#include <mie/parse/token.h>
|
2026-01-08 19:19:45 +00:00
|
|
|
#include <mie/type/function.h>
|
2026-01-08 22:16:50 +00:00
|
|
|
#include <mie/type/type-definition.h>
|
2026-01-11 14:26:54 +00:00
|
|
|
#include <mie/vector.h>
|
2026-01-04 14:08:57 +00:00
|
|
|
|
|
|
|
|
struct mie_parser {
|
|
|
|
|
struct mie_ctx *p_ctx;
|
|
|
|
|
struct mie_lex *p_lex;
|
|
|
|
|
enum mie_status p_status;
|
2026-01-11 14:26:54 +00:00
|
|
|
b_string *s_tmp;
|
2026-01-04 14:08:57 +00:00
|
|
|
};
|
|
|
|
|
|
2026-01-11 14:26:54 +00:00
|
|
|
static b_string *get_temp_string(struct mie_parser *parser)
|
|
|
|
|
{
|
|
|
|
|
b_string_clear(parser->s_tmp);
|
|
|
|
|
return parser->s_tmp;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-04 14:08:57 +00:00
|
|
|
struct mie_parser *mie_parser_create(struct mie_ctx *ctx, struct mie_lex *lex)
|
|
|
|
|
{
|
|
|
|
|
struct mie_parser *out = malloc(sizeof *out);
|
|
|
|
|
if (!out) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(out, 0x0, sizeof *out);
|
|
|
|
|
|
2026-01-11 14:26:54 +00:00
|
|
|
out->s_tmp = b_string_create();
|
|
|
|
|
if (!out->s_tmp) {
|
|
|
|
|
free(out);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-04 14:08:57 +00:00
|
|
|
out->p_ctx = ctx;
|
|
|
|
|
out->p_lex = lex;
|
|
|
|
|
out->p_status = MIE_SUCCESS;
|
|
|
|
|
|
|
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mie_parser_destroy(struct mie_parser *ctx)
|
|
|
|
|
{
|
2026-01-11 14:26:54 +00:00
|
|
|
if (ctx->s_tmp) {
|
|
|
|
|
b_string_unref(ctx->s_tmp);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-04 14:08:57 +00:00
|
|
|
free(ctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum mie_status mie_parser_get_status(const struct mie_parser *ctx)
|
|
|
|
|
{
|
|
|
|
|
return ctx->p_status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_token *mie_parser_peek(struct mie_parser *ctx)
|
|
|
|
|
{
|
|
|
|
|
return mie_lex_peek(ctx->p_lex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum mie_token_type mie_parser_peek_type(struct mie_parser *ctx)
|
|
|
|
|
{
|
|
|
|
|
return MIE_TOKEN_TYPE(mie_lex_peek(ctx->p_lex));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum mie_token_symbol mie_parser_peek_symbol(struct mie_parser *ctx)
|
|
|
|
|
{
|
|
|
|
|
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
|
|
|
|
|
|
|
|
|
|
if (MIE_TOKEN_TYPE(tok) != MIE_TOK_SYMBOL) {
|
|
|
|
|
return MIE_SYM_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return tok->tok_sym;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_check_eof(struct mie_parser *ctx)
|
|
|
|
|
{
|
|
|
|
|
return mie_lex_peek(ctx->p_lex) == NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_check_type(struct mie_parser *ctx, enum mie_token_type type)
|
|
|
|
|
{
|
|
|
|
|
return MIE_TOKEN_IS(mie_lex_peek(ctx->p_lex), type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_check_symbol(struct mie_parser *ctx, enum mie_token_symbol sym)
|
|
|
|
|
{
|
|
|
|
|
return MIE_TOKEN_IS_SYMBOL(mie_lex_peek(ctx->p_lex), sym);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_advance(struct mie_parser *ctx)
|
|
|
|
|
{
|
|
|
|
|
mie_lex_advance(ctx->p_lex);
|
|
|
|
|
return mie_lex_get_status(ctx->p_lex) == MIE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-11 14:26:54 +00:00
|
|
|
bool mie_parser_parse_int(
|
|
|
|
|
struct mie_parser *ctx, long long *out, struct mie_file_span *loc)
|
|
|
|
|
{
|
|
|
|
|
if (!mie_parser_check_type(ctx, MIE_TOK_INT)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
|
|
|
|
|
if (tok->tok_value_type != MIE_TOK_V_INT) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (loc) {
|
|
|
|
|
mie_file_span_init(loc, tok);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*out = tok->tok_int;
|
|
|
|
|
mie_lex_advance(ctx->p_lex);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_float(
|
|
|
|
|
struct mie_parser *ctx, double *out, struct mie_file_span *loc)
|
|
|
|
|
{
|
|
|
|
|
if (!mie_parser_check_type(ctx, MIE_TOK_FLOAT)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
|
|
|
|
|
if (tok->tok_value_type != MIE_TOK_V_FLOAT) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (loc) {
|
|
|
|
|
mie_file_span_init(loc, tok);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*out = tok->tok_float;
|
|
|
|
|
mie_lex_advance(ctx->p_lex);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-08 19:19:45 +00:00
|
|
|
#define TOKEN_PARSER(name, id) \
|
|
|
|
|
bool mie_parser_parse_##name( \
|
|
|
|
|
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc) \
|
|
|
|
|
{ \
|
|
|
|
|
if (!mie_parser_check_type(ctx, id)) { \
|
|
|
|
|
return false; \
|
|
|
|
|
} \
|
|
|
|
|
struct mie_token *tok = mie_lex_peek(ctx->p_lex); \
|
2026-01-11 14:26:54 +00:00
|
|
|
switch (tok->tok_value_type) { \
|
|
|
|
|
case MIE_TOK_V_STRING: \
|
|
|
|
|
b_string_append_cstr(out, tok->tok_str); \
|
|
|
|
|
break; \
|
|
|
|
|
case MIE_TOK_V_INT: \
|
|
|
|
|
b_string_append_cstrf(out, "%lld", tok->tok_int); \
|
|
|
|
|
break; \
|
|
|
|
|
default: \
|
|
|
|
|
return false; \
|
|
|
|
|
} \
|
2026-01-08 19:19:45 +00:00
|
|
|
if (loc) { \
|
|
|
|
|
mie_file_span_init(loc, tok); \
|
|
|
|
|
} \
|
|
|
|
|
mie_lex_advance(ctx->p_lex); \
|
|
|
|
|
return true; \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TOKEN_PARSER(word, MIE_TOK_WORD);
|
|
|
|
|
TOKEN_PARSER(instname, MIE_TOK_INSTNAME);
|
|
|
|
|
TOKEN_PARSER(graphname, MIE_TOK_GRAPHNAME);
|
|
|
|
|
TOKEN_PARSER(opname, MIE_TOK_OPNAME);
|
|
|
|
|
TOKEN_PARSER(vregname, MIE_TOK_VREGNAME);
|
|
|
|
|
TOKEN_PARSER(mregname, MIE_TOK_MREGNAME);
|
|
|
|
|
TOKEN_PARSER(blockname, MIE_TOK_BLOCKNAME);
|
|
|
|
|
TOKEN_PARSER(typename, MIE_TOK_TYPENAME);
|
|
|
|
|
TOKEN_PARSER(symname, MIE_TOK_SYMNAME);
|
|
|
|
|
TOKEN_PARSER(string, MIE_TOK_STRING);
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_symbol(struct mie_parser *ctx, enum mie_token_symbol sym)
|
2026-01-04 14:08:57 +00:00
|
|
|
{
|
2026-01-08 19:19:45 +00:00
|
|
|
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
|
|
|
|
|
if (!MIE_TOKEN_IS_SYMBOL(tok, sym)) {
|
2026-01-04 14:08:57 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mie_lex_advance(ctx->p_lex);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-11 14:26:54 +00:00
|
|
|
bool mie_parser_parse_linefeed(struct mie_parser *ctx)
|
|
|
|
|
{
|
|
|
|
|
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
|
|
|
|
|
if (tok->tok_type != MIE_TOK_LINEFEED) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mie_lex_advance(ctx->p_lex);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-08 19:19:45 +00:00
|
|
|
static bool parse_builtin_type_name(
|
|
|
|
|
struct mie_parser *ctx, const struct mie_type **out)
|
2026-01-04 14:08:57 +00:00
|
|
|
{
|
2026-01-11 14:26:54 +00:00
|
|
|
b_string *name = get_temp_string(ctx);
|
2026-01-08 19:19:45 +00:00
|
|
|
struct mie_file_span loc;
|
|
|
|
|
if (!mie_parser_parse_word(ctx, name, &loc)) {
|
2026-01-04 14:08:57 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-08 22:16:50 +00:00
|
|
|
const struct mie_type_definition *type_info = NULL;
|
2026-01-08 19:19:45 +00:00
|
|
|
const struct mie_type *type = NULL;
|
|
|
|
|
size_t width = 0;
|
|
|
|
|
char tmp = 0;
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
NONE = 0,
|
|
|
|
|
INT,
|
|
|
|
|
FLOAT
|
|
|
|
|
} base_type = NONE;
|
|
|
|
|
|
|
|
|
|
const char *name_cstr = b_string_ptr(name);
|
|
|
|
|
|
|
|
|
|
if (!strcmp(name_cstr, "memref")) {
|
2026-01-08 22:16:50 +00:00
|
|
|
type_info = mie_ctx_get_type_definition(
|
2026-01-08 19:19:45 +00:00
|
|
|
ctx->p_ctx, "memref", "memref");
|
|
|
|
|
} else if (!strcmp(name_cstr, "index")) {
|
2026-01-08 22:16:50 +00:00
|
|
|
type_info = mie_ctx_get_type_definition(
|
|
|
|
|
ctx->p_ctx, "index", "index");
|
2026-01-08 19:19:45 +00:00
|
|
|
} else if (!strcmp(name_cstr, "str")) {
|
2026-01-08 22:16:50 +00:00
|
|
|
type_info = mie_ctx_get_type_definition(
|
2026-01-08 19:19:45 +00:00
|
|
|
ctx->p_ctx, "builtin", "string");
|
|
|
|
|
} else if (sscanf(name_cstr, "i%zu%c", &width, &tmp) == 1) {
|
2026-01-08 22:16:50 +00:00
|
|
|
type_info = mie_ctx_get_type_definition(
|
|
|
|
|
ctx->p_ctx, "arith", "int");
|
2026-01-08 19:19:45 +00:00
|
|
|
base_type = INT;
|
|
|
|
|
} else if (sscanf(name_cstr, "f%zu%c", &width, &tmp) == 1) {
|
2026-01-08 22:16:50 +00:00
|
|
|
type_info = mie_ctx_get_type_definition(
|
|
|
|
|
ctx->p_ctx, "arith", "float");
|
2026-01-08 19:19:45 +00:00
|
|
|
base_type = FLOAT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!type_info) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (base_type) {
|
|
|
|
|
case INT:
|
|
|
|
|
type = mie_arith_int_get_type(ctx->p_ctx, width);
|
|
|
|
|
break;
|
|
|
|
|
case FLOAT:
|
|
|
|
|
type = mie_arith_float_get_type(ctx->p_ctx, width);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
type = mie_ctx_get_type(
|
|
|
|
|
ctx->p_ctx, type_info->ty_parent->d_name,
|
|
|
|
|
type_info->ty_name);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*out = type;
|
|
|
|
|
return type != NULL;
|
2026-01-04 14:08:57 +00:00
|
|
|
}
|
|
|
|
|
|
2026-01-08 19:19:45 +00:00
|
|
|
static bool parse_type_name(struct mie_parser *ctx, const struct mie_type **out)
|
2026-01-04 14:08:57 +00:00
|
|
|
{
|
2026-01-11 14:26:54 +00:00
|
|
|
b_string *name = get_temp_string(ctx);
|
2026-01-08 19:19:45 +00:00
|
|
|
struct mie_file_span loc;
|
|
|
|
|
if (!mie_parser_parse_typename(ctx, name, &loc)) {
|
2026-01-04 14:08:57 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-08 19:19:45 +00:00
|
|
|
*out = NULL;
|
|
|
|
|
return false;
|
2026-01-04 14:08:57 +00:00
|
|
|
}
|
|
|
|
|
|
2026-01-08 19:19:45 +00:00
|
|
|
static bool parse_composite_type(struct mie_parser *ctx, const struct mie_type **out)
|
2026-01-04 14:08:57 +00:00
|
|
|
{
|
2026-01-08 19:19:45 +00:00
|
|
|
const struct mie_type *temp = NULL;
|
|
|
|
|
MIE_VECTOR_DEFINE(const struct mie_type *, type_list_1);
|
|
|
|
|
MIE_VECTOR_DEFINE(const struct mie_type *, type_list_2);
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_type_list(ctx, MIE_VECTOR_REF(type_list_1))) {
|
2026-01-04 14:08:57 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-08 19:19:45 +00:00
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_HYPHEN_RIGHT_ANGLE)) {
|
|
|
|
|
*out = mie_ctx_get_storage_type(
|
|
|
|
|
ctx->p_ctx, type_list_1.items, type_list_1.count);
|
|
|
|
|
return *out != NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ok = false;
|
|
|
|
|
if (mie_parser_peek_symbol(ctx) == MIE_SYM_LEFT_PAREN) {
|
|
|
|
|
ok = mie_parser_parse_type_list(ctx, MIE_VECTOR_REF(type_list_2));
|
|
|
|
|
} else {
|
|
|
|
|
ok = mie_parser_parse_type(ctx, &temp);
|
|
|
|
|
|
|
|
|
|
if (temp) {
|
|
|
|
|
mie_vector_push_back(type_list_2, &temp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ok) {
|
|
|
|
|
mie_vector_destroy(type_list_1, NULL);
|
|
|
|
|
mie_vector_destroy(type_list_2, NULL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
temp = mie_ctx_get_function_type(
|
|
|
|
|
ctx->p_ctx, type_list_1.items, type_list_1.count,
|
|
|
|
|
type_list_2.items, type_list_2.count);
|
|
|
|
|
mie_vector_destroy(type_list_1, NULL);
|
|
|
|
|
mie_vector_destroy(type_list_2, NULL);
|
|
|
|
|
|
|
|
|
|
*out = temp;
|
|
|
|
|
return temp != NULL;
|
2026-01-04 14:08:57 +00:00
|
|
|
}
|
|
|
|
|
|
2026-01-08 19:19:45 +00:00
|
|
|
bool mie_parser_parse_type(struct mie_parser *ctx, const struct mie_type **out)
|
2026-01-04 14:08:57 +00:00
|
|
|
{
|
2026-01-08 19:19:45 +00:00
|
|
|
if (mie_parser_peek_symbol(ctx) == MIE_SYM_LEFT_PAREN) {
|
|
|
|
|
return parse_composite_type(ctx, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (mie_parser_peek_type(ctx)) {
|
|
|
|
|
case MIE_TOK_WORD:
|
|
|
|
|
return parse_builtin_type_name(ctx, out);
|
|
|
|
|
case MIE_TOK_TYPENAME:
|
|
|
|
|
return parse_type_name(ctx, out);
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2026-01-04 14:08:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_type_list(
|
2026-01-08 19:19:45 +00:00
|
|
|
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(const struct mie_type *, out))
|
2026-01-04 14:08:57 +00:00
|
|
|
{
|
|
|
|
|
bool ok = false;
|
2026-01-08 19:19:45 +00:00
|
|
|
const struct mie_type **type_slot = NULL;
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
|
|
|
|
|
/* empty type list */
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2026-01-04 14:08:57 +00:00
|
|
|
|
|
|
|
|
type_slot = mie_vector_ref_emplace_back(out);
|
|
|
|
|
if (!type_slot) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_type(ctx, type_slot)) {
|
|
|
|
|
mie_vector_ref_pop_back(out);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COMMA)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type_slot = mie_vector_ref_emplace_back(out);
|
|
|
|
|
if (!type_slot) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_type(ctx, type_slot)) {
|
|
|
|
|
mie_vector_ref_pop_back(out);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-08 19:19:45 +00:00
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-04 14:08:57 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-08 19:19:45 +00:00
|
|
|
MIE_API bool mie_parser_parse_function_type(
|
|
|
|
|
struct mie_parser *ctx, struct mie_type **out)
|
2026-01-04 14:08:57 +00:00
|
|
|
{
|
2026-01-08 19:19:45 +00:00
|
|
|
const struct mie_type *type = NULL;
|
|
|
|
|
MIE_VECTOR_DEFINE(const struct mie_type *, in_parts);
|
|
|
|
|
MIE_VECTOR_DEFINE(const struct mie_type *, out_parts);
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_type_list(ctx, MIE_VECTOR_REF(in_parts))) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_HYPHEN_RIGHT_ANGLE)) {
|
|
|
|
|
mie_vector_destroy(in_parts, NULL);
|
|
|
|
|
mie_vector_destroy(out_parts, NULL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ok = false;
|
|
|
|
|
if (mie_parser_peek_symbol(ctx) == MIE_SYM_LEFT_PAREN) {
|
|
|
|
|
ok = mie_parser_parse_type_list(ctx, MIE_VECTOR_REF(out_parts));
|
2026-01-04 14:08:57 +00:00
|
|
|
} else {
|
2026-01-08 19:19:45 +00:00
|
|
|
ok = mie_parser_parse_type(ctx, &type);
|
|
|
|
|
|
|
|
|
|
if (type) {
|
|
|
|
|
mie_vector_push_back(out_parts, &type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ok) {
|
|
|
|
|
mie_vector_destroy(in_parts, NULL);
|
|
|
|
|
mie_vector_destroy(out_parts, NULL);
|
2026-01-04 14:08:57 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-08 19:19:45 +00:00
|
|
|
type = mie_ctx_get_function_type(
|
|
|
|
|
ctx->p_ctx, in_parts.items, in_parts.count, out_parts.items,
|
|
|
|
|
out_parts.count);
|
|
|
|
|
mie_vector_destroy(in_parts, NULL);
|
|
|
|
|
mie_vector_destroy(out_parts, NULL);
|
|
|
|
|
|
|
|
|
|
*out = (struct mie_type *)type;
|
|
|
|
|
return type != NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_operand(struct mie_parser *ctx, struct mie_op_arg *out)
|
|
|
|
|
{
|
|
|
|
|
memset(out, 0x0, sizeof *out);
|
2026-01-11 14:26:54 +00:00
|
|
|
b_string *str = get_temp_string(ctx);
|
2026-01-08 19:19:45 +00:00
|
|
|
bool result = false;
|
|
|
|
|
|
|
|
|
|
struct mie_file_span loc;
|
|
|
|
|
if (mie_parser_parse_vregname(ctx, str, &loc)) {
|
|
|
|
|
out->arg_unresolved.reg_name = b_string_steal(str);
|
|
|
|
|
out->arg_unresolved.reg_flags = MIE_REGISTER_F_VIRTUAL;
|
|
|
|
|
result = true;
|
|
|
|
|
} else if (mie_parser_parse_mregname(ctx, str, &loc)) {
|
|
|
|
|
out->arg_unresolved.reg_name = b_string_steal(str);
|
|
|
|
|
out->arg_unresolved.reg_flags = MIE_REGISTER_F_MACHINE;
|
|
|
|
|
result = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
2026-01-04 14:08:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_operand_list(
|
2026-01-08 19:19:45 +00:00
|
|
|
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out))
|
2026-01-04 14:08:57 +00:00
|
|
|
{
|
|
|
|
|
bool ok = false;
|
2026-01-08 19:19:45 +00:00
|
|
|
struct mie_op_arg *operand = NULL;
|
2026-01-04 14:08:57 +00:00
|
|
|
|
|
|
|
|
struct mie_token *tok = mie_parser_peek(ctx);
|
|
|
|
|
enum mie_token_type type = MIE_TOKEN_TYPE(tok);
|
|
|
|
|
if (type != MIE_TOK_VREGNAME && type != MIE_TOK_MREGNAME) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
operand = mie_vector_ref_emplace_back(out);
|
|
|
|
|
if (!operand) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_operand(ctx, operand)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
tok = mie_parser_peek(ctx);
|
|
|
|
|
|
|
|
|
|
if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mie_parser_advance(ctx);
|
|
|
|
|
tok = mie_parser_peek(ctx);
|
|
|
|
|
type = MIE_TOKEN_TYPE(tok);
|
|
|
|
|
|
|
|
|
|
if (type != MIE_TOK_VREGNAME && type != MIE_TOK_MREGNAME) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
operand = mie_vector_ref_emplace_back(out);
|
|
|
|
|
if (!operand) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_operand(ctx, operand)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-11 14:26:54 +00:00
|
|
|
bool mie_parser_parse_parameter(struct mie_parser *ctx, struct mie_op_arg *out)
|
|
|
|
|
{
|
|
|
|
|
memset(out, 0x0, sizeof *out);
|
|
|
|
|
b_string *str = get_temp_string(ctx);
|
|
|
|
|
|
|
|
|
|
struct mie_file_span loc;
|
|
|
|
|
if (mie_parser_parse_vregname(ctx, str, &loc)) {
|
|
|
|
|
out->arg_unresolved.reg_name = b_string_steal(str);
|
|
|
|
|
out->arg_unresolved.reg_flags = MIE_REGISTER_F_VIRTUAL;
|
|
|
|
|
} else if (mie_parser_parse_mregname(ctx, str, &loc)) {
|
|
|
|
|
out->arg_unresolved.reg_name = b_string_steal(str);
|
|
|
|
|
out->arg_unresolved.reg_flags = MIE_REGISTER_F_MACHINE;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_type(ctx, &out->arg_unresolved.reg_type)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_parameter_list(
|
|
|
|
|
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out))
|
|
|
|
|
{
|
|
|
|
|
bool ok = false;
|
|
|
|
|
struct mie_op_arg *operand = NULL;
|
|
|
|
|
|
|
|
|
|
struct mie_token *tok = mie_parser_peek(ctx);
|
|
|
|
|
enum mie_token_type type = MIE_TOKEN_TYPE(tok);
|
|
|
|
|
if (type != MIE_TOK_VREGNAME && type != MIE_TOK_MREGNAME) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
operand = mie_vector_ref_emplace_back(out);
|
|
|
|
|
if (!operand) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_parameter(ctx, operand)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
tok = mie_parser_peek(ctx);
|
|
|
|
|
|
|
|
|
|
if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mie_parser_advance(ctx);
|
|
|
|
|
tok = mie_parser_peek(ctx);
|
|
|
|
|
type = MIE_TOKEN_TYPE(tok);
|
|
|
|
|
|
|
|
|
|
if (type != MIE_TOK_VREGNAME && type != MIE_TOK_MREGNAME) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
operand = mie_vector_ref_emplace_back(out);
|
|
|
|
|
if (!operand) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_parameter(ctx, operand)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-04 14:08:57 +00:00
|
|
|
bool mie_parser_parse_register(
|
|
|
|
|
struct mie_parser *ctx, struct mie_name_map *names, struct mie_register *out)
|
|
|
|
|
{
|
|
|
|
|
memset(out, 0x0, sizeof *out);
|
|
|
|
|
|
|
|
|
|
struct mie_token *tok = mie_parser_peek(ctx);
|
|
|
|
|
enum mie_token_type type = MIE_TOKEN_TYPE(tok);
|
|
|
|
|
switch (type) {
|
|
|
|
|
case MIE_TOK_VREGNAME:
|
|
|
|
|
out->reg_flags |= MIE_REGISTER_F_VIRTUAL;
|
|
|
|
|
break;
|
|
|
|
|
case MIE_TOK_MREGNAME:
|
|
|
|
|
out->reg_flags |= MIE_REGISTER_F_MACHINE;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-11 14:26:54 +00:00
|
|
|
struct mie_name *name = NULL;
|
|
|
|
|
b_string *tmp = get_temp_string(ctx);
|
|
|
|
|
switch (tok->tok_value_type) {
|
|
|
|
|
case MIE_TOK_V_STRING:
|
|
|
|
|
name = mie_name_map_put(
|
|
|
|
|
names, &out->reg_name, tok->tok_str, MIE_NAME_MAP_F_STRICT);
|
|
|
|
|
break;
|
|
|
|
|
case MIE_TOK_V_INT:
|
|
|
|
|
b_string_append_cstrf(tmp, "%lld", tok->tok_int);
|
|
|
|
|
name = mie_name_map_put(
|
|
|
|
|
names, &out->reg_name, b_string_ptr(tmp),
|
|
|
|
|
MIE_NAME_MAP_F_STRICT);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2026-01-04 14:08:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mie_parser_advance(ctx);
|
|
|
|
|
|
2026-01-11 14:26:54 +00:00
|
|
|
return name != NULL;
|
2026-01-04 14:08:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_register_list(
|
|
|
|
|
struct mie_parser *ctx, struct mie_name_map *names,
|
2026-01-08 19:15:35 +00:00
|
|
|
MIE_VECTOR_REF_PARAM(struct mie_register, out))
|
2026-01-04 14:08:57 +00:00
|
|
|
{
|
|
|
|
|
bool ok = false;
|
|
|
|
|
struct mie_register *reg = NULL;
|
|
|
|
|
|
|
|
|
|
struct mie_token *tok = mie_parser_peek(ctx);
|
|
|
|
|
enum mie_token_type type = MIE_TOKEN_TYPE(tok);
|
|
|
|
|
if (type != MIE_TOK_VREGNAME && type != MIE_TOK_MREGNAME) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg = mie_vector_ref_emplace_back(out);
|
|
|
|
|
if (!reg) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_register(ctx, names, reg)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
tok = mie_parser_peek(ctx);
|
|
|
|
|
|
|
|
|
|
if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mie_parser_advance(ctx);
|
|
|
|
|
tok = mie_parser_peek(ctx);
|
|
|
|
|
type = MIE_TOKEN_TYPE(tok);
|
|
|
|
|
|
|
|
|
|
if (type != MIE_TOK_VREGNAME && type != MIE_TOK_MREGNAME) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg = mie_vector_ref_emplace_back(out);
|
|
|
|
|
if (!reg) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_register(ctx, names, reg)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod)
|
|
|
|
|
{
|
|
|
|
|
#define OP_TOKEN_TYPES \
|
|
|
|
|
(MIE_TOK_NAME | MIE_TOK_OPNAME | MIE_TOK_VREGNAME | MIE_TOK_MREGNAME \
|
|
|
|
|
| MIE_TOK_GRAPHNAME | MIE_TOK_INSTNAME)
|
|
|
|
|
while (1) {
|
|
|
|
|
enum mie_token_type type = mie_parser_peek_type(ctx);
|
|
|
|
|
bool is_op = (type & OP_TOKEN_TYPES);
|
|
|
|
|
|
|
|
|
|
if (!is_op) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_op *op = mie_vector_emplace_back(mod->m_ops);
|
|
|
|
|
if (!op) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_op(ctx, mod->m_names, op)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_region(struct mie_parser *ctx, struct mie_region *region)
|
|
|
|
|
{
|
2026-01-11 14:26:54 +00:00
|
|
|
region->r_names = mie_name_map_create(NULL);
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACE)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mie_parser_parse_linefeed(ctx);
|
|
|
|
|
struct mie_block *block = NULL;
|
|
|
|
|
|
|
|
|
|
if (mie_parser_peek_type(ctx) != MIE_TOK_BLOCKNAME) {
|
|
|
|
|
block = mie_vector_emplace_back(region->r_blocks);
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_anonymous_block(ctx, region->r_names, block)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
if (mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACE)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
block = mie_vector_emplace_back(region->r_blocks);
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_block(ctx, region->r_names, block)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-04 14:08:57 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_region_list(
|
2026-01-08 19:15:35 +00:00
|
|
|
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_region, out))
|
2026-01-04 14:08:57 +00:00
|
|
|
{
|
|
|
|
|
if (!mie_parser_check_symbol(ctx, MIE_SYM_LEFT_BRACE)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_region *region = mie_vector_ref_emplace_back(out);
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_region(ctx, region)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COMMA)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_check_symbol(ctx, MIE_SYM_LEFT_BRACE)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_region *region = mie_vector_ref_emplace_back(out);
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_region(ctx, region)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-11 14:26:54 +00:00
|
|
|
bool mie_parser_parse_anonymous_block(
|
|
|
|
|
struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block)
|
|
|
|
|
{
|
|
|
|
|
mie_parser_parse_linefeed(ctx);
|
|
|
|
|
|
|
|
|
|
struct mie_op *op = mie_vector_emplace_back(block->b_ops);
|
|
|
|
|
if (!mie_parser_parse_op(ctx, names, op)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mie_parser_parse_linefeed(ctx);
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
if (mie_parser_peek_type(ctx) == MIE_TOK_BLOCKNAME) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mie_parser_peek_symbol(ctx) == MIE_SYM_RIGHT_BRACE) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_op *op = mie_vector_emplace_back(block->b_ops);
|
|
|
|
|
if (!mie_parser_parse_op(ctx, names, op)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_linefeed(ctx)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool parse_block_parameters(
|
|
|
|
|
struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block)
|
|
|
|
|
{
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MIE_VECTOR_DEFINE(struct mie_op_arg, block_params);
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_parameter_list(ctx, MIE_VECTOR_REF(block_params))) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)
|
|
|
|
|
|| !mie_parser_parse_symbol(ctx, MIE_SYM_COLON)
|
|
|
|
|
|| !mie_parser_parse_linefeed(ctx)) {
|
|
|
|
|
mie_vector_destroy(block_params, NULL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(block_params); i++) {
|
|
|
|
|
struct mie_register *param_reg
|
|
|
|
|
= mie_vector_emplace_back(block->b_params);
|
|
|
|
|
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 = block;
|
|
|
|
|
if (!mie_name_map_put(
|
|
|
|
|
names, ¶m_reg->reg_name,
|
|
|
|
|
block_params.items[i].arg_unresolved.reg_name,
|
|
|
|
|
MIE_NAME_MAP_F_STRICT)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_block(
|
|
|
|
|
struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block)
|
|
|
|
|
{
|
|
|
|
|
b_string *str = get_temp_string(ctx);
|
|
|
|
|
struct mie_file_span span;
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_blockname(ctx, str, &span)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_name_map_put(
|
|
|
|
|
names, &block->b_name, b_string_ptr(str),
|
|
|
|
|
MIE_NAME_MAP_F_STRICT)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mie_parser_peek_symbol(ctx) == MIE_SYM_LEFT_PAREN
|
|
|
|
|
&& !parse_block_parameters(ctx, names, block)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)
|
|
|
|
|
|| !mie_parser_parse_linefeed(ctx)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
if (mie_parser_peek_type(ctx) == MIE_TOK_BLOCKNAME) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mie_parser_peek_symbol(ctx) == MIE_SYM_RIGHT_BRACE) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_op *op = mie_vector_emplace_back(block->b_ops);
|
|
|
|
|
if (!mie_parser_parse_op(ctx, names, op)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_linefeed(ctx)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-04 14:08:57 +00:00
|
|
|
bool mie_parser_parse_attribute(
|
|
|
|
|
struct mie_parser *ctx, struct mie_op_attribute *attrib)
|
|
|
|
|
{
|
2026-01-11 14:26:54 +00:00
|
|
|
b_string *str = get_temp_string(ctx);
|
|
|
|
|
struct mie_file_span span;
|
|
|
|
|
if (!mie_parser_parse_word(ctx, str, &span)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
attrib->attrib_name = b_string_steal(str);
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_EQUAL)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_value *value = NULL;
|
|
|
|
|
if (!mie_parser_parse_value(ctx, &value)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
attrib->attrib_value = value;
|
|
|
|
|
|
|
|
|
|
return true;
|
2026-01-04 14:08:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_attribute_list(
|
2026-01-08 19:15:35 +00:00
|
|
|
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_attribute, out))
|
2026-01-04 14:08:57 +00:00
|
|
|
{
|
2026-01-11 14:26:54 +00:00
|
|
|
bool ok = false;
|
|
|
|
|
struct mie_op_attribute *attrib = NULL;
|
|
|
|
|
|
|
|
|
|
attrib = mie_vector_ref_emplace_back(out);
|
|
|
|
|
if (!attrib) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_attribute(ctx, attrib)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
const struct mie_token *tok = mie_parser_peek(ctx);
|
|
|
|
|
|
|
|
|
|
if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mie_parser_advance(ctx);
|
|
|
|
|
mie_parser_parse_linefeed(ctx);
|
|
|
|
|
|
|
|
|
|
attrib = mie_vector_ref_emplace_back(out);
|
|
|
|
|
if (!attrib) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_attribute(ctx, attrib)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
2026-01-04 14:08:57 +00:00
|
|
|
}
|
|
|
|
|
|
2026-01-11 14:26:54 +00:00
|
|
|
bool mie_parser_parse_successor(struct mie_parser *ctx, struct mie_op_successor *out)
|
2026-01-04 14:08:57 +00:00
|
|
|
{
|
2026-01-11 14:26:54 +00:00
|
|
|
memset(out, 0x0, sizeof *out);
|
|
|
|
|
b_string *str = get_temp_string(ctx);
|
|
|
|
|
bool result = false;
|
|
|
|
|
struct mie_file_span span;
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_blockname(ctx, str, &span)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out->s_block_name = b_string_steal(str);
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_parameter_list(ctx, MIE_VECTOR_REF(out->s_args))) {
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-04 14:08:57 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_successor_list(
|
2026-01-08 19:15:35 +00:00
|
|
|
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_successor, out))
|
2026-01-04 14:08:57 +00:00
|
|
|
{
|
2026-01-11 14:26:54 +00:00
|
|
|
bool ok = false;
|
|
|
|
|
struct mie_op_successor *successor = NULL;
|
|
|
|
|
|
|
|
|
|
successor = mie_vector_ref_emplace_back(out);
|
|
|
|
|
if (!successor) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_successor(ctx, successor)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
const struct mie_token *tok = mie_parser_peek(ctx);
|
|
|
|
|
|
|
|
|
|
if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mie_parser_advance(ctx);
|
|
|
|
|
mie_parser_parse_linefeed(ctx);
|
|
|
|
|
|
|
|
|
|
successor = mie_vector_ref_emplace_back(out);
|
|
|
|
|
if (!successor) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_successor(ctx, successor)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
2026-01-04 14:08:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool parse_custom_op(
|
|
|
|
|
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool parse_generic_op(
|
|
|
|
|
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest)
|
|
|
|
|
{
|
2026-01-11 14:26:54 +00:00
|
|
|
b_string *str = get_temp_string(ctx);
|
2026-01-08 19:07:19 +00:00
|
|
|
struct mie_file_span loc;
|
|
|
|
|
if (!mie_parser_parse_opname(ctx, str, &loc)) {
|
2026-01-04 14:08:57 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dest->op_name = b_string_steal(str);
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-11 14:26:54 +00:00
|
|
|
if (mie_parser_peek_symbol(ctx) != MIE_SYM_RIGHT_PAREN
|
|
|
|
|
&& !mie_parser_parse_operand_list(ctx, MIE_VECTOR_REF(dest->op_args))) {
|
2026-01-04 14:08:57 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-11 14:26:54 +00:00
|
|
|
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACKET)) {
|
|
|
|
|
mie_parser_parse_linefeed(ctx);
|
|
|
|
|
if (!mie_parser_parse_successor_list(
|
|
|
|
|
ctx, MIE_VECTOR_REF(dest->op_successors))) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACKET)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
|
|
|
|
|
mie_parser_parse_linefeed(ctx);
|
|
|
|
|
if (!mie_parser_parse_region_list(
|
|
|
|
|
ctx, MIE_VECTOR_REF(dest->op_regions))) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-04 14:08:57 +00:00
|
|
|
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACKET)) {
|
|
|
|
|
if (!mie_parser_parse_successor_list(
|
2026-01-08 19:15:35 +00:00
|
|
|
ctx, MIE_VECTOR_REF(dest->op_successors))) {
|
2026-01-04 14:08:57 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACKET)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
|
|
|
|
|
if (!mie_parser_parse_region_list(
|
2026-01-08 19:15:35 +00:00
|
|
|
ctx, MIE_VECTOR_REF(dest->op_regions))) {
|
2026-01-04 14:08:57 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACE)) {
|
|
|
|
|
if (!mie_parser_parse_attribute_list(
|
2026-01-08 19:15:35 +00:00
|
|
|
ctx, MIE_VECTOR_REF(dest->op_attrib))) {
|
2026-01-04 14:08:57 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACE)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-08 19:19:45 +00:00
|
|
|
struct mie_function_type *func_type = NULL;
|
|
|
|
|
if (!mie_parser_parse_function_type(ctx, (struct mie_type **)&func_type)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2026-01-04 14:08:57 +00:00
|
|
|
|
2026-01-08 19:19:45 +00:00
|
|
|
if (MIE_VECTOR_COUNT(func_type->func_in)
|
|
|
|
|
!= MIE_VECTOR_COUNT(dest->op_args)) {
|
2026-01-04 14:08:57 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-08 19:19:45 +00:00
|
|
|
if (MIE_VECTOR_COUNT(func_type->func_out)
|
|
|
|
|
!= MIE_VECTOR_COUNT(dest->op_result)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2026-01-04 14:08:57 +00:00
|
|
|
|
2026-01-08 19:19:45 +00:00
|
|
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(func_type->func_in); i++) {
|
|
|
|
|
dest->op_args.items[i].arg_unresolved.reg_type
|
|
|
|
|
= func_type->func_in.items[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(func_type->func_out); i++) {
|
|
|
|
|
dest->op_result.items[i].reg_type = func_type->func_out.items[i];
|
|
|
|
|
}
|
2026-01-04 14:08:57 +00:00
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool parse_graph_op(
|
|
|
|
|
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_op(
|
|
|
|
|
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest)
|
|
|
|
|
{
|
|
|
|
|
memset(dest, 0x0, sizeof *dest);
|
|
|
|
|
|
|
|
|
|
if (mie_parser_check_eof(ctx)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mie_parser_check_type(ctx, MIE_TOK_MREGNAME | MIE_TOK_VREGNAME)) {
|
|
|
|
|
if (!mie_parser_parse_register_list(
|
2026-01-08 19:15:35 +00:00
|
|
|
ctx, names, MIE_VECTOR_REF(dest->op_result))) {
|
2026-01-04 14:08:57 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_EQUAL)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mie_parser_check_type(ctx, MIE_TOK_NAME)) {
|
|
|
|
|
/* custom-format operation */
|
|
|
|
|
return parse_custom_op(ctx, names, dest);
|
|
|
|
|
} else if (mie_parser_check_type(ctx, MIE_TOK_OPNAME)) {
|
|
|
|
|
/* generic-format operation */
|
|
|
|
|
return parse_generic_op(ctx, names, dest);
|
|
|
|
|
} else if (mie_parser_check_type(ctx, MIE_TOK_GRAPHNAME)) {
|
|
|
|
|
/* graph-node operation */
|
|
|
|
|
return parse_graph_op(ctx, names, dest);
|
|
|
|
|
} else {
|
|
|
|
|
/* not sure what this is */
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-11 14:26:54 +00:00
|
|
|
|
|
|
|
|
static bool parse_string(struct mie_parser *ctx, struct mie_value **dest)
|
|
|
|
|
{
|
|
|
|
|
b_string *str = get_temp_string(ctx);
|
|
|
|
|
struct mie_file_span span;
|
|
|
|
|
if (!mie_parser_parse_string(ctx, str, &span)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_value *v = mie_ctx_get_string(ctx->p_ctx, b_string_ptr(str));
|
|
|
|
|
|
|
|
|
|
if (!v) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*dest = v;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool parse_int(struct mie_parser *ctx, struct mie_value **dest)
|
|
|
|
|
{
|
|
|
|
|
long long value = 0;
|
|
|
|
|
struct mie_file_span span;
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_int(ctx, &value, &span)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const struct mie_type *type = NULL;
|
|
|
|
|
if (!mie_parser_parse_type(ctx, &type)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t width = mie_arith_int_type_get_width(type);
|
|
|
|
|
if (width == (size_t)-1) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_value *v = mie_ctx_get_int(ctx->p_ctx, value, width);
|
|
|
|
|
if (!v) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*dest = v;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool parse_float(struct mie_parser *ctx, struct mie_value **dest)
|
|
|
|
|
{
|
|
|
|
|
double value = 0;
|
|
|
|
|
struct mie_file_span span;
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_float(ctx, &value, &span)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const struct mie_type *type = NULL;
|
|
|
|
|
if (!mie_parser_parse_type(ctx, &type)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t width = mie_arith_float_type_get_width(type);
|
|
|
|
|
if (width == (size_t)-1) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_value *v = mie_ctx_get_float(ctx->p_ctx, value, width);
|
|
|
|
|
if (!v) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*dest = v;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_parser_parse_value(struct mie_parser *ctx, struct mie_value **dest)
|
|
|
|
|
{
|
|
|
|
|
enum mie_token_type type = mie_parser_peek_type(ctx);
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case MIE_TOK_STRING:
|
|
|
|
|
return parse_string(ctx, dest);
|
|
|
|
|
case MIE_TOK_INT:
|
|
|
|
|
return parse_int(ctx, dest);
|
|
|
|
|
case MIE_TOK_FLOAT:
|
|
|
|
|
return parse_float(ctx, dest);
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|