feat: trait 接口系统 — trait Show { fn method } + extend Trait Struct { }
This commit is contained in:
+24
-1
@@ -558,6 +558,26 @@ static void analyze_method_call(AstNode* node, Scope* scope, ErrorList* errors,
|
||||
snprintf(mangled, sizeof(mangled), "%s$%s", recv_struct,
|
||||
node->as.method_call.method_name);
|
||||
Symbol* sym = scope_lookup(scope, mangled);
|
||||
// trait 方法 fallback: 搜索所有作用域中以 $method_name 结尾的符号
|
||||
if (!sym || sym->kind != SYM_FUNCTION) {
|
||||
char suffix[256];
|
||||
snprintf(suffix, sizeof(suffix), "$%s", node->as.method_call.method_name);
|
||||
size_t suf_len = strlen(suffix);
|
||||
for (const Scope* sc = scope; sc; sc = sc->parent) {
|
||||
for (Symbol* s = sc->head; s; s = s->next) {
|
||||
if (s->kind == SYM_FUNCTION) {
|
||||
size_t name_len = strlen(s->name);
|
||||
if (name_len > suf_len && strcmp(s->name + name_len - suf_len, suffix) == 0) {
|
||||
sym = s;
|
||||
// 更新 method_name 为找到的完整函数名(codegen 需要)
|
||||
node->as.method_call.method_name = s->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sym) break;
|
||||
}
|
||||
}
|
||||
if (!sym || sym->kind != SYM_FUNCTION) {
|
||||
error_add(errors, "<sema>", node->loc.line, node->loc.col,
|
||||
"结构体 '%s' 没有方法 '%s'", recv_struct,
|
||||
@@ -657,6 +677,7 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
|
||||
size_t extra_fn = 0;
|
||||
for (size_t i = 0; i < node->as.program.impl_count; i++) {
|
||||
AstNode* impl = node->as.program.impls[i];
|
||||
if (impl->kind == AST_TRAIT_DECL) continue;
|
||||
extra_fn += impl->as.impl_block.method_count;
|
||||
}
|
||||
if (extra_fn > 0) {
|
||||
@@ -668,6 +689,7 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
|
||||
|
||||
for (size_t i = 0; i < node->as.program.impl_count; i++) {
|
||||
AstNode* impl = node->as.program.impls[i];
|
||||
if (impl->kind == AST_TRAIT_DECL) continue; // 跳过 trait 声明
|
||||
const char* st_name = impl->as.impl_block.struct_name;
|
||||
// 验证目标结构体存在
|
||||
Symbol* st_sym = scope_lookup_struct(scope, st_name);
|
||||
@@ -802,7 +824,8 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
|
||||
const char* saved_name = current_return_struct_name;
|
||||
current_return_type = node->as.function.return_type;
|
||||
current_return_struct_name = node->as.function.return_struct_type_name;
|
||||
analyze_node(node->as.function.body, fn_scope, errors, a);
|
||||
if (node->as.function.body)
|
||||
analyze_node(node->as.function.body, fn_scope, errors, a);
|
||||
current_return_type = saved;
|
||||
current_return_struct_name = saved_name;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user