#include "cmd.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include enum { ARG_FILEPATH, }; 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); mie_builtin_passes_register(ctx); 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); struct mie_op *root = mie_op_create(); if (!mie_parser_parse_op(parse, NULL, root)) { printf("parse failed\n"); return -1; } 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); 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); 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); struct mie_pass *prefix_func_with_underscore = NULL; enum mie_status status = mie_ctx_get_pass( ctx, "prefix-func-with-underscore", NULL, &prefix_func_with_underscore); if (status != MIE_SUCCESS) { printf("cannot load pass prefix-func-with-underscore\n"); return -1; } 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); #if 0 mie_pass_manager_parse( pm, "builtin.module(func.func(prefix-func-with-underscore))"); #endif mie_pass_manager_run(pm, root); struct mie_printer printer; mie_printer_init(&printer, ctx, b_stdout, MIE_PRINT_F_ABBREVIATED); mie_printer_print_op(&printer, root); printf("\n"); 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); #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; } B_COMMAND(CMD_VALIDATE, CMD_ROOT) { 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(); }