feat: use 语句 — use module::item 导入模块符号
修复审查 #2: use 语句从 skippable TODO 实现为完整符号导入 use math_mod::add → 加载模块, 匹配 pub 函数/结构体/枚举, 零前缀导入 新增 37_use.l 集成测试 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+41
-4
@@ -534,10 +534,47 @@ AstNode* parse(Arena* a, const Token* tokens, size_t count,
|
|||||||
enums[enum_count++] = sub->as.program.enums[i];
|
enums[enum_count++] = sub->as.program.enums[i];
|
||||||
}
|
}
|
||||||
} else if (peek(&p)->kind == TOK_USE) {
|
} else if (peek(&p)->kind == TOK_USE) {
|
||||||
/* TODO: use 语句待实现符号导入 */ ;
|
advance(&p); // 跳过 use
|
||||||
advance(&p);
|
const Token* mod_tok = expect(&p, TOK_IDENT, error, "use 后应为模块名");
|
||||||
while (peek(&p)->kind != TOK_SEMICOLON && peek(&p)->kind != TOK_EOF) advance(&p);
|
if (!mod_tok) return NULL;
|
||||||
if (peek(&p)->kind == TOK_SEMICOLON) advance(&p);
|
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) {
|
} 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; }
|
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);
|
functions[fn_count++] = parse_function(&p, is_pub, error);
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
use math_mod::add;
|
||||||
|
|
||||||
|
fn main() -> i64 {
|
||||||
|
print_i64(add(3, 4));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user