补充
This commit is contained in:
190
wiki/05-classes.md
Normal file
190
wiki/05-classes.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# 05 - 类与数据布局
|
||||
|
||||
Viper 中的 `class` 有两种用途:定义**数据布局**(结构体/联合体/枚举,本章内容),以及定义**面向对象的对象类型**(见 [06-oop.md](06-oop.md))。
|
||||
|
||||
## 结构体定义
|
||||
|
||||
普通 `class` 定义编译为 LLVM 结构体类型:
|
||||
|
||||
```python
|
||||
class point:
|
||||
x: t.CInt
|
||||
y: t.CInt
|
||||
```
|
||||
|
||||
在 C 中:
|
||||
```c
|
||||
struct point {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
```
|
||||
|
||||
在 LLVM IR 中:
|
||||
```llvm
|
||||
%"<SHA1>.point" = type { i32, i32 }
|
||||
```
|
||||
|
||||
### 带属性的结构体
|
||||
|
||||
```python
|
||||
@c.Attribute(t.attr.packed)
|
||||
class idt_entry:
|
||||
base_low: t.CUInt16T
|
||||
selector: t.CUInt16T
|
||||
ist_attr: t.CUInt8T
|
||||
type_attr: t.CUInt8T
|
||||
base_middle: t.CUInt16T
|
||||
base_high: t.CUInt32T
|
||||
reserved1: t.CUInt32T
|
||||
```
|
||||
|
||||
### 结构体数组
|
||||
|
||||
```python
|
||||
idt: list[idt_entry, 256] = []
|
||||
```
|
||||
|
||||
### 结构体指针成员
|
||||
|
||||
```python
|
||||
class node:
|
||||
value: t.CInt
|
||||
next: node | t.CPtr # 指向自身的指针(有向图链表)
|
||||
```
|
||||
|
||||
### 结构体实例化与初始化
|
||||
|
||||
```python
|
||||
entry: idt_entry = idt_entry()
|
||||
```
|
||||
|
||||
或带构造函数:
|
||||
|
||||
```python
|
||||
mousepoint = Point(x=1, y=2)
|
||||
```
|
||||
|
||||
乱序传参或带参传参对于结构体的初始化同样有效:
|
||||
|
||||
```python
|
||||
entry: idt_entry = idt_entry(selector=0x08, base_low=0x0000)
|
||||
```
|
||||
|
||||
也可以给结构体成员指定默认值:
|
||||
|
||||
```python
|
||||
class config:
|
||||
width: t.CInt = 640
|
||||
height: t.CInt = 480
|
||||
depth: t.CInt = 32
|
||||
```
|
||||
|
||||
使用 `c.Addr` 获取实例指针:
|
||||
|
||||
```python
|
||||
obj_ptr: MyClass | t.CPtr = c.Addr(MyClass(arg1, arg2))
|
||||
```
|
||||
|
||||
### 匿名结构体成员(❌)
|
||||
|
||||
> WARNING: **警告:** 由于 Viper 在声明结构体,枚举等处不需要关键字,因此 `t.Anonymouse` 是不需要使用的。此关键字不再维护,强行使用可能导致未定义行为。
|
||||
|
||||
继承 `t.Anonymous` 的类作为匿名成员嵌入:
|
||||
|
||||
```python
|
||||
class header(t.Anonymous):
|
||||
magic: t.CUInt32T
|
||||
version: t.CUInt32T
|
||||
|
||||
class packet:
|
||||
header # 匿名嵌入,可直接访问 packet.magic
|
||||
length: t.CUInt32T
|
||||
```
|
||||
|
||||
### 字节序标记
|
||||
|
||||
> WARNING: **警告:** 此关键字是实验性的。未经充分测试,不当使用可能导致未定义行为。
|
||||
|
||||
使用 `t.BigEndian` 或 `t.LittleEndian` 标记成员的字节序:
|
||||
|
||||
```python
|
||||
class network_packet:
|
||||
length: t.CUInt16T | t.BigEndian # 大端序存储
|
||||
type: t.CUInt8T # 默认小端序
|
||||
```
|
||||
|
||||
## 联合体
|
||||
|
||||
继承 `t.CUnion` 定义联合体:
|
||||
|
||||
```python
|
||||
class value(t.CUnion):
|
||||
ival: t.CInt
|
||||
fval: t.CFloat
|
||||
pval: t.CVoid | t.CPtr
|
||||
```
|
||||
|
||||
等价 C 代码:
|
||||
```c
|
||||
union value {
|
||||
int ival;
|
||||
float fval;
|
||||
void* pval;
|
||||
};
|
||||
```
|
||||
|
||||
## 枚举
|
||||
|
||||
继承 `t.CEnum` 定义枚举:
|
||||
|
||||
```python
|
||||
class color(t.CEnum):
|
||||
RED: t.CEnum = 0
|
||||
GREEN: t.CEnum = 1
|
||||
BLUE: t.CEnum = 2
|
||||
```
|
||||
|
||||
等价 C 代码:
|
||||
```c
|
||||
enum color {
|
||||
RED = 0,
|
||||
GREEN = 1,
|
||||
BLUE = 2
|
||||
};
|
||||
```
|
||||
|
||||
枚举成员可直接使用名称:
|
||||
|
||||
```python
|
||||
c: t.CInt = color.RED
|
||||
```
|
||||
|
||||
## Typedef
|
||||
|
||||
使用 `t.CTypedef` 创建类型别名:
|
||||
|
||||
```python
|
||||
irq_handler_t: t.CTypedef | t.Callable[[], t.CInt] # typedef int (*irq_handler_t)();
|
||||
```
|
||||
|
||||
或通过注解赋值:
|
||||
|
||||
```python
|
||||
MyStruct: t.CTypedef = original_struct # typedef struct original_struct MyStruct;
|
||||
```
|
||||
|
||||
更推荐通过后者的形式,前者编译器不一定能够识别到注解是对 `t.CTypedef` 的,还是后面的注解的,而且容易触发未定义行为。
|
||||
|
||||
## 位域
|
||||
|
||||
使用 `t.Bit(n)` 定义位域成员:
|
||||
|
||||
```python
|
||||
class flags:
|
||||
a: t.CUInt32T | t.Bit[1]
|
||||
b: t.CUInt32T | t.Bit[3]
|
||||
c: t.CUInt32T | t.Bit[4]
|
||||
```
|
||||
|
||||
注意:如果存入超出位域宽度的值,会被截断。例如 `a` 为 1 位,存入 2(二进制 `10`)会被截断为 0。
|
||||
Reference in New Issue
Block a user