diff --git a/App/lib/core/Handles/HandlesAnnAssign.vp b/App/lib/core/Handles/HandlesAnnAssign.vp index 68f0581..5356d3a 100644 --- a/App/lib/core/Handles/HandlesAnnAssign.vp +++ b/App/lib/core/Handles/HandlesAnnAssign.vp @@ -338,11 +338,11 @@ class AnnAssignHandle(HandlesBase.Mixin): if resolved is not None: var_ty = resolved else: - # fast-fail: 注解类型解析失败,不再静默回退 i32(会导致变量类型错误) - VLogger.error( + # fast-fail: 注解类型解析失败,Python traceback 立即终止(不静默回退 i32) + HandlesType.fatal_error( + aa, f"变量类型注解解析失败,变量名: {nm.id}", - "HandlesAnnAssign") - var_ty = llvmlite.Int32(pool) + "TypeError") else: # fast-fail: AnnAssign 必须有 annotation VLogger.error( @@ -411,11 +411,11 @@ class AnnAssignHandle(HandlesBase.Mixin): if resolved is not None: var_ty = resolved else: - # fast-fail: 注解类型解析失败,不再静默回退 i32 - VLogger.error( + # fast-fail: 注解类型解析失败,Python traceback 立即终止(不静默回退 i32) + HandlesType.fatal_error( + aa, f"变量类型注解解析失败,变量名: {nm.id}", - "HandlesAnnAssign") - var_ty = llvmlite.Int32(pool) + "TypeError") else: # fast-fail: AnnAssign 必须有 annotation VLogger.error( diff --git a/App/lib/core/Handles/HandlesExprCall.vp b/App/lib/core/Handles/HandlesExprCall.vp index a9284c3..9d2e871 100644 --- a/App/lib/core/Handles/HandlesExprCall.vp +++ b/App/lib/core/Handles/HandlesExprCall.vp @@ -2166,12 +2166,12 @@ def translate_c_llvmir(pool: memhub.MemBuddy | t.CPtr, _llvmir_store_outputs(pool, builder, binop_result, output_targets, output_count) return binop_result - # 未识别的指令,返回 0 - fb_li: t.CChar | t.CPtr = VLogger.fmt_buf() - if fb_li is not None: - viperlib.snprintf(fb_li, 1024, "unsupported instruction: %s", instr_kw) - VLogger.error(fb_li, "LLVMIR") - return None + # 未识别的指令:fast-fail,Python traceback 立即终止。 + # 静默返回 None 会让上层把 None 当 0 处理,产生错误 IR 或崩溃,丢失错误现场。 + HandlesType.fatal_error( + cl, + f"unsupported instruction: {instr_kw}", + "SyntaxError") # ============================================================ # _apply_struct_defaults — 应用结构体字段的默认值 @@ -4883,9 +4883,12 @@ def translate_call(pool: memhub.MemBuddy | t.CPtr, if cl.func is not None and cl.func.kind() == ast.ASTKind.Name: bare_fn_name: str = HandlesType.resolve_generic_type_name(func_name) bare_ty: llvmlite.LLVMType | t.CPtr = None - # 泛型上下文解析出的内建名(如 T→"double"):map_t_type 只认 t.CDouble - if string.strcmp(bare_fn_name, "double") == 0 or string.strcmp(bare_fn_name, "float") == 0: + # 泛型上下文解析出的内建名(如 T→"double"/"float"):map_t_type 只认 t.CDouble, + # 且 float 必须映射 t.CFloat(f32)而非 f64(与注解语义一致) + if string.strcmp(bare_fn_name, "double") == 0: bare_ty = llvmlite.Double(pool) + elif string.strcmp(bare_fn_name, "float") == 0: + bare_ty = llvmlite.Float(pool) else: bare_ty = HandlesType.map_t_type(pool, bare_fn_name) # 泛型上下文替换出的类型名(如 T→"t.CInt")map_t_type 不识别(只认无前缀名), diff --git a/App/lib/core/Handles/HandlesFunctions.vp b/App/lib/core/Handles/HandlesFunctions.vp index 1a79f27..9a4a6ca 100644 --- a/App/lib/core/Handles/HandlesFunctions.vp +++ b/App/lib/core/Handles/HandlesFunctions.vp @@ -300,6 +300,16 @@ def forward_declare_functions(trans: HT.Translator | t.CPtr, ch: list[ast.AST | t.CPtr] | t.CPtr = tree.children if ch is None: return 0 + + # 解析函数签名期间临时切换到"仅声明"模式: + # 签名里的泛型类注解(如 _empty_like(a: ndarray[t.CDouble]))会触发泛型特化, + # 若此时特化立即翻译方法体,方法体前向引用同模块后续函数(如 _empty_like 自身) + # 会因 declare 尚未创建而报"裸名调用未定义且未导入"。 + # 临时 declare_only=1 使特化只注册结构体(mark_only 不译方法体), + # 方法体由后续 resolve_annotation_type 命中已注册结构体时补译 + # (_specialize_generic_class 的 Phase B 补译分支)。 + saved_declare_only: int = trans._declare_only + trans._declare_only = 1 cn_count: t.CSizeT = ch.__len__() for ci in range(cn_count): @@ -419,6 +429,8 @@ def forward_declare_functions(trans: HT.Translator | t.CPtr, # 参数添加完成,补全全局函数表的 TypeStr(供 vtable 在 func 被 reset 后使用) HandlesExprCall.update_global_func_typestr(trans.Pool, fd.name, func) + # 恢复原始声明模式 + trans._declare_only = saved_declare_only return 0 diff --git a/App/lib/core/Handles/HandlesType.vp b/App/lib/core/Handles/HandlesType.vp index c3bf2b3..427d86e 100644 --- a/App/lib/core/Handles/HandlesType.vp +++ b/App/lib/core/Handles/HandlesType.vp @@ -1044,6 +1044,11 @@ def map_t_type(pool: memhub.MemBuddy | t.CPtr, return llvmlite.Float(pool) elif string.strcmp(type_name, "DOUBLE") == 0: return llvmlite.Double(pool) + # 小写裸名浮点类型(float = t.CFloat = f32, double = t.CDouble = f64) + elif string.strcmp(type_name, "float") == 0: + return llvmlite.Float(pool) + elif string.strcmp(type_name, "double") == 0: + return llvmlite.Double(pool) elif string.strcmp(type_name, "FSIZE_t") == 0: return llvmlite.Int32(pool) elif string.strcmp(type_name, "LBA_t") == 0: @@ -1392,6 +1397,10 @@ def extract_class_name_from_annotation(node: ast.AST | t.CPtr, return None if string.strcmp(cn.str_val, "bool") == 0: return None + if string.strcmp(cn.str_val, "float") == 0: + return None + if string.strcmp(cn.str_val, "double") == 0: + return None return cn.str_val return None @@ -1409,6 +1418,10 @@ def extract_class_name_from_annotation(node: ast.AST | t.CPtr, return None if string.strcmp(nm.id, "bool") == 0: return None + if string.strcmp(nm.id, "float") == 0: + return None + if string.strcmp(nm.id, "double") == 0: + return None return nm.id # Attribute 节点: memhub.MemBuddy → "memhub.MemBuddy"(模块限定名) @@ -1580,6 +1593,11 @@ def resolve_annotation_type(pool: memhub.MemBuddy | t.CPtr, elif string.strcmp(nm.id, "bool") == 0: # bool = t.CBool = i1(与 map_t_type 中 CBool 映射一致) return llvmlite.Int1(pool) + # 裸名浮点类型: float = t.CFloat = f32, double = t.CDouble = f64 + elif string.strcmp(nm.id, "float") == 0: + return llvmlite.Float(pool) + elif string.strcmp(nm.id, "double") == 0: + return llvmlite.Double(pool) # class 名称: 查找已注册的 StructType,返回 StructType 本身(不包装 Ptr) # 这样 build_alloca 会分配结构体大小的空间,alloca 返回 struct_ty* # 命名空间隔离:严格模式下仅解析可见的结构体