import t, c from stdint import * import ast import llvmlite import memhub import string import stdio import viperlib import lib.core.Handles.HandlesBase as HandlesBase import lib.core.Handles.HandlesTranslator as HT import lib.core.Handles.HandlesExpr as HandlesExpr import lib.core.Handles.HandlesBody as HandlesBody # ============================================================ # HandlesIf - if/elif/else 语句处理(Mixin 继承模式) # # 翻译 if 语句为 LLVM IR 控制流: # br i1 %cond, label %then, label %else # then: # ... body ... # br label %end # else: # ... orelse ... # br label %end # end: # ============================================================ @t.NoVTable class IfHandle(HandlesBase.Mixin): """if/elif/else 语句处理器:继承 Mixin 获得 Trans 回指针""" def __init__(self, trans: HT.Translator | t.CPtr): self.Trans = trans # ============================================================ # Handle - 处理 if 语句,返回新增变量数 # ============================================================ def Handle(self, node: ast.AST | t.CPtr) -> int: """翻译 if/elif/else 语句""" if node is None: return 0 trans: HT.Translator | t.CPtr = self.Trans pool: memhub.MemBuddy | t.CPtr = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func if builder is None or func is None: return 0 if_node: ast.If | t.CPtr = (ast.If | t.CPtr)(node) # 1. 求值条件表达式 cond_val: llvmlite.Value | t.CPtr = HandlesExpr.translate_value( builder, pool, trans.Module, if_node.test, trans._funcs, trans._func_count, trans) # 2. 转换为 i1 条件 # Compare/Not 表达式已返回 i1,直接使用;其他类型与 0 比较 if cond_val is None: cond_val = llvmlite.const_int32(pool, 0) cond_bits: int = HandlesExpr.get_llvm_type_bits(cond_val.Ty) if cond_bits == 1: cond_i1: llvmlite.Value | t.CPtr = cond_val else: zero: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, 0) cond_i1 = llvmlite.build_icmp( builder, llvmlite.ICMP_NE, cond_val, zero) # 3. 创建基本块(使用 trans._label_counter 生成唯一标签名,不与 SSA 名共享) cnt: int = trans._label_counter trans._label_counter = cnt + 1 name_buf: t.CChar | t.CPtr = pool.alloc(32) viperlib.snprintf(name_buf, 32, "if.then.%d", cnt) then_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, name_buf) viperlib.snprintf(name_buf, 32, "if.end.%d", cnt) merge_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, name_buf) # 检查是否有 else 分支 has_else: int = 0 orelse_list: list[ast.AST | t.CPtr] | t.CPtr = if_node.orelse if orelse_list is not None: if orelse_list.__len__() > 0: has_else = 1 else_bb: llvmlite.BasicBlock | t.CPtr = None if has_else == 1: viperlib.snprintf(name_buf, 32, "if.else.%d", cnt) else_bb = llvmlite.create_block(pool, func, name_buf) # 4. 发射条件分支 if has_else == 1: llvmlite.build_cond_br(builder, cond_i1, then_bb, else_bb) else: llvmlite.build_cond_br(builder, cond_i1, then_bb, merge_bb) # 5. 翻译 then body llvmlite.position_at_end(builder, then_bb) body: list[ast.AST | t.CPtr] | t.CPtr = if_node.children if body is not None: body_count: t.CSizeT = body.__len__() for bi in range(body_count): stmt: ast.AST | t.CPtr = body.get(bi) if stmt is not None: HandlesBody.translate_stmt(trans, stmt) # then 块未终止则跳到 merge if llvmlite.builder_cur_block_is_terminated(builder) == 0: llvmlite.build_br(builder, merge_bb) # 6. 翻译 else body(若有) if has_else == 1: llvmlite.position_at_end(builder, else_bb) else_count: t.CSizeT = orelse_list.__len__() for ei in range(else_count): stmt: ast.AST | t.CPtr = orelse_list.get(ei) if stmt is not None: HandlesBody.translate_stmt(trans, stmt) if llvmlite.builder_cur_block_is_terminated(builder) == 0: llvmlite.build_br(builder, merge_bb) # 7. 定位到 merge 块继续后续代码 llvmlite.position_at_end(builder, merge_bb) return 0 # ============================================================ # NewIfHandle - 工厂函数 # ============================================================ def NewIfHandle(pool: memhub.MemBuddy | t.CPtr, trans: HT.Translator | t.CPtr) -> IfHandle | t.CPtr: h: IfHandle | t.CPtr = pool.alloc(IfHandle.__sizeof__()) if h is None: return None string.memset(h, 0, IfHandle.__sizeof__()) h.Trans = trans return h