修正章节

This commit is contained in:
TermiNexus committed 2026-10-13 15:36:42 +08:00
1 parent bb79d36fd2
commit ac9ed01e24
13 files changed
+96 -96

No files matched your search

+9 -9
View File
@@ -6,7 +6,7 @@ Viper 的类型系统通过 `t` 模块提供,所有类型注解继承 `t.CType
> **三端承载差异(同一套注解,三种实现)**:
> - **TPC**(CPython 实现的种子编译器):类型是**继承 `t.CType` 的类**,命名形如 `t.C{TypeName:PascalCase}`(如 `t.CInt`、`t.CUInt64T`),类型注解即这些类的实例/注解组合。
> - **TPV**(Viper 自举实现的现行编译器):这些类型是**编译器内建**,直接映射到 LLVM 类型,不依赖 `t.CType` 继承链。
> - **VPC**(Viper 自举实现的现行编译器):这些类型是**编译器内建**,直接映射到 LLVM 类型,不依赖 `t.CType` 继承链。
> - **Vipeye**(基于 pyright 的 VSCode 分析插件):通过 `t.vpi` 与 `c.vpi` 两个存根**统一解析**类型,从而对源码给出与编译期一致的类型信息。
>
> 因此源码层面短名别名与 `t.C*` 写法等价,具体承载方式由各端自行决定。
@@ -38,7 +38,7 @@ Viper 的类型系统通过 `t` 模块提供,所有类型注解继承 `t.CType
别名来源:[includes/builtins.vp](../includes/builtins.vp)(C 基础类型裸名)、[includes/stdint.vp](../includes/stdint.vp)(定长与 `*_t`);`int`/`char`/`bool`/`float`/`double`/`str`/`bytes`/`void` 为编译器内置直通。
> 尚未实现 / 不可用:`schar`;`wchar_t`、注解位的 `f32`/`f64`、`char8_t`/`char16_t`/`char32_t`、`intfast*`/`intleast*`(声明存在但 TPV 类型映射缺失)。
> 尚未实现 / 不可用:`schar`;`wchar_t`、注解位的 `f32`/`f64`、`char8_t`/`char16_t`/`char32_t`、`intfast*`/`intleast*`(声明存在但 VPC 类型映射缺失)。
### 指针:统一写 `T*`
@@ -115,7 +115,7 @@ s: []char = "hi" # 长度推导 ≡ t.CArray[char, None]
| `t.CSignedChar` | `signed char` | 8 | 是 |
> **平台相关(`long` / `unsigned long`)**:宽度随目标平台——Windows(LLP64)下为 **32 位**(对齐 `ULONG`/`DWORD`),其余目标(LP64 / 裸机 ELF)为 **64 位**;`long long` / `unsigned long long` 恒为 64 位。
> TPC 由 `configure_platform(triple)` 设置 `_LONG_SIZE` / `_UNSIGNED_LONG_SIZE`(`TransPyC/lib/includes/t.py`),TPV 由 `TypeGenResolve._long_llvm_ty` 按同一口径给出(Windows triple ⇒ `i32`,否则 `i64`)。
> TPC 由 `configure_platform(triple)` 设置 `_LONG_SIZE` / `_UNSIGNED_LONG_SIZE`(`TransPyC/lib/includes/t.py`),VPC 由 `TypeGenResolve._long_llvm_ty` 按同一口径给出(Windows triple ⇒ `i32`,否则 `i64`)。
值得注意的是,t.CUnsigned 一般不单独使用,而是配合其它有符号类型,替换表示无符号,比如 `t.CUnsigned | t.CInt`,由于为了便于使用一些常用类型,则将其组合为常用的 `t.CUnsignedInt` 等。
@@ -346,7 +346,7 @@ int** pp;
- 裸 `rawptr` / 裸 `t.CPtr`(无下标)本身 = `void*` = `i8*`。
- `void*`(`t.CVoid | t.CPtr` 或 `void | t.CPtr`)= `i8*`,是**通配指针**:与任意 `T*` 双向隐式可转(单级)。
- `rawptr` 是**编译器内置语法保留字**(TPC/TPV 双端),用户对它做 `typedef` 会被忽略;`t.CPtr` 是 `t` 模块提供的类型名,二者类型语义等价。
- `rawptr` 是**编译器内置语法保留字**(TPC/VPC 双端),用户对它做 `typedef` 会被忽略;`t.CPtr` 是 `t` 模块提供的类型名,二者类型语义等价。
- 复用 Python 高亮插件时,`T | t.CPtr` 通常比 `t.CPtr[T]` 更易被识别为属性访问。
- 裸类名恒为**原型 struct**(值/布局语义);堆对象引用必须显式写指针(`T*` / `T | t.CPtr` / `rawptr[T]`)。
@@ -372,11 +372,11 @@ x is None # ≡ x == 0 x == None # ≡ x == 0
- **TPC**:`TransPyC/lib/core/Handles/HandlesExprOps.py:400-420` —— 一侧是 `IntType`、另一侧是空指针常量(`None`)时,
把 `None` 侧换成该整型的常量 0 再发 `icmp eq`,`is not` / `!=` 取反。该分支刻意排在「指针 vs 整型」特例之前,
否则 `i8` 会命中 `Gen._load(null)`(从空指针 load)。
- **TPV**:`TransPyV/App/lib/core/Gen/Expr/ExprGenOps.vp:649-694` —— 同样把 `None` 侧物化为整数 0 后走 `icmp eq/ne`
- **VPC**:`ViperC/App/lib/core/Gen/Expr/ExprGenOps.vp:649-694` —— 同样把 `None` 侧物化为整数 0 后走 `icmp eq/ne`
(`None is x` 与 `x is None` 两个方向、`is` 与 `==` 都覆盖)。
> 历史:早期 TPC 把「整型 vs None」直接折成常量(`is not None` → `i1 1`、`is None` → `i1 0`),
> 于是「整型守卫」恒真/恒假、判不出空;而 TPV 已按 0 比较 ⇒ 两侧不一致。现已统一为「整数上的 None = 0」。
> 于是「整型守卫」恒真/恒假、判不出空;而 VPC 已按 0 比较 ⇒ 两侧不一致。现已统一为「整数上的 None = 0」。
> 修复前的现场与逐字 IR 证据见 `Debugger/rawptr-migration-and-fastfail.md` §36。
#### 双侧 IR 证据(判据写法 → 生成码)
@@ -388,7 +388,7 @@ x is None # ≡ x == 0 x == None # ≡ x == 0
| `x is None` / `x == None` / `x == 0` | 整型 | `icmp eq <int> %x, 0` | 有效(两侧同效) |
逐字实证(**语义统一之前**的历史现场):`x = elem_ptr.Ty.Pointee`(`LLVMType*` 的 REnum 载荷槽,偏移 8、`load i64`)时,
`TransPyV/output/818a0677d1e7fe22.ll:17979-17991` 中指针侧有 `icmp`,整型侧却只有
`ViperC/output/818a0677d1e7fe22.ll:17979-17991` 中指针侧有 `icmp`,整型侧却只有
`%"and.result.4" = phi i1 [0, %"endif.19"], [1, %"and.rhs0.4"]`(`and.rhs0.4` 块内 `load i64` 后直接 `br`)
——那是 TPC 把「整型 vs None」折成常量的结果;现已统一为整数 0 比较,该现场不再出现。
@@ -404,7 +404,7 @@ if v == 0: ... # 地址值比较,有效
v2: rawptr = rawptr(*(uint64*)p) # ❌ 被折成裸 0(inttoptr i32 0 to i8*),读不到 vptr
*ptr = <rawptr 值> # ❌ 目标 LHS 是结构体类型的解引用时**可能一条指令都不发射**(静默丢失)
```
(IR 实证:`TransPyV/output/b5883dc9c114a604.ll:10382-10384` 对比 `:10611-10615`。)
(IR 实证:`ViperC/output/b5883dc9c114a604.ll:10382-10384` 对比 `:10611-10615`。)
### 类型限定符组合
@@ -498,7 +498,7 @@ lp: [12]int* # int (*lp)[12] — 数组指针
vp: callable[[int, int], int] # 函数指针(带签名)
```
**函数指针(callable)**:以下写法在类型域全部等价,统一生成 **`i8*`**(函数值按 TPV 惯例 bitcast 为 `i8*` 存储 / 传递):
**函数指针(callable)**:以下写法在类型域全部等价,统一生成 **`i8*`**(函数值按 VPC 惯例 bitcast 为 `i8*` 存储 / 传递):
| 写法 | 说明 |
|------|------|
+1 -1
View File
@@ -295,7 +295,7 @@ lst.append(node) # 类型安全:append 只接受 GNode
## 位域
> 待实现(TPC/TPV 均无解析路径)。
> 待实现(TPC/VPC 均无解析路径)。
使用 `t.Bit(n)` 定义位域成员(**仍需 `|`**):
+2 -2
View File
@@ -390,7 +390,7 @@ class SpecificError(MyError):
## 运算符重载
对象类支持运算符重载。编译器在遇到运算符时,先尝试**左操作数**的 dunder 方法;左操作数无对应方法时,回退**右操作数的反向 dunder**(`a + b` → 先 `a.__add__(b)`,缺失再 `b.__radd__(a)`)。TPC 与 TPV 两端行为一致。
对象类支持运算符重载。编译器在遇到运算符时,先尝试**左操作数**的 dunder 方法;左操作数无对应方法时,回退**右操作数的反向 dunder**(`a + b` → 先 `a.__add__(b)`,缺失再 `b.__radd__(a)`)。TPC 与 VPC 两端行为一致。
### 算术运算符重载
@@ -454,7 +454,7 @@ class Vec2:
| `<<=` | `__ilshift__` | `__lshift__` |
| `>>=` | `__irshift__` | `__rshift__` |
> 调度范围与 TPC 一致:仅**局部变量**目标调度增量 dunder(全局 / `nonlocal` 目标不调度)。重载返回值须与目标变量类型兼容(TPV 侧不兼容时编译期 fail-fast)。
> 调度范围与 TPC 一致:仅**局部变量**目标调度增量 dunder(全局 / `nonlocal` 目标不调度)。重载返回值须与目标变量类型兼容(VPC 侧不兼容时编译期 fail-fast)。
### 比较运算符重载
+3 -3
View File
@@ -119,7 +119,7 @@ def outb(port: uint16, value: uint8):
### ASM_DESCR 约束字符
> 下表为 `ASM_DESCR`(即 `t.ASM_DESCR`)的完整期望常量集;TPV 实际已映射子集见本节末。
> 下表为 `ASM_DESCR`(即 `t.ASM_DESCR`)的完整期望常量集;VPC 实际已映射子集见本节末。
> 常量既可写 `ASM_DESCR.XXX`,也可写 `t.ASM_DESCR.XXX`。
#### 操作数修饰符
@@ -177,7 +177,7 @@ def outb(port: uint16, value: uint8):
| `CLOBBER_MEMORY` | 破坏内存 |
| `CLOBBER_R8` ~ `CLOBBER_R15` | 破坏 R8~R15 |
> TPV 实际已映射子集:`REG_ANY` / `REG_EAX..RDI` / `RAX..R15`、`OUTPUT_REG` / `OUTPUT_MEM` / `OUTPUT_EAX`、`INPUT_REG` / `INPUT_MEM` / `INPUT_EAX`…、`CLOBBER_MEMORY` / `CLOBBER_CC` / `CLOBBER_RAX..R15`。`REG_XMM` / `MEMORY` / `IMMEDIATE` / `ANY` / `MODIFIER_OUTPUT` / `READWRITE` / `INPUT` / `GLOBAL` 等期望实现。
> VPC 实际已映射子集:`REG_ANY` / `REG_EAX..RDI` / `RAX..R15`、`OUTPUT_REG` / `OUTPUT_MEM` / `OUTPUT_EAX`、`INPUT_REG` / `INPUT_MEM` / `INPUT_EAX`…、`CLOBBER_MEMORY` / `CLOBBER_CC` / `CLOBBER_RAX..R15`。`REG_XMM` / `MEMORY` / `IMMEDIATE` / `ANY` / `MODIFIER_OUTPUT` / `READWRITE` / `INPUT` / `GLOBAL` 等期望实现。
## 预处理指令
@@ -197,7 +197,7 @@ define MAX_SIZE = 1024 # #define MAX_SIZE 1024(推荐)
`define` 软关键字与 `def f(...) -> t.CDefine` 声明的函数均为宏函数:存根保留完整函数体,调用点在编译期内联展开。
> TPC 已实现;TransPyV 的展开尚未对齐。
> TPC 已实现;ViperC 的展开尚未对齐。
### 条件编译
+3 -3
View File
@@ -110,7 +110,7 @@ viperlib.snprintf(&buf, 64, "value=%d", 42) # snprintf(&buf, 64, "value=%d",
### `ast` 模块(自研解析器)
[includes/ast](../includes/ast) 是**完全自研的 Python 解析器**(词法器 + 语法器 + AST 构造,现行 9 个文件约 8K 行;"约 4176 LOC"为 2026-06 历史口径),覆盖 CPython 几乎全部语法。这是向 `TransPyV` 完全自举的关键组件——自举后编译器不再依赖 Python 运行时解析源文件。
[includes/ast](../includes/ast) 是**完全自研的 Python 解析器**(词法器 + 语法器 + AST 构造,现行 9 个文件约 8K 行;"约 4176 LOC"为 2026-06 历史口径),覆盖 CPython 几乎全部语法。这是向 `ViperC` 完全自举的关键组件——自举后编译器不再依赖 Python 运行时解析源文件。
```python
from ast import parse, parse_expression
@@ -198,14 +198,14 @@ Viper 的 `import` 是编译时操作,不涉及运行时模块加载。完整
### 类型存根文件(.vpi)
`.vpi` 文件是模块的声明接口,由 `PythonToStubConverter` 在阶段一生成。TPV 自举路径使用自研 `StubGen`/`Converter.vp`(从 AST 直接生成,不依赖 CPython 的 `PythonToStubConverter`)。存根文件的内容规则:
`.vpi` 文件是模块的声明接口,由 `PythonToStubConverter` 在阶段一生成。VPC 自举路径使用自研 `StubGen`/`Converter.vp`(从 AST 直接生成,不依赖 CPython 的 `PythonToStubConverter`)。存根文件的内容规则:
| 元素 | 存根表示 |
|------|---------|
| `t.CDefine` 常量 | 保留完整定义(含赋值) |
| `t.CDefine` 函数 | 保留完整函数体 |
| 普通函数 | 仅保留签名:`def foo(...) -> T: pass` |
| 全局变量 | TPC 一代 `PythonToStubConverter` 会添加 `t.CExtern`;TPV 自研 `StubGen`/`Converter.vp` 不再添加(跨模块 external declare 由 `VpiReader` 依 vpi 全局自动注入) |
| 全局变量 | TPC 一代 `PythonToStubConverter` 会添加 `t.CExtern`;VPC 自研 `StubGen`/`Converter.vp` 不再添加(跨模块 external declare 由 `VpiReader` 依 vpi 全局自动注入) |
| 类定义 | 保留成员类型注解和方法签名 |
### SHA1 命名空间与导入
+2 -2
View File
@@ -26,7 +26,7 @@ s: size_t = sizeof(int) # sizeof(int)
s: size_t = obj.__sizeof__() # sizeof(obj)
```
> **注意**:裸 `sizeof()` 为 TPC 支持;TransPyV 以 `X.__sizeof__()`/`len(数组)` 为主。
> **注意**:裸 `sizeof()` 为 TPC 支持;ViperC 以 `X.__sizeof__()`/`len(数组)` 为主。
### abs
@@ -34,7 +34,7 @@ s: size_t = obj.__sizeof__() # sizeof(obj)
a: int = abs(x) # abs(x)
```
> **注意**:TPC 为硬编码内建;TransPyV 按 C 库裸名调用 `@abs`(两者并存)。
> **注意**:TPC 为硬编码内建;ViperC 按 C 库裸名调用 `@abs`(两者并存)。
### int / float / bool / char / double(裸内建强转)
+14 -14
View File
@@ -9,7 +9,7 @@ Viper 目前有两条编译路径,二者共享同一套语言语义:
| 编译器 | 实现语言 | 定位 |
|--------|----------|------|
| **TPC**(TransPyC) | Python | 种子编译器:纯 Python 实现,用于自举起点与快速试验 |
| **TPV**(TransPyV) | Viper | 自举产物:由 TPC 编译出的 Viper 原生编译器,日常构建走它 |
| **VPC**(ViperC) | Viper | 自举产物:由 TPC 编译出的 Viper 原生编译器,日常构建走它 |
两阶段编译模型:
@@ -37,7 +37,7 @@ Viper 目前有两条编译路径,二者共享同一套语言语义:
"name": "Kernel",
"version": "1.0.0",
"source_dir": "./Kernel",
"build_dir": "./.tpv_build",
"build_dir": "./__vpcbuild__",
"compiler": {
"cmd": "llc",
"flags": ["-filetype=obj", "-mtriple=x86_64-none-elf", "-relocation-model=static", "-O2"]
@@ -69,7 +69,7 @@ Viper 目前有两条编译路径,二者共享同一套语言语义:
|------|------|------|
| `name` / `version` | string | 项目名 / 版本 |
| `source_dir` | string | 源代码目录(相对 `project.vpj` 所在目录) |
| `build_dir` | string | 构建目录(默认 `./.tpv_build`);`temp` / `output` 均由它派生 |
| `build_dir` | string | 构建目录(默认 `./__vpcbuild__`);`temp` / `output` 均由它派生 |
| `compiler.cmd` / `compiler.flags` | string / string[] | 编译器命令(通常 `llc`)与标志 |
| `linker.cmd` / `linker.flags` | string / string[] | 链接器命令与标志 |
| `linker.static_libs` | string[] | 静态库 / 目标文件(`.a` / `.obj`) |
@@ -83,7 +83,7 @@ Viper 目前有两条编译路径,二者共享同一套语言语义:
| `options.target` | string | 编译目标(目前仅 `llvm`) |
| `options.strict_mode` | bool | 严格模式 |
**无统一默认 triple**:由各工程自行指定(TransPyV 自身为 `x86_64-pc-windows-gnu`;ViperOS 内核为 `x86_64-none-elf`)。`target.datalayout` 与 `target.triple` 会写入 `.ll` 模块头(`target triple` / `target datalayout`)。
**无统一默认 triple**:由各工程自行指定(ViperC 自身为 `x86_64-pc-windows-gnu`;ViperOS 内核为 `x86_64-none-elf`)。`target.datalayout` 与 `target.triple` 会写入 `.ll` 模块头(`target triple` / `target datalayout`)。
常用 `llc` 标志:`-filetype=obj`(出目标文件)、`-mtriple=...`、`-relocation-model=pic|static`、`-O0..3`。
@@ -105,7 +105,7 @@ Viper 目前有两条编译路径,二者共享同一套语言语义:
HelloWorld/
├── project.vpj # 项目配置
├── main.vp # 入口
└── .tpv_build/ # 构建目录(build_dir,自动生成)
└── __vpcbuild__/ # 构建目录(build_dir,自动生成)
├── temp/ # 临时文件
│ └── <sha1[0:2]>/ # SHA1 切片子目录(sha1_slice_level ≥ 1)
│ ├── <SHA1>.vpi # 签名存根
@@ -136,17 +136,17 @@ python TransPyC.py -f InputFile -o OutputFile [options]
| `-run` / `-args` | 编译后运行 / 运行参数 |
| `-h` | 辅助文件(C 或 Python) |
### TPV(自举产物)
### VPC(自举产物)
```bash
# 工程模式:按 project.vpj 构建
TransPyV.exe --project project.vpj [--clean] [--run]
viperc.exe --project project.vpj [--clean] [--run]
# viperbuild 模式:入口文件自带构建配置(无需 project.vpj)
TransPyV.exe --src App/main.vp [--run]
viperc.exe --src App/main.vp [--run]
```
常用开关(完整清单见 [TransPyV/README.md](../TransPyV/README.md)):
常用开关(完整清单见 [ViperC/README.md](../ViperC/README.md)):
| 开关 | 说明 |
|------|------|
@@ -191,15 +191,15 @@ import viperbuild as vb
COMMON_FLAGS = ["-O0", "-g"]
proj = vb.Project("TransPyV", "1.0.0") # 也支持 Project(name=..., version=...)
proj = vb.Project("ViperC", "1.0.0") # 也支持 Project(name=..., version=...)
proj.source = "./App" # 缺省 = 入口文件所在目录
proj.buildroot = "./.tpv_build" # 缺省 = source + "/.tpv_build"
proj.buildroot = "./__vpcbuild__" # 缺省 = source + "/__vpcbuild__"
proj.includes = ["../includes"] # 缺省 = 从 exe 目录向上 0..3 层探测 includes
proj.compiler = ["llc", "-filetype=obj", "-relocation-model=pic", *COMMON_FLAGS]
proj.linker = ["clang++", "-fuse-ld=lld", "-lmsvcrt", "-lucrt", "-g"]
proj.static_libs = [".../libclang_rt.asan_dynamic-x86_64.dll.a"]
proj.dynamic_libs = []
proj.output = "TransPyV.exe" # 缺省 = 入口文件名 + ".exe"
proj.output = "viperc.exe" # 缺省 = 入口文件名 + ".exe"
proj.build(triple="x86_64-pc-windows-gnu",
datalayout="e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128")
@@ -208,7 +208,7 @@ proj.build(triple="x86_64-pc-windows-gnu",
也可以批量赋值:
```python
proj.config(source="./App", buildroot="./.tpv_build", includes=["../includes"], ...)
proj.config(source="./App", buildroot="./__vpcbuild__", includes=["../includes"], ...)
```
`build()` 的目标平台三种写法(**互斥**):
@@ -245,7 +245,7 @@ proj.config(source="./App", buildroot="./.tpv_build", includes=["../includes"],
翻译期 `viperbuild` 的宏语句(`proj = vb.Project(...)` / `proj.<字段> = ...` / `proj.config()` / `proj.build()`)会由翻译器**整体擦除**,不生成任何 IR;`import viperbuild` 本身也只记账不产码。
> Pass 0 的实现位于 [TransPyV/App/lib/core/builtin/ViperBuild.vp](../TransPyV/App/lib/core/builtin/ViperBuild.vp)。
> Pass 0 的实现位于 [ViperC/App/lib/core/builtin/ViperBuild.vp](../ViperC/App/lib/core/builtin/ViperBuild.vp)。
## 平台说明
+8 -8
View File
@@ -3,8 +3,8 @@
> **状态**:已完成(本文为 2026-06-30 可行性分析历史记录)
> **创建时间**:2026-06-26
> **最后更新**:2026-06-30
> **结论**:完全自举可行——已于 2026-08 后实现:TPC 编译 TransPyV → `TransPyV/output/TransPyV.exe`(Phase A)→ 自举编译自身(Phase B/C 已跑通);当前编译器脱离 Python 运行时,由 includes/ast 自研解析器 + Viper 编译器自举
> **现状说明**:本文全部 LOC/文件结构数据(includes/ast 4,176 行、`__tokens`/`__nodes`/`__parser` 文件名、llvmlite ~1,500 行、main.vp 10 个 llvmlite 测试等)均为 2026-06-30 历史数据。现状:includes/ast 为 tokens/base/exprs/stmts/parser 等 9 文件约 8K 行;llvmlite 7 文件约 5.9K 行;TransPyV/App/main.vp 现为编译器 CLI 入口。
> **结论**:完全自举可行——已于 2026-08 后实现:TPC 编译 ViperC → `ViperC/output/viperc.exe`(Phase A)→ 自举编译自身(Phase B/C 已跑通);当前编译器脱离 Python 运行时,由 includes/ast 自研解析器 + Viper 编译器自举
> **现状说明**:本文全部 LOC/文件结构数据(includes/ast 4,176 行、`__tokens`/`__nodes`/`__parser` 文件名、llvmlite ~1,500 行、main.vp 10 个 llvmlite 测试等)均为 2026-06-30 历史数据。现状:includes/ast 为 tokens/base/exprs/stmts/parser 等 9 文件约 8K 行;llvmlite 7 文件约 5.9K 行;ViperC/App/main.vp 现为编译器 CLI 入口。
---
@@ -104,7 +104,7 @@
### 3.2 ✅ includes/llvmlite —— LLVM IR 生成库自举
**状态**:完成,LLvmLiteTest 18/18 通过,TransPyV 自举实验跑通
**状态**:完成,LLvmLiteTest 18/18 通过,ViperC 自举实验跑通
| 文件 | 功能 |
|------|------|
@@ -122,7 +122,7 @@
- IR 文本生成用 `viperlib.snprintf` 格式化,避免手写逐字符拼接
- 对象分配用普通类 + `mpool`,不持有全局 `mbuddy`
**验证**:[TransPyV/App/main.vp](../TransPyV/App/main.vp) 10 个 llvmlite 测试覆盖类型打印、值打印、build_add、if-else、模块打印、lli 实际执行。TransPyV 程序运行时自己生成合法 IR,被 `lli` 成功执行。(历史数据,2026-06-30;该 main.vp 现为编译器 CLI 入口)
**验证**:[ViperC/App/main.vp](../ViperC/App/main.vp) 10 个 llvmlite 测试覆盖类型打印、值打印、build_add、if-else、模块打印、lli 实际执行。ViperC 程序运行时自己生成合法 IR,被 `lli` 成功执行。(历史数据,2026-06-30;该 main.vp 现为编译器 CLI 入口)
### 3.3 ✅ 基础设施库
@@ -146,7 +146,7 @@
**原问题**:编译器通过 `llvmlite.ir` 生成 IR,TransPyC 无法调用 Python 库。
**解决**:`includes/llvmlite/` 用 TransPyC 自身实现了 LLVM IR 文本生成库,API 与 Python `llvmlite.ir` 对齐。采用"字符串拼 IR"路径(路径 A),不绑定 LLVM C API。18/18 测试通过,TransPyV 自举实验验证可生成可执行 IR。
**解决**:`includes/llvmlite/` 用 TransPyC 自身实现了 LLVM IR 文本生成库,API 与 Python `llvmlite.ir` 对齐。采用"字符串拼 IR"路径(路径 A),不绑定 LLVM C API。18/18 测试通过,ViperC 自举实验验证可生成可执行 IR。
### 4.2 ~~ast 模块依赖(原:致命)~~ → ✅ 已解决
@@ -260,9 +260,9 @@
## 9. 当前自举状态(2026-08 后)
完整构建流程、产物与命令见 [TransPyV/README.md](../TransPyV/README.md) 与 [MCP/protocol.md](../MCP/protocol.md)(在仓库根目录执行):
完整构建流程、产物与命令见 [ViperC/README.md](../ViperC/README.md) 与 [MCP/protocol.md](../MCP/protocol.md)(在仓库根目录执行):
```text
python Projectrans.py --project TransPyV\project.vpj --clean
TransPyV/.tpv_build/output/TransPyV.exe --help
python Projectrans.py --project ViperC\project.vpj --clean
ViperC/__vpcbuild__/output/viperc.exe --help
```
+4 -4
View File
@@ -98,13 +98,13 @@ def get_mro_parent_entries(entry) -> 父类 StructEntry 数组
## 8. TPC 同步清单
TPC(Python,`lib/core/`)与 TPV 结构一致,按顺序同步:
TPC(Python,`lib/core/`)与 VPC 结构一致,按顺序同步:
1. `Handles/HandlesStruct.py`:StructEntry 父类数组 + MRO 辅助
2. `Handles/HandlesClassDef.py`:字段展平多父、vtable 多父合并、parent 收集
3. `Handles/HandlesExprCall.py`:方法查找/运算符重载多父链
4. `Handles/HandlesExpr.py`(若 TPC 属性访问在 HandlesExprAttr.py):多父回退
**顺序**:先 TPV(活跃编译器)实现 + 验证,再 TPC 同步(保持一致,防分叉)。
**顺序**:先 VPC(活跃编译器)实现 + 验证,再 TPC 同步(保持一致,防分叉)。
## 9. 实施计划
@@ -119,7 +119,7 @@ TPC(Python,`lib/core/`)与 TPV 结构一致,按顺序同步:
## 10. 验证用例(Test/MultiInheritTest/App/main.vp)
*注:回归用例位于仓库根 Test/MultiInheritTest 与 Test/NoVTableCrossMixinTest(TransPyV/Test 自身无双父用例)。*
*注:回归用例位于仓库根 Test/MultiInheritTest 与 Test/NoVTableCrossMixinTest(ViperC/Test 自身无双父用例)。*
- 多父字段合并 + 属性访问(`d = D(); d.a + d.b`)
- 多父方法调用(非虚 + 虚 vtable 分派)
@@ -136,7 +136,7 @@ TPC(Python,`lib/core/`)与 TPV 结构一致,按顺序同步:
| vtable 合并槽位错误 | 多继承 vtable 用例 + obj 反汇编核对 |
| Viper 方法符号不转发(P1 已踩坑) | 多继承下子类仍只调自己文件定义的方法;父类方法用字段/模块函数 |
| 菱形去重遗漏 | MRO 已访问集合严格实现 |
| TPC/TPV 分叉 | TPV 先验,TPC 紧跟同步 |
| TPC/VPC 分叉 | VPC 先验,TPC 紧跟同步 |
## 12. 规模上限(实现常量)
+13 -13
View File
@@ -1,20 +1,20 @@
# 15 - 交互式 REPL
`TransPyV` 内置一个交互式 REPL:把每一行/每一块 Viper 片段**即时编译成 DLL 并加载调用**,把结果回显出来。它支持会话变量(M2)与跨片段会话函数(M3),适合快速试验语法、验证表达式与类型行为。
`ViperC` 内置一个交互式 REPL:把每一行/每一块 Viper 片段**即时编译成 DLL 并加载调用**,把结果回显出来。它支持会话变量(M2)与跨片段会话函数(M3),适合快速试验语法、验证表达式与类型行为。
> 实现位置:[TransPyV/App/lib/core/Repl.vp](../TransPyV/App/lib/core/Repl.vp);入口开关在 [TransPyV/App/main.vp](../TransPyV/App/main.vp)。
> 实现位置:[ViperC/App/lib/core/Repl.vp](../ViperC/App/lib/core/Repl.vp);入口开关在 [ViperC/App/main.vp](../ViperC/App/main.vp)。
## 启动
```bat
TransPyV.exe --repl
viperc.exe --repl
:: 也可显式指定工程(REPL 的编译/链接参数取自工程配置)
TransPyV.exe --repl --project TransPyV\repl.vpj
viperc.exe --repl --project ViperC\repl.vpj
```
- `--repl` 是布尔开关;未给 `--project` 时,按 **当前工作目录 → `TransPyV.exe` 同目录** 的顺序查找 `repl.vpj`;两处都没有则 fail-fast,并在诊断里打印已查找位置与模板位置。
- 模板工程 [TransPyV/repl.vpj](../TransPyV/repl.vpj) 刻意**不含 `source_dir`**(让 REPL 走「全量扫描 + 注册」而非 Phase1 的可达性分析),`sha1_slice_level = 1`。
- REPL 的片段临时目录是 `%TEMP%\TransPyV_repl\<pid>`,与 `repl.vpj` 的 `build_dir` 无关。
- `--repl` 是布尔开关;未给 `--project` 时,按 **当前工作目录 → `viperc.exe` 同目录** 的顺序查找 `repl.vpj`;两处都没有则 fail-fast,并在诊断里打印已查找位置与模板位置。
- 模板工程 [ViperC/repl.vpj](../ViperC/repl.vpj) 刻意**不含 `source_dir`**(让 REPL 走「全量扫描 + 注册」而非 Phase1 的可达性分析),`sha1_slice_level = 1`。
- REPL 的片段临时目录是 `%TEMP%\ViperC_repl\<pid>`,与 `repl.vpj` 的 `build_dir` 无关。
### 与其它模式互斥
@@ -29,7 +29,7 @@ TransPyV.exe --repl --project TransPyV\repl.vpj
启动横幅自述支持范围:
```text
TransPyV REPL (M2/M3/M4) - 会话变量 + 会话函数(跨片段)+ ctx 回传结果;
ViperC REPL (M2/M3/M4) - 会话变量 + 会话函数(跨片段)+ ctx 回传结果;
支持表达式(1+2)、定义(x = 1 / x: int = 5)、引用(x + 1)、
增强赋值(x += 2)、取址(p = &x)等;空行跳过,Ctrl+Z 或 EOF 退出
多行块:行尾 ':' 进入续行(提示符 ...),空行结束并整块执行一次
@@ -65,7 +65,7 @@ TransPyV REPL (M2/M3/M4) - 会话变量 + 会话函数(跨片段)+ ctx 回
## 会话上下文(ctx)
宿主与片段**同进程共享**一段 ctx 内存,用于回传会话变量与结果。布局由 [TransPyV/App/lib/core/Gen/GenTypes.vp](../TransPyV/App/lib/core/Gen/GenTypes.vp) 定义:
宿主与片段**同进程共享**一段 ctx 内存,用于回传会话变量与结果。布局由 [ViperC/App/lib/core/Gen/GenTypes.vp](../ViperC/App/lib/core/Gen/GenTypes.vp) 定义:
| 常量 | 值 | 说明 |
|------|----|------|
@@ -97,7 +97,7 @@ REPL 用两个 `MemBuddy` 池:
## 相关文件
- [TransPyV/App/lib/core/Repl.vp](../TransPyV/App/lib/core/Repl.vp)
- [TransPyV/App/main.vp](../TransPyV/App/main.vp)(`--repl` / `ReplFindProject`)
- [TransPyV/repl.vpj](../TransPyV/repl.vpj)(模板工程)
- [TransPyV/App/lib/core/Gen/GenTypes.vp](../TransPyV/App/lib/core/Gen/GenTypes.vp)(ctx 布局常量)
- [ViperC/App/lib/core/Repl.vp](../ViperC/App/lib/core/Repl.vp)
- [ViperC/App/main.vp](../ViperC/App/main.vp)(`--repl` / `ReplFindProject`)
- [ViperC/repl.vpj](../ViperC/repl.vpj)(模板工程)
- [ViperC/App/lib/core/Gen/GenTypes.vp](../ViperC/App/lib/core/Gen/GenTypes.vp)(ctx 布局常量)
+7 -7
View File
@@ -1,6 +1,6 @@
# 16 - 栈回溯与调试信息
TransPyV 里的 "traceback" 有**两套完全不同的东西**,务必区分:
ViperC 里的 "traceback" 有**两套完全不同的东西**,务必区分:
| | 编译期 traceback | 运行期栈回溯 |
|---|---|---|
@@ -18,7 +18,7 @@ Traceback (most recent call last, compile-time error):
File "D:\...\App\main.vp", line 238
```
实现位于 [TransPyV/App/lib/core/Gen/Type/TypeGenErr.vp](../TransPyV/App/lib/core/Gen/Type/TypeGenErr.vp)(`fatal_error`),入口 `GenApi.dump_parse_traceback`,在 Phase1 / Phase2 失败路径上调用。它与运行期无关。
实现位于 [ViperC/App/lib/core/Gen/Type/TypeGenErr.vp](../ViperC/App/lib/core/Gen/Type/TypeGenErr.vp)(`fatal_error`),入口 `GenApi.dump_parse_traceback`,在 Phase1 / Phase2 失败路径上调用。它与运行期无关。
## 运行期栈回溯(`--traceback`)
@@ -57,7 +57,7 @@ Traceback (most recent call last):
### DWARF 元数据由编译器自己发射
DWARF 不是靠 llc 的 `-g`,而是编译器在 LLVM IR 里自己发 DI 元数据([TransPyV/App/lib/core/Gen/DebugInfoGen.vp](../TransPyV/App/lib/core/Gen/DebugInfoGen.vp)):
DWARF 不是靠 llc 的 `-g`,而是编译器在 LLVM IR 里自己发 DI 元数据([ViperC/App/lib/core/Gen/DebugInfoGen.vp](../ViperC/App/lib/core/Gen/DebugInfoGen.vp)):
- 节点层次:`!DIFile → !{ null } → !DISubroutineType → distinct !DICompileUnit → distinct !DISubprogram(每个 define)→ !DILocation(每条语句)`;
- 模块尾部追加 `!llvm.dbg.cu` 与 `!llvm.module.flags`(Debug Info Version 3);
@@ -86,7 +86,7 @@ ASan 运行时也会注册 DbgHelp 符号化器,但 DbgHelp 状态是**进程
## ASan 与 MemBuddy 检测
- **`--asan`**:在 `.ll → obj` 之前先跑 `opt -passes=forceattrs,asan -force-attribute=sanitize_address -asan-globals=false` 插桩。ASan 运行库**不由 TPV 注入**,必须由 `project.vpj` 的 `linker.static_libs` / `dynamic_libs` / `flags` 显式声明(出现 "asan" 即视为已声明),否则 fail-fast。
- **`--asan`**:在 `.ll → obj` 之前先跑 `opt -passes=forceattrs,asan -force-attribute=sanitize_address -asan-globals=false` 插桩。ASan 运行库**不由 VPC 注入**,必须由 `project.vpj` 的 `linker.static_libs` / `dynamic_libs` / `flags` 显式声明(出现 "asan" 即视为已声明),否则 fail-fast。
- **`--detection` / `--detection-deep`**:`MemBuddy` 内存池的分配检测(用户区前后各 2 字节 `0xCDCD` 标记 + 记录表探针),与 traceback 无关,是独立的内存诊断开关,作用于 `mb` 与 `perm_pool` 两个池。
## 已知限制
@@ -101,7 +101,7 @@ ASan 运行时也会注册 DbgHelp 符号化器,但 DbgHelp 状态是**进程
## 相关文件
- [includes/traceback.vp](../includes/traceback.vp)(运行期栈回溯模块)
- [TransPyV/App/lib/core/Gen/DebugInfoGen.vp](../TransPyV/App/lib/core/Gen/DebugInfoGen.vp)(DWARF IR 发射)
- [TransPyV/App/lib/Phase/BuildPipeline.vp](../TransPyV/App/lib/Phase/BuildPipeline.vp)(llc / 链接 / stackmap 旁文件)
- [TransPyV/App/lib/core/Gen/Type/TypeGenErr.vp](../TransPyV/App/lib/core/Gen/Type/TypeGenErr.vp)(编译期 traceback)
- [ViperC/App/lib/core/Gen/DebugInfoGen.vp](../ViperC/App/lib/core/Gen/DebugInfoGen.vp)(DWARF IR 发射)
- [ViperC/App/lib/Phase/BuildPipeline.vp](../ViperC/App/lib/Phase/BuildPipeline.vp)(llc / 链接 / stackmap 旁文件)
- [ViperC/App/lib/core/Gen/Type/TypeGenErr.vp](../ViperC/App/lib/core/Gen/Type/TypeGenErr.vp)(编译期 traceback)
- [includes/memhub.vp](../includes/memhub.vp)(`--detection` 语义)
+18 -18
View File
@@ -4,7 +4,7 @@
| 项目 | 位置 | 定位 |
|------|------|------|
| **TransPyV** | [../TransPyV](../TransPyV) | Viper 语言编译器本体(自举) |
| **ViperC** | [../ViperC](../ViperC) | Viper 语言编译器本体(自举) |
| **Test** | [../Test](../Test) | 回归测试工程集(编译器的质量门禁) |
| **VET** | [../VET](../VET) | Viper 环境/产物检查器 |
| **ViperOS** | [../ViperApps/ViperOS](../ViperApps/ViperOS) | 用 Viper 写的裸机操作系统 |
@@ -12,20 +12,20 @@
---
## TransPyV —— 编译器本体
## ViperC —— 编译器本体
[TransPyV](../TransPyV) 是 Viper 的**第二代编译器**:**用 Viper 写、也被 Viper 编译**。整条编译链路没有任何 Python 运行时参与——词法/语法分析走自研的 [includes/ast](../includes/ast)(9 个文件),IR 生成走 `App/lib/core/Gen/`,目标代码由 `llc` + `clang++` 产出。
[ViperC](../ViperC) 是 Viper 的**第二代编译器**:**用 Viper 写、也被 Viper 编译**。整条编译链路没有任何 Python 运行时参与——词法/语法分析走自研的 [includes/ast](../includes/ast)(9 个文件),IR 生成走 `App/lib/core/Gen/`,目标代码由 `llc` + `clang++` 产出。
自举链路:
```text
TransPyC(种子,CPython 实现)
│ 只做一次:把 TransPyV 源码编译成 TransPyV.exe
│ 只做一次:把 ViperC 源码编译成 viperc.exe
▼
TransPyV.exe(第一阶段产物)
│ 自举:用这个 exe 再编译 TransPyV 自身
viperc.exe(第一阶段产物)
│ 自举:用这个 exe 再编译 ViperC 自身
▼
TransPyV.exe(自举产物,当前随 exe\ 提供的那份)
viperc.exe(自举产物,当前随 exe\ 提供的那份)
│
└─ 用它编译任意 Viper 工程(ViperApps\*、Test\* …)
```
@@ -43,8 +43,8 @@ TransPyV.exe(自举产物,当前随 exe\ 提供的那份)
目录骨架:
```text
TransPyV/
├── project.vpj # 工程配置(source_dir=./App,输出 TransPyV.exe)
ViperC/
├── project.vpj # 工程配置(source_dir=./App,输出 viperc.exe)
├── App/
│ ├── main.vp # CLI 入口:内存池、单例注入、参数解析、Phase 调度
│ └── lib/
@@ -60,7 +60,7 @@ TransPyV/
编译任意工程(用自举产物):
```bat
exe\TransPyV.exe --project ViperApps\ViperMNIST\project.vpj --clean --run
exe\viperc.exe --project ViperApps\ViperMNIST\project.vpj --clean --run
```
命令行参数详见 [12-compilation-system.md](12-compilation-system.md);自举过程与可行性分析详见 [13-bootstrapping.md](13-bootstrapping.md);交互式 REPL 见 [15-repl.md](15-repl.md)。
@@ -120,10 +120,10 @@ python Test\SequentialRegressionTest.py
> `regression_test.py` 会把 stdout 中出现 `failed` / `error` / `traceback` 等关键词的运行也记为失败,并回显匹配行与上下 5 行。
TPV 侧另有自测套件 [TransPyV/Test](../TransPyV/Test)(39 个 `.vp`:`App/` 36 + `NegativeTest/` 2 + `Sha1Test/` 1),入口 `test_main.vp` 聚合全部用例:
VPC 侧另有自测套件 [ViperC/Test](../ViperC/Test)(39 个 `.vp`:`App/` 36 + `NegativeTest/` 2 + `Sha1Test/` 1),入口 `test_main.vp` 聚合全部用例:
```bat
exe\TransPyV.exe --project TransPyV\Test\project.vpj --clean --run
exe\viperc.exe --project ViperC\Test\project.vpj --clean --run
```
> 注:`Test/README.md` 的清单已补录至 77 个(含 `CharTest` / `RawArrayTest` / `DefaultArgTest` / `CoroTest` / `ThreadingTest` / `ZlibDbg` / `MLIRLiteTest` / `PtrOpProbe` / `ProbeGen`),并列出 `NegativeTest` 负向测试容器。
@@ -134,7 +134,7 @@ exe\TransPyV.exe --project TransPyV\Test\project.vpj --clean --run
[VET](../VET)(Viper Environment Tool)是一个用 Viper 写的**工具链产物检查器**,定位类似 PET。两种模式:
- **`ver <exe>`**:对给定 Windows PE 做三项校验,确认它确由 TransPyV 工具链生成。
- **`ver <exe>`**:对给定 Windows PE 做三项校验,确认它确由 ViperC 工具链生成。
| 检查项 | 说明 |
|--------|------|
@@ -148,7 +148,7 @@ exe\TransPyV.exe --project TransPyV\Test\project.vpj --clean --run
```powershell
# 单 exe 校验(日志在 stderr)
VET.exe ver ..\exe\TransPyV.exe
VET.exe ver ..\exe\viperc.exe
# 扫盘:只跑一轮;stdout 重定向即得到 JSON
VET.exe scan --cache .\vet_cache.json --once > result.json
@@ -163,10 +163,10 @@ VET.exe scan --search-paths
```powershell
$env:PATH = "D:\msys64\mingw64\bin;D:\LLVM\bin;$env:PATH"
..\exe\TransPyV.exe --project .\project.vpj
..\exe\viperc.exe --project .\project.vpj
```
产物位于 `VET\.tpv_build\output\VET.exe`。
产物位于 `VET\__vpcbuild__\output\VET.exe`。
---
@@ -265,8 +265,8 @@ app.exe --mode use --data-dir data --load models/mnist.bin --show 10
| 能力 | 由谁验证 |
|------|---------|
| 自举(编译器编译自己,无 Python 运行时) | TransPyV |
| 全语言面回归(语法 / 类型 / 泛型 / OOP / 闭包 / 容器 / 自举库 / 负向报错) | Test、TransPyV/Test |
| 自举(编译器编译自己,无 Python 运行时) | ViperC |
| 全语言面回归(语法 / 类型 / 泛型 / OOP / 闭包 / 容器 / 自举库 / 负向报错) | Test、ViperC/Test |
| FFI、PE 解析、Win32 绑定、进程/管道、JSON 库 | VET |
| 裸机内核、中断/分页/调度、驱动(FAT32/USB/IDE/网络)、ELF + 动态库、UEFI 启动 | ViperOS |
| 数值计算、SIMD 加速、Qt6 GUI、自定义训练循环 | ViperMNIST |
+12 -12
View File
@@ -6,11 +6,11 @@
`Viper` 是一种 **系统级编程语言**,其语法基于 `Python`,但编译目标为 `LLVM IR`(注意,在计划中,我们期望迁移到 `MLIR`,这点是 `Viper` 的预期受众方向所要求的,`Viper` 期望走 边缘 `AI`等路线,仅提及),最终生成原生机器码。`Viper` 不是 `Python` 的超集或子集,也不是"`C` 的语法糖"——它是一门拥有独立类型系统、独立编译模型、独立模块体系的语言。`Viper` 选择 `Python` 语法作为表达形式,是因为至少在作者角度认为,`ABC-LIKE` 的可读性比 `C-LIKE` 要高得多,作者想要证明 `ABC-LIKE` 比 `C-LIKE` 更好,不过这是来自于作者很早期的不成熟想法。实际上,两者并没有实际可比性,二者语法均可以映射同一层的语义,其工程表达力不受语法家族限制。语法家族不决定你能表达什么,但决定你多容易表达。Viper 的赌注是:`ABC-LIKE` 的可读性与低样板收益,值得用工程手段(软关键字、自研前端、`LSP` 存根)去换取底层语义的落地能力。
当前编译器 `TransPyC`(用 Python 实现)早期使用 Python 标准库 `ast` 解析源文件,将精力集中在语义翻译而非词法/语法分析上。**自举已完成**:`TransPyV`(用 Viper 重写编译器自身)先由 TPC 编译出 `TransPyV.exe`,再由其自举编译自身(Phase A/B/C 已跑通),编译已脱离 Python 运行时——解析、类型检查、IR 生成均由原生机器码完成。解析器为 [includes/ast](../includes/ast) 的**完全自研词法/语法器**(词法器 + 语法器 + AST 构造,`AstTest` 综合测试通过),覆盖 CPython 几乎全部语法。详见 [13-bootstrapping.md](13-bootstrapping.md)。
当前编译器 `TransPyC`(用 Python 实现)早期使用 Python 标准库 `ast` 解析源文件,将精力集中在语义翻译而非词法/语法分析上。**自举已完成**:`ViperC`(用 Viper 重写编译器自身)先由 TPC 编译出 `viperc.exe`,再由其自举编译自身(Phase A/B/C 已跑通),编译已脱离 Python 运行时——解析、类型检查、IR 生成均由原生机器码完成。解析器为 [includes/ast](../includes/ast) 的**完全自研词法/语法器**(词法器 + 语法器 + AST 构造,`AstTest` 综合测试通过),覆盖 CPython 几乎全部语法。详见 [13-bootstrapping.md](13-bootstrapping.md)。
而实际上,下文中所有提到的 `C` 语言都是为了便于使用 `C` 的底层开发者理解。由于历史原因,在旧版本中我们使用 `C` 来作为中间语言,如同旧版本的 `C++` 一样,但现在 `target="c"` 的路径已经完全删除,`C` 路径永久不再受维护。
> **成熟度与当前任务(重要)**:Viper 的**语法在最新版本已经相当稳定**,对**现实工程已经可用**——[17-flagship-project.md](17-flagship-project.md) 中的 TransPyV(自举编译器)、ViperOS(裸机操作系统)、ViperMNIST(深度学习)等都是实证。因此当前的主要工作**不是**继续改动语法,而是**更正内部的存量代码**:把历史遗留的旧写法(`t.C*` / `c.*` / `T | t.CPtr` 等)迁移到新语法,详见 [02-type-system.md 类型书写规范](02-type-system.md#类型书写规范新语法推荐) 与仓库根目录的 `新规范`。
> **成熟度与当前任务(重要)**:Viper 的**语法在最新版本已经相当稳定**,对**现实工程已经可用**——[17-flagship-project.md](17-flagship-project.md) 中的 ViperC(自举编译器)、ViperOS(裸机操作系统)、ViperMNIST(深度学习)等都是实证。因此当前的主要工作**不是**继续改动语法,而是**更正内部的存量代码**:把历史遗留的旧写法(`t.C*` / `c.*` / `T | t.CPtr` 等)迁移到新语法,详见 [02-type-system.md 类型书写规范](02-type-system.md#类型书写规范新语法推荐) 与仓库根目录的 `新规范`。
>
> **Viper 的前身是一个玩具项目**(把 Python 转成 C),**但我们期望 Viper 不再是**:它拥有独立的类型系统、两阶段编译模型、`SHA1` 命名空间模块体系与自举编译器,目标是成为一门可用于真实系统开发的编程语言。
@@ -56,7 +56,7 @@ Viper 的语法形态以 `Python`(ABC 系)为蓝本,但自研语法器 [in
## 两阶段编译流程
Viper 的编译由入口驱动(TPC:`Projectrans.py`;TPV:`App/main.vp`),分为两个阶段。这是 Viper 编译模型的核心,理解两阶段编译是理解 `t.CDefine`、`t.CExport`、`t.CInline` 等关键概念的前提。
Viper 的编译由入口驱动(TPC:`Projectrans.py`;VPC:`App/main.vp`),分为两个阶段。这是 Viper 编译模型的核心,理解两阶段编译是理解 `t.CDefine`、`t.CExport`、`t.CInline` 等关键概念的前提。
```
源文件 (.vp) ──────────────────────────────────────────────────────
@@ -90,7 +90,7 @@ Viper 的编译由入口驱动(TPC:`Projectrans.py`;TPV:`App/main.vp`)
#### 步骤 1:可达文件发现与拓扑排序
从工程根出发,通过 `import` 语句递归遍历,找出所有可达的 `.vp` 源文件,再对文件进行拓扑排序,确保被依赖的模块先被处理。工程根由工程配置的 `source_dir` 指定(`TransPyV` 与 `TransPyV/Test` 用 `project.vpj`,`Test/*` 用同格式的 `project.json`);也可用 `--src <入口文件>`,此时构建配置由依赖闭包内的 `viperbuild` 提供(见 [12-compilation-system.md](12-compilation-system.md))。**不存在「只编一个文件」的单文件模式。**
从工程根出发,通过 `import` 语句递归遍历,找出所有可达的 `.vp` 源文件,再对文件进行拓扑排序,确保被依赖的模块先被处理。工程根由工程配置的 `source_dir` 指定(`ViperC` 与 `ViperC/Test` 用 `project.vpj`,`Test/*` 用同格式的 `project.json`);也可用 `--src <入口文件>`,此时构建配置由依赖闭包内的 `viperbuild` 提供(见 [12-compilation-system.md](12-compilation-system.md))。**不存在「只编一个文件」的单文件模式。**
```
main.vp → import serial → import drivers.serial.uart.serial → ...
@@ -113,7 +113,7 @@ sha1 = hashlib.sha1(content.encode('utf-8')).hexdigest()[:16]
| 宏函数(`define F(...)`,或返回 `t.CDefine`) | 保留完整函数体(宏展开需要) |
| 普通函数 | 仅保留签名:`def foo(x: int) -> void: pass` |
| 类 / `struct` 定义 | 保留成员类型注解和方法签名 |
| 全局变量 | TPC 一代 `PythonToStubConverter` 会添加 `t.CExtern`(`extern x: int` 的旧标记形态);TPV 自研 `StubGen`/`Converter.vp` 不再添加——跨模块 `external declare` 由 `VpiReader` 依 vpi 全局自动注入 |
| 全局变量 | TPC 一代 `PythonToStubConverter` 会添加 `t.CExtern`(`extern x: int` 的旧标记形态);VPC 自研 `StubGen`/`Converter.vp` 不再添加——跨模块 `external declare` 由 `VpiReader` 依 vpi 全局自动注入 |
| `cif` / `celif` / `celse` 条件编译块(含 `defined(NAME)` 谓词) | 保留原样(旧的 `c.CIfdef` 等已删除) |
| `import` 语句 | 保留原样 |
@@ -167,11 +167,11 @@ sha1 = hashlib.sha1(content.encode('utf-8')).hexdigest()[:16]
扫描 `includes/` 目录中被引用的模块,收集标记为内联的函数(旧标记 `t.CInline`)。内联函数的完整 AST body 被保存,在翻译调用点时直接展开。值得注意的是,和 C 语言不同,这种前端内联不是优化建议,而是强制性的。
> 注:上述 `_collect_inline_symbols` 预收集机制属 TPC Python 侧实现;TransPyV 无对应实现——`t.CInline` 仅作为存储类标记,实际内联经 `@c.Attribute(t.attr.always_inline())`。
> 注:上述 `_collect_inline_symbols` 预收集机制属 TPC Python 侧实现;ViperC 无对应实现——`t.CInline` 仅作为存储类标记,实际内联经 `@c.Attribute(t.attr.always_inline())`。
#### 步骤 4:翻译源文件
对每个源文件,使用对应翻译器(TPC `TransPyC` / TPV `lib/core/Gen`)将 AST 翻译为 LLVM IR:
对每个源文件,使用对应翻译器(TPC `TransPyC` / VPC `lib/core/Gen`)将 AST 翻译为 LLVM IR:
1. 将对应模块的 `.stub.ll` 声明嵌入到生成的 `.ll` 文件头部
2. 所有被引用模块的 `.stub.ll` 声明也被嵌入
3. 翻译 AST 节点为 LLVM IR 指令
@@ -180,7 +180,7 @@ sha1 = hashlib.sha1(content.encode('utf-8')).hexdigest()[:16]
#### 步骤 5:编译与链接
- `llc`:将每个 `.ll` 编译为 `.o` 目标文件
- 链接:将所有 `.o` 链接为最终可执行文件。链接器由工程配置 `linker.cmd` 决定——TransPyV 宿主工程为 `clang++`;`ld.lld`/`x86_64-none-elf` 用于 ViperOS 内核工程
- 链接:将所有 `.o` 链接为最终可执行文件。链接器由工程配置 `linker.cmd` 决定——ViperC 宿主工程为 `clang++`;`ld.lld`/`x86_64-none-elf` 用于 ViperOS 内核工程
## SHA1 命名空间机制
@@ -406,13 +406,13 @@ Viper **原本的语法完全符合 CPython**——源文件是合法的 Python
| 项目 | 说明 |
|------|------|
| **Vipeye** | 基于 **pyright** 的 VSCode **Viper LSP** 分析插件(外部项目,本工作区不含其源码) |
| [VET](../VET) | Viper Environment Tool:校验产物确由 TransPyV 工具链生成,并常驻扫盘发现 Viper 产物 |
| [VET](../VET) | Viper Environment Tool:校验产物确由 ViperC 工具链生成,并常驻扫盘发现 Viper 产物 |
| [Venom](../Venom) | Windows 桌面应用最小模板(UTF-8 控制台 + Hello World → `app.exe`) |
| [ViperTemplateProject](../ViperTemplateProject) | 同上定位的 Windows 桌面应用模板 |
| [ViperApps](../ViperApps) | 示例应用集(Qt6 / MNIST / FLTK / Requests / OpenSSL / [ViperOS](../ViperApps/ViperOS) 等) |
| [Test](../Test) | TPC 测试工程集(68 个,`project.json`);[TransPyV/Test](../TransPyV/Test) 为 TPV 自测套件 |
| [Test](../Test) | TPC 测试工程集(68 个,`project.json`);[ViperC/Test](../ViperC/Test) 为 VPC 自测套件 |
| [TransPyC](../TransPyC) | 第一代编译器(CPython 实现,自举**种子**) |
| [TransPyV](../TransPyV) | 第二代编译器(Viper 自举,**现行编译器**) |
| [ViperC](../ViperC) | 第二代编译器(Viper 自举,**现行编译器**) |
| [Tools](../Tools) | 辅助脚本;`sendaiandsplit.py` 可合并/分割源码,`ai` 模式产出带**弱时效性**声明的 AI 快照 |
| [wiki](../wiki) | 本文档;`MergeWiki.py` 可把全部章节合并成 AI 快照 |
@@ -420,7 +420,7 @@ Viper **原本的语法完全符合 CPython**——源文件是合法的 Python
- 交互式 REPL(`--repl`)见 [15-repl.md](15-repl.md);
- 栈回溯与调试信息(`--traceback` / DWARF)见 [16-traceback.md](16-traceback.md);
- 用 Viper 写成的旗舰工程(TransPyV / VET / ViperOS / ViperMNIST)见 [17-flagship-project.md](17-flagship-project.md)。
- 用 Viper 写成的旗舰工程(ViperC / VET / ViperOS / ViperMNIST)见 [17-flagship-project.md](17-flagship-project.md)。
## Hello World 示例(标准写法)