From bcf6508c4c5c2e1d5f8d8066494469e81d098435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=88=AA=E5=AE=87?= <3364451258@qq.com> Date: Sun, 7 Jun 2026 12:53:18 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20use=20=E8=AF=AD=E5=8F=A5=20=E2=80=94=20?= =?UTF-8?q?use=20module::item=20=E5=AF=BC=E5=85=A5=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E7=AC=A6=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复审查 #2: use 语句从 skippable TODO 实现为完整符号导入 use math_mod::add → 加载模块, 匹配 pub 函数/结构体/枚举, 零前缀导入 新增 37_use.l 集成测试 Co-Authored-By: Claude Opus 4.7 --- src/parser/parser.c | 45 ++++++++++++++++++++++++++++++++++++++---- test/programs/37_use.l | 6 ++++++ 2 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 test/programs/37_use.l diff --git a/src/parser/parser.c b/src/parser/parser.c index d13226f..2d330ab 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -534,10 +534,47 @@ AstNode* parse(Arena* a, const Token* tokens, size_t count, enums[enum_count++] = sub->as.program.enums[i]; } } else if (peek(&p)->kind == TOK_USE) { - /* TODO: use 语句待实现符号导入 */ ; - advance(&p); - while (peek(&p)->kind != TOK_SEMICOLON && peek(&p)->kind != TOK_EOF) advance(&p); - if (peek(&p)->kind == TOK_SEMICOLON) advance(&p); + advance(&p); // 跳过 use + const Token* mod_tok = expect(&p, TOK_IDENT, error, "use 后应为模块名"); + if (!mod_tok) return NULL; + if (!expect(&p, TOK_COLON_COLON, error, "缺少 '::'")) return NULL; + const Token* item_tok = expect(&p, TOK_IDENT, error, "use 后应为项目名"); + if (!item_tok) return NULL; + if (!expect(&p, TOK_SEMICOLON, error, "缺少 ';'")) return NULL; + const char* mod_name = arena_strdup_impl(p.arena, mod_tok->start, mod_tok->length); + const char* item_name = arena_strdup_impl(p.arena, item_tok->start, item_tok->length); + AstNode* sub = load_module(a, filename, mod_name, error); + if (!sub) return NULL; + // 在模块中搜索指定项目(函数/结构体/枚举) + bool found = false; + for (size_t i = 0; i < sub->as.program.fn_count; i++) { + AstNode* fn = sub->as.program.functions[i]; + if (fn->as.function.is_pub && strcmp(fn->as.function.name, item_name) == 0) { + if (fn_count >= 256) { error->message = "函数过多"; error->filename = p.filename; return NULL; } + functions[fn_count++] = fn; + found = true; break; + } + } + if (!found) { + for (size_t i = 0; i < sub->as.program.struct_count; i++) { + AstNode* sd = sub->as.program.structs[i]; + if (strcmp(sd->as.struct_decl.name, item_name) == 0) { + if (struct_count >= 64) break; + structs[struct_count++] = sd; + found = true; break; + } + } + } + if (!found) { + for (size_t i = 0; i < sub->as.program.enum_count; i++) { + AstNode* ed = sub->as.program.enums[i]; + if (strcmp(ed->as.enum_decl.name, item_name) == 0) { + if (enum_count >= 64) break; + enums[enum_count++] = ed; + found = true; break; + } + } + } } else if (peek(&p)->kind == TOK_FN) { if (fn_count >= 256) { error->message = "函数过多 (最多256)"; error->filename = p.filename; error->line = peek(&p)->line; error->col = peek(&p)->col; return NULL; } functions[fn_count++] = parse_function(&p, is_pub, error); diff --git a/test/programs/37_use.l b/test/programs/37_use.l new file mode 100644 index 0000000..85254be --- /dev/null +++ b/test/programs/37_use.l @@ -0,0 +1,6 @@ +use math_mod::add; + +fn main() -> i64 { + print_i64(add(3, 4)); + return 0; +}