From 58733261385fba999097340ce70449fae710e6ef Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 25 Jan 2026 15:10:23 +0000 Subject: [PATCH] mie: tool: split internal command into several different subcommands --- tool/CMakeLists.txt | 3 +- tool/cmd/cmd.h | 2 + tool/cmd/internal.c | 50 ----- tool/cmd/internal/builder-test.c | 182 +++++++++++++++ tool/cmd/internal/ctx-dump.c | 366 +++++++++++++++++++++++++++++++ tool/cmd/internal/internal.c | 20 ++ 6 files changed, 572 insertions(+), 51 deletions(-) delete mode 100644 tool/cmd/internal.c create mode 100644 tool/cmd/internal/builder-test.c create mode 100644 tool/cmd/internal/ctx-dump.c create mode 100644 tool/cmd/internal/internal.c diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt index bd36979..7c7b188 100644 --- a/tool/CMakeLists.txt +++ b/tool/CMakeLists.txt @@ -1,6 +1,7 @@ file(GLOB tool_sources *.c *.h - cmd/*.c cmd/*.h) + cmd/*.c cmd/*.h + cmd/internal/*.c) if (WIN32) set(rc_file ${CMAKE_CURRENT_SOURCE_DIR}/../res/win32/frontend.rc) diff --git a/tool/cmd/cmd.h b/tool/cmd/cmd.h index 518d190..14cde7c 100644 --- a/tool/cmd/cmd.h +++ b/tool/cmd/cmd.h @@ -5,6 +5,8 @@ enum command_id { CMD_ROOT, CMD_VALIDATE, CMD_INTERNAL, + CMD_INTERNAL_BUILDER_TEST, + CMD_INTERNAL_CTX_DUMP, }; #endif diff --git a/tool/cmd/internal.c b/tool/cmd/internal.c deleted file mode 100644 index be9aea9..0000000 --- a/tool/cmd/internal.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "cmd.h" -#include -#include - -enum { - OPT_PRINT_SYMBOLS = 0x1000, - OPT_PRINT_KEYWORDS, -}; - -static int internal(const b_command* cmd, const b_arglist* args, const b_array* _) -{ -#if 0 - if (b_arglist_get_count(args, OPT_PRINT_SYMBOLS, B_COMMAND_INVALID_ID)) { - internal_lexer_print_symbol_tree(lex); - } - - if (b_arglist_get_count(args, OPT_PRINT_KEYWORDS, B_COMMAND_INVALID_ID)) { - internal_lexer_print_keyword_dict(lex); - } - -#endif - - return 0; -} - -B_COMMAND(CMD_INTERNAL, CMD_ROOT) -{ - B_COMMAND_NAME("internal"); - B_COMMAND_SHORT_NAME('X'); - B_COMMAND_DESC("internal frontend debugging tools."); - B_COMMAND_FUNCTION(internal); - - B_COMMAND_OPTION(OPT_PRINT_SYMBOLS) - { - B_OPTION_LONG_NAME("print-symbols"); - B_OPTION_SHORT_NAME('s'); - B_OPTION_DESC( - "print the symbol tree used by the language lexer."); - } - - B_COMMAND_OPTION(OPT_PRINT_KEYWORDS) - { - B_OPTION_LONG_NAME("print-keywords"); - B_OPTION_SHORT_NAME('k'); - B_OPTION_DESC( - "print the keyword dictionary used by the language lexer."); - } - - B_COMMAND_HELP_OPTION(); -} diff --git a/tool/cmd/internal/builder-test.c b/tool/cmd/internal/builder-test.c new file mode 100644 index 0000000..da4c1b7 --- /dev/null +++ b/tool/cmd/internal/builder-test.c @@ -0,0 +1,182 @@ +#include "../cmd.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + OPT_GENERIC, + OPT_NO_ABBREV, + OPT_PASS_OFFSET = 100, +}; + +static int builder_test( + const b_command *cmd, const b_arglist *args, const b_array *_) +{ + 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_op *module = mie_ctx_create_op(ctx, "builtin", "module"); + struct mie_builder *builder = mie_builder_create(ctx, module); + + const struct mie_type *i32 = mie_ctx_get_int_type(ctx, 32); + const struct mie_type *i64 = mie_ctx_get_int_type(ctx, 64); + + struct mie_func_parameter params[] = { + {.param_name = "p1", .param_type = i32}, + {.param_name = "p2", .param_type = i64}, + }; + size_t nr_params = sizeof params / sizeof params[0]; + const struct mie_type *ret_type = mie_ctx_get_int_type(ctx, 64); + + struct mie_op *func = mie_func_func_put( + MIE_EMITTER(builder), "test_func", params, nr_params, &ret_type, 1); + mie_builder_step_into_op(builder, func); + + struct mie_region *r_true, *r_false; + struct mie_op *if_op = mie_scf_if_put( + MIE_EMITTER(builder), params[0].param_reg, i32, &r_true, + &r_false, NULL); + + struct mie_register *tmp = NULL; + + mie_builder_step_into_region(builder, r_true); + tmp = mie_arith_constant_i_put(MIE_EMITTER(builder), 10, NULL); + mie_scf_yield_put(MIE_EMITTER(builder), tmp); + mie_builder_step_out(builder); + + mie_builder_step_into_region(builder, r_false); + tmp = mie_arith_constant_i_put(MIE_EMITTER(builder), 20, NULL); + mie_scf_yield_put(MIE_EMITTER(builder), tmp); + mie_builder_step_out(builder); + + struct mie_register *v1 + = mie_arith_constant_i_put(MIE_EMITTER(builder), 1024, NULL); + struct mie_register *v2 + = mie_arith_constant_i_put(MIE_EMITTER(builder), 2048, NULL); + struct mie_register *add + = mie_arith_addi_put(MIE_EMITTER(builder), v1, v2, NULL); + struct mie_register *add2 = mie_arith_addi_put( + MIE_EMITTER(builder), add, &if_op->op_result.items[0], NULL); + + mie_builder_step_out(builder); + + 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"); + + b_arglist_iterator it; + b_arglist_foreach(&it, args) + { + if (it.opt_id < OPT_PASS_OFFSET) { + continue; + } + + const b_command_option *opt = b_command_get_option(cmd, it.opt_id); + if (!opt) { + continue; + } + + const char *pass_name = b_command_option_get_long_name(opt); + struct mie_pass *pass = NULL; + enum mie_status status + = mie_ctx_get_pass(ctx, pass_name, NULL, &pass); + if (status != MIE_SUCCESS) { + printf("cannot load pass %s\n", pass_name); + return -1; + } + + mie_pass_manager_add_pass(func_pm, pass); + } + + mie_pass_manager_run(pm, module); + + enum mie_print_flags flags = 0; + if (b_arglist_get_count(args, OPT_GENERIC, B_COMMAND_INVALID_ID) > 0) { + flags |= MIE_PRINT_F_GENERIC; + } + + if (b_arglist_get_count(args, OPT_NO_ABBREV, B_COMMAND_INVALID_ID) == 0) { + flags |= MIE_PRINT_F_ABBREVIATED; + } + + struct mie_printer printer; + mie_printer_init(&printer, ctx, b_stdout, flags); + mie_printer_print_op(&printer, module); + printf("\n"); + + return 0; +} + +B_COMMAND(CMD_INTERNAL_BUILDER_TEST, CMD_INTERNAL) +{ + B_COMMAND_NAME("builder-test"); + B_COMMAND_DESC("mie_builder test"); + B_COMMAND_FUNCTION(builder_test); + + B_COMMAND_OPTION(OPT_GENERIC) + { + B_OPTION_LONG_NAME("generic"); + B_OPTION_SHORT_NAME('g'); + B_OPTION_DESC("print operations in generic format."); + } + + B_COMMAND_OPTION(OPT_NO_ABBREV) + { + B_OPTION_LONG_NAME("no-abbrev"); + B_OPTION_SHORT_NAME('n'); + B_OPTION_DESC( + "don't use abbreviations for builtin types and ops."); + } + + B_COMMAND_HELP_OPTION(); + + struct mie_ctx *ctx = mie_ctx_create(); + mie_builtin_passes_register(ctx); + + size_t i = 0; + b_btree_node *node = b_btree_first(&ctx->ctx_passes.map_entries); + while (node) { + mie_id *id = b_unbox(mie_id, node, e_node); + struct mie_pass_definition *pass + = b_unbox(struct mie_pass_definition, id, p_id); + + B_COMMAND_OPTION_GEN(OPT_PASS_OFFSET + i) + { + B_OPTION_LONG_NAME(pass->p_name); + B_OPTION_DESC(pass->p_description); + } + + node = b_btree_next(node); + i++; + } +} diff --git a/tool/cmd/internal/ctx-dump.c b/tool/cmd/internal/ctx-dump.c new file mode 100644 index 0000000..be88329 --- /dev/null +++ b/tool/cmd/internal/ctx-dump.c @@ -0,0 +1,366 @@ +#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 + +static int trait_ref_print(const struct mie_trait *trait, void *arg) +{ + fputc(' ', stdout); + mie_trait_print(trait, b_stdout); + + return 0; +} + +static void op_arg_dump(struct mie_printer *printer, const struct mie_op_arg *arg) +{ + enum mie_register_flags arg_flags = 0; + const char *arg_name = NULL; + const struct mie_type *arg_type = NULL; + + if (MIE_TEST_FLAGS(arg->arg_flags, MIE_OP_F_ARG_RESOLVED)) { + arg_flags = arg->arg_value.u_reg->reg_flags; + arg_name = arg->arg_value.u_reg->reg_name.n_str; + arg_type = arg->arg_value.u_reg->reg_type; + } else { + arg_flags = arg->arg_unresolved.reg_flags; + arg_name = arg->arg_unresolved.reg_name; + arg_type = arg->arg_unresolved.reg_type; + } + + if (arg_flags & MIE_REGISTER_F_MACHINE) { + b_printf(" [bold,red]MR"); + } else { + b_printf(" [bold,magenta]VR"); + } + + printf(":("); + mie_printer_print_type(printer, arg_type); + b_printf(")%s[reset]", arg_name); +} + +static void op_dump(const struct mie_op *op) +{ + b_stringstream *tmp = b_stringstream_create(); + struct mie_printer printer; + mie_printer_init(&printer, NULL, b_stdout, MIE_PRINT_F_GENERIC); + + printf("FLAGS:"); + (op->op_flags & MIE_OP_F_OP_RESOLVED) && printf(" OP_RESOLVED"); + (op->op_flags & MIE_OP_F_ARG_RESOLVED) && printf(" ARG_RESOLVED"); + printf("\n"); + printf("DIALECT: %s\n", + op->op_dialect ? op->op_dialect->d_name : ""); + printf("OP: %s\n", op->op_info ? op->op_info->op_name : ""); + printf("NAME: %s\n", op->op_name ? op->op_name : ""); + printf("TRAITS:"); + mie_trait_table_iterate(&op->op_info->op_traits, trait_ref_print, NULL); + printf("\n"); + printf("ATTRIBUTES:"); +#if 0 + for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_attrib); i++) { + printf(" (%s = ", op->op_attrib.items[i].attrib_name); + mie_printer_print_value( + &printer, op->op_attrib.items[i].attrib_value); + printf(")"); + } +#endif + printf("\n"); + + printf("REGIONS: %zu\n", b_queue_length(&op->op_regions)); + printf("SUCCESSORS:"); + for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_successors); i++) { + const struct mie_op_successor *s = &op->op_successors.items[i]; + if (MIE_TEST_FLAGS(s->s_flags, MIE_OP_F_SUCCESSOR_RESOLVED)) { + printf(" ^%s", s->s_block->b_name.n_str); + } else { + printf(" ^%s?", s->s_block_name); + } + + printf(":("); + + for (size_t i = 0; i < MIE_VECTOR_COUNT(s->s_args); i++) { + const struct mie_op_arg *arg = &s->s_args.items[i]; + op_arg_dump(&printer, arg); + } + + printf(" )"); + } + printf("\n"); + + printf("ARGS:"); + for (size_t i = 0; i < op->op_args.count; i++) { + const struct mie_op_arg *arg = &op->op_args.items[i]; + op_arg_dump(&printer, arg); + } + printf("\n"); + + printf("RESULT:"); + for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) { + const struct mie_register *reg = &op->op_result.items[i]; + printf(" %s:(", + (reg->reg_flags & MIE_REGISTER_F_MACHINE) ? "MR" : "VR"); + mie_printer_print_type(&printer, reg->reg_type); + printf(")%s", reg->reg_name.n_str); + } + printf("\n"); +} + +static void mie_op_definition_print(const struct mie_op_definition *op) +{ + char id_str[MIE_ID_STRING_MAX]; + mie_id_to_string(&op->op_id, id_str, sizeof id_str); + b_printf( + " [bold,red]Op:[reset]%-20s [dark_grey]{%s}[reset]\n", + op->op_name, id_str); +} + +static void mie_type_definition_print(const struct mie_type_definition *type) +{ + char id_str[MIE_ID_STRING_MAX]; + mie_id_to_string(&type->ty_id, id_str, sizeof id_str); + b_printf( + " [bold,blue]Ty:[reset]%-20s [dark_grey]{%s}[reset]\n", + type->ty_name, id_str); +} + +static void mie_trait_definition_print(const struct mie_trait_definition *trait) +{ + char id_str[MIE_ID_STRING_MAX]; + mie_id_to_string(&trait->tr_id, id_str, sizeof id_str); + b_printf( + " [bold,yellow]Tr:[reset]%-20s [dark_grey]{%s}[reset]\n", + trait->tr_name, id_str); +} + +static void mie_attribute_definition_print( + const struct mie_attribute_definition *attribute) +{ + char id_str[MIE_ID_STRING_MAX]; + mie_id_to_string(&attribute->a_id, id_str, sizeof id_str); + b_printf( + " [bold,magenta]At:[reset]%-20s [dark_grey]{%s}[reset]\n", + attribute->a_name, id_str); +} + +static void mie_interface_definition_print( + const struct mie_interface_definition *interface) +{ + char id_str[MIE_ID_STRING_MAX]; + mie_id_to_string(&interface->if_id, id_str, sizeof id_str); + b_printf( + " [bold,cyan]If:[reset]%-20s [dark_grey]{%s}[reset]\n", + interface->if_name, id_str); +} + +static void mie_pass_definition_print(const struct mie_pass_definition *interface) +{ + char id_str[MIE_ID_STRING_MAX]; + mie_id_to_string(&interface->p_id, id_str, sizeof id_str); + b_printf( + " [bold,cyan]Ps:[reset]%-20s [dark_grey]{%s}[reset]\n", + interface->p_name, id_str); +} + +static void mie_dialect_print(const struct mie_dialect *dialect) +{ + char id_str[MIE_ID_STRING_MAX]; + mie_id_to_string(&dialect->d_id, id_str, sizeof id_str); + b_printf( + "[bold,green]D:[reset]%-20s [dark_grey]{%s}[reset]\n", + dialect->d_name, id_str); + + b_btree_node *node = b_btree_first(&dialect->d_ops.map_entries); + while (node) { + mie_id *id = b_unbox(mie_id, node, e_node); + struct mie_op_definition *op + = b_unbox(struct mie_op_definition, id, op_id); + + mie_op_definition_print(op); + node = b_btree_next(node); + } + + node = b_btree_first(&dialect->d_types.map_entries); + while (node) { + mie_id *id = b_unbox(mie_id, node, e_node); + struct mie_type_definition *type + = b_unbox(struct mie_type_definition, id, ty_id); + + mie_type_definition_print(type); + node = b_btree_next(node); + } + + node = b_btree_first(&dialect->d_traits.map_entries); + while (node) { + mie_id *id = b_unbox(mie_id, node, e_node); + struct mie_trait_definition *trait + = b_unbox(struct mie_trait_definition, id, tr_id); + + mie_trait_definition_print(trait); + node = b_btree_next(node); + } + + node = b_btree_first(&dialect->d_attributes.map_entries); + while (node) { + mie_id *id = b_unbox(mie_id, node, e_node); + struct mie_attribute_definition *attribute + = b_unbox(struct mie_attribute_definition, id, a_id); + + mie_attribute_definition_print(attribute); + node = b_btree_next(node); + } + + node = b_btree_first(&dialect->d_interfaces.map_entries); + while (node) { + mie_id *id = b_unbox(mie_id, node, e_node); + struct mie_interface_definition *interface = b_unbox( + struct mie_interface_definition, id, if_id); + + mie_interface_definition_print(interface); + node = b_btree_next(node); + } +} + +static void mie_ctx_print(const struct mie_ctx *ctx) +{ + printf("Dialects:\n"); + b_btree_node *node = b_btree_first(&ctx->ctx_dialects.map_entries); + while (node) { + mie_id *id = b_unbox(mie_id, node, e_node); + struct mie_dialect *dialect + = b_unbox(struct mie_dialect, id, d_id); + + mie_dialect_print(dialect); + node = b_btree_next(node); + } + + printf("\nPasses:\n"); + node = b_btree_first(&ctx->ctx_passes.map_entries); + while (node) { + mie_id *id = b_unbox(mie_id, node, e_node); + struct mie_pass_definition *pass + = b_unbox(struct mie_pass_definition, id, p_id); + + mie_pass_definition_print(pass); + node = b_btree_next(node); + } +} + +static int ctx_dump(const b_command *cmd, const b_arglist *args, const b_array *_) +{ + 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); + + mie_ctx_print(ctx); + + struct mie_type *i32 = mie_ctx_get_int_type(ctx, 32); + struct mie_type *str = mie_ctx_get_type(ctx, "builtin", "string"); + struct mie_type *index = mie_ctx_get_type(ctx, "builtin", "index"); + struct mie_attribute *i32_value = mie_ctx_get_int(ctx, 1024, 32); + struct mie_attribute *index_value = mie_ctx_get_index(ctx, 25000); + struct mie_attribute *str_value + = mie_ctx_get_string(ctx, "Hello, world!"); + + const struct mie_type *storage_type_parts[] = {i32, str, index}; + struct mie_type *storage_type = mie_ctx_get_storage_type( + ctx, storage_type_parts, + sizeof storage_type_parts / sizeof *storage_type_parts); + + const struct mie_type *func_in_parts[] = {i32, str}; + const struct mie_type *func_out_parts[] = {index}; + struct mie_type *func_type = mie_ctx_get_function_type( + ctx, func_in_parts, sizeof func_in_parts / sizeof *func_in_parts, + func_out_parts, sizeof func_out_parts / sizeof *func_out_parts); + + /* make sure storage/function type caching is working */ + assert(storage_type + == mie_ctx_get_storage_type( + ctx, storage_type_parts, + sizeof storage_type_parts / sizeof *storage_type_parts)); + assert(func_type + == mie_ctx_get_function_type( + ctx, func_in_parts, + sizeof func_in_parts / sizeof *func_in_parts, func_out_parts, + sizeof func_out_parts / sizeof *func_out_parts)); + + struct mie_printer printer; + mie_printer_init(&printer, ctx, b_stdout, MIE_PRINT_F_ABBREVIATED); + + char id_str[MIE_ID_STRING_MAX]; + mie_id_to_string(&i32->ty_id, id_str, sizeof id_str); + printf("i32 type: {%s} %s (instance of %s.%s)\n", id_str, i32->ty_name, + i32->ty_def->ty_parent->d_name, i32->ty_def->ty_name); + mie_id_to_string(&str->ty_id, id_str, sizeof id_str); + printf("str type: {%s} %s (instance of %s.%s)\n", id_str, str->ty_name, + str->ty_def->ty_parent->d_name, str->ty_def->ty_name); + mie_id_to_string(&index->ty_id, id_str, sizeof id_str); + printf("index type: {%s} %s (instance of %s.%s)\n", id_str, index->ty_name, + index->ty_def->ty_parent->d_name, index->ty_def->ty_name); + mie_id_to_string(&storage_type->ty_id, id_str, sizeof id_str); + printf("storage type: {%s} ", id_str); + mie_printer_print_type(&printer, storage_type); + printf("\n"); + + mie_id_to_string(&func_type->ty_id, id_str, sizeof id_str); + printf("function type: {%s} ", id_str); + mie_printer_print_type(&printer, func_type); + printf("\n"); + + printf("i32 value: "); + mie_printer_print_attribute(&printer, i32_value); + printf("\n"); + + printf("index value: "); + mie_printer_print_attribute(&printer, index_value); + printf("\n"); + + printf("str value: "); + mie_printer_print_attribute(&printer, str_value); + printf("\n"); + + return 0; +} + +B_COMMAND(CMD_INTERNAL_CTX_DUMP, CMD_INTERNAL) +{ + B_COMMAND_NAME("ctx-dump"); + B_COMMAND_DESC("mie_ctx dump"); + B_COMMAND_FUNCTION(ctx_dump); + + B_COMMAND_HELP_OPTION(); +} diff --git a/tool/cmd/internal/internal.c b/tool/cmd/internal/internal.c new file mode 100644 index 0000000..59757be --- /dev/null +++ b/tool/cmd/internal/internal.c @@ -0,0 +1,20 @@ +#include "../cmd.h" + +#include +#include + +static int internal(const b_command *cmd, const b_arglist *args, const b_array *_) +{ + + return 0; +} + +B_COMMAND(CMD_INTERNAL, CMD_ROOT) +{ + B_COMMAND_SHORT_NAME('X'); + B_COMMAND_DESC("internal frontend debugging tools."); + B_COMMAND_FUNCTION(internal); + B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT); + + B_COMMAND_HELP_OPTION(); +}