feat(stmt): 支持 raise 语句(对齐 TPC StopIteration 语义)

Viper 无异常传播:raise 统一按终止函数并返回零值处理,对齐 TPC HandlesRaise——迭代器 __next__ 用 null/0 表示迭代结束(dict.__next__ 的 raise StopIteration)。此前 translate_stmt 不识别 raise 静默跳过(越界后继续执行读垃圾),且未知语句 fail-fast 会误杀。
This commit is contained in:
TermiNexus committed 2026-08-13 02:50:07 +08:00
1 parent 8b8b716523
commit 9eee43c304
1 file changed
+44
+44
View File
@@ -123,6 +123,8 @@ class StmtGenMixin:
return trans.MatchH.Handle(node)
elif k == ast.ASTKind.Delete:
return self.translate_delete(trans, node)
elif k == ast.ASTKind.Raise:
return self.translate_raise(trans, node)
# 未知语句类型:直接报错终止(fail-fast),暴露上游解析问题
HandlesType.fatal_error(node, f"未知语句类型 kind={k}", "SyntaxError")
return 0
@@ -153,6 +155,48 @@ class StmtGenMixin:
pool, builder, mod, del_at, trans)
return 0
def translate_raise(self, trans: HT.Translator | t.CPtr,
node: ast.AST | t.CPtr) -> int:
"""翻译 raise 语句,返回 0
Viper 无异常传播机制:raise 统一按"终止当前函数并返回零值"处理,
对齐 TPC HandlesRaise 的 StopIteration 语义——迭代器 __next__ 用
null/0 表示迭代结束(如 dict.__next__ 的 `raise StopIteration`)。
非 StopIteration 的 raise 同样返回零值(异常消息忽略)。
"""
if trans is None or node is None:
return 0
pool: memhub.MemBuddy | t.CPtr = trans.Pool
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
if pool is None or builder is None:
return 0
cur_func: llvmlite.Function | t.CPtr = trans._cur_func
if cur_func is None:
return 0
ret_ty: llvmlite.LLVMType | t.CPtr = llvmlite.function_get_ret_ty(cur_func)
if ret_ty is None:
return 0
match ret_ty:
case llvmlite.LLVMType.Void():
llvmlite.build_ret_void(builder)
case llvmlite.LLVMType.Ptr(_pe):
null_v: llvmlite.Value | t.CPtr = llvmlite.ConstNull(pool, ret_ty, "null")
if null_v is not None:
llvmlite.build_ret(builder, null_v)
case llvmlite.LLVMType.Float(_fb):
zero_f: llvmlite.Value | t.CPtr = llvmlite.ConstFloat(pool, ret_ty, 0.0)
if zero_f is not None:
llvmlite.build_ret(builder, zero_f)
case llvmlite.LLVMType.Double(_db):
zero_f2: llvmlite.Value | t.CPtr = llvmlite.ConstFloat(pool, ret_ty, 0.0)
if zero_f2 is not None:
llvmlite.build_ret(builder, zero_f2)
case _:
zero_v: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, ret_ty)
if zero_v is not None:
llvmlite.build_ret(builder, zero_v)
return 0
def translate_global(self, trans: HT.Translator | t.CPtr,
node: ast.AST | t.CPtr) -> int:
"""翻译 global 语句:记录 global 变量名"""