mie: parse: implement more IR-parsing functions

This commit is contained in:
2026-01-04 14:08:57 +00:00
parent 21bcbb7edc
commit 86005451cb
3 changed files with 635 additions and 50 deletions

View File

@@ -5,58 +5,107 @@
#include <mie/misc.h>
#include <mie/parse/token.h>
#include <mie/status.h>
#include <mie/vector.h>
#include <stdbool.h>
struct mie_parse_ctx;
enum mie_unresolved_operand_type {
MIE_UNRESOLVED_OPERAND_NONE = 0,
MIE_UNRESOLVED_OPERAND_VIRTUAL_REGISTER,
MIE_UNRESOLVED_OPERAND_MACHINE_REGISTER,
};
struct mie_parser;
struct mie_name_map;
struct mie_lex;
struct mie_ctx;
struct mie_type;
struct mie_module;
struct mie_region;
struct mie_op;
struct mie_op_attribute;
struct mie_op_successor;
struct mie_register;
/* these structs are temporary, and are just here for documentation purposes atm */
struct mie_argument {
};
struct mie_unresolved_operand {
enum mie_unresolved_operand_type op_type;
b_string *op_name;
};
struct mie_region {
};
struct mie_type {
};
MIE_API struct mie_parse_ctx *mie_parse_ctx_create(
MIE_API struct mie_parser *mie_parser_create(
struct mie_ctx *ctx, struct mie_lex *lex);
MIE_API void mie_parse_ctx_destroy(struct mie_parse_ctx *ctx);
MIE_API enum mie_status mie_parse_ctx_get_status(const struct mie_parse_ctx *ctx);
MIE_API void mie_parser_destroy(struct mie_parser *ctx);
MIE_API enum mie_status mie_parser_get_status(const struct mie_parser *ctx);
MIE_API enum mie_token_type mie_parse_ctx_peek(struct mie_parse_ctx *ctx);
MIE_API bool mie_parse_ctx_advance(struct mie_parse_ctx *ctx);
MIE_API struct mie_token *mie_parser_peek(struct mie_parser *ctx);
MIE_API enum mie_token_type mie_parser_peek_type(struct mie_parser *ctx);
MIE_API enum mie_token_symbol mie_parser_peek_symbol(struct mie_parser *ctx);
MIE_API bool mie_parser_advance(struct mie_parser *ctx);
MIE_API bool mie_parse_ctx_parse_instname(struct mie_parse_ctx *ctx, b_string *out);
MIE_API bool mie_parse_ctx_parse_graphname(struct mie_parse_ctx *ctx, b_string *out);
MIE_API bool mie_parse_ctx_parse_vregname(struct mie_parse_ctx *ctx, b_string *out);
MIE_API bool mie_parse_ctx_parse_mregname(struct mie_parse_ctx *ctx, b_string *out);
MIE_API bool mie_parse_ctx_parse_blockname(struct mie_parse_ctx *ctx, b_string *out);
MIE_API bool mie_parse_ctx_parse_typename(struct mie_parse_ctx *ctx, b_string *out);
MIE_API bool mie_parse_ctx_parse_symname(struct mie_parse_ctx *ctx, b_string *out);
MIE_API bool mie_parse_ctx_parse_string(struct mie_parse_ctx *ctx, b_string *out);
MIE_API bool mie_parse_ctx_parse_keyword(struct mie_parse_ctx *ctx, const char *kw);
MIE_API bool mie_parse_ctx_parse_symbol(
struct mie_parse_ctx *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parse_ctx_parse_operand(
struct mie_parse_ctx *ctx, struct mie_unresolved_operand *out);
MIE_API bool mie_parse_ctx_parse_region(
struct mie_parse_ctx *ctx, struct mie_region *region);
MIE_API bool mie_parse_ctx_parse_type(
struct mie_parse_ctx *ctx, struct mie_type **out);
MIE_API bool mie_parse_ctx_parse_assignment_list(
struct mie_parse_ctx *ctx, struct mie_argument **out_lhs,
MIE_API bool mie_parser_check_eof(struct mie_parser *ctx);
MIE_API bool mie_parser_check_type(struct mie_parser *ctx, enum mie_token_type type);
MIE_API bool mie_parser_check_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_instname(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_graphname(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_opname(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_vregname(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_mregname(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_blockname(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_typename(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_symname(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_string(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_keyword(struct mie_parser *ctx, const char *kw);
MIE_API bool mie_parser_parse_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_assignment_list(
struct mie_parser *ctx, struct mie_argument **out_lhs,
struct mie_unresolved_operand **out_rhs, size_t *out_count);
MIE_API bool mie_parse_ctx_parse_unknown_keyword(
struct mie_parse_ctx *ctx, b_string *out);
MIE_API bool mie_parse_ctx_parse_unknown_symbol(
struct mie_parse_ctx *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_type(struct mie_parser *ctx, struct mie_type **out);
MIE_API bool mie_parser_parse_type_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_type *, out));
MIE_API bool mie_parser_parse_operand(
struct mie_parser *ctx, struct mie_unresolved_operand *out);
MIE_API bool mie_parser_parse_operand_list(
struct mie_parser *ctx,
MIE_VECTOR_PARAM(struct mie_unresolved_operand, out));
MIE_API bool mie_parser_parse_unknown_keyword(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_unknown_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_register(
struct mie_parser *ctx, struct mie_name_map *names,
struct mie_register *out);
MIE_API bool mie_parser_parse_register_list(
struct mie_parser *ctx, struct mie_name_map *names,
MIE_VECTOR_PARAM(struct mie_register, out));
MIE_API bool mie_parser_parse_region(
struct mie_parser *ctx, struct mie_region *region);
MIE_API bool mie_parser_parse_region_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_region, out));
MIE_API bool mie_parser_parse_attribute(
struct mie_parser *ctx, struct mie_op_attribute *attrib);
MIE_API bool mie_parser_parse_attribute_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_op_attribute, out));
MIE_API bool mie_parser_parse_successor(
struct mie_parser *ctx, struct mie_op_successor *successor);
MIE_API bool mie_parser_parse_successor_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_op_successor, out));
MIE_API bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod);
MIE_API bool mie_parser_parse_op(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest);
#endif

View File

@@ -4,23 +4,38 @@
#include <blue/core/queue.h>
#include <mie/misc.h>
#define MIE_TOKEN_TYPE(tok) ((tok) ? (tok)->tok_type : MIE_TOK_NONE)
#define MIE_TOKEN_IS(tok, type) ((tok) && ((tok)->tok_type & (type)) != 0)
#define MIE_TOKEN_IS_SYMBOL(tok, sym) \
((tok) && (tok)->tok_type == MIE_TOK_SYMBOL && (tok)->tok_sym == (sym))
enum mie_token_type {
MIE_TOK_NONE = 0,
MIE_TOK_LINEFEED,
MIE_TOK_INT,
MIE_TOK_DOUBLE,
MIE_TOK_SYMBOL,
MIE_TOK_STRING,
MIE_TOK_WORD, /* single words, not dot-delimited */
MIE_TOK_NAME, /* set of words with at least one dot */
MIE_TOK_INSTNAME, /* word or name, prefixed with an * asterisk */
MIE_TOK_SYMNAME, /* word or name, prefixed with an @ at */
MIE_TOK_OPNAME, /* word or name, prefixed with a ~ tilde */
MIE_TOK_GRAPHNAME, /* word or name, prefixed with a + plus */
MIE_TOK_VREGNAME, /* word or name, prefixed with a % percent */
MIE_TOK_MREGNAME, /* word or name, prefixed with a $ dollar */
MIE_TOK_BLOCKNAME, /* word or name, prefixed with a ^ caret */
MIE_TOK_TYPENAME, /* word or name, prefixed with a # hash */
MIE_TOK_LINEFEED = 0x0001u,
MIE_TOK_INT = 0x0002u,
MIE_TOK_DOUBLE = 0x0004u,
MIE_TOK_SYMBOL = 0x0008u,
MIE_TOK_STRING = 0x0010u,
/* single words, not dot-delimited */
MIE_TOK_WORD = 0x0020u,
/* set of words with at least one dot */
MIE_TOK_NAME = 0x0040u,
/* word or name, prefixed with an * asterisk */
MIE_TOK_INSTNAME = 0x0080u,
/* word or name, prefixed with an @ at */
MIE_TOK_SYMNAME = 0x0100u,
/* word or name, prefixed with a ~ tilde */
MIE_TOK_OPNAME = 0x0200u,
/* word or name, prefixed with a + plus */
MIE_TOK_GRAPHNAME = 0x0400u,
/* word or name, prefixed with a % percent */
MIE_TOK_VREGNAME = 0x0800u,
/* word or name, prefixed with a $ dollar */
MIE_TOK_MREGNAME = 0x1000u,
/* word or name, prefixed with a ^ caret */
MIE_TOK_BLOCKNAME = 0x2000u,
/* word or name, prefixed with a # hash */
MIE_TOK_TYPENAME = 0x4000u,
};
enum mie_token_value_type {

View File

@@ -0,0 +1,521 @@
#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>
struct mie_parser {
struct mie_ctx *p_ctx;
struct mie_lex *p_lex;
enum mie_status p_status;
};
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);
out->p_ctx = ctx;
out->p_lex = lex;
out->p_status = MIE_SUCCESS;
return out;
}
void mie_parser_destroy(struct mie_parser *ctx)
{
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;
}
bool mie_parser_parse_vregname(struct mie_parser *ctx, b_string *out)
{
if (!mie_parser_check_type(ctx, MIE_TOK_VREGNAME)) {
return false;
}
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
b_string_append_cstr(out, tok->tok_str);
mie_lex_advance(ctx->p_lex);
return true;
}
bool mie_parser_parse_mregname(struct mie_parser *ctx, b_string *out)
{
if (!mie_parser_check_type(ctx, MIE_TOK_MREGNAME)) {
return false;
}
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
b_string_append_cstr(out, tok->tok_str);
mie_lex_advance(ctx->p_lex);
return true;
}
bool mie_parser_parse_opname(struct mie_parser *ctx, b_string *out)
{
if (!mie_parser_check_type(ctx, MIE_TOK_OPNAME)) {
return false;
}
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
b_string_append_cstr(out, tok->tok_str);
mie_lex_advance(ctx->p_lex);
return true;
}
bool mie_parser_parse_symbol(struct mie_parser *ctx, enum mie_token_symbol sym)
{
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
if (!MIE_TOKEN_IS_SYMBOL(tok, sym)) {
return false;
}
mie_lex_advance(ctx->p_lex);
return true;
}
bool mie_parser_parse_type(struct mie_parser *ctx, struct mie_type **out)
{
return false;
}
bool mie_parser_parse_type_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_type *, out))
{
bool ok = false;
struct mie_type **type_slot = NULL;
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;
}
}
return true;
}
bool mie_parser_parse_operand(
struct mie_parser *ctx, struct mie_unresolved_operand *out)
{
memset(out, 0x0, sizeof *out);
out->op_name = b_string_create();
if (mie_parser_parse_vregname(ctx, out->op_name)) {
out->op_type = MIE_UNRESOLVED_OPERAND_VIRTUAL_REGISTER;
} else if (mie_parser_parse_mregname(ctx, out->op_name)) {
out->op_type = MIE_UNRESOLVED_OPERAND_MACHINE_REGISTER;
} else {
b_string_unref(out->op_name);
return false;
}
return true;
}
bool mie_parser_parse_operand_list(
struct mie_parser *ctx,
MIE_VECTOR_PARAM(struct mie_unresolved_operand, out))
{
bool ok = false;
struct mie_unresolved_operand *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_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;
}
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;
}
if (!mie_name_map_put(
names, &out->reg_name, tok->tok_str, MIE_NAME_MAP_STRICT)) {
return false;
}
mie_parser_advance(ctx);
return true;
}
bool mie_parser_parse_register_list(
struct mie_parser *ctx, struct mie_name_map *names,
MIE_VECTOR_PARAM(struct mie_register, out))
{
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)
{
return true;
}
bool mie_parser_parse_region_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_region, out))
{
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;
}
bool mie_parser_parse_attribute(
struct mie_parser *ctx, struct mie_op_attribute *attrib)
{
return false;
}
bool mie_parser_parse_attribute_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_op_attribute, out))
{
return false;
}
bool mie_parser_parse_successor(
struct mie_parser *ctx, struct mie_op_successor *successor)
{
return false;
}
bool mie_parser_parse_successor_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_op_successor, out))
{
return false;
}
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)
{
b_string *str = b_string_create();
if (!mie_parser_parse_opname(ctx, str)) {
return false;
}
dest->op_name = b_string_steal(str);
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
return false;
}
MIE_VECTOR_DEFINE(struct mie_unresolved_operand, operands);
if (mie_parser_parse_operand_list(ctx, MIE_VECTOR_ARG(operands))) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
return false;
}
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACKET)) {
if (!mie_parser_parse_successor_list(
ctx, MIE_VECTOR_ARG(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)) {
if (!mie_parser_parse_region_list(
ctx, MIE_VECTOR_ARG(dest->op_regions))) {
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(
ctx, MIE_VECTOR_ARG(dest->op_attrib))) {
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;
}
/* parse input type list */
if (!mie_parser_parse_symbol(ctx, MIE_SYM_HYPHEN_RIGHT_ANGLE)) {
return false;
}
/* parse output type list */
mie_vector_destroy(operands, NULL);
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(
ctx, names, MIE_VECTOR_ARG(dest->op_result))) {
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;
}
}