修复了一些错误,更改了一点语法

This commit is contained in:
TermiNexus committed 2026-09-18 20:00:40 +08:00
1 parent 9e2ccbfab7
commit 9910e05760
61 files changed
+2810 -2810

No files matched your search

+107 -107
View File
@@ -125,7 +125,7 @@ class AssignGenMixin:
cl: rawptr[ast.Call] = rawptr[ast.Call](val_node)
# 必须先把属性赋给显式类型为 list[...] | t.CPtr 的局部变量再调用 __len__(),
# 否则编译器无法识别属性返回的 list 类型,GEP base 会变成 i32 0 导致 llc 报错
cl_args_list: list[rawptr[ast.AST]] | t.CPtr = cl.args
cl_args_list: rawptr[list[rawptr[ast.AST]]] = cl.args
if cl_args_list is not None and len(cl_args_list) > 0:
first_arg: rawptr[ast.AST] = cl_args_list.get(0)
arg_val: int64 = self.extract_cdefine_int_value(first_arg)
@@ -167,7 +167,7 @@ class AssignGenMixin:
if val_node is not None and val_node.kind() == ast.ASTKind.Call:
cl_cd: rawptr[ast.Call] = rawptr[ast.Call](val_node)
if cl_cd is not None and cl_cd.args is not None:
cl_args_cd: list[rawptr[ast.AST]] | t.CPtr = cl_cd.args
cl_args_cd: rawptr[list[rawptr[ast.AST]]] = cl_cd.args
if len(cl_args_cd) > 0:
first_arg_cd: rawptr[ast.AST] = cl_args_cd.get(0)
if first_arg_cd is not None and first_arg_cd.kind() == ast.ASTKind.Constant:
@@ -609,10 +609,10 @@ class AssignGenMixin:
# Returns:
# 0 成功,1 失败
# ============================================================
def _init_global_array_from_list(self, builder: llvmlite.IRBuilder | t.CPtr,
def _init_global_array_from_list(self, builder: rawptr[llvmlite.IRBuilder],
pool: rawptr[memhub.MemBuddy],
mod: rawptr[llvmlite.LLVMModule],
array_alloca: llvmlite.Value | t.CPtr,
array_alloca: rawptr[llvmlite.Value],
list_node: rawptr[ast.AST],
trans: rawptr[HT.Translator]) -> int:
"""从列表字面量初始化全局数组,为每个元素生成 GEP + store"""
@@ -637,10 +637,10 @@ class AssignGenMixin:
return 1
# 获取列表元素
lst: ast.List | t.CPtr = (ast.List | t.CPtr)(list_node)
lst: rawptr[ast.List] = rawptr[ast.List](list_node)
if lst is None or lst.elts is None:
return 1
elts: list[rawptr[ast.AST]] | t.CPtr = lst.elts
elts: rawptr[list[rawptr[ast.AST]]] = lst.elts
elts_count: sizet = len(elts)
# 特例:单个字符串字面量初始化字符数组([N x i8],N = strlen+1)
@@ -660,13 +660,13 @@ class AssignGenMixin:
"OverflowError")
bi_s: sizet = 0
while bi_s < n_s:
bidx_s: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, bi_s)
bp_s: llvmlite.Value | t.CPtr = llvmlite.build_gep_array(
bidx_s: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, bi_s)
bp_s: rawptr[llvmlite.Value] = llvmlite.build_gep_array(
builder, arr_ty, elem_ty, array_alloca, bidx_s)
if bp_s is None:
break
bvv: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, sv_s[bi_s])
bsv: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
bvv: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, sv_s[bi_s])
bsv: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
builder, bvv, elem_ty, e0_s)
llvmlite.build_store(builder, bsv, bp_s)
bi_s += 1
@@ -682,8 +682,8 @@ class AssignGenMixin:
# 为每个元素生成 GEP + store
for i in range(elts_count):
elem_node: rawptr[ast.AST] = elts.get(i)
idx_val: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, i)
elem_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_array(
idx_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, i)
elem_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_array(
builder, arr_ty, elem_ty, array_alloca, idx_val)
if elem_ptr is None:
continue
@@ -697,13 +697,13 @@ class AssignGenMixin:
if inner_arr != 0:
self._init_global_array_from_list(builder, pool, mod, elem_ptr, elem_node, trans)
continue
elem_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
elem_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
builder, pool, mod, elem_node, None, 0, trans)
if elem_val is None:
# 元素翻译失败:直接报错终止(fail-fast),暴露上游根因
self.Gen.TypeGenErr.fatal_error(elem_node, "全局数组初始化元素翻译失败", "TypeError")
# 类型转换(如 i32 → i8 截断)
store_val: llvmlite.Value | t.CPtr = elem_val
store_val: rawptr[llvmlite.Value] = elem_val
if elem_ptr.Ty is not None and elem_ptr.Ty.Pointee is not None:
store_val = self.Gen.ExprGenBase.coerce_to_type(
builder, elem_val, elem_ptr.Ty.Pointee, elem_node)
@@ -718,13 +718,13 @@ class AssignGenMixin:
# 整数运算自动类型提升
# ============================================================
def _apply_aug_op(self, pool: rawptr[memhub.MemBuddy],
builder: llvmlite.IRBuilder | t.CPtr,
builder: rawptr[llvmlite.IRBuilder],
op: int,
lhs: llvmlite.Value | t.CPtr,
rhs: llvmlite.Value | t.CPtr,
lhs: rawptr[llvmlite.Value],
rhs: rawptr[llvmlite.Value],
node: rawptr[ast.AST] = None,
trans: rawptr[HT.Translator] = None,
lhs_node: rawptr[ast.AST] = None) -> llvmlite.Value | t.CPtr:
lhs_node: rawptr[ast.AST] = None) -> rawptr[llvmlite.Value]:
"""应用增强赋值的二元运算(浮点 + 指针算术 + 整数运算)"""
lhs_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(lhs.Ty)
rhs_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(rhs.Ty)
@@ -808,7 +808,7 @@ class AssignGenMixin:
if node is None:
return 0
aug: ast.AugAssign | t.CPtr = (ast.AugAssign | t.CPtr)(node)
aug: rawptr[ast.AugAssign] = rawptr[ast.AugAssign](node)
if aug is None:
return 0
@@ -822,11 +822,11 @@ class AssignGenMixin:
# 流程: get_attribute_ptr → load → binop → store
if tk == ast.ASTKind.Attribute:
pool: rawptr[memhub.MemBuddy] = trans.Pool
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
mod: rawptr[llvmlite.LLVMModule] = trans.Module
# 1. 获取字段指针
field_ptr: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.get_attribute_ptr(
field_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr(
builder, pool, mod, target, trans)
if field_ptr is None:
# fail-fast: 属性指针解析失败
@@ -839,21 +839,21 @@ class AssignGenMixin:
if target_ty is None:
# fail-fast: 字段类型信息缺失,禁止兜底 i32
self.Gen.TypeGenErr.fatal_error(target, "字段类型信息缺失", "TypeError")
cur_val: llvmlite.Value | t.CPtr = llvmlite.build_load(
cur_val: rawptr[llvmlite.Value] = llvmlite.build_load(
builder, target_ty, field_ptr)
if cur_val is None:
# fail-fast: 属性当前值加载失败
self.Gen.TypeGenErr.fatal_error(target, "无法加载 attribute 当前值", "TypeError")
# 3. 翻译 RHS 值
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
builder, pool, mod, aug.value, None, 0, trans)
if rhs_val is None:
# fail-fast: RHS 翻译失败
self.Gen.TypeGenErr.fatal_error(target, "rhs 翻译失败", "TypeError")
# 4. 应用二元运算
result: llvmlite.Value | t.CPtr = self._apply_aug_op(
result: rawptr[llvmlite.Value] = self._apply_aug_op(
pool, builder, aug.op, cur_val, rhs_val, node, trans, target)
if result is None:
# fail-fast: attribute 二元运算失败
@@ -871,11 +871,11 @@ class AssignGenMixin:
# 流程: get_subscript_ptr → load → binop → store
if tk == ast.ASTKind.Subscript:
pool: rawptr[memhub.MemBuddy] = trans.Pool
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
mod: rawptr[llvmlite.LLVMModule] = trans.Module
# 1. 获取元素指针
elem_ptr: llvmlite.Value | t.CPtr = self.Gen.ExprGenName.get_subscript_ptr(
elem_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenName.get_subscript_ptr(
builder, pool, mod, target, trans)
if elem_ptr is None:
# fail-fast: 下标指针解析失败
@@ -888,21 +888,21 @@ class AssignGenMixin:
if target_ty is None:
# fail-fast: 元素类型信息缺失,禁止兜底 i32
self.Gen.TypeGenErr.fatal_error(target, "元素类型信息缺失", "TypeError")
cur_val: llvmlite.Value | t.CPtr = llvmlite.build_load(
cur_val: rawptr[llvmlite.Value] = llvmlite.build_load(
builder, target_ty, elem_ptr)
if cur_val is None:
# fail-fast: 元素当前值加载失败
self.Gen.TypeGenErr.fatal_error(target, "无法加载 subscript 元素当前值", "TypeError")
# 3. 翻译 RHS 值
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
builder, pool, mod, aug.value, None, 0, trans)
if rhs_val is None:
# fail-fast: RHS 翻译失败
self.Gen.TypeGenErr.fatal_error(target, "rhs 翻译失败", "TypeError")
# 4. 应用二元运算
result: llvmlite.Value | t.CPtr = self._apply_aug_op(
result: rawptr[llvmlite.Value] = self._apply_aug_op(
pool, builder, aug.op, cur_val, rhs_val, node, trans, target)
if result is None:
# fail-fast: subscript 二元运算失败
@@ -926,7 +926,7 @@ class AssignGenMixin:
return 0
pool: rawptr[memhub.MemBuddy] = trans.Pool
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
mod: rawptr[llvmlite.LLVMModule] = trans.Module
# 1. 确定变量作用域类型: 0=local, 1=global, 2=nonlocal
@@ -937,8 +937,8 @@ class AssignGenMixin:
scope_type = 2
# 2. 加载当前值
cur_val: llvmlite.Value | t.CPtr = None
target_alloca: llvmlite.Value | t.CPtr = None
cur_val: rawptr[llvmlite.Value] = None
target_alloca: rawptr[llvmlite.Value] = None
target_ty: rawptr[llvmlite.LLVMType] = None
if scope_type == 1:
@@ -970,7 +970,7 @@ class AssignGenMixin:
self.Gen.TypeGenErr.fatal_error(target, f"无法加载目标变量 '{nm.id}' 的当前值", "TypeError")
# 3. 翻译 RHS 值
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
builder, pool, mod, aug.value, None, 0, trans)
if rhs_val is None:
# fail-fast: RHS 翻译失败
@@ -978,7 +978,7 @@ class AssignGenMixin:
# 4. 类型对齐 + 应用二元运算
# 注意: AugAssign 不走运算符重载(语义上需要 __iadd__ 而非 __add__)
result: llvmlite.Value | t.CPtr = self._apply_aug_op(
result: rawptr[llvmlite.Value] = self._apply_aug_op(
pool, builder, aug.op, cur_val, rhs_val, node, trans, target)
if result is None:
# fail-fast: 二元运算失败
@@ -999,7 +999,7 @@ class AssignGenMixin:
llvmlite.build_store(builder, result, target_alloca)
elif scope_type == 2:
# nonlocal 变量
nl_ptr: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
nl_ptr: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
trans, nm.id)
if nl_ptr is not None:
llvmlite.build_store(builder, result, nl_ptr)
@@ -1083,7 +1083,7 @@ class AssignGenMixin:
if value is not None and value.kind() == ast.ASTKind.List and resolved_ty is not None:
if self._is_single_param_carray_annot(annot) != 0:
elem_ty_arr: rawptr[llvmlite.LLVMType] = resolved_ty.Pointee
lst_arr: ast.List | t.CPtr = (ast.List | t.CPtr)(value)
lst_arr: rawptr[ast.List] = rawptr[ast.List](value)
cnt_arr: int = 0
if lst_arr.elts is not None:
cnt_arr = len(lst_arr.elts)
@@ -1190,13 +1190,13 @@ class AssignGenMixin:
return 0
# 检查是否已存在
existing: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_current(
existing: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current(
trans.SymTab, nm.id)
if existing is not None:
return 0
pool: rawptr[memhub.MemBuddy] = trans.Pool
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
# 从 annotation 推断类型(修复:原硬编码 i32 导致 str 等类型错误)
var_ty: rawptr[llvmlite.LLVMType] = None
@@ -1235,7 +1235,7 @@ class AssignGenMixin:
# 确保跨模块结构体的完整定义在当前模块中可用(供 alloca 分配空间)
self.Gen.StructGen.ensure_struct_def_in_module(pool, trans.Module, var_ty)
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(builder, var_ty)
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, var_ty)
if alloca is not None:
if self.Gen.VarGen.define_var(
trans.SymTab, nm.id, alloca) == 0:
@@ -1402,7 +1402,7 @@ class AssignGenMixin:
return 0
pool: rawptr[memhub.MemBuddy] = trans.Pool
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
mod: rawptr[llvmlite.LLVMModule] = trans.Module
# 确定类型(从 annotation 推断)
@@ -1438,7 +1438,7 @@ class AssignGenMixin:
# global 变量:写入模块作用域中的全局变量
if GenApi.is_global_name(trans, nm.id) != 0:
mod_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
mod_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(
trans.SymTab, nm.id)
if mod_alloca is not None and aa.value is not None:
# P1-A(上下文位宽传播):把目标变量的类型作为 target_ty 传入,
@@ -1455,12 +1455,12 @@ class AssignGenMixin:
# 的类型实参推断都会拿不到注解。
trans.CurAssignAnnot = aa.annotation
trans.CurAssignNode = aa.value
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
builder, pool, mod, aa.value,
None, 0, trans, aa_glob_ty)
if rhs_val is not None:
# 对象类全局(有静态 storage):对象构造/赋值 → 绑定 storage + 复制对象
stg_ref_aa: llvmlite.Value | t.CPtr = None
stg_ref_aa: rawptr[llvmlite.Value] = None
if nm.id is not None:
stg_key_aa: str = pool.alloc(sizet(string.strlen(nm.id)) + 8)
if stg_key_aa is not None:
@@ -1479,7 +1479,7 @@ class AssignGenMixin:
if rhs_inner_aa is not None and rhs_inner_aa.kind() == llvmlite.LLVMType.Struct \
and self._stg_ty_equal(pool, stg_ty_aa, rhs_inner_aa) != 0:
llvmlite.build_store(builder, stg_ref_aa, mod_alloca)
stg_obj_val_aa: llvmlite.Value | t.CPtr = llvmlite.build_load(
stg_obj_val_aa: rawptr[llvmlite.Value] = llvmlite.build_load(
builder, stg_ty_aa, rhs_val)
if stg_obj_val_aa is not None:
llvmlite.build_store(builder, stg_obj_val_aa, stg_ref_aa)
@@ -1508,7 +1508,7 @@ class AssignGenMixin:
# P1-A:先把 nonlocal 槽位指针取出(原先在 RHS 翻译之后),以便把
# 槽位类型作为 target_ty 传入;槽位/类型缺失时直接返回,不再发射
# 无用的 RHS 死值。
nl_ptr: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
nl_ptr: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
trans, nm.id)
# 从 nl_ptr 的类型推断 nonlocal 变量实际类型,
# 不再强制 i32(会截断指针/结构体/i64 导致闭包数据损坏)
@@ -1523,7 +1523,7 @@ class AssignGenMixin:
# `nonlocal s: Stack[int] = Stack()` 的类型实参推断都会拿不到注解。
trans.CurAssignAnnot = aa.annotation
trans.CurAssignNode = aa.value
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
builder, pool, mod, aa.value,
None, 0, trans, nl_target_ty)
if rhs_val is not None:
@@ -1538,7 +1538,7 @@ class AssignGenMixin:
trans.CurAssignAnnot = None
trans.CurAssignNode = None
return 0
rhs_coerced: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
rhs_coerced: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
builder, rhs_val, nl_target_ty, node)
llvmlite.build_store(builder, rhs_coerced, nl_ptr)
# 清除赋值上下文(防残留):与主分支清空时机同款。四处(主分支 /
@@ -1553,7 +1553,7 @@ class AssignGenMixin:
# Python 语义:仅模块级代码(Current == Root)时修改全局变量;
# 函数内无 global 声明时应创建局部变量(走后面的 get_or_create_sym 路径)。
if self.Gen.VarGen.is_module_scope(trans.SymTab) != 0:
mod_glob: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
mod_glob: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(
trans.SymTab, nm.id)
else:
mod_glob = None
@@ -1575,12 +1575,12 @@ class AssignGenMixin:
# 上方 nonlocal 分支)必须同步。
trans.CurAssignAnnot = aa.annotation
trans.CurAssignNode = aa.value
rhs_val_mg: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
rhs_val_mg: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
builder, pool, mod, aa.value,
None, 0, trans, mg_val_ty)
if rhs_val_mg is not None:
# 对象类全局(有静态 storage):对象构造/赋值 → 绑定 storage + 复制对象
stg_ref_mg: llvmlite.Value | t.CPtr = None
stg_ref_mg: rawptr[llvmlite.Value] = None
if nm.id is not None:
stg_key_mg: str = pool.alloc(sizet(string.strlen(nm.id)) + 8)
if stg_key_mg is not None:
@@ -1599,7 +1599,7 @@ class AssignGenMixin:
if rhs_inner_mg is not None and rhs_inner_mg.kind() == llvmlite.LLVMType.Struct \
and self._stg_ty_equal(pool, stg_ty_mg, rhs_inner_mg) != 0:
llvmlite.build_store(builder, stg_ref_mg, mod_glob)
stg_obj_val_mg: llvmlite.Value | t.CPtr = llvmlite.build_load(
stg_obj_val_mg: rawptr[llvmlite.Value] = llvmlite.build_load(
builder, stg_ty_mg, rhs_val_mg)
if stg_obj_val_mg is not None:
llvmlite.build_store(builder, stg_obj_val_mg, stg_ref_mg)
@@ -1631,7 +1631,7 @@ class AssignGenMixin:
# 普通局部变量
# 创建 alloca
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.get_or_create_sym(
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.get_or_create_sym(
trans.SymTab, pool, builder, nm.id, var_ty)
if alloca is None:
# fail-fast: 存储创建失败,立即终止(禁止静默跳过)
@@ -1675,7 +1675,7 @@ class AssignGenMixin:
# a 保持为 i8*(可 printf/len),a__meta__ 存 __data__/__mbuddy__ 等字段,
# 属性读写(fd3)与方法调用(fd5)均通过该影子解析。
fd_str_ty: rawptr[llvmlite.LLVMType] = None
fd_meta_alloca: llvmlite.Value | t.CPtr = None
fd_meta_alloca: rawptr[llvmlite.Value] = None
fd_meta_name: str = None
if annot is not None and annot.kind() == ast.ASTKind.Name:
fd_annot: rawptr[ast.Name] = rawptr[ast.Name](annot)
@@ -1713,7 +1713,7 @@ class AssignGenMixin:
trans.SymTab, nm.id)
new_vars: int = 0
existing: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_current(
existing: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current(
trans.SymTab, nm.id)
if existing is None:
new_vars = 1
@@ -1752,7 +1752,7 @@ class AssignGenMixin:
if self.Gen.ExprGenBase.is_array_type(pt_l) != 0:
local_arr_ty = pt_l
if local_arr_ty is not None:
zero_arr: llvmlite.Value | t.CPtr = llvmlite.ConstZero(
zero_arr: rawptr[llvmlite.Value] = llvmlite.ConstZero(
pool, local_arr_ty)
if zero_arr is not None:
llvmlite.build_store(builder, zero_arr, alloca)
@@ -1772,7 +1772,7 @@ class AssignGenMixin:
lv_target_ty: rawptr[llvmlite.LLVMType] = None
if alloca.Ty is not None:
lv_target_ty = alloca.Ty.Pointee
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
builder, pool, mod, aa.value,
None, 0, trans, lv_target_ty)
if rhs_val is not None:
@@ -1839,10 +1839,10 @@ class AssignGenMixin:
if alloca_pt is not None and \
uint64(alloca_pt) != uint64(precise_rhs_ty) \
and rb_is_bare_generic == 0:
new_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(
new_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(
builder, precise_rhs_ty)
if new_alloca is not None:
v_entry_rb: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
v_entry_rb: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
trans.SymTab, nm.id)
if v_entry_rb is not None:
v_entry_rb.Alloca = new_alloca
@@ -1858,10 +1858,10 @@ class AssignGenMixin:
# FakeDuck: 初始化影子结构体 __data__ 字段 = 初始字符串指针
# (对齐 TPC HandlesAnnAssign.py: 仅当有初值时写入 __data__)
if fd_str_ty is not None and fd_meta_alloca is not None:
fd_data_fe: GenTypes.FieldEntry | t.CPtr = \
fd_data_fe: rawptr[GenTypes.FieldEntry] = \
self.Gen.StructGen.lookup_field(fd_str_ty, "__data__")
if fd_data_fe is not None:
fd_data_ptr: llvmlite.Value | t.CPtr = \
fd_data_ptr: rawptr[llvmlite.Value] = \
llvmlite.build_gep_struct(
builder, fd_str_ty, fd_data_fe.Ty,
fd_meta_alloca, fd_data_fe.Index)
@@ -1878,12 +1878,12 @@ class AssignGenMixin:
# with 上下文提供的 __mbuddy__ 注入由 _inject_requires_fields(fd4)完成,
# 此处仅确保影子结构体初始为空指针(对齐 TPC HandlesAnnAssign.py L667-670)。
if fd_str_ty is not None and fd_meta_alloca is not None:
fd_buddy_fe: GenTypes.FieldEntry | t.CPtr = \
fd_buddy_fe: rawptr[GenTypes.FieldEntry] = \
self.Gen.StructGen.lookup_field(fd_str_ty, "__mbuddy__")
if fd_buddy_fe is not None and fd_buddy_fe.Ty is not None:
fd_null: llvmlite.Value | t.CPtr = llvmlite.ConstNull(
fd_null: rawptr[llvmlite.Value] = llvmlite.ConstNull(
pool, fd_buddy_fe.Ty, "null")
fd_buddy_ptr: llvmlite.Value | t.CPtr = \
fd_buddy_ptr: rawptr[llvmlite.Value] = \
llvmlite.build_gep_struct(
builder, fd_str_ty, fd_buddy_fe.Ty,
fd_meta_alloca, fd_buddy_fe.Index)
@@ -1911,14 +1911,14 @@ class AssignGenMixin:
VLogger.error("cast failed", "ASGN")
return 0
targets: list[rawptr[ast.AST]] | t.CPtr = asgn.targets
targets: rawptr[list[rawptr[ast.AST]]] = asgn.targets
if targets is None:
VLogger.error("targets is None", "ASGN")
return 0
# 从 trans 取共享状态(替代 11 个参数)
pool: rawptr[memhub.MemBuddy] = trans.Pool
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
mod: rawptr[llvmlite.LLVMModule] = trans.Module
# 翻译 RHS 值
@@ -1936,14 +1936,14 @@ class AssignGenMixin:
if asg_t0 is not None and asg_t0.kind() == ast.ASTKind.Name:
asg_nm0: rawptr[ast.Name] = rawptr[ast.Name](asg_t0)
if asg_nm0.id is not None:
asg_slot: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
asg_slot: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
trans.SymTab, asg_nm0.id)
if asg_slot is None:
asg_slot = self.Gen.VarGen.lookup_module_var(
trans.SymTab, asg_nm0.id)
if asg_slot is not None and asg_slot.Ty is not None:
asg_target_ty = asg_slot.Ty.Pointee
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
builder, pool, mod, asgn.value, None, 0, trans, asg_target_ty)
if rhs_val is None:
# 增强错误信息:包含文件名 + lineno + AST 节点详情,便于定位
@@ -2008,14 +2008,14 @@ class AssignGenMixin:
# store + GEP 逐字段 load → store 到各 Name 目标。
if tk == ast.ASTKind.Tuple:
tgt_tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](target)
tgt_elts: list[rawptr[ast.AST]] | t.CPtr = tgt_tup.elts
tgt_elts: rawptr[list[rawptr[ast.AST]]] = tgt_tup.elts
# 守卫:rhs 不是 struct(tuple 打包)时跳过本 target
if tgt_elts is None or rhs_val is None or rhs_val.Ty is None:
continue
match rhs_val.Ty:
case llvmlite.LLVMType.Struct(_, _, _):
tgt_n: sizet = len(tgt_elts)
tmp_s: llvmlite.Value | t.CPtr = llvmlite.build_alloca(builder, rhs_val.Ty)
tmp_s: rawptr[llvmlite.Value] = llvmlite.build_alloca(builder, rhs_val.Ty)
if tmp_s is not None:
llvmlite.build_store(builder, rhs_val, tmp_s)
fchain: rawptr[llvmlite.Function] = llvmlite.get_struct_fields(rhs_val.Ty)
@@ -2036,19 +2036,19 @@ class AssignGenMixin:
tgt_nm2: rawptr[ast.Name] = rawptr[ast.Name](tgt_elt)
if tgt_nm2.id is None:
continue
fp2: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
fp2: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
builder, rhs_val.Ty, fty, tmp_s, fti)
if fp2 is None:
continue
fv2: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, fty, fp2)
tgt_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
fv2: rawptr[llvmlite.Value] = llvmlite.build_load(builder, fty, fp2)
tgt_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
trans.SymTab, tgt_nm2.id)
if tgt_alloca is None:
tgt_alloca = self.Gen.VarGen.get_or_create_sym(
trans.SymTab, pool, builder, tgt_nm2.id, fty)
if tgt_alloca is None:
continue
sval: llvmlite.Value | t.CPtr = fv2
sval: rawptr[llvmlite.Value] = fv2
if tgt_alloca.Ty is not None and tgt_alloca.Ty.Pointee is not None:
sval = self.Gen.ExprGenBase.coerce_to_type(
builder, fv2, tgt_alloca.Ty.Pointee, node, trans)
@@ -2061,13 +2061,13 @@ class AssignGenMixin:
if tk == ast.ASTKind.Subscript:
# 检查是否是 list[T] 类型的 Subscript(泛型类不注册 struct)
# list 的 subscript 赋值走 __setitem__ 内联路径
list_obj: llvmlite.Value | t.CPtr = self.Gen.ExprGenName.is_list_subscript(
list_obj: rawptr[llvmlite.Value] = self.Gen.ExprGenName.is_list_subscript(
target, trans)
if list_obj is not None:
# list[T] 类型: 内联生成 __setitem__ 逻辑
sub_node: rawptr[ast.Subscript] = rawptr[ast.Subscript](target)
if sub_node is not None and sub_node.slice is not None:
list_idx_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
list_idx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
builder, pool, mod, sub_node.slice, None, 0, trans)
if list_idx_val is None:
# fail-fast: list 下标翻译失败,立即终止
@@ -2076,10 +2076,10 @@ class AssignGenMixin:
builder, pool, list_obj, list_idx_val, rhs_val, target)
continue
# 普通 Subscript 赋值
elem_ptr: llvmlite.Value | t.CPtr = self.Gen.ExprGenName.get_subscript_ptr(
elem_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenName.get_subscript_ptr(
builder, pool, mod, target, trans)
if elem_ptr is not None:
store_val: llvmlite.Value | t.CPtr = rhs_val
store_val: rawptr[llvmlite.Value] = rhs_val
# 守卫短路:elem 类型完整才做类型转换
if elem_ptr.Ty is not None and elem_ptr.Ty.Pointee is not None:
store_val = self.Gen.ExprGenBase.coerce_to_type(
@@ -2094,14 +2094,14 @@ class AssignGenMixin:
if sub_asgn.value.kind() == ast.ASTKind.Name:
sub_nm: rawptr[ast.Name] = rawptr[ast.Name](sub_asgn.value)
if sub_nm.id is not None:
sub_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
sub_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
trans.SymTab, sub_nm.id)
if sub_alloca is not None and sub_alloca.Ty is not None \
and sub_alloca.Ty.Pointee is not None \
and self.Gen.ExprGenBase.is_ptr_type(sub_alloca.Ty) != 0:
sub_pointee: rawptr[llvmlite.LLVMType] = sub_alloca.Ty.Pointee
cls_nm_set: str = self.Gen.StructGen.get_class_name_by_type(pool, sub_pointee)
obj_val_set: llvmlite.Value | t.CPtr = llvmlite.build_load(
obj_val_set: rawptr[llvmlite.Value] = llvmlite.build_load(
builder, sub_pointee, sub_alloca)
# 指针类型变量 (X|t.CPtr): sub_pointee 是 Ptr(Struct),
# 需 load 获取 Ptr(Struct) 再检查 inner struct
@@ -2111,7 +2111,7 @@ class AssignGenMixin:
cls_nm_set = self.Gen.StructGen.get_class_name_by_type(
pool, sub_pointee.Pointee)
if cls_nm_set is not None and obj_val_set is not None:
key_val_set: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
key_val_set: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
builder, pool, mod, sub_asgn.slice, None, 0, trans)
if key_val_set is not None:
arg_vals_set: sizet | t.CPtr = pool.alloc(16)
@@ -2125,14 +2125,14 @@ class AssignGenMixin:
elif sub_asgn.value.kind() == ast.ASTKind.Attribute:
# self._ht[key] = val → self._ht.__setitem__(key, val)
# 通过 get_attribute_ptr 获取字段指针,再调用 __setitem__
field_ptr_set: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.get_attribute_ptr(
field_ptr_set: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr(
builder, pool, mod, sub_asgn.value, trans)
if field_ptr_set is not None and field_ptr_set.Ty is not None \
and field_ptr_set.Ty.Pointee is not None \
and self.Gen.ExprGenBase.is_ptr_type(field_ptr_set.Ty) != 0:
field_pointee_set: rawptr[llvmlite.LLVMType] = field_ptr_set.Ty.Pointee
cls_nm_attr: str = self.Gen.StructGen.get_class_name_by_type(pool, field_pointee_set)
obj_val_attr: llvmlite.Value | t.CPtr = field_ptr_set
obj_val_attr: rawptr[llvmlite.Value] = field_ptr_set
# field_ptr 是 Ptr(Ptr(Struct)) (X|t.CPtr 字段):
# load 解引用获取 Ptr(Struct)
if cls_nm_attr is None \
@@ -2144,7 +2144,7 @@ class AssignGenMixin:
obj_val_attr = llvmlite.build_load(
builder, field_pointee_set, field_ptr_set)
if cls_nm_attr is not None and obj_val_attr is not None:
key_val_attr: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
key_val_attr: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
builder, pool, mod, sub_asgn.slice, None, 0, trans)
if key_val_attr is not None:
arg_vals_attr: sizet | t.CPtr = pool.alloc(16)
@@ -2159,9 +2159,9 @@ class AssignGenMixin:
# 通用 fallback: 翻译 sub.value 并尝试 __setitem__ 或直接 GEP+store
# 处理 Name/Attribute 之外的节点以及 SymTab 查找失败的情况
if sub_asgn is not None and sub_asgn.value is not None:
obj_val_gen: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
obj_val_gen: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
builder, pool, mod, sub_asgn.value, None, 0, trans)
key_val_gen: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
key_val_gen: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
builder, pool, mod, sub_asgn.slice, None, 0, trans)
if obj_val_gen is not None and key_val_gen is not None \
and obj_val_gen.Ty is not None:
@@ -2187,8 +2187,8 @@ class AssignGenMixin:
# 非自定义结构体: 直接 GEP + store
# 处理 get_subscript_ptr 因边界情况返回 None 的指针下标
elem_gen: rawptr[llvmlite.LLVMType] = obj_val_gen.Ty.Pointee
store_val_gen: llvmlite.Value | t.CPtr = rhs_val
elem_ptr_gen: llvmlite.Value | t.CPtr = None
store_val_gen: rawptr[llvmlite.Value] = rhs_val
elem_ptr_gen: rawptr[llvmlite.Value] = None
match elem_gen:
case llvmlite.LLVMType.Array(arr_elem_gen, _):
elem_ptr_gen = llvmlite.build_gep_array(
@@ -2228,21 +2228,21 @@ class AssignGenMixin:
fd_meta_w: str = pool.alloc(256)
if fd_meta_w is not None:
viperlib.snprintf(fd_meta_w, 256, "%s__meta__", fd_obj_nm.id)
fd_meta_vw: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_current(
fd_meta_vw: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current(
trans.SymTab, fd_meta_w)
if fd_meta_vw is not None:
fd_sty_w: rawptr[llvmlite.LLVMType] = \
self.Gen.StructGen.get_struct_type("_str")
if fd_sty_w is not None:
fd_fe_w: GenTypes.FieldEntry | t.CPtr = \
fd_fe_w: rawptr[GenTypes.FieldEntry] = \
self.Gen.StructGen.lookup_field(fd_sty_w, fd_an.attr)
if fd_fe_w is not None and fd_fe_w.Ty is not None:
fd_fp_w: llvmlite.Value | t.CPtr = \
fd_fp_w: rawptr[llvmlite.Value] = \
llvmlite.build_gep_struct(
builder, fd_sty_w, fd_fe_w.Ty,
fd_meta_vw, fd_fe_w.Index)
if fd_fp_w is not None:
sv_fd: llvmlite.Value | t.CPtr = \
sv_fd: rawptr[llvmlite.Value] = \
self.Gen.ExprGenBase.coerce_to_type(
builder, rhs_val, fd_fe_w.Ty, node)
llvmlite.build_store(builder, sv_fd, fd_fp_w)
@@ -2254,11 +2254,11 @@ class AssignGenMixin:
if self.Gen.CallGenVt._write_vtable_attr(
builder, pool, mod, target, rhs_val, trans) == 1:
continue
field_ptr: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.get_attribute_ptr(
field_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr(
builder, pool, mod, target, trans)
if field_ptr is not None:
# 获取字段类型,对 rhs_val 进行类型转换(如 i32 → i64)
store_val: llvmlite.Value | t.CPtr = rhs_val
store_val: rawptr[llvmlite.Value] = rhs_val
if field_ptr.Ty is not None and field_ptr.Ty.Pointee is not None:
store_val = self.Gen.ExprGenBase.coerce_to_type(
builder, rhs_val, field_ptr.Ty.Pointee, node, trans)
@@ -2291,7 +2291,7 @@ class AssignGenMixin:
continue
# global 变量:写入模块作用域中的全局变量
if GenApi.is_global_name(trans, nm.id) != 0:
mod_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
mod_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(
trans.SymTab, nm.id)
if mod_alloca is None:
# fail-fast: global 变量未注册,无法赋值
@@ -2302,7 +2302,7 @@ class AssignGenMixin:
# 对象类全局(裸类名注解 → 静态 storage):对象构造/赋值 → 引用绑定
# 到 storage + 复制对象到 storage;否则 store 栈 alloca 指针悬垂,
# 或模块级构造初始化器被丢弃后全局保持 NULL(见 TranslatorGenMixin)。
stg_ref_as: llvmlite.Value | t.CPtr = None
stg_ref_as: rawptr[llvmlite.Value] = None
if nm.id is not None:
stg_key_as: str = pool.alloc(sizet(string.strlen(nm.id)) + 8)
if stg_key_as is not None:
@@ -2323,7 +2323,7 @@ class AssignGenMixin:
# 1) @g 引用绑定到 storage(丢弃临时 alloca,避免悬垂)
llvmlite.build_store(builder, stg_ref_as, mod_alloca)
# 2) 复制构造结果(临时对象)到 storage(函数内复制,alloca 仍有效)
stg_obj_val_as: llvmlite.Value | t.CPtr = llvmlite.build_load(
stg_obj_val_as: rawptr[llvmlite.Value] = llvmlite.build_load(
builder, stg_ty_as, rhs_val)
if stg_obj_val_as is not None:
llvmlite.build_store(builder, stg_obj_val_as, stg_ref_as)
@@ -2338,7 +2338,7 @@ class AssignGenMixin:
# nonlocal 变量:通过闭包 env 写入
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
nl_ptr: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
nl_ptr: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
trans, nm.id)
if nl_ptr is None:
# fail-fast: nonlocal 变量指针解析失败
@@ -2357,7 +2357,7 @@ class AssignGenMixin:
target,
f"nonlocal 变量 '{nm.id}' 类型信息丢失,无法写入",
"TypeError")
rhs_coerced: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
rhs_coerced: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
builder, rhs_val, nl_target_ty, node, trans)
llvmlite.build_store(builder, rhs_coerced, nl_ptr)
continue
@@ -2366,13 +2366,13 @@ class AssignGenMixin:
# 否则静默创建局部变量遮蔽全局,全局保持 null 导致运行时崩溃
# (_mbuddy = mb 缺 global 声明即此类 bug:Int32 解引用 null 崩溃)
if self.Gen.VarGen.is_module_scope(trans.SymTab) == 0:
mod_gv: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
mod_gv: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(
trans.SymTab, nm.id)
if mod_gv is not None:
self.Gen.TypeGenErr.fatal_error(target, f"变量 '{nm.id}' 是模块级全局变量,函数内赋值需用 global 声明(否则创建局部变量遮蔽全局,导致全局保持 null 崩溃)", "SyntaxError")
# 普通局部变量
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.get_or_create_sym(
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.get_or_create_sym(
trans.SymTab, pool, builder, nm.id, rhs_val.Ty)
if alloca is not None:
# 无注解赋值:从 RHS 表达式推断类名设置变量注解
@@ -2383,7 +2383,7 @@ class AssignGenMixin:
self.Gen.VarGen.set_var_annot_class_name(
trans.SymTab, nm.id, cls_inf)
# 按 alloca 类型对值进行转换(如 double → float)
store_val: llvmlite.Value | t.CPtr = rhs_val
store_val: rawptr[llvmlite.Value] = rhs_val
if alloca.Ty is not None and alloca.Ty.Pointee is not None:
store_val = self.Gen.ExprGenBase.coerce_to_type(
builder, rhs_val, alloca.Ty.Pointee, node, trans)
@@ -2395,7 +2395,7 @@ class AssignGenMixin:
if asgn.value is not None \
and asgn.value.kind() == ast.ASTKind.Lambda:
self.Gen.CallGenLeafKit.register_closure_name(nm.id)
existing: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_current(
existing: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current(
trans.SymTab, nm.id)
if existing is None:
new_vars += 1
@@ -2427,7 +2427,7 @@ class AssignGenMixin:
mod: rawptr[llvmlite.LLVMModule],
node: rawptr[ast.AST],
trans: rawptr[HT.Translator],
rhs_val: llvmlite.Value | t.CPtr = None) -> str:
rhs_val: rawptr[llvmlite.Value] = None) -> str:
"""从 RHS 表达式推断类名,无法推断返回 None"""
if node is None or trans is None:
return None
@@ -2442,7 +2442,7 @@ class AssignGenMixin:
cand: str = (rawptr[ast.Name](cl.func)).id
if cand is None:
return None
se: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(cand)
se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(cand)
if se is not None:
return cand
return None
@@ -2504,7 +2504,7 @@ class AssignGenMixin:
nm: rawptr[ast.Name] = rawptr[ast.Name](node)
if nm is None or nm.id is None:
return None
ve: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
trans.SymTab, nm.id)
if ve is None:
return None
@@ -2572,7 +2572,7 @@ class AssignGenMixin:
if seglen > 0 and seglen < 256:
string.strncpy(seg, annot + s, seglen)
seg[seglen] = '\0'
se: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(seg)
se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(seg)
if se is not None:
return seg
start = i + 1
@@ -2587,7 +2587,7 @@ class AssignGenMixin:
if seglen > 0 and seglen < 256:
string.strncpy(seg, annot + s, seglen)
seg[seglen] = '\0'
se: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(seg)
se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(seg)
if se is not None:
return seg
return None