# 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: t.CInt = 1 if (info.attr & AM_DIR) else 0 ``` 等价 C 代码: ```c int is_dir = (info.attr & AM_DIR) ? 1 : 0; ``` ### None 检查 ```python if BootInfo != 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: t.CInt = 0 while i < 10: buf[i] = 0 i += 1 ``` 等价 C 代码: ```c int i = 0; while (i < 10) { buf[i] = 0; i += 1; } ``` ### while-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 ```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 或模式 ```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`。 ## assert 语句 > 避免使用此语句,此语句未经充分测试,在多数情况下,编译器不知道如何展示结果。 ```python assert ptr != None, "null pointer" ``` 编译为条件检查和错误报告。 ## with 语句 `with` 语句用于资源管理,要求对象实现 `__enter__` 和 `__exit__` 方法: ```python with File("/test.txt", FA_READ) as f: data: t.CInt = f.read() ``` 等价 C 代码: ```c File* f = File_enter(File_new("/test.txt", FA_READ)); int data = File_read(f); File_exit(f); ```