Files
ViperOS/vpsdk/wiki/13-bootstrapping.md
2026-07-19 12:38:20 +08:00

12 KiB
Raw Permalink Blame History

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 structvtype 区分)—— 避免 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 命名)

设计要点

  • LLVMTypet.REnumtagged union—— 少变体、无通用字段、match 分派的理想场景
  • 指令 opcode 用 t.CEnumIROp—— 类型安全且零开销
  • IR 文本生成用 viperlib.snprintf 格式化,避免手写逐字符拼接
  • 对象分配用普通类 + mpool,不持有全局 mbuddy

验证TransPyV/App/main.py 10 个测试覆盖类型打印、值打印、build_add、if-else、模块打印、lli 实际执行。TransPyV 程序运行时自己生成合法 IRlli 成功执行。

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__ 堆分配
  • 平台 FFIw32/ 的 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/astincludes/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 完成)