15 KiB
17 - 旗舰项目
前面 16 章讲的是 Viper 这门语言本身。本章介绍用 Viper 写出来的几个真实、完整的工程——它们既是语言能力的实证,也是编译器最重要的回归对象。
| 项目 | 位置 | 定位 |
|---|---|---|
| ViperC | ../ViperC | Viper 语言编译器本体(自举) |
| Test | ../Test | 回归测试工程集(编译器的质量门禁) |
| VET | ../VET | Viper 环境/产物检查器 |
| ViperOS | ../ViperApps/ViperOS | 用 Viper 写的裸机操作系统 |
| ViperMNIST | ../ViperApps/ViperMNIST | 用 Viper 做深度学习(手写数字识别) |
ViperC —— 编译器本体
ViperC 是 Viper 的第二代编译器:用 Viper 写、也被 Viper 编译。整条编译链路没有任何 Python 运行时参与——词法/语法分析走自研的 includes/ast(9 个文件),IR 生成走 App/lib/core/Gen/,目标代码由 llc + clang++ 产出。
自举链路:
TransPyC(种子,CPython 实现)
│ 只做一次:把 ViperC 源码编译成 viperc.exe
▼
viperc.exe(第一阶段产物)
│ 自举:用这个 exe 再编译 ViperC 自身
▼
viperc.exe(自举产物,当前随 exe\ 提供的那份)
│
└─ 用它编译任意 Viper 工程(ViperApps\*、Test\* …)
规模(本机实测):
| 项 | 值 |
|---|---|
| 编译器源码 | App/ 下 76 个 .vp 文件,约 64,656 行 |
| 翻译器核心 | App/lib/core/Gen/ 52 个文件,约 49,978 行 |
| 阶段与合并 | App/lib/Phase/ 6 文件;App/lib/Stub/ 9 文件 |
| 自测用例 | Test/ 下 39 个 .vp(App/ 36 + NegativeTest/ 2 + Sha1Test/ 1) |
| 平台 | Windows x64(源码直接 import w32.*) |
目录骨架:
ViperC/
├── project.vpj # 工程配置(source_dir=./App,输出 viperc.exe)
├── App/
│ ├── main.vp # CLI 入口:内存池、单例注入、参数解析、Phase 调度
│ └── lib/
│ ├── Projectrans/ # project.vpj 加载与路径解析
│ ├── core/Gen/ # 翻译器(AST → LLVM IR)
│ ├── Phase/ # Phase1(stub 分离)/ Phase2(组合编译)/ BuildPipeline
│ └── Stub/ # StubGen(.vpi 读取)/ StubMerger(拓扑合并)
└── Test/ # 编译器自测(Viper)
内存模型:全程无系统 malloc 抖动,只有两个 MemBuddy 伙伴分配器池——主池 mb(1 GiB)与常驻池 perm_pool(≈512 MiB)。--detection 可把两个池切到检测模式(0xCDCD 填充 + 记录表探针)排查越界写。
编译任意工程(用自举产物):
exe\viperc.exe --project ViperApps\ViperMNIST\project.vpj --clean --run
命令行参数详见 12-compilation-system.md;自举过程与可行性分析详见 13-bootstrapping.md;交互式 REPL 见 15-repl.md。
自举注意点:自举后模块级全局变量带 SHA1 前缀(模块隔离),像
_g_gen这类单例必须逐模块赋值,不能只在main.vp里赋裸名,否则部分模块会读到自己的None。
Test —— 回归测试工程集
Test 是编译器的质量门禁:每个子目录一个独立可编译工程(App/main.vp + project.json),Test/README.md 收录 77 个并按实现难度升序排列,供编译器开发按序推进(另有 NegativeTest 负向测试容器,不计入难度序列)。
约定:
- 几乎所有项目用
testcheck库(begin/section/check/ok/end)输出 PASS/FAIL 并汇总; - 多数项目依赖
memhub内存分配器与 C 互操作类型。
难度分层(README 口径):
| 层 | 数量 | 代表项目 |
|---|---|---|
| 简单 | 16 | FuncTest、LoopTest、StringTest、StructTest、EqTest、ShortCircuitTest、IterTest |
| 简单→中等 | 3 | GenericTest、GenericTest3 / GenericTest4(泛型入门) |
| 中等 | 21 | TypeCastTest、PointerTest、DictTest、ClassArrayTest、HashLibTest、ArgparseTest |
| 较难 | 26 | GenericTest2、G4/G5/G7、MultiInheritTest、SuperTest、IsinstanceTest、AstTest、NewAstTest、LLvmLiteTest、ZlibTest、CPythonTest |
| 环境依赖 / 回归 | 2 | WebTest(需真实网络)、NoVTableCrossMixinTest |
| 补录(2026-10) | 9 | CharTest、RawArrayTest、DefaultArgTest、CoroTest、ThreadingTest、ZlibDbg、MLIRLiteTest、PtrOpProbe、ProbeGen |
回归复现型(缺陷最小化)——修 bug 时常单独跑这几个:
| 项目 | 复现的问题 |
|---|---|
G7 |
类名与全局变量同名导致 struct body 不完整(符号表命名冲突) |
ClosureCallTest |
闭包返回函数指针后直接 f() 调用 |
Extern2Test |
外部声明被重复 define(应只生成一次 declare) |
SlotsBugTest |
__slots__ + 类型注解误判崩溃(编译通过即达标) |
SprintfTest |
%g 精度 / 变参整数提升 |
NoVTableCrossMixinTest |
NoVTable 多继承下跨 Mixin self. 调用(this 指针前移 sizeof(定义类)) |
自举相关(编译器自身依赖的库,自举前置检查):
AstTest—— AST 解析 / 遍历 /dump,运行时isinstance区分节点;NewAstTest——ast模块 93 项全面回归,语法面最广(match / async / lambda / f-string);LLvmLiteTest——llvmlite库 27 节(类型 / 指令 / phi / switch / 原子操作 / SSA 验证)。
负向测试 —— Test/NegativeTest:9 个故意编译失败的用例(call_too_few / call_too_many / call_wrong_type / call_float_to_int / missing_return / undefined_func / import_missing_module / import_wrong_path / import_stale_path)+ run_negative_tests.py,用于验证 fail-fast 报错行为。
运行方式:
:: 全量回归:遍历所有含 project.json 的工程,编译后多线程运行(超时强制结束)
python Test\regression_test.py
:: 顺序回归:按 README 的「建议实现顺序」逐个编译并立即运行,失败即停
python Test\SequentialRegressionTest.py
regression_test.py会把 stdout 中出现failed/error/traceback等关键词的运行也记为失败,并回显匹配行与上下 5 行。
VPC 侧另有自测套件 ViperC/Test(39 个 .vp:App/ 36 + NegativeTest/ 2 + Sha1Test/ 1),入口 test_main.vp 聚合全部用例:
exe\viperc.exe --project ViperC\Test\project.vpj --clean --run
注:
Test/README.md的清单已补录至 77 个(含CharTest/RawArrayTest/DefaultArgTest/CoroTest/ThreadingTest/ZlibDbg/MLIRLiteTest/PtrOpProbe/ProbeGen),并列出NegativeTest负向测试容器。
VET —— Viper 环境 / 产物检查器
VET(Viper Environment Tool)是一个用 Viper 写的工具链产物检查器,定位类似 PET。两种模式:
-
ver <exe>:对给定 Windows PE 做三项校验,确认它确由 ViperC 工具链生成。检查项 说明 [0/3] 常用目录表构建常用目录清单( C:\Viper、D:\Viper+ 各盘Program Files+ 用户桌面),非空即通过[1/3] 内嵌版本段解析 PE 段表,定位 .PRVERSN段并读出其中的版本串[2/3] --version 前缀执行 <目标 exe> --version,校验 stdout 前 5 个字符是否为Viper -
scan --cache <path>:常驻扫盘发现器,默认每 10 秒一轮(--sleep可改),递归查找所有同时满足"可解析 PE + 含.PRVERSN段 +--version输出以Viper开头"的 exe,结果以单行 JSON 数组写到 stdout,并把发现记录写入缓存文件。另提供scan --search-paths查询开关(建表后打印即退出,不扫盘)。
约定:stdout 只放 JSON,所有人类可读日志走 stderr(安静模式默认只保留启动摘要 + 每轮一行 + 告警,--verbose 恢复全部过程日志)。
# 单 exe 校验(日志在 stderr)
VET.exe ver ..\exe\viperc.exe
# 扫盘:只跑一轮;stdout 重定向即得到 JSON
VET.exe scan --cache .\vet_cache.json --once > result.json
# 查询将搜索的路径(建表后逐行打印到 stderr 即退出)
VET.exe scan --search-paths
看点:--need-confirm <秒> 的心跳确认由独立的看门狗子进程(VET.exe confirm-watch …)驱动,失败时 TerminateProcess 强杀 scan——用子进程而非线程,是为了避开 VLog / VScan 进程级缓冲与 MemBuddy 的线程安全假设。--need-confirm 开启时另有一条附带的 check 请求通道(往 stdin 写一行 JSON 即可点名校验某个 exe)。
构建(本机自编译,本仓库不预置产物):
$env:PATH = "D:\msys64\mingw64\bin;D:\LLVM\bin;$env:PATH"
..\exe\viperc.exe --project .\project.vpj
产物位于 VET\__vpcbuild__\output\VET.exe。
ViperOS —— 用 Viper 写的操作系统
ViperOS 是 Viper 的旗舰演示项目:一个完整可启动的裸机 64 位操作系统。与"教学用 mini-OS"不同,ViperOS 用 Viper 写一切——内核、驱动、用户程序、库、SDK 都是同一种语言。
主要组成:
- VKernel —— 64 位微内核(目标三元组
x86_64-none-elf) - UEFI 引导器 ——
boot/boot.c(GNU-EFI 编译为disk/EFI/BOOT/bootx64.efi) - FAT32 驱动 —— 自研实现,支持挂载 / 目录 / 文件操作
- 4 个用户应用 —— HelloWorld / Terminal / Gargantua / Scene3D
- 2 个动态库 —— SerialLogger / VPUI64
- ViperPOS SDK —— 用户态开发库(系统调用、窗口、文件系统、进程)
ViperOS/
├── build.py # 顶层构建入口:构建 → 打包 → 启动 QEMU
├── boot/ # UEFI 引导器(Makefile + boot.c)
├── VKernel/Kernel/ # 内核
│ ├── drivers/ # core/cpu、devfs、fs/fat32、input、serial、storage、usb、video
│ ├── execrunner/ # ELF 加载器
│ ├── intr/ # GDT/IDT/ISR/Syscall
│ ├── mm/ paging/ sched/ # 内存管理 / 分页 / 协程·进程·调度
│ ├── services/ # 内核服务
│ └── platform/ # PIC / PIT / RTC / Timer
├── Apps/ # 用户应用(每个子目录一个独立 ELF)
├── Libs/ # 动态库(每个子目录一个 .so)
├── vpsdk/ # ViperPOS SDK(应用开发用)
├── Scripts/ # disk.ps1(ImDisk 打包 FAT32 镜像)/ disk.sh
└── disk/ # 被打包进 disk.img 的文件
快速开始:
cd D:\Users\TermiNexus\Desktop\TransPyC\ViperApps\ViperOS
python build.py # 完整构建并启动 QEMU
build.py 会依次:编译 VKernel → 编译 2 个动态库与 4 个应用 → 拷贝产物到 disk/apps/、disk/libs/、disk/sys/kernel/x86_64/ → 用 Scripts/disk.ps1 生成 64 MB FAT32 镜像 disk.img → 启动 QEMU(-no-reboot 防止三重错误后重启)。退出 QEMU 后查看 serial.log 可见内核启动日志。常用参数:--noclean(保留 temp/ 加速二次构建)、--kernel-only(只重编译内核)。
平台:Windows 10/11 + mingw + QEMU 为主平台;Linux 理论可用(需改用 disk.sh);macOS 未测试;真实硬件暂未支持(仅 UEFI x86_64)。
ViperMNIST —— 用 Viper 做深度学习
ViperMNIST 是 28×28 手写数字识别示例,纯 Viper 实现的 MLP / CNN 训练与推理(torch-lite)。
模型:
- MLP:
Linear(784→hidden) → ReLU → Linear(hidden→10) - CNN:
Conv(1→c1,3×3,pad1) → ReLU → MaxPool2 → Conv(c1→c2,3×3,pad1) → ReLU → MaxPool2 → Linear(49*c2→hidden) → ReLU → Linear(hidden→10)
权重形状同 PyTorch(Conv(out,in,k,k) / Linear(out,in),偏置 b(out));线性前向走 vipersimd.simd_dot4d,relu 走 simd_max4d——即用 Viper 的 SIMD 封装做计算加速。
入口分发:
- 无命令行参数 → 启动 Qt6 图形面板(数据 / 训练 / 推理,含 3D 网络图)
- 带命令行参数 → 走 CLI(
train/use)
:: 训练(MLP,5 轮,批 64)
app.exe --mode train --data-dir data --epochs 5 --batch 64 --lr 0.01 ^
--hidden 256 --save models/mnist.bin --limit 60000
:: 训练(CNN:卷积 + 池化,更抗形变)
app.exe --mode train --arch cnn --c1 8 --c2 16
:: 推理:加载模型并打印前 10 条预测
app.exe --mode use --data-dir data --load models/mnist.bin --show 10
常用开关:
| 开关 | 含义 |
|---|---|
--arch mlp|cnn |
架构:全连接 / 卷积+池化 |
--hidden / --c1 / --c2 |
隐藏层宽度 / CNN 两段卷积通道数 |
--epochs / --batch / --lr |
训练轮数 / 批大小 / 学习率 |
--no-aug |
关闭数据增强(默认开启:训练时随机平移 ±2px) |
--download / --file |
自动下载缺失的 MNIST 数据 / 指定本地已下载的 .gz |
--seed |
随机种子 |
--limit |
样本上限(0 = 全部) |
--save / --load |
训练保存路径 / 推理加载路径 |
目录:App/main.vp(入口与 CLI)、App/lib/MnistData.vp(IDX 数据加载)、App/lib/MnistNet.vp(网络与训练)、App/lib/AppGui.vp(Qt6 面板)、data/(MNIST 数据与 mnist.bin)。
use模式的架构 /hidden/ 通道数以模型文件头为准,无需与命令行走一致。
它们证明了什么
| 能力 | 由谁验证 |
|---|---|
| 自举(编译器编译自己,无 Python 运行时) | ViperC |
| 全语言面回归(语法 / 类型 / 泛型 / OOP / 闭包 / 容器 / 自举库 / 负向报错) | Test、ViperC/Test |
| FFI、PE 解析、Win32 绑定、进程/管道、JSON 库 | VET |
| 裸机内核、中断/分页/调度、驱动(FAT32/USB/IDE/网络)、ELF + 动态库、UEFI 启动 | ViperOS |
| 数值计算、SIMD 加速、Qt6 GUI、自定义训练循环 | ViperMNIST |
这些工程是编译器最真实的回归面:任何一处语言/代码生成回退,通常都能在这里暴露出来。
未来展望
上面这些项目证明的是 Viper 的当下能力;我们对它的期望不止于此——我们未来期望 Viper 在高并发、底层、AI 场景、边缘(端侧)能够发光发热:
- 高并发:微内核调度、协程与进程模型已在 ViperOS 里跑通;无
GC的确定性内存模型(MemBuddy池 + 显式所有权)让延迟可预测,适合并发密集的场景。 - 底层:裸机、驱动、引导器、可自举的工具链都已用 Viper 自己写成,且不依赖任何运行时。
- AI 场景:ViperMNIST 已经开了个头(用 Viper 做手写数字识别);强类型 + 零开销抽象适合把数值计算与算子直接编译到原生机器码。
- 边缘(端侧):编译目标就是原生机器码、启动即运行、无解释器与运行时开销,适合资源受限的端侧设备。