Files
ViperOS/vpsdk/wiki/07-control-flow.md
2026-07-19 12:38:20 +08:00

3.9 KiB
Raw Permalink Blame History

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);