2025-11-16 20:07:22 +00:00
|
|
|
#include "cmd.h"
|
|
|
|
|
|
2026-01-11 14:51:37 +00:00
|
|
|
#include <assert.h>
|
2025-11-16 20:07:22 +00:00
|
|
|
#include <blue/cmd.h>
|
2026-01-11 14:51:37 +00:00
|
|
|
#include <blue/io/file.h>
|
|
|
|
|
#include <blue/io/path.h>
|
2025-11-16 20:07:22 +00:00
|
|
|
#include <blue/term.h>
|
2026-01-19 14:00:25 +00:00
|
|
|
#include <mie/attribute/attribute-definition.h>
|
2025-11-16 20:07:22 +00:00
|
|
|
#include <mie/ctx.h>
|
2026-01-11 14:51:37 +00:00
|
|
|
#include <mie/dialect/arith.h>
|
|
|
|
|
#include <mie/dialect/builtin.h>
|
|
|
|
|
#include <mie/dialect/cf.h>
|
|
|
|
|
#include <mie/dialect/dialect.h>
|
|
|
|
|
#include <mie/dialect/func.h>
|
|
|
|
|
#include <mie/dialect/index.h>
|
|
|
|
|
#include <mie/dialect/meta.h>
|
|
|
|
|
#include <mie/dialect/ptr.h>
|
|
|
|
|
#include <mie/dialect/scf.h>
|
|
|
|
|
#include <mie/dialect/select.h>
|
2026-01-19 14:00:25 +00:00
|
|
|
#include <mie/interface/interface-definition.h>
|
2026-01-11 14:51:37 +00:00
|
|
|
#include <mie/ir/block.h>
|
|
|
|
|
#include <mie/ir/op-definition.h>
|
|
|
|
|
#include <mie/ir/op.h>
|
|
|
|
|
#include <mie/ir/region.h>
|
|
|
|
|
#include <mie/ir/register.h>
|
2026-01-19 14:00:25 +00:00
|
|
|
#include <mie/ir/walk.h>
|
2026-01-11 14:51:37 +00:00
|
|
|
#include <mie/name.h>
|
|
|
|
|
#include <mie/parse/lex.h>
|
2026-01-19 14:00:25 +00:00
|
|
|
#include <mie/parse/parser.h>
|
2026-01-11 14:51:37 +00:00
|
|
|
#include <mie/parse/token.h>
|
2026-01-19 14:00:25 +00:00
|
|
|
#include <mie/pass/builtin.h>
|
|
|
|
|
#include <mie/pass/pass-manager.h>
|
|
|
|
|
#include <mie/print/printer.h>
|
2026-01-11 14:51:37 +00:00
|
|
|
#include <mie/trait/trait-definition.h>
|
|
|
|
|
#include <mie/trait/trait.h>
|
|
|
|
|
#include <mie/type/type-definition.h>
|
|
|
|
|
#include <mie/type/type.h>
|
2025-11-16 20:07:22 +00:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
enum {
|
2026-01-11 14:51:37 +00:00
|
|
|
ARG_FILEPATH,
|
2025-11-16 20:07:22 +00:00
|
|
|
};
|
|
|
|
|
|
2026-01-11 14:51:37 +00:00
|
|
|
static int validate_file(const char *path, const b_arglist *args)
|
|
|
|
|
{
|
|
|
|
|
b_file *file = NULL;
|
|
|
|
|
b_result result
|
|
|
|
|
= b_file_open(NULL, B_RV_PATH(path), B_FILE_READ_ONLY, &file);
|
|
|
|
|
if (b_result_is_error(result)) {
|
|
|
|
|
b_throw(result);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("File OK\n");
|
|
|
|
|
|
|
|
|
|
struct mie_ctx *ctx = mie_ctx_create();
|
|
|
|
|
mie_builtin_dialect_create(ctx);
|
|
|
|
|
mie_meta_dialect_create(ctx);
|
|
|
|
|
mie_select_dialect_create(ctx);
|
|
|
|
|
mie_ptr_dialect_create(ctx);
|
|
|
|
|
mie_arith_dialect_create(ctx);
|
|
|
|
|
mie_func_dialect_create(ctx);
|
|
|
|
|
mie_cf_dialect_create(ctx);
|
|
|
|
|
mie_scf_dialect_create(ctx);
|
|
|
|
|
mie_index_dialect_create(ctx);
|
|
|
|
|
|
2026-01-19 14:00:25 +00:00
|
|
|
mie_builtin_passes_register(ctx);
|
|
|
|
|
|
2026-01-11 14:51:37 +00:00
|
|
|
struct mie_lex *lex = mie_lex_create(file);
|
|
|
|
|
struct mie_parser *parse = mie_parser_create(ctx, lex);
|
|
|
|
|
|
|
|
|
|
struct mie_name_map *names = mie_name_map_create(NULL);
|
|
|
|
|
|
2026-01-19 14:00:25 +00:00
|
|
|
struct mie_op *root = mie_op_create();
|
2026-01-11 14:51:37 +00:00
|
|
|
|
2026-01-19 14:00:25 +00:00
|
|
|
if (!mie_parser_parse_op(parse, NULL, root)) {
|
2026-01-11 14:51:37 +00:00
|
|
|
printf("parse failed\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-25 15:11:06 +00:00
|
|
|
enum mie_walker_flags walk_flags
|
|
|
|
|
= MIE_WALKER_F_INCLUDE_OPS | MIE_WALKER_F_PREORDER
|
|
|
|
|
| MIE_WALKER_F_FORWARD | MIE_WALKER_F_RECURSIVE;
|
|
|
|
|
struct mie_walker walker;
|
|
|
|
|
mie_walker_begin(&walker, root, walk_flags);
|
2026-01-19 14:00:25 +00:00
|
|
|
|
|
|
|
|
do {
|
2026-01-25 15:11:06 +00:00
|
|
|
const struct mie_walk_item *item = mie_walker_get(&walker);
|
2026-01-19 14:00:25 +00:00
|
|
|
for (size_t i = 0; i < item->i_depth; i++) {
|
|
|
|
|
fputs(" ", stdout);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-25 15:11:06 +00:00
|
|
|
switch (item->i_type) {
|
|
|
|
|
case MIE_WALK_ITEM_REGION:
|
|
|
|
|
printf("looking at region %p...\n", item->i_region);
|
|
|
|
|
continue;
|
|
|
|
|
case MIE_WALK_ITEM_BLOCK:
|
|
|
|
|
printf("looking at block %p %s...\n", item->i_block,
|
|
|
|
|
item->i_block->b_name.n_str);
|
|
|
|
|
continue;
|
|
|
|
|
case MIE_WALK_ITEM_OP:
|
|
|
|
|
|
|
|
|
|
printf("resolving %p %s... ", item->i_op,
|
|
|
|
|
item->i_op->op_name);
|
|
|
|
|
bool ok = mie_ctx_resolve_op(ctx, item->i_op);
|
|
|
|
|
printf("%s\n", ok ? "OK" : "FAIL");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} while (mie_walker_step(&walker) == MIE_SUCCESS);
|
|
|
|
|
mie_walker_end(&walker);
|
2026-01-19 14:00:25 +00:00
|
|
|
|
|
|
|
|
struct mie_pass *prefix_func_with_underscore = NULL;
|
2026-01-25 15:11:06 +00:00
|
|
|
enum mie_status status = mie_ctx_get_pass(
|
|
|
|
|
ctx, "prefix-func-with-underscore", NULL,
|
|
|
|
|
&prefix_func_with_underscore);
|
|
|
|
|
if (status != MIE_SUCCESS) {
|
2026-01-19 14:00:25 +00:00
|
|
|
printf("cannot load pass prefix-func-with-underscore\n");
|
2026-01-11 14:51:37 +00:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-19 14:00:25 +00:00
|
|
|
struct mie_pass_manager *pm = mie_pass_manager_create(ctx);
|
|
|
|
|
struct mie_pass_manager *module_pm = mie_pass_manager_nest(pm);
|
|
|
|
|
mie_pass_manager_filter_op(module_pm, "builtin", "module");
|
|
|
|
|
|
|
|
|
|
struct mie_pass_manager *func_pm = mie_pass_manager_nest(pm);
|
|
|
|
|
mie_pass_manager_filter_op(module_pm, "func", "func");
|
|
|
|
|
|
|
|
|
|
mie_pass_manager_add_pass(func_pm, prefix_func_with_underscore);
|
|
|
|
|
|
2026-01-25 15:11:06 +00:00
|
|
|
#if 0
|
2026-01-19 14:00:25 +00:00
|
|
|
mie_pass_manager_parse(
|
|
|
|
|
pm, "builtin.module(func.func(prefix-func-with-underscore))");
|
2026-01-25 15:11:06 +00:00
|
|
|
#endif
|
2026-01-19 14:00:25 +00:00
|
|
|
mie_pass_manager_run(pm, root);
|
|
|
|
|
|
2026-01-25 15:11:06 +00:00
|
|
|
struct mie_printer printer;
|
|
|
|
|
mie_printer_init(&printer, ctx, b_stdout, MIE_PRINT_F_ABBREVIATED);
|
2026-01-19 14:00:25 +00:00
|
|
|
mie_printer_print_op(&printer, root);
|
|
|
|
|
printf("\n");
|
2026-01-11 14:51:37 +00:00
|
|
|
|
2026-01-25 15:11:06 +00:00
|
|
|
struct mie_op *func = mie_op_get_first_child_op(root);
|
|
|
|
|
walk_flags = MIE_WALKER_F_INCLUDE_OPS | MIE_WALKER_F_PREORDER
|
|
|
|
|
| MIE_WALKER_F_FORWARD;
|
|
|
|
|
mie_walker_begin(&walker, func, walk_flags);
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
const struct mie_walk_item *item = mie_walker_get(&walker);
|
|
|
|
|
for (size_t i = 0; i < item->i_depth; i++) {
|
|
|
|
|
fputs(" ", stdout);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (item->i_type) {
|
|
|
|
|
case MIE_WALK_ITEM_REGION:
|
|
|
|
|
printf("looking at region %p...\n", item->i_region);
|
|
|
|
|
break;
|
|
|
|
|
case MIE_WALK_ITEM_BLOCK:
|
|
|
|
|
printf("looking at block %p %s...\n", item->i_block,
|
|
|
|
|
item->i_block->b_name.n_str);
|
|
|
|
|
break;
|
|
|
|
|
case MIE_WALK_ITEM_OP:
|
|
|
|
|
if (item->i_op->op_flags & MIE_OP_F_OP_RESOLVED) {
|
|
|
|
|
printf("looking at %p %s.%s...\n", item->i_op,
|
|
|
|
|
item->i_op->op_dialect->d_name,
|
|
|
|
|
item->i_op->op_info->op_name);
|
|
|
|
|
} else {
|
|
|
|
|
printf("looking at %p %s...\n", item->i_op,
|
|
|
|
|
item->i_op->op_name);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} while (mie_walker_step(&walker) == MIE_SUCCESS);
|
|
|
|
|
mie_walker_end(&walker);
|
|
|
|
|
|
2026-01-11 14:51:37 +00:00
|
|
|
#if 0
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
struct mie_token *tok = mie_lex_peek(lex);
|
|
|
|
|
if (!tok) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("%s[%d:%d -> %d:%d]",
|
|
|
|
|
mie_token_type_to_string(tok->tok_type),
|
|
|
|
|
tok->tok_start.c_row, tok->tok_start.c_col,
|
|
|
|
|
tok->tok_end.c_row, tok->tok_end.c_col);
|
|
|
|
|
|
|
|
|
|
switch (tok->tok_value_type) {
|
|
|
|
|
case MIE_TOK_V_STRING:
|
|
|
|
|
printf(" S:%s", tok->tok_str);
|
|
|
|
|
break;
|
|
|
|
|
case MIE_TOK_V_INT:
|
|
|
|
|
printf(" I:%lld", tok->tok_int);
|
|
|
|
|
break;
|
|
|
|
|
case MIE_TOK_V_DOUBLE:
|
|
|
|
|
printf(" D:%lf", tok->tok_double);
|
|
|
|
|
break;
|
|
|
|
|
case MIE_TOK_V_SYMBOL:
|
|
|
|
|
printf(" SYM:%s", mie_token_symbol_to_string(tok->tok_sym));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
|
|
mie_lex_advance(lex);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
mie_lex_destroy(lex);
|
|
|
|
|
|
|
|
|
|
b_file_unref(file);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int validate(const b_command *cmd, const b_arglist *args, const b_array *_)
|
|
|
|
|
{
|
|
|
|
|
b_arglist_iterator it;
|
|
|
|
|
b_arglist_foreach_filtered(&it, args, B_COMMAND_INVALID_ID, ARG_FILEPATH)
|
|
|
|
|
{
|
|
|
|
|
b_arglist_value *path = it.value;
|
|
|
|
|
if (path->val_type != B_COMMAND_ARG_STRING) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int r = validate_file(path->val_str, args);
|
|
|
|
|
if (r != 0) {
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
2025-11-16 20:07:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
B_COMMAND(CMD_VALIDATE, CMD_ROOT)
|
|
|
|
|
{
|
2026-01-11 14:51:37 +00:00
|
|
|
B_COMMAND_NAME("validate");
|
|
|
|
|
B_COMMAND_SHORT_NAME('V');
|
|
|
|
|
B_COMMAND_DESC("validate a mie ir file.");
|
|
|
|
|
B_COMMAND_HELP_OPTION();
|
|
|
|
|
B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT);
|
|
|
|
|
B_COMMAND_FUNCTION(validate);
|
|
|
|
|
|
|
|
|
|
B_COMMAND_ARG(ARG_FILEPATH)
|
|
|
|
|
{
|
|
|
|
|
B_ARG_NAME("filepath");
|
|
|
|
|
B_ARG_DESC("the mie file to validate");
|
|
|
|
|
B_ARG_NR_VALUES(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
B_COMMAND_HELP_OPTION();
|
2025-11-16 20:07:22 +00:00
|
|
|
}
|