From 2594a81034b544b5eef551ae952d2aa948ac25db Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Thu, 17 Sep 2026 16:30:38 +0800 Subject: [PATCH] =?UTF-8?q?stage1=20=E8=A7=A3=E5=86=B3@self=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E5=9C=A8=E6=96=87=E4=BB=B6=E5=86=85=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nob.c | 87 +++++++++++++++++++++++++++--------------- stage1/spl_lang_type.c | 4 +- stage1/spl_sema.c | 36 +++++++++-------- 3 files changed, 81 insertions(+), 46 deletions(-) diff --git a/nob.c b/nob.c index 9b8ddb2..0ee9404 100644 --- a/nob.c +++ b/nob.c @@ -288,32 +288,55 @@ static const char *stage_dir_of(const char *stage) { } typedef bool (*test_fn_t)(const char *fname, void *user_data); -static bool run_test(Nob_Files *files, test_fn_t test_once, void *user_data) { - const char *test_folder = "./tests/stage1/"; +typedef struct { + Nob_Files *files; + test_fn_t test_once; + void *user_data; +} test_walk_ctx_t; - if (!prepare_build()) { - return 1; - } +static bool test_walk_entry(Nob_Walk_Entry entry) { + if (entry.type != NOB_FILE_REGULAR) + return true; - Nob_File_Paths paths = {0}; - nob_read_entire_dir(test_folder, &paths); - for (int i = 0; i < files->count; i += 1) { - for (int j = 0; j < paths.count; j += 1) { - String_View sv = sv_from_cstr(paths.items[j]); - // printf("--- test " SV_Fmt " ---\n", SV_Arg(sv)); - if (!strstr(paths.items[j], files->items[i])) { - continue; - } - const char *tname = nob_temp_sprintf("%s%s", test_folder, paths.items[j]); - printf("--- test %s ---\n", tname); - if (test_once(tname, user_data) == false) - return false; - } + const char *dot = strrchr(entry.path, '.'); + if (!dot || strcmp(dot, ".spl") != 0) + return true; + + test_walk_ctx_t *ctx = (test_walk_ctx_t *)entry.data; + bool run_all = (ctx->files->count == 0); + bool matched = run_all; + for (int i = 0; !matched && i < ctx->files->count; i += 1) { + if (strstr(entry.path, ctx->files->items[i])) + matched = true; } + if (!matched) + return true; + printf("--- test %s ---\n", entry.path); + if (ctx->test_once(entry.path, ctx->user_data) == false) + return false; return true; } +static bool run_test(const char *stage, Nob_Files *files, test_fn_t test_once, void *user_data) { + const char *test_folder = stage_dir_of(stage); + + if (!prepare_build()) + return false; + + if (!nob_file_exists(test_folder)) { + nob_log(NOB_INFO, "%s does not exist, skip", test_folder); + return true; + } + + test_walk_ctx_t ctx = { + .files = files, + .test_once = test_once, + .user_data = user_data, + }; + return nob_walk_dir(test_folder, test_walk_entry, .data = &ctx); +} + static bool delete_walk_entry(Nob_Walk_Entry entry) { return nob_delete_file(entry.path); } static bool delete_directory_recursively(const char *dir_path) { @@ -387,33 +410,37 @@ int main(int argc, char **argv) { } if (strcmp(command_name, "test") == 0) { - Nob_Files files = {0}; + // 1. stage(可选,默认 stage1) + const char *stage = "stage1"; + if (argc > 0 && is_stage_name(argv[0])) { + stage = nob_shift(argv, argc); + } + + // 2. mode(可选) test_fn_t tfn = test_once; const char *mode_name = NULL; if (argc > 0) { - mode_name = nob_shift(argv, argc); - if (strcmp(mode_name, "lex") == 0 || strcmp(mode_name, "ast") == 0 || - strcmp(mode_name, "sema") == 0 || strcmp(mode_name, "ir") == 0 || - strcmp(mode_name, "vm") == 0) { + if (is_dump_mode(argv[0])) { tfn = test_once_with_dump; - } else if (strcmp(mode_name, "run") == 0) { - // HACK + mode_name = nob_shift(argv, argc); + } else if (strcmp(argv[0], "run") == 0) { + nob_shift(argv, argc); + // HACK:只对 stage1 有意义,跑上次生成的 build/test.sir Nob_Cmd cmd = {0}; nob_cmd_append(&cmd, BUILD_FOLDER "spl_cli", "-d"); nob_cmd_append(&cmd, BUILD_FOLDER "test.sir"); return nob_cmd_run(&cmd) ? 0 : 1; - } else { - da_append(&files, mode_name); } } + // 3. 剩下的都当 pattern + Nob_Files files = {0}; while (argc > 0) { da_append(&files, nob_shift(argv, argc)); } - return run_test(&files, tfn, (void *)mode_name) ? 0 : 1; + return run_test(stage, &files, tfn, (void *)mode_name) ? 0 : 1; } - if (strcmp(command_name, "clean") == 0) { if (nob_file_exists(BUILD_FOLDER)) { if (!delete_directory_recursively(BUILD_FOLDER)) diff --git a/stage1/spl_lang_type.c b/stage1/spl_lang_type.c index b0ad50e..39c8e17 100644 --- a/stage1/spl_lang_type.c +++ b/stage1/spl_lang_type.c @@ -633,8 +633,10 @@ spl_def_id_t spl_def_alloc(spl_lang_type_t *type, spl_def_node_kind_t kind, cons void spl_def_resolve(spl_lang_type_t *type, spl_def_id_t id, spl_lang_type_id_t lang_id) { spl_def_node_t *d = spl_def_node(type, id); - if (d) + if (d) { d->lang_id = lang_id; + d->state = SPL_DECL_RESOLVED; + } } spl_lang_type_id_t spl_def_get_lang_id(spl_lang_type_t *type, spl_def_id_t def_id) { diff --git a/stage1/spl_sema.c b/stage1/spl_sema.c index 16bd725..c67bc2b 100644 --- a/stage1/spl_sema.c +++ b/stage1/spl_sema.c @@ -518,8 +518,11 @@ static spl_lang_type_id_t sema_import(spl_sema_t *sema, spl_ast_node_t *n, spl_lang_type_id_t t = 0; spl_ast_node_t *cm_after = spl_ast_node(mod_ast, cm_ref); - if (cm_after->resolved_def_id) - t = sema_eval_decl(sema, cm_after->resolved_def_id); + if (cm_after->resolved_def_id) { + spl_def_node_t *d = spl_def_node(sema->type, cm_after->resolved_def_id); + if (d) + t = d->lang_id; + } sema->ast = saved_ast; sema->scope->root_scope = saved_root; @@ -766,12 +769,6 @@ static void sema_collect_signatures(spl_sema_t *sema) { } } -static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) { - sema_collect_names(sema, ref); - sema_collect_types(sema, ref); - sema_collect_signatures(sema); -} - static spl_lang_type_id_t sema_intrin_call(spl_sema_t *sema, spl_ast_node_t *n, spl_intrin_t in, spl_ast_node_ref_vec_t *args) { const spl_intrin_info_t *info = spl_intrin_info(in); @@ -2609,10 +2606,23 @@ void spl_sema_run_module(spl_sema_t *sema, spl_ast_node_ref_t module_ref) { spl_ast_node_t *mod = spl_ast_node(sema->ast, module_ref); if (!mod || mod->kind != SPL_AST_CONTAINER_MEMBERS) return; - spl_scope_id_t saved = sema->scope->current_scope; - sema_collect(sema, module_ref); + + spl_scope_id_t saved_scope = sema->scope->current_scope; + spl_lang_type_id_t saved_agg = sema->current_aggregate_lang; + + sema_collect_names(sema, module_ref); + + spl_lang_type_id_t container_lang = 0; + if (mod->resolved_def_id) + container_lang = sema_eval_decl(sema, mod->resolved_def_id); + sema->current_aggregate_lang = container_lang; + + sema_collect_types(sema, module_ref); + sema_collect_signatures(sema); sema_infer(sema, module_ref); - sema->scope->current_scope = saved; + + sema->current_aggregate_lang = saved_agg; + sema->scope->current_scope = saved_scope; } void spl_sema_run(spl_sema_t *sema) { @@ -2622,10 +2632,6 @@ void spl_sema_run(spl_sema_t *sema) { if (!root || root->kind != SPL_AST_ROOT) return; spl_sema_run_module(sema, root->root.members); - - spl_ast_node_t *cm = spl_ast_node(sema->ast, root->root.members); - if (cm && cm->resolved_def_id) - sema_eval_decl(sema, cm->resolved_def_id); } void spl_sema_dump(spl_sema_t *sema) {