diff --git a/App/lib/core/Gen/AssignGenMixin.vp b/App/lib/core/Gen/AssignGenMixin.vp index f6efeee..376353f 100644 --- a/App/lib/core/Gen/AssignGenMixin.vp +++ b/App/lib/core/Gen/AssignGenMixin.vp @@ -585,9 +585,7 @@ novirtual class AssignGenMixin: # UnaryOp(USub, Constant)),故只拦 CONST_FLOAT 这一种内层形态。 if val_node is not None and val_node.kind() == ast.ASTKind.UnaryOp: uu_cd: ast.UnaryOp* = ast.UnaryOp*(val_node) - if uu_cd is not None and uu_cd.op == OpKind.USub \ - and uu_cd.operand is not None \ - and uu_cd.operand.kind() == ast.ASTKind.Constant: + if uu_cd is not None and uu_cd.op == ast.OpKind.USub and uu_cd.operand is not None and uu_cd.operand.kind() == ast.ASTKind.Constant: ic_cd: ast.Constant* = ast.Constant*(uu_cd.operand) if ic_cd is not None and ic_cd.const_kind == ast.CONST_FLOAT: val_node = uu_cd.operand @@ -3034,16 +3032,20 @@ novirtual class AssignGenMixin: # Attribute 赋值: obj.field = val if tk == ast.ASTKind.Attribute: + # 目标类型已由上面的 ASTKind 判据确定为 Attribute ⇒ 在此显式窄化。 + # 必须窄化:_try_property_setter 的形参是 ast.Attribute*,而 target + # 是基类 ast.AST*;基类指针传派生类形参属向下转型,严格指针规则下禁止。 + at_tg: ast.Attribute* = ast.Attribute*(target) # property setter 拦截: obj.attr = v 且 attr 是 @x.setter 方法时, # 生成 call Class.attr$set(obj, v),跳过字段存储 # 注意参数顺序:_try_property_setter(pool, builder, mod, ...)。 - if self.Gen.CallGenProp._try_property_setter(pool, builder, mod, target, rhs_val, trans) == 1: + if self.Gen.CallGenProp._try_property_setter(pool, builder, mod, at_tg, rhs_val, trans) == 1: continue # FakeDuck: 影子结构体属性写入 (str 变量的 per-instance 字段) # a.__data__ = v → GEP {a}__meta__[field] 并 store # 对齐 TPC HandlesAssign.py L67-76:对象是 Name 变量且存在 # {var}__meta__ 影子(fd2 创建)时,属性写入改走影子结构体。 - fd_an: ast.Attribute* = ast.Attribute*(target) + fd_an: ast.Attribute* = at_tg if fd_an is not None and fd_an.value is not None and fd_an.attr is not None: if fd_an.value.kind() == ast.ASTKind.Name: fd_obj_nm: ast.Name* = ast.Name*(fd_an.value) @@ -3544,7 +3546,7 @@ novirtual class AssignGenMixin: mro_ptr: sizet* = self.Gen.StructGen.get_mro_chain(pool, class_name) mi: int = 1 while mro_ptr is not None and mro_ptr[mi] != 0: - anc: str = (str | t.CPtr)(mro_ptr[mi]) + anc: str = rawptr(mro_ptr[mi]) if anc is not None: anc_lookup: str = pool.alloc(128) if anc_lookup is not None: diff --git a/App/lib/core/Gen/Type/TypeGenResolve.vp b/App/lib/core/Gen/Type/TypeGenResolve.vp index 1eead2f..32ab540 100644 --- a/App/lib/core/Gen/Type/TypeGenResolve.vp +++ b/App/lib/core/Gen/Type/TypeGenResolve.vp @@ -1218,7 +1218,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): stdlib.free(key_buf) if v is None: return None - return (str | t.CPtr)(v) + return t.CPtr(v) def _lookup_library_typedef(self, pool: memhub.MemBuddy*, mod: str, attr: str) -> str: """查库模块源文件中 "attr: t.CTypedef = TYPE" 并注册,返回 TYPE 或 None @@ -1365,36 +1365,36 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): or string.strstr(triple, "msvc") is not None: return llvmlite.Int32(pool) return llvmlite.Int64(pool) - # ============================================================ - # _IsCallableSubscriptValue - Subscript 的 value 是否为函数指针类型构造子 - # - # 两种书写形态逐点等价(同 i8*): - # t.Callable[...] / c.Callable[...] → Attribute(attr="Callable") - # callable[...] / Callable[...] → Name(内建别名,注解位置生效) - # 用于放行"空下标/空参数表"的无签名形态(slice=None / 空 List): - # t.Callable[] / t.Callable[[]] / callable[] / callable[[]] - # ============================================================ - def _IsCallableSubscriptValue(self, value_node: ast.AST*) -> int: - if value_node is None: - return 0 - vk: int = value_node.kind() - if vk == ast.ASTKind.Attribute: - at: ast.Attribute* = ast.Attribute*(value_node) - if at.attr is None: - return 0 - if string.strcmp(at.attr, "Callable") == 0: - return 1 - return 0 - if vk == ast.ASTKind.Name: - nm: ast.Name* = ast.Name*(value_node) - if nm.id is None: - return 0 - if string.strcmp(nm.id, "callable") == 0: - return 1 - if string.strcmp(nm.id, "Callable") == 0: - return 1 - return 0 - + # ============================================================ + # _IsCallableSubscriptValue - Subscript 的 value 是否为函数指针类型构造子 + # + # 两种书写形态逐点等价(同 i8*): + # t.Callable[...] / c.Callable[...] → Attribute(attr="Callable") + # callable[...] / Callable[...] → Name(内建别名,注解位置生效) + # 用于放行"空下标/空参数表"的无签名形态(slice=None / 空 List): + # t.Callable[] / t.Callable[[]] / callable[] / callable[[]] + # ============================================================ + def _IsCallableSubscriptValue(self, value_node: ast.AST*) -> int: + if value_node is None: + return 0 + vk: int = value_node.kind() + if vk == ast.ASTKind.Attribute: + at: ast.Attribute* = ast.Attribute*(value_node) + if at.attr is None: + return 0 + if string.strcmp(at.attr, "Callable") == 0: + return 1 + return 0 + if vk == ast.ASTKind.Name: + nm: ast.Name* = ast.Name*(value_node) + if nm.id is None: + return 0 + if string.strcmp(nm.id, "callable") == 0: + return 1 + if string.strcmp(nm.id, "Callable") == 0: + return 1 + return 0 + def map_t_type(self, pool: memhub.MemBuddy*, type_name: str) -> llvmlite.LLVMType*: """将 t.CXxx / c.CXxx 类型名映射到 LLVMType