fix(compiler): 支持裸名 float/double 映射 + 前向声明时序 + 类型解析 fast-fail traceback

- resolve_annotation_type Name 分支与 map_t_type 补小写 float(→f32)/double(→f64),
  float(0.0) 转换原误映射 f64 改为 f32(vipermath fmodf result: float 修复)
- forward_declare_functions 解析签名期间临时切 declare_only=1,
  签名触发的泛型特化只注册结构体,方法体延迟补译(numpy _empty_like 前向引用修复)
- HandlesAnnAssign 变量类型注解解析失败改 fatal_error(Python traceback)
- c.LLVMIR 未识别指令改 fatal_error 立即终止(原静默返回 None)
This commit is contained in:
TermiNexus committed 2026-08-08 15:59:08 +08:00
1 parent ee8f532dc5
commit 3a6296d638
4 files changed
+49 -16

No files matched your search

+8 -8
View File
@@ -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(
+11 -8
View File
@@ -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 不识别(只认无前缀名),
+12
View File
@@ -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
+18
View File
@@ -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*
# 命名空间隔离:严格模式下仅解析可见的结构体