Files
TransPyC/wiki/13-bootstrapping.md
2026-07-18 19:25:40 +08:00

253 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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` 生成 IRTransPyC 无法调用 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 LOCPhase1/Phase2/DeclarationGenerator
4. **lib/StubGen 重写**~2K LOC
5. **Python 标准库缺口补齐**os/subprocess/re/pickle~5K LOC
**预计新增代码量**30-35K LOC TransPyC。与已完成的 includes/ast4,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 LOCAstTest 通过) |
| "4241 处动态反射致命" | 90% 是工程偷懒isinstance 节点分派/IR 类型分派),真实反射约 200-500 处 |
| "推荐路径 C不自举" | 推荐路径 A完全自举 |
| "预计自举后 60K-80K LOC" | 修正为 30-35K LOC基础组件已 5,700 LOC 完成) |