修正了一些错误
This commit is contained in:
@@ -12,6 +12,7 @@ import lib.core.Handles.HandlesType as HandlesType
|
||||
import lib.core.Handles.HandlesNonlocal as HandlesNonlocal
|
||||
import lib.core.Handles.HandlesClassDef as HandlesClassDef
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Handles.HandlesStruct as HandlesStruct
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -62,6 +63,64 @@ def extract_cdefine_int_value(val_node: ast.AST | t.CPtr) -> int:
|
||||
return cn.int_val
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _annotation_contains_name - 递归检查注解中是否包含指定名称
|
||||
#
|
||||
# 支持 BinOp(BitOr) 递归,同时检查 Attribute.attr 和 Name.id。
|
||||
# ============================================================
|
||||
def _annotation_contains_name(annot: ast.AST | t.CPtr, name: str) -> int:
|
||||
"""递归检查注解中是否包含指定名称,返回 1=包含 / 0=不包含"""
|
||||
if annot is None or name is None:
|
||||
return 0
|
||||
k: int = annot.kind()
|
||||
if k == ast.ASTKind.Attribute:
|
||||
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(annot)
|
||||
if at.attr is not None and string.strcmp(at.attr, name) == 0:
|
||||
return 1
|
||||
return 0
|
||||
if k == ast.ASTKind.Name:
|
||||
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(annot)
|
||||
if nm.id is not None and string.strcmp(nm.id, name) == 0:
|
||||
return 1
|
||||
return 0
|
||||
if k == ast.ASTKind.BinOp:
|
||||
bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(annot)
|
||||
if _annotation_contains_name(bop.left, name) != 0:
|
||||
return 1
|
||||
if _annotation_contains_name(bop.right, name) != 0:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _is_ptr_element_annotation - 检查注解是否为 bytes|t.CPtr 或 str|t.CPtr
|
||||
#
|
||||
# 返回 1=是(下标按 8 字节步长, i8** 语义), 0=否(下标按 1 字节步长, i8* 语义)
|
||||
#
|
||||
# 规则:
|
||||
# bytes|t.CPtr / str|t.CPtr → i8**(8 字节步长)→ 返回 1
|
||||
# t.CChar|t.CPtr / t.CInt8T|t.CPtr → i8*(1 字节步长)→ 返回 0
|
||||
# 纯 bytes / str → i8*(1 字节步长)→ 返回 0
|
||||
#
|
||||
# 注: 注解中的 "|" 是"和"的意思(组合类型),非右值中的位或运算
|
||||
# ============================================================
|
||||
def _is_ptr_element_annotation(annot: ast.AST | t.CPtr) -> int:
|
||||
"""检查注解是否为 bytes|t.CPtr 或 str|t.CPtr 形式"""
|
||||
if annot is None:
|
||||
return 0
|
||||
k: int = annot.kind()
|
||||
if k != ast.ASTKind.BinOp:
|
||||
return 0
|
||||
bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(annot)
|
||||
if bop.op != ast.OpKind.BitOr:
|
||||
return 0
|
||||
if _annotation_contains_name(annot, "str") != 0:
|
||||
return 1
|
||||
if _annotation_contains_name(annot, "bytes") != 0:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
@t.NoVTable
|
||||
class AnnAssignHandle(HandlesBase.Mixin):
|
||||
"""AnnAssign 语句处理器:继承 Mixin 获得 Trans 回指针"""
|
||||
@@ -121,7 +180,7 @@ class AnnAssignHandle(HandlesBase.Mixin):
|
||||
annot: ast.AST | t.CPtr = aa.annotation
|
||||
if annot is not None:
|
||||
resolved: llvmlite.LLVMType | t.CPtr = HandlesType.resolve_annotation_type(
|
||||
pool, annot, self.Trans._imported_modules, self.Trans._from_imports)
|
||||
pool, annot, self.Trans._imported_modules, self.Trans._from_imports, self.Trans)
|
||||
if resolved is None:
|
||||
# 尝试特化泛型类注解(如 list[str])
|
||||
# resolve_annotation_type 返回 None 可能是因为泛型类未特化
|
||||
@@ -138,11 +197,13 @@ class AnnAssignHandle(HandlesBase.Mixin):
|
||||
self.Trans, sub_nm.id, type_args_ps)
|
||||
if spec_name_ps is not None:
|
||||
resolved = HandlesType.resolve_annotation_type(
|
||||
pool, annot, self.Trans._imported_modules, self.Trans._from_imports)
|
||||
pool, annot, self.Trans._imported_modules, self.Trans._from_imports, self.Trans)
|
||||
if resolved is not None:
|
||||
var_ty = resolved
|
||||
|
||||
alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(builder, var_ty)
|
||||
# 确保跨模块结构体的完整定义在当前模块中可用(供 alloca 分配空间)
|
||||
HandlesStruct.ensure_struct_def_in_module(pool, self.Trans.Module, var_ty)
|
||||
alloca: llvmlite.Value | t.CPtr = HandlesVar._alloca_at_entry(builder, var_ty)
|
||||
if alloca is not None:
|
||||
if HandlesVar.define_var(
|
||||
self.Trans.SymTab, nm.id, alloca) == 0:
|
||||
@@ -153,6 +214,10 @@ class AnnAssignHandle(HandlesBase.Mixin):
|
||||
if cls_nm_ps is not None:
|
||||
HandlesVar.set_var_annot_class_name(
|
||||
self.Trans.SymTab, nm.id, cls_nm_ps)
|
||||
# 检查是否为 bytes|t.CPtr 或 str|t.CPtr(i8** 语义,8 字节步长)
|
||||
if _is_ptr_element_annotation(annot) != 0:
|
||||
HandlesVar.set_var_ptr_element(
|
||||
self.Trans.SymTab, nm.id)
|
||||
return 0
|
||||
return 0
|
||||
|
||||
@@ -193,7 +258,7 @@ class AnnAssignHandle(HandlesBase.Mixin):
|
||||
annot: ast.AST | t.CPtr = aa.annotation
|
||||
if annot is not None:
|
||||
resolved: llvmlite.LLVMType | t.CPtr = HandlesType.resolve_annotation_type(
|
||||
pool, annot, self.Trans._imported_modules, self.Trans._from_imports)
|
||||
pool, annot, self.Trans._imported_modules, self.Trans._from_imports, self.Trans)
|
||||
if resolved is not None:
|
||||
var_ty = resolved
|
||||
|
||||
@@ -243,6 +308,10 @@ class AnnAssignHandle(HandlesBase.Mixin):
|
||||
if cls_nm_hd is not None:
|
||||
HandlesVar.set_var_annot_class_name(
|
||||
self.Trans.SymTab, nm.id, cls_nm_hd)
|
||||
# 检查是否为 bytes|t.CPtr 或 str|t.CPtr(i8** 语义,8 字节步长)
|
||||
if _is_ptr_element_annotation(annot) != 0:
|
||||
HandlesVar.set_var_ptr_element(
|
||||
self.Trans.SymTab, nm.id)
|
||||
|
||||
new_vars: int = 0
|
||||
existing: llvmlite.Value | t.CPtr = HandlesVar.lookup_current(
|
||||
|
||||
Reference in New Issue
Block a user