3.9 KiB
3.9 KiB
07 - 控制流
Viper 支持 Python 风格的控制流语句,编译为 LLVM IR 的基本块和分支指令。
条件语句
if / elif / else
if x > 0:
y = 1
elif x == 0:
y = 0
else:
y = -1
等价 C 代码:
if (x > 0) {
y = 1;
} else if (x == 0) {
y = 0;
} else {
y = -1;
}
条件表达式
is_dir: t.CInt = 1 if (info.attr & AM_DIR) else 0
等价 C 代码:
int is_dir = (info.attr & AM_DIR) ? 1 : 0;
None 检查
if BootInfo != None:
paging.init(BootInfo.MemmapAddr, BootInfo.MemmapSize)
else:
paging.init(0, 0)
等价 C 代码:
if (BootInfo != NULL) {
paging_init(BootInfo->MemmapAddr, BootInfo->MemmapSize);
} else {
paging_init(0, 0);
}
循环语句
while 循环
i: t.CInt = 0
while i < 10:
buf[i] = 0
i += 1
等价 C 代码:
int i = 0;
while (i < 10) {
buf[i] = 0;
i += 1;
}
while-else
while i < count:
if found:
break
else:
serial.puts("not found\n")
else 块在循环正常结束(非 break 退出)时执行。
无限循环
while True:
sched.Scheduler._yield()
等价 C 代码:
while (1) {
scheduler_yield();
}
for 循环(range)(关于 for 循环的更多用法,参见 06-oop.md 中 迭代器协议)
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 代码:
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 迭代:
container: Iter = Iter()
for item in container:
process(item)
for-else
for i in range(count):
if items[i] == target:
break
else:
serial.puts("not found\n")
break 和 continue
while True:
if done:
break
if skip:
continue
process()
match 语句
Viper 支持 Python 3.10+ 的 match 语句,编译为 C 的 switch 语句:
match self.ctype:
case UI_LABEL:
self.RenderLabel(sh)
case UI_BUTTON:
self.RenderButton(sh)
case UI_PANEL:
self.RenderPanel(sh)
case _:
pass
等价 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 值匹配
match code:
case 0:
serial.puts("OK\n")
case 1:
serial.puts("Error\n")
case _:
serial.puts("Unknown\n")
match 或模式
match value:
case 1 | 2 | 3:
serial.puts("small\n")
case _:
serial.puts("other\n")
fallthrough(无 break)
默认每个 case 自动添加 break。如需 fallthrough,使用 c.NoBreak:
match value:
case 1:
do_one()
c.NoBreak
case 2:
do_two()
如果需要提前 break,需要使用 c.Break(),因为在 Python 中,match 分支不支持直接使用 break。
assert 语句
避免使用此语句,此语句未经充分测试,在多数情况下,编译器不知道如何展示结果。
assert ptr != None, "null pointer"
编译为条件检查和错误报告。
with 语句
with 语句用于资源管理,要求对象实现 __enter__ 和 __exit__ 方法:
with File("/test.txt", FA_READ) as f:
data: t.CInt = f.read()
等价 C 代码:
File* f = File_enter(File_new("/test.txt", FA_READ));
int data = File_read(f);
File_exit(f);