# TransPyC 自举可行性分析 > **状态**:进行中 > **创建时间**:2026-06-26 > **最后更新**:2026-06-30 > **结论**:完全自举可行,核心障碍已被攻克,剩余工作明确 --- ## 1. 背景 自举(bootstrapping)指用 TransPyC 语言重写 TransPyC 编译器自身,然后用现有编译器编译,得到新的原生编译器。本文档分析自举的可行性、进展与剩余工作。 **当前目标**:完全自举。TransPyC 的定位是独立的系统级语言,不是"Python → 原生 的工具"。自举是语言成熟度的证明,也是脱离 Python 运行时性能限制的必经之路。 --- ## 2. LOC 统计 ### 2.1 编译器主体(lib 目录) | 子目录 | 文件数 | LOC | 说明 | |--------|--------|-----|------| | `lib/core` | 64 | 28,610 | 编译器核心 | | ├─ `core/Handles` | 30 | 18,885 | AST 节点处理器(最大模块) | | ├─ `core/LLVMCG` | 8 | 2,782 | LLVM 代码生成 | | └─ `core/Translator` | 6 | 1,751 | 翻译器框架 | | `lib/Projectrans` | 6 | 4,371 | 项目级翻译(Phase1/Phase2) | | `lib/StubGen` | 4 | 1,187 | Stub 生成器 | | `lib/Shell` | 4 | 630 | CLI 入口 | | `lib/includes` | 2 | 1,609 | t.py(968) + c.py(641) 类型定义 | | `lib/utils` | 1 | 40 | 辅助 | | `lib/constants` | 1 | 36 | 配置 | | **lib 总计** | **80** | **36,483** | | ### 2.2 Top 15 文件 | 文件 | LOC | |------|-----| | `lib/core/Handles/HandlesExprCall.py` | 3,153 | | `lib/Projectrans/Phase2Translator.py` | 2,693 | | `lib/core/Handles/HandlesImports.py` | 1,994 | | `lib/core/Handles/HandlesFunctions.py` | 1,612 | | `lib/core/Handles/HandlesAssign.py` | 1,544 | | `lib/core/Handles/HandlesExprAttr.py` | 1,168 | | `lib/core/Handles/HandlesClassDef.py` | 1,039 | | `lib/core/Handles/HandlesFor.py` | 997 | | `lib/core/Handles/HandlesTypeMerge.py` | 991 | | `lib/includes/t.py` | 968 | | `lib/StubGen/Converter.py` | 893 | | `lib/core/Handles/HandlesExprBuiltin.py` | 868 | | `lib/Projectrans/DeclarationGenerator.py` | 845 | | `lib/core/Handles/HandlesBase.py` | 756 | | `lib/core/stub_generator.py` | 699 | ### 2.3 运行时库(includes 目录) | 模块 | LOC | 说明 | |------|-----|------| | `includes/numpy/__init__.py` | 1,016 | ndarray n 维数组 | | `includes/zlib/` | ~1,900 | 完整 deflate/inflate/huffman/checksum | | `includes/ast/` | 4,176 | **自研 Python 解析器(自举组件)** | | `includes/llvmlite/` | ~1,500 | **自研 LLVM IR 生成库(自举组件)** | | `includes/linkedlist.py` | ~400 | 泛型链表(@t.NoVTable + PEP 695) | | `includes/vipermath.py` | 450 | 数学库 | | ...(30+ 文件) | ... | mpool/mbuddy/string/stdio/json/w32 等 | | **includes 总计** | **~12,000** | | ### 2.4 全项目总计 ``` 全项目 .py 总计:~48,000 LOC ``` **自举相关核心数字:** - 编译器主体(lib 不含 t.py/c.py):~34,874 LOC - 自举基础组件(includes/ast + includes/llvmlite):~5,700 LOC ✅ 已完成 - 运行时库(includes 其余):~9,500 LOC --- ## 3. 自举进展(已完成的核心组件) ### 3.1 ✅ includes/ast —— Python 解析器自举 **状态**:完成,AstTest 通过(解析 CPython 几乎全部语法) | 文件 | LOC | 功能 | |------|-----|------| | `__tokens.py` | ~600 | TokenType/Keyword/TokOp 枚举 + 查找表 | | `__nodes.py` | ~1,400 | AST 胖节点 + ASTVType/ASTCtx/OpKind CEnum | | `__lexer.py` | ~800 | 词法分析器 | | `__parser.py` | 4,176(含表格) | 递归下降语法分析器 | **覆盖语法**:装饰器、async/await、match(含复杂模式 `[x,*rest]`/`{'type':t,**rest}`/`Point(x,y)`/`0|1|2`)、try/except/finally/raise from、with、lambda、列表/集合/字典/生成器推导式、f-string(含 `!r`/`!s` 转换和 `:>{width}` 格式说明)、链式比较、walrus、yield from、global/nonlocal、切片、嵌套三元。 **设计要点**: - 胖节点设计(所有节点共用一个 `AST` struct,用 `vtype` 区分)—— 避免 REnum 在 70+ 变体下的内存膨胀 - 从 `mpool.MPool` 分配,零 Python 运行时依赖 - API 与 Python `ast` 模块对齐:`parse(src, pool) -> AST` ### 3.2 ✅ includes/llvmlite —— LLVM IR 生成库自举 **状态**:完成,LLvmLiteTest 18/18 通过,TransPyV 自举实验跑通 | 文件 | 功能 | |------|------| | `__types.py` | `LLVMType` REnum + 类型构造/打印 | | `__values.py` | Value/Constant/SSA 值表示 | | `__function.py` | Function + BasicBlock + 参数管理 | | `__module.py` | Module 容器 + 目标三元组 + 输出 .ll | | `__builder.py` | IRBuilder(指令发射 + SSA 命名) | **设计要点**: - `LLVMType` 用 `t.REnum`(tagged union)—— 少变体、无通用字段、match 分派的理想场景 - 指令 opcode 用 `t.CEnum`(IROp)—— 类型安全且零开销 - IR 文本生成用 `viperlib.snprintf` 格式化,避免手写逐字符拼接 - 对象分配用普通类 + `mpool`,不持有全局 `mbuddy` **验证**:[TransPyV/App/main.py](../TransPyV/App/main.py) 10 个测试覆盖类型打印、值打印、build_add、if-else、模块打印、lli 实际执行。TransPyV 程序运行时自己生成合法 IR,被 `lli` 成功执行。 ### 3.3 ✅ 基础设施库 以下 includes/ 库为自举后的编译器提供数据结构和系统调用基础: | 库 | 自举中的作用 | |----|-------------| | `linkedlist.py` | AST 节点树、符号表链、IR 指令链的容器(`@t.NoVTable` + PEP 695 递归泛型继承) | | `mpool.py` / `mbuddy.py` | 编译器内存管理(替代 Python GC) | | `string.py` / `viperlib.py` | 字符串处理 + snprintf(替代 Python 字符串方法) | | `w32/` | FFI 声明,自举后编译器调用 llc/clang/linker 的基础 | | `json/` | 符号表序列化(替代 pickle) | --- ## 4. 障碍分析(修正版) 原版本文档列出的"三大致命依赖"已被逐一攻克或降级: ### 4.1 ~~llvmlite 依赖(原:致命)~~ → ✅ 已解决 **原问题**:编译器通过 `llvmlite.ir` 生成 IR,TransPyC 无法调用 Python 库。 **解决**:`includes/llvmlite/` 用 TransPyC 自身实现了 LLVM IR 文本生成库,API 与 Python `llvmlite.ir` 对齐。采用"字符串拼 IR"路径(路径 A),不绑定 LLVM C API。18/18 测试通过,TransPyV 自举实验验证可生成可执行 IR。 ### 4.2 ~~ast 模块依赖(原:致命)~~ → ✅ 已解决 **原问题**:编译器用 Python `ast` 模块解析源码,自举需自己写 Python 解析器(预计 5,000-10,000 LOC)。 **解决**:`includes/ast/` 4,176 LOC 实现完整 Python 解析器,AstTest 解析 CPython 凥乎全部语法通过。预言已兑现,且实际规模(4,176 LOC)低于预估下限(5,000 LOC)。 ### 4.3 ~~动态反射 4241 处(原:致命)~~ → ⚠️ 降级为可控 **原问题**:`getattr`/`setattr`/`hasattr`/`isinstance`/`issubclass` 共 4,241 处,静态语言无法直接表达。 **修正分析**:4241 这个数字按 Python 语法 grep 统计,未区分"语义上需要反射"和"用反射偷懒"。实际分类: | 用法 | 数量估计 | 是否真反射 | TransPyC 解法 | |------|----------|-----------|--------------| | `isinstance(node, ast.Xxx)` AST 节点分派 | ~2000 | ❌ 否 | 胖节点 `node.vtype == ASTVType.Xxx` 整数比较 | | `isinstance(x, ir.IntType)` IR 类型分派 | ~500 | ❌ 否 | REnum `match x: case LLVMType.Int:` tag 比较 | | `getattr(t, name, None)` 字符串→类型查表 | ~35 | ❌ 否 | 注册表 `t_type_registry: dict[str, t.CInt]` | | `CTypeInfo.__getattr__` 门面路由 | ~100 | ✅ 是 | 重构为 REnum + match 显式分派 | | `copy.deepcopy` / `pickle` | ~10 | ✅ 是 | 已解决(`__getstate__/__setstate__`) | | `hasattr` 防御性检查 | ~1500 | ⚠️ 多数可消除 | 显式字段声明 + None 检查 | **真实反射障碍约 200-500 处**,集中体现在 `CTypeInfo` 门面模式(FIELD_ROUTES 动态路由到 `_ts`/`_sm`)。重构方案:用 REnum + match 替换 `__getattr__` 路由,已在 `includes/llvmlite/__types.py` 验证此范式可行。 ### 4.4 Python 标准库依赖(原:严重)→ ⚠️ 部分已解决 | Python 库 | 用途 | TransPyC 现状 | |-----------|------|--------------| | `ast` | 源码解析 | ✅ `includes/ast/` | | `llvmlite.ir` | LLVM IR 生成 | ✅ `includes/llvmlite/` | | `json` | 序列化 | ✅ `includes/json/` | | `os`/`sys` | 文件/路径 | ⚠️ `includes/os/` + `w32/`(Windows) | | `subprocess` | 调用 llc/clang | ❌ 待实现(w32 CreateProcess 可基础) | | `pickle` | 符号表序列化 | ❌ 待实现(json 替代) | | `concurrent.futures` | 并行编译 | ❌ 待实现(w32 线程可基础) | | `re` | 正则表达式 | ❌ 待实现 | | `traceback` | 异常栈 | ❌ 待实现 | --- ## 5. 自举路径 ### 5.1 路径 A:完全自举(当前目标,可行) **已完成**: 1. ✅ `includes/ast/` Python 解析器(4,176 LOC) 2. ✅ `includes/llvmlite/` LLVM IR 生成库(~1,500 LOC) 3. ✅ 基础设施库(linkedlist/mpool/mbuddy/string/json/w32) **剩余工作**: 1. **CTypeInfo 门面重构**(~200-500 处真反射 → REnum + match) 2. **lib/core 重写**(~20K LOC TransPyC,含 Handles/LLVMCG/Translator) 3. **lib/Projectrans 重写**(~5K LOC,Phase1/Phase2/DeclarationGenerator) 4. **lib/StubGen 重写**(~2K LOC) 5. **Python 标准库缺口补齐**(os/subprocess/re/pickle,~5K LOC) **预计新增代码量**:30-35K LOC TransPyC。与已完成的 includes/ast(4,176 LOC)+ includes/llvmlite(~1,500 LOC)+ 其他基础库为同一量级——已经证明过两次能做这件事。 ### 5.2 关键技术验证点(已完成) 以下能力已在 includes/ 库中验证,证明 TransPyC 能承载编译器复杂度: - **复杂泛型容器**:`linkedlist.py` 的递归泛型继承 `class GNode(GSListNode[GNode])`(C/C++/Rust 均无法如此简洁表达) - **复杂算法**:`zlib/` 的完整 deflate/inflate/huffman(~1,900 LOC 生产级压缩) - **n 维数组**:`numpy/__init__.py` 的 ndarray + 运算符重载 + `__new__` 堆分配 - **平台 FFI**:`w32/` 的 Win32 API 绑定(file/memory/process/sync/console) - **LLVM IR 生成**:`llvmlite/` 的 REnum 类型系统 + IRBuilder + ModulePrint --- ## 6. 自举的意义 1. **性能**:当前 Python 编译器翻译 6 个文件 0.6s,全量编译 36K LOC 编译器自身时 Python 解释器开销显著。自举后编译器是原生码,编译速度数量级提升。 2. **部署**:当前分发需 Python 运行时 + llvmlite + ast 依赖。自举后只需一个可执行文件 + llc/clang——系统级语言编译器该有的形态。 3. **语言成熟度证明**:能写自己的编译器是系统级语言的"成人礼"。C、C++、Rust、Go、Zig 全都走过这条路。 4. **dogfooding 闭环**:自举后每次改编译器都用编译器自己编译自己,持续暴露 bug 和性能瓶颈,形成正反馈。`includes/ast` 和 `includes/llvmlite` 的开发过程已经产出了大量深层 bug 修复(REnum 变体名冲突、跨模块继承字段展平、NoVTable OOP 方法继承等)。 --- ## 7. 结论 | 维度 | 评估 | |------|------| | 理论可行性 | ✅ 可行(图灵完备) | | 实践可行性 | ✅ 完全自举可行(核心障碍已攻克) | | 当前进展 | ⚠️ 前端(ast)+ 后端(llvmlite)+ 基础库已就位,剩中间层(lib/core)重构 | | 剩余工作量 | ~30-35K LOC TransPyC 重写 + CTypeInfo 门面重构 | | 推荐策略 | 路径 A:完全自举,按 lib/core → lib/Projectrans → lib/StubGen 顺序推进 | **核心判断**:原版本文档的"三大致命依赖"结论已全部失效——llvmlite 和 ast 已被 includes/ 下的自研库替代,4241 处反射中 90% 是工程偷懒而非语义需要。完全自举从"几乎不可能"变为"明确可行",剩余工作是体量问题而非技术障碍。 --- ## 8. 附录:原版本文档的修正说明 本文档(2026-06-30 版)修正了 2026-06-26 原版的以下错误判断: | 原版断言 | 修正 | |---------|------| | "完全自举几乎不可能" | 完全自举可行,核心障碍已攻克 | | "llvmlite 依赖致命" | 已被 `includes/llvmlite/` 解决(18/18 测试) | | "ast 模块依赖致命" | 已被 `includes/ast/` 解决(4,176 LOC,AstTest 通过) | | "4241 处动态反射致命" | 90% 是工程偷懒(isinstance 节点分派/IR 类型分派),真实反射约 200-500 处 | | "推荐路径 C:不自举" | 推荐路径 A:完全自举 | | "预计自举后 60K-80K LOC" | 修正为 30-35K LOC(基础组件已 5,700 LOC 完成) |