取消了 i8* == i8* 实际使用 strcmp 的规则
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
|
||||
1. **Python 语法,LLVM 语义**:源文件是完全合法的 `Python` 语法,但通过 `t` 模块的类型注解系统赋予完全不同的语义 —— `t.CInt` 不是 `Python` 的 `int`,而是 `LLVM` 的 `i32`
|
||||
2. **类型注解即编译指令**:Viper 的类型注解不是可选的提示,而是编译器生成 `LLVM IR` 的决定性依据。`x: t.CInt` 生成 `i32`,`x: t.CInt | t.CPtr` 生成 `i32*`,但无注解时会自动推导,详见下文。
|
||||
3. **两阶段编译**:先从源文件提取声明接口(`.pyi` + `.stub.ll`),再使用声明接口翻译源文件为含代码的 `.ll`。这是 `Viper` 区别于简单"`Python` 转 `C`"工具的关键架构
|
||||
3. **两阶段编译**:先从源文件提取声明接口(`.vpi` + `.stub.ll`),再使用声明接口翻译源文件为含代码的 `.ll`。这是 `Viper` 区别于简单"`Python` 转 `C`"工具的关键架构
|
||||
4. **`SHA1` 命名空间**:每个源文件按内容 `SHA1` 哈希命名,非导出函数和结构体自动加上 `SHA1` 前缀,从根本上消除跨模块的符号冲突
|
||||
5. **万物皆数据**:为便于底层开发,实际上所有的变量和类型一般并不适用于鸭子类型,但在语义层面我们会尽可能贴近鸭子类型。
|
||||
|
||||
@@ -37,7 +37,7 @@ Viper 编译后的代码在底层等价于 `C` 编译后的机器码(都经过
|
||||
- **声明式内联汇编**:`c.Asm(f"mov {c.AsmOut(x, t.ASM_DESCR.OUTPUT_REG)}, rdi")` 比裸 `__asm__` 更安全,也更具可读性。
|
||||
- **结构化预处理**:`c.CIfdef`/`c.CEndif()` 替代 `#ifdef`/`#endif`。
|
||||
- **面向对象**:`@t.Object` + `@t.CVTable` 提供 `vtable` 支持的多态 `OOP`;`@t.NoVTable` 提供 C++ 风格的非多态继承(零 vtable 开销);PEP 695 泛型 + 递归泛型继承实现强类型自引用结构
|
||||
- **存根驱动的模块系统**:`.pyi` 存根文件实现跨模块类型解析,无需头文件
|
||||
- **存根驱动的模块系统**:`.vpi` 存根文件实现跨模块类型解析,无需头文件
|
||||
- **更多内容**:额外更多的不依赖操作系统的函数和语法
|
||||
|
||||
## 两阶段编译流程
|
||||
@@ -45,12 +45,12 @@ Viper 编译后的代码在底层等价于 `C` 编译后的机器码(都经过
|
||||
Viper 的编译由 `Projectrans.py` 驱动,分为两个阶段。这是 Viper 编译模型的核心,理解两阶段编译是理解 `t.CDefine`、`t.CExport`、`t.CInline` 等关键概念的前提。
|
||||
|
||||
```
|
||||
源文件 (.py) ──────────────────────────────────────────────────────
|
||||
源文件 (.vp) ──────────────────────────────────────────────────────
|
||||
│ │
|
||||
│ ┌─────────────── 阶段一:声明提取 ───────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ 1. 计算源文件 SHA1 │ │
|
||||
│ │ 2. 生成 <SHA1>.pyi(签名存根) │ │
|
||||
│ │ 2. 生成 <SHA1>.vpi(签名存根) │ │
|
||||
│ │ 3. 构建结构体注册表 │ │
|
||||
│ │ 4. 生成 <SHA1>.stub.ll(LLVM IR 声明) │ │
|
||||
│ │ │ │
|
||||
@@ -58,7 +58,7 @@ Viper 的编译由 `Projectrans.py` 驱动,分为两个阶段。这是 Viper
|
||||
│ │
|
||||
│ ┌─────────────── 阶段二:代码翻译 ───────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ 1. 加载所有 .pyi 和 .stub.ll │ │
|
||||
│ │ 1. 加载所有 .vpi 和 .stub.ll │ │
|
||||
│ │ 2. 构建共享符号表 │ │
|
||||
│ │ 3. 收集内联函数符号 │ │
|
||||
│ │ 4. 翻译源文件 → <SHA1>.ll(含代码) │ │
|
||||
@@ -76,15 +76,15 @@ Viper 的编译由 `Projectrans.py` 驱动,分为两个阶段。这是 Viper
|
||||
|
||||
#### 步骤 1:可达文件发现与拓扑排序
|
||||
|
||||
从入口文件(`main.py` 或 `project.json` 指定)出发,通过 `import` 语句递归遍历,找出所有可达的 `.py` 源文件。然后对文件进行拓扑排序,确保被依赖的模块先被处理。
|
||||
从入口文件(`main.vp` 或 `project.json` 指定)出发,通过 `import` 语句递归遍历,找出所有可达的 `.vp` 源文件。然后对文件进行拓扑排序,确保被依赖的模块先被处理。
|
||||
|
||||
```
|
||||
main.py → import serial → import drivers.serial.uart.serial → ...
|
||||
main.vp → import serial → import drivers.serial.uart.serial → ...
|
||||
```
|
||||
|
||||
#### 步骤 2:生成 `.pyi` 签名存根
|
||||
#### 步骤 2:生成 `.vpi` 签名存根
|
||||
|
||||
对每个源文件,计算其内容的 SHA1 哈希(16位),然后调用 `PythonToStubConverter` 生成签名存根文件 `<SHA1>.pyi`。
|
||||
对每个源文件,计算其内容的 SHA1 哈希(16位),然后调用 `PythonToStubConverter` 生成签名存根文件 `<SHA1>.vpi`。
|
||||
|
||||
**SHA1 计算方式**:
|
||||
```python
|
||||
@@ -108,7 +108,7 @@ sha1 = hashlib.sha1(content.encode('utf-8')).hexdigest()[:16]
|
||||
|
||||
#### 步骤 3:构建结构体注册表
|
||||
|
||||
扫描所有已生成的 `.pyi` 文件,提取:
|
||||
扫描所有已生成的 `.vpi` 文件,提取:
|
||||
- **结构体名称集合**:所有非枚举、非异常的 `class` 定义
|
||||
- **枚举名称集合**:继承 `t.CEnum` 的类
|
||||
- **异常名称集合**:继承 `Exception` 的类
|
||||
@@ -118,7 +118,7 @@ sha1 = hashlib.sha1(content.encode('utf-8')).hexdigest()[:16]
|
||||
|
||||
#### 步骤 4:生成 `.stub.ll` LLVM IR 声明
|
||||
|
||||
对每个 `.pyi` 文件,由 `DeclarationGenerator` 生成对应的 LLVM IR 声明文件 `<SHA1>.stub.ll`。
|
||||
对每个 `.vpi` 文件,由 `DeclarationGenerator` 生成对应的 LLVM IR 声明文件 `<SHA1>.stub.ll`。
|
||||
|
||||
**声明生成规则**:
|
||||
|
||||
@@ -132,7 +132,7 @@ sha1 = hashlib.sha1(content.encode('utf-8')).hexdigest()[:16]
|
||||
| `t.CTypedef` 别名 | **不生成声明**(类型别名,在类型解析时展开) |
|
||||
| 枚举 | 为每个枚举成员生成 `@__config_EnumName_member = external global i32` |
|
||||
|
||||
**增量编译**:如果 `<SHA1>.pyi` 或 `<SHA1>.stub.ll` 已存在,则跳过生成(缓存命中)。只有源文件内容变化导致 SHA1 变化时才重新生成。
|
||||
**增量编译**:如果 `<SHA1>.vpi` 或 `<SHA1>.stub.ll` 已存在,则跳过生成(缓存命中)。只有源文件内容变化导致 SHA1 变化时才重新生成。
|
||||
|
||||
### 阶段二:代码翻译(Phase2Translator)
|
||||
|
||||
@@ -140,14 +140,14 @@ sha1 = hashlib.sha1(content.encode('utf-8')).hexdigest()[:16]
|
||||
|
||||
#### 步骤 1:加载声明接口
|
||||
|
||||
加载 `temp/` 目录中所有的 `.pyi` 和 `.stub.ll` 文件,构建:
|
||||
- `sig_files`:SHA1 → `.pyi` 文件路径映射
|
||||
加载 `temp/` 目录中所有的 `.vpi` 和 `.stub.ll` 文件,构建:
|
||||
- `sig_files`:SHA1 → `.vpi` 文件路径映射
|
||||
- `stub_files`:SHA1 → `.stub.ll` 文件路径映射
|
||||
- `sha1_map`:SHA1 → 源文件相对路径映射
|
||||
|
||||
#### 步骤 2:构建共享符号表
|
||||
|
||||
一次性构建所有文件共享的符号表数据,避免每个文件重复加载。将所有 `.pyi` 存根和 `.stub.ll` 声明中的类型信息注册到统一的 `SymbolTable` 中。
|
||||
一次性构建所有文件共享的符号表数据,避免每个文件重复加载。将所有 `.vpi` 存根和 `.stub.ll` 声明中的类型信息注册到统一的 `SymbolTable` 中。
|
||||
|
||||
#### 步骤 3:收集内联函数符号
|
||||
|
||||
@@ -179,20 +179,20 @@ SHA1 命名空间是 Viper 解决跨模块符号冲突的核心机制。
|
||||
Viper 使用源文件内容的 SHA1 哈希作为命名空间前缀:
|
||||
|
||||
```
|
||||
源文件 A.py(SHA1 = a1b2c3d4e5f6g7h8)中定义:
|
||||
源文件 A.vp(SHA1 = a1b2c3d4e5f6g7h8)中定义:
|
||||
class Point: x: t.CInt; y: t.CInt
|
||||
def draw(p: Point) -> t.CVoid: ...
|
||||
|
||||
源文件 B.py(SHA1 = i9j0k1l2m3n4o5p6)中也定义:
|
||||
源文件 B.vp(SHA1 = i9j0k1l2m3n4o5p6)中也定义:
|
||||
class Point: x: t.CFloat; y: t.CFloat # 不同的结构体!
|
||||
def draw(p: Point) -> t.CVoid: ...
|
||||
|
||||
编译后:
|
||||
A.py 的结构体 → %"a1b2c3d4e5f6g7h8.Point" = type { i32, i32 }
|
||||
A.py 的函数 → declare void @"a1b2c3d4e5f6g7h8.draw"(%"a1b2c3d4e5f6g7h8.Point"*)
|
||||
A.vp 的结构体 → %"a1b2c3d4e5f6g7h8.Point" = type { i32, i32 }
|
||||
A.vp 的函数 → declare void @"a1b2c3d4e5f6g7h8.draw"(%"a1b2c3d4e5f6g7h8.Point"*)
|
||||
|
||||
B.py 的结构体 → %"i9j0k1l2m3n4o5p6.Point" = type { float, float }
|
||||
B.py 的函数 → declare void @"i9j0k1l2m3n4o5p6.draw"(%"i9j0k1l2m3n4o5p6.Point"*)
|
||||
B.vp 的结构体 → %"i9j0k1l2m3n4o5p6.Point" = type { float, float }
|
||||
B.vp 的函数 → declare void @"i9j0k1l2m3n4o5p6.draw"(%"i9j0k1l2m3n4o5p6.Point"*)
|
||||
```
|
||||
|
||||
**没有符号冲突**——即使两个模块定义了同名类型和函数,它们的 LLVM IR 符号也是不同的。即便有两个内容完全相同的文件也不会冲突,他们会被识别为同一个文件,然后进行单次编译。
|
||||
@@ -202,7 +202,7 @@ Viper 使用源文件内容的 SHA1 哈希作为命名空间前缀:
|
||||
标记为 `t.CExport` 的函数**不加 SHA1 前缀**,保持原始函数名。这是模块向外部暴露 API/ABI 的机制:
|
||||
|
||||
```python
|
||||
# main.py — 入口函数,必须全局可见
|
||||
# main.vp — 入口函数,必须全局可见
|
||||
def main() -> t.CInt | t.CExport:
|
||||
return 0
|
||||
|
||||
@@ -210,7 +210,7 @@ def main() -> t.CInt | t.CExport:
|
||||
```
|
||||
|
||||
```python
|
||||
# serial.py — 驱动接口,对外暴露
|
||||
# serial.vp — 驱动接口,对外暴露
|
||||
def init() -> t.CVoid | t.CExport:
|
||||
serial_puts("init\n")
|
||||
|
||||
@@ -220,7 +220,7 @@ def init() -> t.CVoid | t.CExport:
|
||||
### SHA1 与增量编译
|
||||
|
||||
SHA1 同时服务于增量编译:
|
||||
- 源文件内容不变 → SHA1 不变 → `.pyi` 和 `.stub.ll` 缓存命中,跳过阶段一
|
||||
- 源文件内容不变 → SHA1 不变 → `.vpi` 和 `.stub.ll` 缓存命中,跳过阶段一
|
||||
- 源文件内容变化 → SHA1 变化 → 重新生成声明接口
|
||||
- `temp/_sha1_map.txt` 记录 SHA1 → 源文件路径的映射,供阶段二加载
|
||||
|
||||
@@ -305,7 +305,7 @@ def _helper() -> t.CInt:
|
||||
|
||||
### `t.CExport` 在存根中的表现
|
||||
|
||||
在 `.pyi` 存根文件中,`t.CExport` 函数与普通函数一样只保留签名(添加 `c.State`,表示单纯声明),但 `t.CExport` 标记被保留在返回类型注解中。阶段一的 `DeclarationGenerator` 检查 `t.CExport` 标记来决定是否添加 SHA1 前缀。
|
||||
在 `.vpi` 存根文件中,`t.CExport` 函数与普通函数一样只保留签名(添加 `c.State`,表示单纯声明),但 `t.CExport` 标记被保留在返回类型注解中。阶段一的 `DeclarationGenerator` 检查 `t.CExport` 标记来决定是否添加 SHA1 前缀。
|
||||
|
||||
## `t.CInline` 深度解析
|
||||
|
||||
@@ -351,7 +351,7 @@ def main() -> t.CInt | t.CExport:
|
||||
|
||||
编译流程:
|
||||
|
||||
1. **阶段一**:计算 `main.py` 的 SHA1,生成 `.pyi` 存根(`def main() -> t.CInt | t.CExport | c.State: pass`),生成 `.stub.ll` 声明(`declare i32 @main()`,因为是 CExport 不加前缀)
|
||||
2. **阶段二**:翻译 `main.py` 为 `<SHA1>.ll`,嵌入 `print` 对应的 `puts`/`printf` 声明,生成 `define i32 @main()` 函数体
|
||||
1. **阶段一**:计算 `main.vp` 的 SHA1,生成 `.vpi` 存根(`def main() -> t.CInt | t.CExport | c.State: pass`),生成 `.stub.ll` 声明(`declare i32 @main()`,因为是 CExport 不加前缀)
|
||||
2. **阶段二**:翻译 `main.vp` 为 `<SHA1>.ll`,嵌入 `print` 对应的 `puts`/`printf` 声明,生成 `define i32 @main()` 函数体
|
||||
3. **编译**:`llc` 将 `.ll` 编译为 `.o`
|
||||
4. **链接**:`ld.lld` 链接为可执行文件
|
||||
|
||||
@@ -200,7 +200,7 @@ match ty:
|
||||
string.strcpy(buf, "void")
|
||||
```
|
||||
|
||||
详见 [includes/llvmlite/__types.py](../includes/llvmlite/__types.py) 的 `LLVMType` 实现。
|
||||
详见 [includes/llvmlite/__types.vp](../includes/llvmlite/__types.vp) 的 `LLVMType` 实现。
|
||||
|
||||
## Typedef
|
||||
|
||||
@@ -258,7 +258,7 @@ node: GNode | t.CPtr = GNode()
|
||||
lst.append(node) # 类型安全:append 只接受 GNode
|
||||
```
|
||||
|
||||
详见 [includes/linkedlist.py](../includes/linkedlist.py) 和 [includes/vector.py](../includes/vector.py)。
|
||||
详见 [includes/linkedlist.vp](../includes/linkedlist.vp) 和 [includes/vector.vp](../includes/vector.vp)。
|
||||
|
||||
## 位域
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ func: Function | t.CPtr = mod_core.CreateFunction(mod, "main", ret_ty)
|
||||
|
||||
### `linkedlist` 模块(NoVTable + PEP 695 泛型示范)
|
||||
|
||||
[includes/linkedlist](../includes/linkedlist.py) 提供链表实现,是 `@t.NoVTable` 非多态继承和 PEP 695 递归泛型继承的典范用例:
|
||||
[includes/linkedlist](../includes/linkedlist.vp) 提供链表实现,是 `@t.NoVTable` 非多态继承和 PEP 695 递归泛型继承的典范用例:
|
||||
|
||||
```python
|
||||
from linkedlist import LinkedNode, GSList
|
||||
@@ -193,14 +193,14 @@ handle: HANDLE = CreateFileA("test.txt", GENERIC_READ, FILE_SHARE_READ,
|
||||
Viper 的 `import` 是编译时操作,不涉及运行时模块加载。完整的模块解析流程与两阶段编译紧密耦合:
|
||||
|
||||
1. **阶段一**:从入口文件出发,通过 `import` 语句递归发现所有可达的源文件
|
||||
2. **阶段一**:对每个源文件生成 `<SHA1>.pyi` 签名存根和 `<SHA1>.stub.ll` LLVM IR 声明
|
||||
3. **阶段二**:加载所有 `.pyi` 和 `.stub.ll`,构建共享符号表
|
||||
2. **阶段一**:对每个源文件生成 `<SHA1>.vpi` 签名存根和 `<SHA1>.stub.ll` LLVM IR 声明
|
||||
3. **阶段二**:加载所有 `.vpi` 和 `.stub.ll`,构建共享符号表
|
||||
4. **阶段二**:翻译源文件时,通过符号表解析跨模块的类型和函数引用
|
||||
5. **阶段二**:将被引用模块的 `.stub.ll` 声明嵌入到生成的 `.ll` 文件头部
|
||||
|
||||
### 类型存根文件(.pyi)
|
||||
### 类型存根文件(.vpi)
|
||||
|
||||
`.pyi` 文件是模块的声明接口,由 `PythonToStubConverter` 在阶段一生成。存根文件的内容规则:
|
||||
`.vpi` 文件是模块的声明接口,由 `PythonToStubConverter` 在阶段一生成。存根文件的内容规则:
|
||||
|
||||
| 元素 | 存根表示 |
|
||||
|------|---------|
|
||||
@@ -228,7 +228,7 @@ Viper 的 `import` 是编译时操作,不涉及运行时模块加载。完整
|
||||
### 跨模块类型引用
|
||||
|
||||
```python
|
||||
# 在 fat32_types.py 中定义
|
||||
# 在 fat32_types.vp 中定义
|
||||
class fat32_fileinfo:
|
||||
fname: list[t.CChar, 13]
|
||||
attr: t.CUInt8T
|
||||
|
||||
@@ -47,7 +47,7 @@ Viper 项目使用 `project.json` 配置文件管理编译和链接参数。
|
||||
| `name` | string | 项目名称 |
|
||||
| `version` | string | 项目版本 |
|
||||
| `source_dir` | string | 源代码目录(相对于 project.json 所在目录) |
|
||||
| `temp_dir` | string | 临时文件目录(存放 .pyi 存根等) |
|
||||
| `temp_dir` | string | 临时文件目录(存放 .vpi 存根等) |
|
||||
| `output_dir` | string | 输出文件目录 |
|
||||
|
||||
### 编译器配置
|
||||
@@ -122,12 +122,12 @@ VKernel/
|
||||
├── project.json # 项目配置
|
||||
├── linker.ld # 链接脚本
|
||||
├── Kernel/ # 源代码目录
|
||||
│ ├── main.py # 内核入口
|
||||
│ ├── bootinfo.py
|
||||
│ ├── main.vp # 内核入口
|
||||
│ ├── bootinfo.vp
|
||||
│ ├── intr/
|
||||
│ │ ├── gdt.py
|
||||
│ │ ├── idt.py
|
||||
│ │ └── syscall.py
|
||||
│ │ ├── gdt.vp
|
||||
│ │ ├── idt.vp
|
||||
│ │ └── syscall.vp
|
||||
│ ├── drivers/
|
||||
│ │ ├── serial/
|
||||
│ │ ├── video/
|
||||
@@ -135,7 +135,7 @@ VKernel/
|
||||
│ │ └── ...
|
||||
│ └── ...
|
||||
├── temp/ # 临时文件(自动生成)
|
||||
│ ├── <SHA1>.pyi # 签名存根(阶段一生成)
|
||||
│ ├── <SHA1>.vpi # 签名存根(阶段一生成)
|
||||
│ ├── <SHA1>.stub.ll # LLVM IR 声明(阶段一生成)
|
||||
│ └── _sha1_map.txt # SHA1→源文件路径映射
|
||||
└── output/ # 输出文件(自动生成)
|
||||
@@ -150,7 +150,7 @@ VKernel/
|
||||
HelloWorld/
|
||||
├── project.json # 项目配置
|
||||
├── linker.ld # 链接脚本
|
||||
├── main.py # 应用入口
|
||||
├── main.vp # 应用入口
|
||||
├── temp/ # 临时文件
|
||||
└── output/ # 输出文件
|
||||
└── helloworld.elf # ELF 可执行文件
|
||||
@@ -162,7 +162,7 @@ HelloWorld/
|
||||
SerialLogger/
|
||||
├── project.json # 项目配置
|
||||
├── linker.ld # 链接脚本
|
||||
├── serial_logger.py # 库源码
|
||||
├── serial_logger.vp # 库源码
|
||||
├── temp/ # 临时文件
|
||||
└── output/ # 输出文件
|
||||
```
|
||||
@@ -233,14 +233,14 @@ TransPyC 支持基于 SHA1 的增量编译,与两阶段编译模型紧密耦
|
||||
### 阶段一增量
|
||||
|
||||
- 每个源文件按内容计算 SHA1 哈希(16位)
|
||||
- 如果 `<SHA1>.pyi` 和 `<SHA1>.stub.ll` 已存在,则跳过生成(缓存命中)
|
||||
- 如果 `<SHA1>.vpi` 和 `<SHA1>.stub.ll` 已存在,则跳过生成(缓存命中)
|
||||
- 只有源文件内容变化导致 SHA1 变化时才重新生成声明接口
|
||||
- `temp/_sha1_map.txt` 记录 SHA1 → 源文件路径的映射,格式为 `<sha1>:<relative_path>`
|
||||
|
||||
### 阶段二增量
|
||||
|
||||
- 阶段二加载 `temp/_sha1_map.txt` 重建 SHA1 映射
|
||||
- 过滤掉不在当前 SHA1 映射中的旧 `.pyi` 和 `.stub.ll` 文件
|
||||
- 过滤掉不在当前 SHA1 映射中的旧 `.vpi` 和 `.stub.ll` 文件
|
||||
- 共享符号表一次性构建,避免每个文件重复加载
|
||||
|
||||
### SHA1 命名空间与增量编译的协同
|
||||
|
||||
@@ -57,19 +57,19 @@
|
||||
|
||||
| 模块 | LOC | 说明 |
|
||||
|------|-----|------|
|
||||
| `includes/numpy/__init__.py` | 1,016 | ndarray n 维数组 |
|
||||
| `includes/numpy/__init__.vp` | 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 | 数学库 |
|
||||
| `includes/linkedlist.vp` | ~400 | 泛型链表(@t.NoVTable + PEP 695) |
|
||||
| `includes/vipermath.vp` | 450 | 数学库 |
|
||||
| ...(30+ 文件) | ... | mpool/mbuddy/string/stdio/json/w32 等 |
|
||||
| **includes 总计** | **~12,000** | |
|
||||
|
||||
### 2.4 全项目总计
|
||||
|
||||
```
|
||||
全项目 .py 总计:~48,000 LOC
|
||||
全项目总计:~48,000 LOC
|
||||
```
|
||||
|
||||
**自举相关核心数字:**
|
||||
@@ -87,10 +87,10 @@
|
||||
|
||||
| 文件 | LOC | 功能 |
|
||||
|------|-----|------|
|
||||
| `__tokens.py` | ~600 | TokenType/Keyword/TokOp 枚举 + 查找表 |
|
||||
| `__nodes.py` | ~1,400 | AST 胖节点 + ASTVType/ASTCtx/OpKind CEnum |
|
||||
| `__lexer.py` | ~800 | 词法分析器 |
|
||||
| `__parser.py` | 4,176(含表格) | 递归下降语法分析器 |
|
||||
| `__tokens.vp` | ~600 | TokenType/Keyword/TokOp 枚举 + 查找表 |
|
||||
| `__nodes.vp` | ~1,400 | AST 胖节点 + ASTVType/ASTCtx/OpKind CEnum |
|
||||
| `__lexer.vp` | ~800 | 词法分析器 |
|
||||
| `__parser.vp` | 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、切片、嵌套三元。
|
||||
|
||||
@@ -105,11 +105,11 @@
|
||||
|
||||
| 文件 | 功能 |
|
||||
|------|------|
|
||||
| `__types.py` | `LLVMType` REnum + 类型构造/打印 |
|
||||
| `__values.py` | Value/Constant/SSA 值表示 |
|
||||
| `__function.py` | Function + BasicBlock + 参数管理 |
|
||||
| `__module.py` | Module 容器 + 目标三元组 + 输出 .ll |
|
||||
| `__builder.py` | IRBuilder(指令发射 + SSA 命名) |
|
||||
| `__types.vp` | `LLVMType` REnum + 类型构造/打印 |
|
||||
| `__values.vp` | Value/Constant/SSA 值表示 |
|
||||
| `__function.vp` | Function + BasicBlock + 参数管理 |
|
||||
| `__module.vp` | Module 容器 + 目标三元组 + 输出 .ll |
|
||||
| `__builder.vp` | IRBuilder(指令发射 + SSA 命名) |
|
||||
|
||||
**设计要点**:
|
||||
- `LLVMType` 用 `t.REnum`(tagged union)—— 少变体、无通用字段、match 分派的理想场景
|
||||
@@ -117,7 +117,7 @@
|
||||
- IR 文本生成用 `viperlib.snprintf` 格式化,避免手写逐字符拼接
|
||||
- 对象分配用普通类 + `mpool`,不持有全局 `mbuddy`
|
||||
|
||||
**验证**:[TransPyV/App/main.py](../TransPyV/App/main.py) 10 个测试覆盖类型打印、值打印、build_add、if-else、模块打印、lli 实际执行。TransPyV 程序运行时自己生成合法 IR,被 `lli` 成功执行。
|
||||
**验证**:[TransPyV/App/main.vp](../TransPyV/App/main.vp) 10 个测试覆盖类型打印、值打印、build_add、if-else、模块打印、lli 实际执行。TransPyV 程序运行时自己生成合法 IR,被 `lli` 成功执行。
|
||||
|
||||
### 3.3 ✅ 基础设施库
|
||||
|
||||
@@ -125,9 +125,9 @@
|
||||
|
||||
| 库 | 自举中的作用 |
|
||||
|----|-------------|
|
||||
| `linkedlist.py` | AST 节点树、符号表链、IR 指令链的容器(`@t.NoVTable` + PEP 695 递归泛型继承) |
|
||||
| `mpool.py` / `mbuddy.py` | 编译器内存管理(替代 Python GC) |
|
||||
| `string.py` / `viperlib.py` | 字符串处理 + snprintf(替代 Python 字符串方法) |
|
||||
| `linkedlist.vp` | AST 节点树、符号表链、IR 指令链的容器(`@t.NoVTable` + PEP 695 递归泛型继承) |
|
||||
| `mpool.vp` / `mbuddy.vp` | 编译器内存管理(替代 Python GC) |
|
||||
| `string.vp` / `viperlib.vp` | 字符串处理 + snprintf(替代 Python 字符串方法) |
|
||||
| `w32/` | FFI 声明,自举后编译器调用 llc/clang/linker 的基础 |
|
||||
| `json/` | 符号表序列化(替代 pickle) |
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
| `copy.deepcopy` / `pickle` | ~10 | ✅ 是 | 已解决(`__getstate__/__setstate__`) |
|
||||
| `hasattr` 防御性检查 | ~1500 | ⚠️ 多数可消除 | 显式字段声明 + None 检查 |
|
||||
|
||||
**真实反射障碍约 200-500 处**,集中体现在 `CTypeInfo` 门面模式(FIELD_ROUTES 动态路由到 `_ts`/`_sm`)。重构方案:用 REnum + match 替换 `__getattr__` 路由,已在 `includes/llvmlite/__types.py` 验证此范式可行。
|
||||
**真实反射障碍约 200-500 处**,集中体现在 `CTypeInfo` 门面模式(FIELD_ROUTES 动态路由到 `_ts`/`_sm`)。重构方案:用 REnum + match 替换 `__getattr__` 路由,已在 `includes/llvmlite/__types.vp` 验证此范式可行。
|
||||
|
||||
### 4.4 Python 标准库依赖(原:严重)→ ⚠️ 部分已解决
|
||||
|
||||
@@ -204,9 +204,9 @@
|
||||
|
||||
以下能力已在 includes/ 库中验证,证明 TransPyC 能承载编译器复杂度:
|
||||
|
||||
- **复杂泛型容器**:`linkedlist.py` 的递归泛型继承 `class GNode(GSListNode[GNode])`(C/C++/Rust 均无法如此简洁表达)
|
||||
- **复杂泛型容器**:`linkedlist.vp` 的递归泛型继承 `class GNode(GSListNode[GNode])`(C/C++/Rust 均无法如此简洁表达)
|
||||
- **复杂算法**:`zlib/` 的完整 deflate/inflate/huffman(~1,900 LOC 生产级压缩)
|
||||
- **n 维数组**:`numpy/__init__.py` 的 ndarray + 运算符重载 + `__new__` 堆分配
|
||||
- **n 维数组**:`numpy/__init__.vp` 的 ndarray + 运算符重载 + `__new__` 堆分配
|
||||
- **平台 FFI**:`w32/` 的 Win32 API 绑定(file/memory/process/sync/console)
|
||||
- **LLVM IR 生成**:`llvmlite/` 的 REnum 类型系统 + IRBuilder + ModulePrint
|
||||
|
||||
|
||||
3555
wiki/all.md
3555
wiki/all.md
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user