fix(phase1): 拓扑排序补 import 依赖边,跨模块依赖模块先翻译

仅按类继承建边无法保证跨模块依赖顺序:lexer.vp from-import
tokens.vp 的 _op_head(全局变量 stub 未注入)、astaux 继承 base 的
AST(vtable TypeStr)、base.vp 用 list[...](泛型模板)都在无继承
关系的文件间发生。新增 import 依赖边(读 Phase 1a-pre 填充的
_includes_deps_*,含容器按需注入的 _list/_dict),被 import 的模块
先完整翻译,其 stub.ll/TypeStr/模板先就绪。
This commit is contained in:
TermiNexus committed 2026-08-13 04:36:09 +08:00
1 parent f09b6962f9
commit 0d6891f7bc
1 file changed
+59
+59
View File
@@ -508,6 +508,65 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
cnt_ptr[0] = cur_cnt + 1
break
# 2.5 补充 import 依赖边:被 import 的模块先完整翻译。
#
# 仅按类继承建边不够:跨模块全局变量 stub(lexer.vp from-import
# tokens.vp 的 _op_head)、跨模块 vtable TypeStr(astaux 继承 base 的
# AST)、泛型模板(base.vp 用 list[...])都要求依赖模块先翻译,而它们
# 之间可能无类继承关系。deps(_includes_deps_*)由 Phase 1a-pre 填充
# (含容器按需注入的 _list/_dict)。
store_sz_imp: int = StubMerger.GetSha1StoreCount()
for fi_imp in range(file_count):
fsha1_imp: str = file_sha1s_buf + fi_imp * SHA1_LEN
deps_imp: str = StubMerger.LookupIncludesDeps(fsha1_imp)
if deps_imp is None:
continue
dl_imp: t.CSizeT = string.strlen(deps_imp)
dpos_imp: t.CSizeT = 0
while dpos_imp < dl_imp:
dstart_imp: t.CSizeT = dpos_imp
while dpos_imp < dl_imp and deps_imp[dpos_imp] != ' ':
dpos_imp += 1
dlen_imp: t.CSizeT = dpos_imp - dstart_imp
if dpos_imp < dl_imp:
dpos_imp += 1
if dlen_imp == 0:
continue
dname_imp: bytes = stdlib.malloc(dlen_imp + 1)
if dname_imp is None:
continue
string.strncpy(dname_imp, deps_imp + dstart_imp, dlen_imp)
dname_imp[dlen_imp] = '\0'
dsha1_imp: str = StubMerger._FindSha1ByModName(
StubMerger.GetSha1StoreArrPtr(), StubMerger.GetSha1StoreModArrPtr(),
store_sz_imp, dname_imp)
stdlib.free(dname_imp)
if dsha1_imp is None:
continue
# 找依赖文件在列表中的索引(跳过自身)
for fj_imp in range(file_count):
if string.strcmp(file_sha1s_buf + fj_imp * SHA1_LEN, dsha1_imp) != 0:
continue
if fj_imp == fi_imp:
break
# 去重 + 加边:fi_imp 依赖 fj_imp(InDegree[fi_imp]++)
cnt_addr_imp: t.CUInt64T = t.CUInt64T(file_dep_counts) + fi_imp * 4
cnt_ptr_imp: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(cnt_addr_imp, t.CPtr))
if cnt_ptr_imp is None:
break
cur_cnt_imp: int = cnt_ptr_imp[0]
already_imp: int = 0
for di_imp in range(cur_cnt_imp):
dep_slot_imp: str = file_deps_buf + fi_imp * MAX_DEP_EDGES * SHA1_LEN + di_imp * SHA1_LEN
if string.strcmp(dep_slot_imp, dsha1_imp) == 0:
already_imp = 1
break
if already_imp == 0 and cur_cnt_imp < MAX_DEP_EDGES:
dep_dst_imp: str = file_deps_buf + fi_imp * MAX_DEP_EDGES * SHA1_LEN + cur_cnt_imp * SHA1_LEN
string.strcpy(dep_dst_imp, dsha1_imp)
cnt_ptr_imp[0] = cur_cnt_imp + 1
break
# 3. Kahn 算法:InDegree = DepCount(依赖多少个父文件)
# 依赖为 0 的先处理,处理后减少依赖它的文件入度
for fi in range(file_count):