snapshot before regression test
This commit is contained in:
177
wiki/03-variables.md
Normal file
177
wiki/03-variables.md
Normal file
@@ -0,0 +1,177 @@
|
||||
# 03 - 变量声明与赋值
|
||||
|
||||
Viper 的变量声明使用 Python 的类型注解语法,通过 `t` 模块指定 C 级别的类型信息。
|
||||
|
||||
## 带注解的变量声明
|
||||
|
||||
使用 `变量名: 类型` 语法声明变量:
|
||||
|
||||
```python
|
||||
x: t.CInt = 0 # int x = 0;
|
||||
y: t.CUInt32T = 42 # uint32_t y = 42;
|
||||
name: list[t.CChar, 64] # char name[64];
|
||||
ptr: t.CVoid | t.CPtr # void* ptr;
|
||||
msg: t.CConst | str = "Hello" # const char* msg = "Hello";
|
||||
```
|
||||
|
||||
### 无初始值的声明
|
||||
|
||||
未赋值的变量声明会生成零初始化的变量,此处是未定义行为,即在不同环境位置可能会覆盖0,也可能不会,最好预先复制或用 memset 清除:
|
||||
|
||||
```python
|
||||
count: t.CInt # int count = 0;
|
||||
buffer: list[t.CChar, 256] # char buffer[256] = {0};
|
||||
```
|
||||
|
||||
### 延迟赋值
|
||||
|
||||
变量可以先声明后赋值:
|
||||
|
||||
```python
|
||||
x: t.CInt
|
||||
x = 10
|
||||
```
|
||||
|
||||
### 指针变量
|
||||
|
||||
```python
|
||||
p: t.CInt | t.CPtr # int* p;
|
||||
fb: t.CVoid | t.CPtr # void* fb;
|
||||
str_ptr: t.CConst | t.CChar | t.CPtr # const char* str_ptr;
|
||||
```
|
||||
|
||||
### 指针变量的特殊初始化
|
||||
|
||||
使用 `t.CVoid(0, t.CPtr)` 初始化指针为 NULL:
|
||||
|
||||
```python
|
||||
p: t.CVoid | t.CPtr = t.CVoid(0, t.CPtr) # void* p = NULL;
|
||||
```
|
||||
|
||||
或使用 `None`:
|
||||
|
||||
```python
|
||||
p: t.CVoid | t.CPtr = None # void* p = NULL;
|
||||
```
|
||||
|
||||
## 普通赋值
|
||||
|
||||
```python
|
||||
x: t.CInt = 0
|
||||
x = 42 # x = 42;
|
||||
```
|
||||
|
||||
## 增强赋值
|
||||
|
||||
支持所有 Python 增强赋值运算符:
|
||||
|
||||
```python
|
||||
x: t.CInt = 0
|
||||
x += 1 # x += 1;
|
||||
x -= 1 # x -= 1;
|
||||
x *= 2 # x *= 2;
|
||||
x //= 3 # x /= 3; (整数除法)
|
||||
x %= 5 # x %= 5;
|
||||
x <<= 1 # x <<= 1;
|
||||
x >>= 1 # x >>= 1;
|
||||
x |= 0xFF # x |= 0xFF;
|
||||
x &= 0x0F # x &= 0x0F;
|
||||
x ^= 0xAA # x ^= 0xAA;
|
||||
```
|
||||
|
||||
## 全局变量
|
||||
|
||||
模块顶层声明的变量即为全局变量:
|
||||
|
||||
```python
|
||||
kbd_tid: t.CInt = -1 # 全局 int kbd_tid = -1;
|
||||
BootInfo: bootinfo | t.CPtr # 全局 struct bootinfo* BootInfo;
|
||||
```
|
||||
|
||||
### 静态全局变量
|
||||
|
||||
```python
|
||||
x: t.CStatic | t.CInt = 0 # static int x = 0;
|
||||
```
|
||||
|
||||
### 外部声明
|
||||
|
||||
```python
|
||||
x: t.CExtern | t.CInt # extern int x;
|
||||
```
|
||||
|
||||
## 常量定义
|
||||
|
||||
使用 `t.CDefine` 定义编译时常量。`t.CDefine` 不是数据类型,而是编译时元指令——常量在 LLVM IR 中不生成全局变量,而是在引用处直接内联展开。详见 [01-overview.md 中 t.CDefine 深度解析](01-overview.md#tcdefine-深度解析)。
|
||||
|
||||
```python
|
||||
MAX_SIZE: t.CDefine = 1024
|
||||
PAGE_SIZE: t.CDefine = 4096
|
||||
FA_READ: t.CDefine = 0x01
|
||||
FA_WRITE: t.CDefine = 0x02
|
||||
```
|
||||
|
||||
## 字符串常量
|
||||
|
||||
Viper 中的字符串字面量编译为 C 的字符串常量(`const char*`):
|
||||
|
||||
```python
|
||||
msg: t.CConst | str = "Hello, World!"
|
||||
serial.puts(msg)
|
||||
```
|
||||
|
||||
也可以直接传递字符串字面量:
|
||||
|
||||
```python
|
||||
serial.puts("Hello, World!")
|
||||
```
|
||||
|
||||
## 类型转换
|
||||
|
||||
使用类型构造函数进行显式类型转换:
|
||||
|
||||
```python
|
||||
x: t.CInt = 42
|
||||
y: t.CUInt32T = t.CUInt32T(x) # (uint32_t)x
|
||||
f: t.CFloat = float(x) # (float)x
|
||||
i: t.CInt = int(f) # (int)f
|
||||
```
|
||||
|
||||
### 指针类型转换
|
||||
|
||||
```python
|
||||
ptr: t.CVoid | t.CPtr = some_ptr
|
||||
int_val: t.CUInt64T = t.CUInt64T(ptr) # (uint64_t)ptr — 指针转整数
|
||||
```
|
||||
|
||||
## 结构体实例化
|
||||
|
||||
> 此处不理解参见 ([05-classes.md 中 结构体实例化与初始化](05-classes.md#结构体实例化与初始化))
|
||||
|
||||
直接使用类名作为构造函数:
|
||||
|
||||
```python
|
||||
info: fat32_types.fat32_fileinfo
|
||||
dp: fat32_types.fat32_dirobj
|
||||
```
|
||||
|
||||
带初始化的实例化:
|
||||
|
||||
```python
|
||||
obj: MyClass = MyClass(arg1, arg2)
|
||||
```
|
||||
|
||||
使用 `c.Addr` 获取实例指针:
|
||||
|
||||
```python
|
||||
obj_ptr: MyClass | t.CPtr = c.Addr(MyClass(arg1, arg2))
|
||||
```
|
||||
|
||||
## delete 语句
|
||||
|
||||
`del` 语句可用于调用对象的 `__del__` 或 `__delete__` 方法:
|
||||
|
||||
```python
|
||||
del obj # 调用 obj.__del__() 或 obj.__delete__()
|
||||
del arr[idx] # 调用 arr.__delitem__(idx)
|
||||
```
|
||||
Reference in New Issue
Block a user