From fc2d8f8db4345ec15cdacdd02b7dd6ceafbc6403 Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Thu, 8 Oct 2026 22:46:31 +0800 Subject: [PATCH] =?UTF-8?q?stage2=20=E4=BF=AE=E5=A4=8D=E8=AF=AD=E4=B9=89?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stage1/spl_sema.c | 52 ++++++++++++++++++++++++++++++++--------------- stage2/sema.spl | 50 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 74 insertions(+), 28 deletions(-) diff --git a/stage1/spl_sema.c b/stage1/spl_sema.c index b32ccda..30803cf 100644 --- a/stage1/spl_sema.c +++ b/stage1/spl_sema.c @@ -302,27 +302,23 @@ static spl_lang_type_id_t sema_build_aggregate(spl_sema_t *sema, spl_ast_node_t spl_lang_type_id_t saved_agg = sema->current_aggregate_lang; sema->current_aggregate_lang = agg_lang; + /* 聚合体自成命名空间:成员类型可引用同体声明的嵌套类型(裸名)。 */ + sema_push_scope(sema); spl_type_member_vec_t members; vec_init(members); spl_lang_method_vec_t methods; vec_init(methods); + /* 第一遍:登记嵌套类型/函数的 def,挂进 methods 与聚合作用域。成员类型可能引用它们, + 必须早于成员类型推断,否则限定名(经 methods)与裸名(经作用域)都解析不到。 */ for (usize i = 0; i < vec_size(te->type_aggregate.members); ++i) { spl_ast_node_ref_t mref = vec_at(te->type_aggregate.members, i); spl_ast_node_t *mn = spl_ast_node(sema->ast, mref); if (!mn) continue; - if (mn->kind == SPL_AST_MEMBER_DECL) { - spl_lang_type_id_t mtid = 0; - if (mn->member_decl.type_expr) - mtid = sema_infer(sema, mn->member_decl.type_expr); - spl_type_member_t m = {.name = mn->member_decl.name, - .type_id = spl_lang_type_get_ir_type(sema->type, mtid), - .ast_node_ref = mref}; - vec_push(members, m); - } else if (mn->kind == SPL_AST_FN_DECL) { + if (mn->kind == SPL_AST_FN_DECL) { spl_def_id_t fn_def = mn->resolved_def_id; if (!fn_def) { fn_def = spl_def_alloc(sema->type, SPL_DEF_FN, mn->fn_decl.name, mn->dbg, sema->ast, @@ -334,6 +330,9 @@ static spl_lang_type_id_t sema_build_aggregate(spl_sema_t *sema, spl_ast_node_t fn_d->owner_def = owner_def_id; spl_lang_method_t meth = {.name = mn->fn_decl.name, .def_id = fn_def}; vec_push(methods, meth); + spl_symbol_t fsym = {.name = mn->fn_decl.name, .kind = SPL_SYMBOL_KIND_FN}; + fsym.node = fn_def; + spl_scope_insert(sema->scope, sema->scope->current_scope, fsym); } else if (mn->kind == SPL_AST_TYPE_DECL) { spl_ast_node_t *tpat = spl_ast_node(sema->ast, mn->type_decl.pattern); if (!tpat || tpat->kind != SPL_AST_PATTERN_IDENT) @@ -352,9 +351,37 @@ static spl_lang_type_id_t sema_build_aggregate(spl_sema_t *sema, spl_ast_node_t } spl_lang_method_t meth = {.name = tname, .def_id = tdef}; vec_push(methods, meth); + spl_symbol_t tsym = {.name = tname, .kind = SPL_SYMBOL_KIND_TYPE}; + tsym.node = tdef; + spl_scope_insert(sema->scope, sema->scope->current_scope, tsym); } } + spl_lang_type_node_t *lslot = spl_lang_type_node(sema->type, agg_lang); + if (lslot) { + vec_free(lslot->methods); + lslot->methods = methods; + vec_init(methods); + } + + /* 第二遍:成员(字段/变体)类型推断;此时嵌套名字已可解析。 */ + for (usize i = 0; i < vec_size(te->type_aggregate.members); ++i) { + spl_ast_node_ref_t mref = vec_at(te->type_aggregate.members, i); + spl_ast_node_t *mn = spl_ast_node(sema->ast, mref); + if (!mn) + continue; + if (mn->kind == SPL_AST_MEMBER_DECL) { + spl_lang_type_id_t mtid = 0; + if (mn->member_decl.type_expr) + mtid = sema_infer(sema, mn->member_decl.type_expr); + spl_type_member_t m = {.name = mn->member_decl.name, + .type_id = spl_lang_type_get_ir_type(sema->type, mtid), + .ast_node_ref = mref}; + vec_push(members, m); + } + } + + sema_pop_scope(sema); sema->current_aggregate_lang = saved_agg; spl_type_node_t tn = {0}; @@ -366,13 +393,6 @@ static spl_lang_type_id_t sema_build_aggregate(spl_sema_t *sema, spl_ast_node_t vec_init(members); spl_lang_define_ir(sema->type, agg_ir, &tn); - spl_lang_type_node_t *lslot = spl_lang_type_node(sema->type, agg_lang); - if (lslot) { - vec_free(lslot->methods); - lslot->methods = methods; - vec_init(methods); - } - return agg_lang; } diff --git a/stage2/sema.spl b/stage2/sema.spl index cb1b052..fb5d7ae 100644 --- a/stage2/sema.spl +++ b/stage2/sema.spl @@ -367,6 +367,10 @@ fn build_aggregate(self: *Sema, te: *Node, owner_def_id: usize): usize { var saved = self.current_aggregate_lang; self.current_aggregate_lang = agg_lang; + // 聚合体自成命名空间:成员类型可引用同体声明的嵌套类型(裸名)。 + var saved_scope = self.scope.current_scope; + var agg_scope = Scope.alloc(&self.scope); + self.scope.current_scope = agg_scope; var members = Vec.blank(@sizeof(Member), @alignof(Member)); var methods = Vec.blank(@sizeof(LangMethod), @alignof(LangMethod)); @@ -376,19 +380,15 @@ fn build_aggregate(self: *Sema, te: *Node, owner_def_id: usize): usize { .TypeAggregate(&x) => { mlist = x.members; }, _ => {}, } + + // 第一遍:登记嵌套类型/函数的 def,挂进 methods 与聚合作用域。成员类型可能引用它们, + // 必须早于成员类型推断,否则限定名(经 methods)与裸名(经作用域)都解析不到。 var i: usize = 0; while i < mlist.len { var mref = list_at(mlist, i); var mn = node(self, mref); if mn != null { match mn.body { - .MemberDecl(md) => { - var mtid: usize = 0; - if md.type_expr != 0 { mtid = infer(self, md.type_expr); } - var mm = Member { .name = md.name, .type_id = ir_of(self, mtid), - .ast_node_ref = mref }; - Vec.push(&members, &mm as *u8); - }, .FnDecl(fd) => { var fn_def = mn.resolved_def_id; if fn_def == 0 { @@ -400,6 +400,8 @@ fn build_aggregate(self: *Sema, te: *Node, owner_def_id: usize): usize { if fn_d != null { fn_d.owner_def = owner_def_id; } var meth = LangMethod { .name = fd.name, .def_id = fn_def }; Vec.push(&methods, &meth as *u8); + Scope.insert(&self.scope, agg_scope, + Symbol { .name = fd.name, .kind = .Fn, .node = fn_def }); }, .TypeDecl(td) => { var tpat = node(self, td.pattern); @@ -416,6 +418,8 @@ fn build_aggregate(self: *Sema, te: *Node, owner_def_id: usize): usize { } var meth = LangMethod { .name = tname, .def_id = tdef }; Vec.push(&methods, &meth as *u8); + Scope.insert(&self.scope, agg_scope, + Symbol { .name = tname, .kind = .Type, .node = tdef }); } }, _ => {}, @@ -424,6 +428,33 @@ fn build_aggregate(self: *Sema, te: *Node, owner_def_id: usize): usize { i = i + 1; } + var lslot = LangType.lang_node(&self.types, agg_lang); + if lslot != null { + Vec.drop(&lslot.methods); + lslot.methods = methods; + } + + // 第二遍:成员(字段/变体)类型推断;此时嵌套名字已可解析。 + i = 0; + while i < mlist.len { + var mref = list_at(mlist, i); + var mn = node(self, mref); + if mn != null { + match mn.body { + .MemberDecl(md) => { + var mtid: usize = 0; + if md.type_expr != 0 { mtid = infer(self, md.type_expr); } + var mm = Member { .name = md.name, .type_id = ir_of(self, mtid), + .ast_node_ref = mref }; + Vec.push(&members, &mm as *u8); + }, + _ => {}, + } + } + i = i + 1; + } + + self.scope.current_scope = saved_scope; self.current_aggregate_lang = saved; // IR 节点 @@ -445,11 +476,6 @@ fn build_aggregate(self: *Sema, te: *Node, owner_def_id: usize): usize { } TypeTable.define(&self.types.ir, agg_ir, &tk); - var lslot = LangType.lang_node(&self.types, agg_lang); - if lslot != null { - Vec.drop(&lslot.methods); - lslot.methods = methods; - } ret agg_lang; }