From 6daec5fa587f82063846932d42dc59f973aea78f Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 28 Aug 2026 07:35:03 +0800 Subject: [PATCH] =?UTF-8?q?feat(tpv):=20translate=5Funaryop=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=8D=95=E7=9B=AE=20*=20/=20&=EF=BC=88Deref/AddrOf?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App/lib/core/Gen/ExprGenOps.vp | 96 ++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/App/lib/core/Gen/ExprGenOps.vp b/App/lib/core/Gen/ExprGenOps.vp index 07f54e7..c9219fd 100644 --- a/App/lib/core/Gen/ExprGenOps.vp +++ b/App/lib/core/Gen/ExprGenOps.vp @@ -692,6 +692,102 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if operand_bits_inv == 64: neg1 = llvmlite.const_int64(pool, -1) return llvmlite.build_xor(builder, operand, neg1) + elif uo.op == ast.OpKind.Deref: + # *p → load 按 pointee 类型读取(对齐 translate_c_deref) + if self.Gen.ExprGenBase.is_ptr_type(operand.Ty) != 0: + d_pointee: llvmlite.LLVMType | t.CPtr = operand.Ty.Pointee + if d_pointee is not None: + return llvmlite.build_load(builder, d_pointee, operand) + # 非指针即类型推断退化:fail-fast,绝不按 i8 兜底读取 + self.Gen.TypeGenErr.fatal_error( + node, "单目 '*' 解引用的操作数必须是指针类型(类型推断退化)", "TypeError") + return None + elif uo.op == ast.OpKind.AddrOf: + # &x → 左值地址(不 load):Name 变量 alloca / 模块全局 / 模块函数 / + # Attribute 字段 GEP / Subscript 元素地址(对齐 translate_c_addr 语义) + if trans is None: + return None + if uo.operand.kind() == ast.ASTKind.Name: + nm_ao: ast.Name | t.CPtr = (ast.Name | t.CPtr)(uo.operand) + if nm_ao.id is not None: + # self/cls 对象引用:返回对象指针本身(Ptr(Struct))而非 + # 指针变量的地址(Ptr(Ptr(Struct))) + if string.strcmp(nm_ao.id, "self") == 0 or string.strcmp(nm_ao.id, "cls") == 0: + se_ao: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry( + trans.SymTab, nm_ao.id) + if se_ao is not None and se_ao.Alloca is not None and se_ao.Alloca.Ty is not None: + match se_ao.Alloca.Ty: + case llvmlite.LLVMType.Ptr(sa1): + match sa1: + case llvmlite.LLVMType.Ptr(sa2): + obj_ty_sa: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, sa2) + return llvmlite.build_load(builder, obj_ty_sa, se_ao.Alloca) + case _: + pass + case _: + pass + v_ao: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, nm_ao.id) + if v_ao is None and mod is not None: + # 模块全局变量:经 make_global_ref 转成带引号的 Ptr(Ty) 引用 + gv_ao: llvmlite.GlobalVariable | t.CPtr = self.Gen.ExprGenAttr.find_global_in_module(mod, nm_ao.id) + if gv_ao is not None and gv_ao.Name is not None and gv_ao.Ty is not None: + v_ao = self.Gen.ExprGenAttr.make_global_ref(pool, gv_ao.Name, gv_ao.Ty) + if v_ao is not None and v_ao.Ty is not None: + # 对象指针变量(alloca 是 Ptr(Ptr(Struct)),存对象指针): + # 变量语义即对象,返回对象指针(load 一次),对齐 translate_c_addr + match v_ao.Ty: + case llvmlite.LLVMType.Ptr(ao1): + match ao1: + case llvmlite.LLVMType.Ptr(ao2): + match ao2: + case llvmlite.LLVMType.Struct(_, _, _): + obj_ty_ao: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, ao2) + return llvmlite.build_load(builder, obj_ty_ao, v_ao) + case _: + pass + case _: + pass + case _: + pass + return v_ao + # 模块函数地址:函数符号本身 + if v_ao is None and mod is not None: + f_ao: llvmlite.Function | t.CPtr = self.Gen.CallGenBase.find_func_in_module(mod, nm_ao.id) + if f_ao is not None: + fname_ao: str = llvmlite.function_get_name(f_ao) + if fname_ao is not None: + p_head_ao: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(f_ao) + p_cnt_ao: t.CSizeT = 0 + p_cur_ao: llvmlite.Param | t.CPtr = p_head_ao + while p_cur_ao is not None: + p_cnt_ao += 1 + p_cur_ao = llvmlite.param_get_next(p_cur_ao) + fn_ty_ao: llvmlite.LLVMType | t.CPtr = llvmlite.Func(pool, f_ao.RetTy, p_head_ao, p_cnt_ao) + # 函数引用名按需加引号(数字开头/含 '.' 的 sha1 前缀名) + fnlen_ao: t.CSizeT = string.strlen(fname_ao) + needs_q_ao: int = self.Gen.ClassGenVTable._vtable_name_needs_quote(fname_ao) + fbuf_ao: str = pool.alloc(fnlen_ao + 4) + if fbuf_ao is not None and fn_ty_ao is not None: + if needs_q_ao != 0: + viperlib.snprintf(fbuf_ao, fnlen_ao + 4, "@\"%s\"", fname_ao) + else: + viperlib.snprintf(fbuf_ao, fnlen_ao + 4, "@%s", fname_ao) + return llvmlite.SSAValue(pool, llvmlite.Ptr(pool, fn_ty_ao), fbuf_ao) + elif uo.operand.kind() == ast.ASTKind.Attribute: + # 字段地址(GEP,不 load) + fptr_ao: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.get_attribute_ptr( + builder, pool, mod, uo.operand, trans) + if fptr_ao is not None: + return fptr_ao + elif uo.operand.kind() == ast.ASTKind.Subscript: + # 元素地址(GEP,不 load) + sptr_ao: llvmlite.Value | t.CPtr = self.Gen.ExprGenName.get_subscript_ptr( + builder, pool, mod, uo.operand, trans) + if sptr_ao is not None: + return sptr_ao + self.Gen.TypeGenErr.fatal_error( + node, "单目 '&' 取地址的操作数必须是左值(Name/Attribute/Subscript)", "TypeError") + return None return operand # ============================================================ # 翻译布尔运算 BoolOp(op, values) — 短路求值,返回 i1