stage1 解决@self无法在文件内直接使用的问题

This commit is contained in:
zzy committed 2026-09-17 16:30:38 +08:00
1 parent acfbbeee8b
commit 2594a81034
3 files changed
+84 -49

No files matched your search

+60 -33
View File
@@ -288,30 +288,53 @@ static const char *stage_dir_of(const char *stage) {
} }
typedef bool (*test_fn_t)(const char *fname, void *user_data); 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) { typedef struct {
const char *test_folder = "./tests/stage1/"; Nob_Files *files;
test_fn_t test_once;
if (!prepare_build()) { void *user_data;
return 1; } test_walk_ctx_t;
}
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;
}
}
static bool test_walk_entry(Nob_Walk_Entry entry) {
if (entry.type != NOB_FILE_REGULAR)
return true; return true;
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_walk_entry(Nob_Walk_Entry entry) { return nob_delete_file(entry.path); }
@@ -387,33 +410,37 @@ int main(int argc, char **argv) {
} }
if (strcmp(command_name, "test") == 0) { 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; test_fn_t tfn = test_once;
const char *mode_name = NULL; const char *mode_name = NULL;
if (argc > 0) { if (argc > 0) {
mode_name = nob_shift(argv, argc); if (is_dump_mode(argv[0])) {
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) {
tfn = test_once_with_dump; tfn = test_once_with_dump;
} else if (strcmp(mode_name, "run") == 0) { mode_name = nob_shift(argv, argc);
// HACK } else if (strcmp(argv[0], "run") == 0) {
nob_shift(argv, argc);
// HACK:只对 stage1 有意义,跑上次生成的 build/test.sir
Nob_Cmd cmd = {0}; Nob_Cmd cmd = {0};
nob_cmd_append(&cmd, BUILD_FOLDER "spl_cli", "-d"); nob_cmd_append(&cmd, BUILD_FOLDER "spl_cli", "-d");
nob_cmd_append(&cmd, BUILD_FOLDER "test.sir"); nob_cmd_append(&cmd, BUILD_FOLDER "test.sir");
return nob_cmd_run(&cmd) ? 0 : 1; return nob_cmd_run(&cmd) ? 0 : 1;
} else {
da_append(&files, mode_name);
} }
} }
// 3. 剩下的都当 pattern
Nob_Files files = {0};
while (argc > 0) { while (argc > 0) {
da_append(&files, nob_shift(argv, argc)); 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 (strcmp(command_name, "clean") == 0) {
if (nob_file_exists(BUILD_FOLDER)) { if (nob_file_exists(BUILD_FOLDER)) {
if (!delete_directory_recursively(BUILD_FOLDER)) if (!delete_directory_recursively(BUILD_FOLDER))
+3 -1
View File
@@ -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) { 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); spl_def_node_t *d = spl_def_node(type, id);
if (d) if (d) {
d->lang_id = lang_id; 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) { spl_lang_type_id_t spl_def_get_lang_id(spl_lang_type_t *type, spl_def_id_t def_id) {
+21 -15
View File
@@ -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_lang_type_id_t t = 0;
spl_ast_node_t *cm_after = spl_ast_node(mod_ast, cm_ref); spl_ast_node_t *cm_after = spl_ast_node(mod_ast, cm_ref);
if (cm_after->resolved_def_id) if (cm_after->resolved_def_id) {
t = sema_eval_decl(sema, 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->ast = saved_ast;
sema->scope->root_scope = saved_root; 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, 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) { spl_ast_node_ref_vec_t *args) {
const spl_intrin_info_t *info = spl_intrin_info(in); 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); spl_ast_node_t *mod = spl_ast_node(sema->ast, module_ref);
if (!mod || mod->kind != SPL_AST_CONTAINER_MEMBERS) if (!mod || mod->kind != SPL_AST_CONTAINER_MEMBERS)
return; 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_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) { 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) if (!root || root->kind != SPL_AST_ROOT)
return; return;
spl_sema_run_module(sema, root->root.members); 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) { void spl_sema_dump(spl_sema_t *sema) {