# TransPyV [English](#english) | [中文](#中文) The **Viper language compiler, written in Viper itself**. TransPyV is the self-hosted (bootstrapped) successor of [TransPyC](https://git.gvsds.com/GVSDS/TransPyC). It compiles Viper sources to LLVM IR, then drives `llc` + `clang++` to produce a native Windows executable (`TransPyV.exe`). **用 Viper 语言编写的 Viper 编译器**。TransPyV 是 [TransPyC](https://git.gvsds.com/GVSDS/TransPyC) 的自举(self-hosted)后继版本。它把 Viper 源码编译为 LLVM IR,再调用 `llc` + `clang++` 产出 Windows 原生可执行文件(`TransPyV.exe`)。 --- ## 中文 ### 这是什么 `TransPyV` 是 Viper 项目**自举(bootstrapping)目标**:用 Viper 自身重写编译器。TransPyC 是第一代(用 CPython 写的),TransPyV 是第二代(用 Viper 写,编译后用 LLVM 工具链链接)。 虽然 TransPyV 当前只在 Windows 上能跑通(`App/main.py` 直接 import `w32.*`),但它的目标是**脱离 Python 运行时**:将来一旦 TransPyV 能完整编译自身并产出可执行文件,就完成了 Viper 编译器的完全自举。 ### 目录结构 ``` TransPyV/ ├── .gitignore ├── project.json # 顶层项目配置(输出 TransPyV.exe) ├── App/ # 编译器源码(Viper) │ ├── main.py # CLI 入口 │ └── lib/ │ ├── Projectrans/ │ │ ├── Config.py # project.vpj / project.json 加载 │ │ └── Utils.py │ └── core/ │ ├── BuildPipeline.py # .ll → .obj → .exe │ ├── IncludesScanner.py # includes 目录扫描 │ ├── Phase1.py # stub 分离(生成 .stub.ll + .text.ll) │ ├── Phase2.py # 多文件项目翻译 │ ├── StubMerger.py # stub 合并 │ ├── VLogger.py # 日志系统 │ └── Handles/ # AST 节点翻译(22 个) │ ├── HandlesBase.py │ ├── HandlesBody.py │ ├── HandlesMain.py │ ├── HandlesTranslator.py │ ├── HandlesVar.py / Assign / AnnAssign / AugAssign │ ├── HandlesIf / While / For │ ├── HandlesExpr / ExprCall / ExprOps │ ├── HandlesFunctions │ ├── HandlesClassDef / Struct │ ├── HandlesEnum │ ├── HandlesImports │ ├── HandlesReturn │ ├── HandlesType │ └── HandlesNonlocal └── Test/ # 编译器的自测用例 ├── project.vpj ├── App/ # 33 个测试 .py │ ├── simple_test.py │ ├── func_test.py / func_vtable_test.py │ ├── oop_test.py / vtable_test.py / virtual_dispatch_test.py │ ├── struct_test.py / class_test │ ├── closure_test.py / namespace_test.py │ ├── string_test.py / string_min_test.py │ ├── flow_test.py / for_test.py │ ├── llvmir_test.py │ └── ... (33 个) ├── NegativeTest/ # 错误用法负向测试 └── Sha1Test/ # SHA1 命名空间测试 ``` ### 前提条件 | 工具 | 说明 | |------|------| | `python` ≥ 3.10 | **仅当用 TransPyC 编译 TransPyV 时**需要 | | `llc` | LLVM 静态编译器 | | `clang++` | mingw-w64 工具链链接器 | | Windows 10/11 x64 | TransPyV 当前仅在 Windows 上工作(import w32.*) | | 至少 1GB 可用内存 | TransPyV 启动时 `stdlib.malloc(POOL_SIZE=1<<30)` | | [TransPyC](https://git.gvsds.com/GVSDS/TransPyC) | 用于把 TransPyV 自身编译为 `.exe` | 目录布局要求(编译 TransPyV 时): ``` D:\Users\TermiNexus\Desktop\TransPyC\ ├── TransPyC\ # 编译器仓库 └── TransPyV\ # 本仓库 ``` ### 快速开始 ```powershell # 1. 用 TransPyC 编译 TransPyV(自举的"第一阶段") cd D:\Users\TermiNexus\Desktop\TransPyC python Projectrans.py --project TransPyV\project.json --clean # 2. 产物在 TransPyV\output\TransPyV.exe .\TransPyV\output\TransPyV.exe --help ``` TransPyV CLI 参数(与 TransPyC `Projectrans.py` 一致): | 参数 | 含义 | |------|------| | `--project ` | `project.json` 路径(默认查找当前目录) | | `--src ` | 源文件目录(覆盖 `project.json`) | | `--temp ` | 声明接口临时目录(覆盖 `project.json`) | | `--output ` | 输出目录(覆盖 `project.json`) | | `--phase 1\|2\|all` | 阶段:1=生成声明,2=翻译+编译,all=全部 | | `--cc ` | LLVM 编译器命令(覆盖 `project.json`) | | `--clean` | 清理 `output/` 和 `temp/` | | `--run` | 编译成功后立即执行生成的可执行文件 | | `--rebuild-includes` | 删除 `includes.binary` 预编译缓存 | | `--clear-cache` | 清除 `.transpyc_cache` 全局缓存 | ### 架构 TransPyV 与 TransPyC 共享两阶段编译模型,但实现细节不同: ``` 源文件 (.py) │ ├─ 阶段一:AST 解析 → 翻译 → stub 分离 │ Phase1.py / Handles/* → .stub.ll + .text.ll │ ├─ 阶段二:stub 合并 → 完整 IR → 编译 │ StubMerger.BuildCombinedIR │ (本地 stub + 依赖 stubs + 本地 text) │ BuildPipeline.run_pipeline │ (.ll → llc → .obj → clang++ → .exe) │ └─ 输出可执行文件 ``` **核心模块分工:** | 模块 | 职责 | |------|------| | `App/main.py` | CLI 入口:参数解析、内存池初始化、Phase 调度 | | `lib/Projectrans/Config.py` | `project.json` / `project.vpj` 加载与路径解析 | | `lib/Projectrans/Utils.py` | SHA1 计算、目录清理、杂项工具 | | `lib/core/Phase1.py` | 阶段一入口:扫描 includes、生成 stub | | `lib/core/Phase2.py` | 阶段二入口:多文件项目翻译 | | `lib/core/IncludesScanner.py` | 扫描 `includes/` 目录、决定哪些文件需要重编译 | | `lib/core/StubMerger.py` | 把多个 `.stub.ll` 合并为完整 IR | | `lib/core/BuildPipeline.py` | `.ll` → `.obj` → `.exe`(llc + clang++) | | `lib/core/VLogger.py` | 日志系统(info/warn/error/banner/success) | | `lib/core/Handles/HandlesTranslator.py` | `Translator` 类:状态管理 + `translate()` 入口 | | `lib/core/Handles/HandlesBody.py` | AST Body 分派(按节点类型路由到具体 Handler) | | `lib/core/Handles/Handles*.py` (22 个) | 每种 AST 节点的 LLVM IR 生成 | ### 内存模型 TransPyV 用 `memhub.MemBuddy` 作为全局内存池: - **POOL_SIZE = 1 GiB**(`1073741824`) - 注释(`App/main.py` 第 33 行)说明:Phase1 翻译 87 个 includes + Phase2 翻译 30 个测试文件时,512 MiB 不足 - `_mbuddy` 通过 `sys._mbuddy = mb` 之类的全局指针传递(参见 `App/main.py` 第 61-75 行) ### 与 TransPyC 的关系 | 维度 | TransPyC | TransPyV | |------|----------|----------| | 实现语言 | CPython | Viper | | 自举状态 | ❌ 依赖 Python 运行时 | ✅ 目标完全自举 | | 入口 | `Projectrans.py` | `App/main.py` | | AST 解析 | `ast` 标准库 | `ast`(includes/ast 自研) | | 当前状态 | 主路径,跑通所有测试 | 自举重写中 | | 平台 | Windows / Linux | Windows(依赖 w32.*) | 当前 TransPyC 是"主路径"(所有 Test/ 在用),TransPyV 是"目标"——一旦 TransPyV 能编译自身产出可执行文件,Viper 就完成了完全自举。 ### 进一步阅读 - [TransPyC 编译器仓库](https://git.gvsds.com/GVSDS/TransPyC) - [Viper 语言概览](https://git.gvsds.com/GVSDS/TransPyC/blob/main/wiki/01-overview.md) - [Viper 自举路线图](https://git.gvsds.com/GVSDS/TransPyC/blob/main/wiki/13-bootstrapping.md) - [ViperOS 操作系统(用 Viper 写的 OS)](https://git.gvsds.com/GVSDS/ViperOS) --- ## English ### What is this `TransPyV` is the **Viper compiler, written in Viper itself** — the bootstrapping target. TransPyC is the first generation (implemented in CPython); TransPyV is the second generation (implemented in Viper, linked with the LLVM toolchain). While TransPyV currently only runs on Windows (its `App/main.py` directly imports `w32.*`), its goal is to **escape the Python runtime**: once TransPyV can compile itself end-to-end and produce a self-contained executable, Viper will be fully self-hosted. ### Directory layout ``` TransPyV/ ├── .gitignore ├── project.json # top-level project config (outputs TransPyV.exe) ├── App/ # compiler source (Viper) │ ├── main.py # CLI entry │ └── lib/ │ ├── Projectrans/ │ │ ├── Config.py # project.vpj / project.json loader │ │ └── Utils.py │ └── core/ │ ├── BuildPipeline.py # .ll -> .obj -> .exe │ ├── IncludesScanner.py # includes directory scanner │ ├── Phase1.py # stub split (generates .stub.ll + .text.ll) │ ├── Phase2.py # multi-file project translation │ ├── StubMerger.py # stub merger │ ├── VLogger.py # logging │ └── Handles/ # AST node translators (22 files) │ ├── HandlesBase.py │ ├── HandlesBody.py │ ├── HandlesMain.py │ ├── HandlesTranslator.py │ ├── HandlesVar.py / Assign / AnnAssign / AugAssign │ ├── HandlesIf / While / For │ ├── HandlesExpr / ExprCall / ExprOps │ ├── HandlesFunctions │ ├── HandlesClassDef / Struct │ ├── HandlesEnum │ ├── HandlesImports │ ├── HandlesReturn │ ├── HandlesType │ └── HandlesNonlocal └── Test/ # compiler self-test cases ├── project.vpj ├── App/ # 33 test .py │ ├── simple_test.py │ ├── func_test.py / func_vtable_test.py │ ├── oop_test.py / vtable_test.py / virtual_dispatch_test.py │ ├── struct_test.py │ ├── closure_test.py / namespace_test.py │ ├── string_test.py / string_min_test.py │ ├── flow_test.py / for_test.py │ ├── llvmir_test.py │ └── ... (33 in total) ├── NegativeTest/ # negative tests (error cases) └── Sha1Test/ # SHA1 namespace tests ``` ### Prerequisites | Tool | Notes | |------|-------| | `python` ≥ 3.10 | only needed when compiling TransPyV with TransPyC | | `llc` | LLVM static compiler | | `clang++` | mingw-w64 toolchain linker | | Windows 10/11 x64 | TransPyV currently Windows-only (imports `w32.*`) | | ≥ 1 GiB free RAM | TransPyV allocates `POOL_SIZE=1<<30` at startup | | [TransPyC](https://git.gvsds.com/GVSDS/TransPyC) | needed to compile TransPyV itself into an `.exe` | Required layout (to compile TransPyV): ``` D:\Users\TermiNexus\Desktop\TransPyC\ ├── TransPyC\ # compiler repo └── TransPyV\ # this repo ``` ### Quick start ```powershell # 1. Use TransPyC to compile TransPyV (the "first stage" of bootstrapping) cd D:\Users\TermiNexus\Desktop\TransPyC python Projectrans.py --project TransPyV\project.json --clean # 2. Output is at TransPyV\output\TransPyV.exe .\TransPyV\output\TransPyV.exe --help ``` TransPyV CLI flags (mirrors `Projectrans.py`): | Flag | Meaning | |------|---------| | `--project ` | `project.json` path (default: search current dir) | | `--src ` | source dir (overrides `project.json`) | | `--temp ` | declaration temp dir (overrides `project.json`) | | `--output ` | output dir (overrides `project.json`) | | `--phase 1\|2\|all` | phase: 1=decl only, 2=translate+compile, all=both | | `--cc ` | LLVM compiler command (overrides `project.json`) | | `--clean` | clean `output/` and `temp/` | | `--run` | execute the produced executable on success | | `--rebuild-includes` | delete `includes.binary` precompiled cache | | `--clear-cache` | clear `.transpyc_cache` global cache | ### Architecture TransPyV shares the two-phase model with TransPyC, with these differences: ``` Source files (.py) │ ├─ Phase 1: AST parse -> translate -> stub split │ Phase1.py / Handles/* -> .stub.ll + .text.ll │ ├─ Phase 2: stub merge -> full IR -> compile │ StubMerger.BuildCombinedIR │ (local stub + dep stubs + local text) │ BuildPipeline.run_pipeline │ (.ll -> llc -> .obj -> clang++ -> .exe) │ └─ Native executable ``` **Module responsibilities:** | Module | Responsibility | |--------|---------------| | `App/main.py` | CLI entry: arg parse, memory pool init, phase dispatch | | `lib/Projectrans/Config.py` | `project.json` / `project.vpj` loader + path resolution | | `lib/Projectrans/Utils.py` | SHA1, dir cleanup, misc utilities | | `lib/core/Phase1.py` | Phase 1 entry: scan includes, generate stubs | | `lib/core/Phase2.py` | Phase 2 entry: multi-file project translation | | `lib/core/IncludesScanner.py` | scan `includes/`, decide what to rebuild | | `lib/core/StubMerger.py` | merge multiple `.stub.ll` into a single IR | | `lib/core/BuildPipeline.py` | `.ll` -> `.obj` -> `.exe` (llc + clang++) | | `lib/core/VLogger.py` | logging (info/warn/error/banner/success) | | `lib/core/Handles/HandlesTranslator.py` | `Translator` class: state + `translate()` | | `lib/core/Handles/HandlesBody.py` | AST body dispatcher (route by node type) | | `lib/core/Handles/Handles*.py` (22) | one LLVM-IR generator per AST node type | ### Memory model TransPyV uses `memhub.MemBuddy` as a global arena: - **POOL_SIZE = 1 GiB** (`1073741824`) - The comment on `App/main.py` line 33 explains: Phase1 translates 87 includes files + Phase2 translates 30 test files, 512 MiB is not enough - `_mbuddy` is propagated via globals like `sys._mbuddy = mb` (see `App/main.py` lines 61–75) ### Relation to TransPyC | Dimension | TransPyC | TransPyV | |-----------|----------|----------| | Implementation | CPython | Viper | | Self-hosted? | No (Python runtime required) | Target: yes | | Entry | `Projectrans.py` | `App/main.py` | | AST parsing | standard `ast` | `ast` (self-implemented in `includes/ast`) | | Current status | Main path, all tests pass | Bootstrapping rewrite in progress | | Platform | Windows / Linux | Windows only (depends on `w32.*`) | Currently TransPyC is the main path (all `Test/` use it); TransPyV is the target. Once TransPyV can compile itself into an executable, Viper will be fully self-hosted. ### Further reading - [TransPyC compiler repo](https://git.gvsds.com/GVSDS/TransPyC) - [Viper language overview](https://git.gvsds.com/GVSDS/TransPyC/blob/main/wiki/01-overview.md) - [Viper bootstrapping roadmap](https://git.gvsds.com/GVSDS/TransPyC/blob/main/wiki/13-bootstrapping.md) - [ViperOS (an OS written in Viper)](https://git.gvsds.com/GVSDS/ViperOS)