diff --git a/App/lib/core/Phase1.vp b/App/lib/core/Phase1.vp index 575f9a7..a4edde2 100644 --- a/App/lib/core/Phase1.vp +++ b/App/lib/core/Phase1.vp @@ -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):