Files
Viper_Wiki/07-control-flow.md
T

272 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 07 - 控制流
Viper 支持 Python 风格的控制流语句,编译为 LLVM IR 的基本块和分支指令。
## 条件语句
### if / elif / else
```python
if x > 0:
y = 1
elif x == 0:
y = 0
else:
y = -1
```
等价 C 代码:
```c
if (x > 0) {
y = 1;
} else if (x == 0) {
y = 0;
} else {
y = -1;
}
```
### 条件表达式
```python
is_dir: int = 1 if (info.attr & AM_DIR) else 0
```
等价 C 代码:
```c
int is_dir = (info.attr & AM_DIR) ? 1 : 0;
```
### None 检查
```python
if BootInfo is not None:
paging.init(BootInfo.MemmapAddr, BootInfo.MemmapSize)
else:
paging.init(0, 0)
```
等价 C 代码:
```c
if (BootInfo != NULL) {
paging_init(BootInfo->MemmapAddr, BootInfo->MemmapSize);
} else {
paging_init(0, 0);
}
```
## 循环语句
### while 循环
```python
i: int = 0
while i < 10:
buf[i] = 0
i += 1
```
等价 C 代码:
```c
int i = 0;
while (i < 10) {
buf[i] = 0;
i += 1;
}
```
### while-else
> 期望实现——当前编译器不生成 orelse 代码,else 块会被忽略
```python
while i < count:
if found:
break
else:
serial.puts("not found\n")
```
`else` 块在循环正常结束(非 `break` 退出)时执行。
### 无限循环
```python
while True:
sched.Scheduler._yield()
```
等价 C 代码:
```c
while (1) {
scheduler_yield();
}
```
### for 循环(range)(关于 for 循环的更多用法,参见 [06-oop.md 中 迭代器协议](06-oop.md#迭代器协议))
```python
for i in range(10):
buf[i] = 0
for i in range(5, 10):
buf[i] = 0
for i in range(0, 100, 2):
buf[i] = 0
```
等价 C 代码:
```c
for (int i = 0; i < 10; i++) {
buf[i] = 0;
}
for (int i = 5; i < 10; i++) {
buf[i] = 0;
}
for (int i = 0; i < 100; i += 2) {
buf[i] = 0;
}
```
### for 循环(迭代器)
如果类实现了 `__iter__` 和 `__next__` 方法,可以使用 `for ... in` 迭代:
```python
container: Iter = Iter()
for item in container:
process(item)
```
### for-else
> 期望实现——当前编译器不生成 orelse 代码,else 块会被忽略
```python
for i in range(count):
if items[i] == target:
break
else:
serial.puts("not found\n")
```
### break 和 continue
```python
while True:
if done:
break
if skip:
continue
process()
```
## match 语句
Viper 支持 Python 3.10+ 的 `match` 语句,编译为 C 的 `switch` 语句:
```python
match self.ctype:
case UI_LABEL:
self.RenderLabel(sh)
case UI_BUTTON:
self.RenderButton(sh)
case UI_PANEL:
self.RenderPanel(sh)
case _:
pass
```
等价 C 代码:
```c
switch (self->ctype) {
case UI_LABEL:
self_RenderLabel(self, sh);
break;
case UI_BUTTON:
self_RenderButton(self, sh);
break;
case UI_PANEL:
self_RenderPanel(self, sh);
break;
default:
break;
}
```
### match 值匹配
```python
match code:
case 0:
serial.puts("OK\n")
case 1:
serial.puts("Error\n")
case _:
serial.puts("Unknown\n")
```
### match 或模式
> 期望实现——当前实现只取第一个值做 switch case,其余值会落入默认分支(c.NoBreak 相关)
```python
match value:
case 1 | 2 | 3:
serial.puts("small\n")
case _:
serial.puts("other\n")
```
### fallthrough(无 break)
默认每个 `case` 自动添加 `break`。如需 fallthrough,使用 `c.NoBreak`:
```python
match value:
case 1:
do_one()
c.NoBreak
case 2:
do_two()
```
如果需要提前 break,需要使用 `c.Break()`,因为在 `Python` 中,`match` 分支不支持直接使用 `break`。
> 期望实现——当前不存在 `c.Break()`;case 体默认自动 break,fallthrough 需用 `c.NoBreak`。
## assert 语句
> 避免使用此语句,此语句未经充分测试,在多数情况下,编译器不知道如何展示结果。
> 期望实现——当前语句分派无 assert 分支
```python
assert ptr != None, "null pointer"
```
编译为条件检查和错误报告。
## with 语句
`with` 语句用于资源管理,要求对象实现 `__enter__` 和 `__exit__` 方法:
```python
with File("/test.txt", FA_READ) as f:
data: int = f.read()
```
等价 C 代码:
```c
File* f = File_enter(File_new("/test.txt", FA_READ));
int data = File_read(f);
File_exit(f);
```
## 协程 async/await(已实现)
`async def` / `await` 编译为帧状态机(`AsyncGenMixin`),运行时由 `coro` 模块提供 `coro_run` / `coro_sleep` / `coro_destroy` / `coro_exception` / `coro_exception_msg` / `coro_gather`,`async_test.vp` 提供实证。
`await` 可与 `for` / `try` / `except` / `finally` / 自定义异常等组合使用。