253 lines
12 KiB
Markdown
253 lines
12 KiB
Markdown
# 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 完成) |
|