From c9c9cdf544908c1e97adfb91e24ef327f68c452b Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 11 Jan 2026 14:51:37 +0000 Subject: [PATCH] tool: add temporary parsing and ctx tests to validate subcommand --- tool/cmd/validate.c | 393 ++++++++++++++++++++++++++++++++++++++++++-- tool/main.c | 2 + 2 files changed, 384 insertions(+), 11 deletions(-) diff --git a/tool/cmd/validate.c b/tool/cmd/validate.c index 2268dad..6e214ea 100644 --- a/tool/cmd/validate.c +++ b/tool/cmd/validate.c @@ -1,29 +1,400 @@ #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 enum { - OPT_TEMP, + ARG_FILEPATH, }; -int validate(const b_command* cmd, const b_arglist* args, const b_array* _) +static int trait_ref_print(const struct mie_trait *trait, void *arg) { - return 0; + fputc(' ', stdout); + mie_trait_print(trait, b_stdout); + + return 0; +} + +static void mie_op_arg_print(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->reg_flags; + arg_name = arg->arg_value->reg_name.n_str; + arg_type = arg->arg_value->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_type_print(arg_type, b_stdout); + b_printf(")%s[reset]", arg_name); +} + +static void mie_op_print(const struct mie_op *op) +{ + b_stringstream *tmp = b_stringstream_create(); + + 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:"); + for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_attrib); i++) { + printf(" (%s = ", op->op_attrib.items[i].attrib_name); + mie_value_print(op->op_attrib.items[i].attrib_value, b_stdout); + printf(")"); + } + printf("\n"); + + printf("REGIONS: %zu\n", MIE_VECTOR_COUNT(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]; + mie_op_arg_print(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]; + mie_op_arg_print(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_type_print(reg->reg_type, b_stdout); + 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_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); + } +} + +static void mie_ctx_print(const struct mie_ctx *ctx) +{ + 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); + } +} + +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_ctx_print(ctx); + + struct mie_type *i32 = mie_arith_int_get_type(ctx, 32); + struct mie_type *str = mie_ctx_get_type(ctx, "builtin", "string"); + struct mie_type *index = mie_ctx_get_type(ctx, "index", "index"); + struct mie_value *i32_value = mie_ctx_get_int(ctx, 1024, 32); + struct mie_value *index_value = mie_ctx_get_index(ctx, 25000); + struct mie_value *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)); + + 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_type_print(storage_type, b_stdout); + printf("\n"); + + mie_id_to_string(&func_type->ty_id, id_str, sizeof id_str); + printf("function type: {%s} ", id_str); + mie_type_print(func_type, b_stdout); + printf("\n"); + + printf("i32 value: "); + mie_value_print(i32_value, b_stdout); + printf("\n"); + + printf("index value: "); + mie_value_print(index_value, b_stdout); + printf("\n"); + + printf("str value: "); + mie_value_print(str_value, b_stdout); + printf("\n"); + + 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 op = {}; + + if (!mie_parser_parse_op(parse, names, &op)) { + printf("parse failed\n"); + return -1; + } + + if (!mie_ctx_resolve_op(ctx, &op)) { + printf("op resolve failed\n"); + return -1; + } + + mie_op_print(&op); + +#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_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(); } diff --git a/tool/main.c b/tool/main.c index f0bbbb7..a70a3fc 100644 --- a/tool/main.c +++ b/tool/main.c @@ -1,6 +1,8 @@ #include "cmd/cmd.h" #include +#include +#include int main(int argc, const char **argv) {