refactor(gen): P3 ExprGenMixin - HandlesExpr/ExprOps 51 函数迁移 + 委托层
HandlesExpr 45 个表达式函数(translate_value/subscript/attribute 等) 与 HandlesExprOps 6 个运算符函数(try_operator_overload/translate_binop 等)迁移为 ExprGenMixin 方法;本模块调用 self 化、外部模块调用保留 前缀,_lookup_cross_module_cdefine(490 行)完整迁移。旧函数保留为 _g_gen 单例委托。Generator 多继承追加 ExprGenMixin(4 Mixin 组合)。
This commit is contained in:
1 parent
34a37358c9
commit
24c1aada30
6 files changed
+4396
-3573
No files matched your search
@@ -14,6 +14,8 @@ import lib.core.VLogger as VLogger
|
|||||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||||
import lib.core.Handles.HandlesStruct as HandlesStruct
|
import lib.core.Handles.HandlesStruct as HandlesStruct
|
||||||
import lib.core.Handles.HandlesType as HandlesType
|
import lib.core.Handles.HandlesType as HandlesType
|
||||||
|
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||||
|
import lib.core.Handles.HandlesExprOps as HandlesExprOps
|
||||||
import lib.core.Handles.HandlesImports as HandlesImports
|
import lib.core.Handles.HandlesImports as HandlesImports
|
||||||
import lib.core.StubMerger as StubMerger
|
import lib.core.StubMerger as StubMerger
|
||||||
import lib.StubGen.Converter as StubConverter
|
import lib.StubGen.Converter as StubConverter
|
||||||
@@ -142,10 +144,12 @@ def TranslateFileGetTrans(mb: memhub.MemBuddy | t.CPtr, file_path: str,
|
|||||||
gen.__before_init__()
|
gen.__before_init__()
|
||||||
gen.__init__(mb)
|
gen.__init__(mb)
|
||||||
GenGenerator.set_global_gen(gen)
|
GenGenerator.set_global_gen(gen)
|
||||||
# P2: 注入 HandlesType/HandlesStruct 模块级单例(委托函数经本地 _g_gen 访问,
|
# P2/P3: 注入 HandlesType/HandlesStruct/HandlesExpr/HandlesExprOps 模块级单例
|
||||||
# 避免函数体 import 包模块与 Generator 类/模块名歧义)
|
# (委托函数经本地 _g_gen 访问,避免函数体 import 包模块与类/模块名歧义)
|
||||||
HandlesType.set_global_gen(gen)
|
HandlesType.set_global_gen(gen)
|
||||||
HandlesStruct.set_global_gen(gen)
|
HandlesStruct.set_global_gen(gen)
|
||||||
|
HandlesExpr.set_global_gen(gen)
|
||||||
|
HandlesExprOps.set_global_gen(gen)
|
||||||
# 设置当前文件名(供报错使用)
|
# 设置当前文件名(供报错使用)
|
||||||
HandlesType.set_current_file(file_path)
|
HandlesType.set_current_file(file_path)
|
||||||
# 同步到 HandlesImports(import 时 SHA1 检查报错需要当前文件名,循环依赖无法直接读 HandlesType)
|
# 同步到 HandlesImports(import 时 SHA1 检查报错需要当前文件名,循环依赖无法直接读 HandlesType)
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -5,6 +5,7 @@ import llvmlite
|
|||||||
import lib.core.Gen.BaseGenMixin as BaseGenMixin
|
import lib.core.Gen.BaseGenMixin as BaseGenMixin
|
||||||
import lib.core.Gen.TypeGenMixin as TypeGenMixin
|
import lib.core.Gen.TypeGenMixin as TypeGenMixin
|
||||||
import lib.core.Gen.StructGenMixin as StructGenMixin
|
import lib.core.Gen.StructGenMixin as StructGenMixin
|
||||||
|
import lib.core.Gen.ExprGenMixin as ExprGenMixin
|
||||||
import lib.core.Handles.HandlesVar as HandlesVar
|
import lib.core.Handles.HandlesVar as HandlesVar
|
||||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
|||||||
# ============================================================
|
# ============================================================
|
||||||
@t.NoVTable
|
@t.NoVTable
|
||||||
class Generator(BaseGenMixin.BaseGenMixin, TypeGenMixin.TypeGenMixin,
|
class Generator(BaseGenMixin.BaseGenMixin, TypeGenMixin.TypeGenMixin,
|
||||||
StructGenMixin.StructGenMixin):
|
StructGenMixin.StructGenMixin, ExprGenMixin.ExprGenMixin):
|
||||||
"""生成器:多继承 Mixin 组合(对象化迁移宿主)"""
|
"""生成器:多继承 Mixin 组合(对象化迁移宿主)"""
|
||||||
|
|
||||||
def __init__(self, pool: memhub.MemBuddy | t.CPtr):
|
def __init__(self, pool: memhub.MemBuddy | t.CPtr):
|
||||||
|
|||||||
+294
-3242
File diff suppressed because it is too large.
Load diff
@@ -11,50 +11,64 @@ import lib.core.Handles.HandlesTranslator as HT
|
|||||||
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
# HandlesExprOps - 二元运算处理(模块级纯函数)
|
# HandlesExprOps - 二元运算处理(P3 对象化后的委托层)
|
||||||
|
#
|
||||||
|
# 全部函数已迁移为 lib.core.Gen.ExprGenMixin 的方法,本模块保留
|
||||||
|
# 同名模块级函数作为"一行委托":延迟 import Gen 取全局单例
|
||||||
|
# (BuildPipeline/main 创建后 set_global_gen 注册),再调用 gen
|
||||||
|
# 的对应方法。签名与旧函数完全一致,调用方零改动。
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
# 运算符重载支持
|
# 全局 gen 单例(模块级镜像,同 HandlesType/HandlesStruct 模式)
|
||||||
#
|
#
|
||||||
# 当二元/比较运算的 lhs 是结构体指针时,检查该类是否定义了
|
# 由 BuildPipeline/main 在 gen 创建后调用 set_global_gen 注入。
|
||||||
# 对应的 dunder 方法(如 __add__、__eq__),若有则生成方法调用
|
# P3 委托函数用本地 _g_gen(cast 成 Generator 类型)调
|
||||||
# 而非原生算术/比较指令。
|
# ExprGenMixin 方法。
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
_g_gen: t.CVoid | t.CPtr = None
|
||||||
|
|
||||||
|
|
||||||
|
def set_global_gen(gen: t.CVoid | t.CPtr) -> None:
|
||||||
|
"""注入全局 gen 单例(BuildPipeline/main 调用)"""
|
||||||
|
global _g_gen
|
||||||
|
_g_gen = gen
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# 委托函数:延迟 import Gen 取全局单例 → 调 gen 方法
|
||||||
|
# (gen 未注册时正常流程不会发生;有返回值函数返回默认值)
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
|
||||||
# BinOp 运算符 → dunder 方法名
|
# BinOp 运算符 → dunder 方法名
|
||||||
def _binop_to_dunder(op: int) -> str:
|
def _binop_to_dunder(op: int) -> str:
|
||||||
"""将 BinOp 运算符映射到 dunder 方法名,无映射时返回 None"""
|
"""将 BinOp 运算符映射到 dunder 方法名,无映射时返回 None(委托到 gen._binop_to_dunder)"""
|
||||||
if op == ast.OpKind.Add: return "__add__"
|
import lib.core.Gen.Generator as Generator
|
||||||
if op == ast.OpKind.Sub: return "__sub__"
|
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||||
if op == ast.OpKind.Mult: return "__mul__"
|
if g is not None:
|
||||||
if op == ast.OpKind.Div: return "__div__"
|
return g._binop_to_dunder(op)
|
||||||
if op == ast.OpKind.Mod: return "__mod__"
|
|
||||||
if op == ast.OpKind.BitAnd: return "__and__"
|
|
||||||
if op == ast.OpKind.BitOr: return "__or__"
|
|
||||||
if op == ast.OpKind.BitXor: return "__xor__"
|
|
||||||
if op == ast.OpKind.LShift: return "__lshift__"
|
|
||||||
if op == ast.OpKind.RShift: return "__rshift__"
|
|
||||||
if op == ast.OpKind.FloorDiv: return "__floordiv__"
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
# Compare 运算符 → dunder 方法名
|
# Compare 运算符 → dunder 方法名
|
||||||
def _cmpop_to_dunder(op: int) -> str:
|
def _cmpop_to_dunder(op: int) -> str:
|
||||||
"""将 Compare 运算符映射到 dunder 方法名,无映射时返回 None"""
|
"""将 Compare 运算符映射到 dunder 方法名,无映射时返回 None(委托到 gen._cmpop_to_dunder)"""
|
||||||
if op == ast.OpKind.Eq: return "__eq__"
|
import lib.core.Gen.Generator as Generator
|
||||||
if op == ast.OpKind.Ne: return "__ne__"
|
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||||
if op == ast.OpKind.Lt: return "__lt__"
|
if g is not None:
|
||||||
if op == ast.OpKind.Le: return "__le__"
|
return g._cmpop_to_dunder(op)
|
||||||
if op == ast.OpKind.Gt: return "__gt__"
|
|
||||||
if op == ast.OpKind.Ge: return "__ge__"
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
# UnaryOp 运算符 → dunder 方法名
|
# UnaryOp 运算符 → dunder 方法名
|
||||||
def _unaryop_to_dunder(op: int) -> str:
|
def _unaryop_to_dunder(op: int) -> str:
|
||||||
"""将 UnaryOp 运算符映射到 dunder 方法名,无映射时返回 None"""
|
"""将 UnaryOp 运算符映射到 dunder 方法名,无映射时返回 None(委托到 gen._unaryop_to_dunder)"""
|
||||||
if op == ast.OpKind.USub: return "__neg__"
|
import lib.core.Gen.Generator as Generator
|
||||||
if op == ast.OpKind.UAdd: return "__pos__"
|
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||||
if op == ast.OpKind.Invert: return "__invert__"
|
if g is not None:
|
||||||
|
return g._unaryop_to_dunder(op)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -64,19 +78,6 @@ def _unaryop_to_dunder(op: int) -> str:
|
|||||||
# 检查 lhs 是否为结构体指针,并在该类(含继承链)中查找对应的
|
# 检查 lhs 是否为结构体指针,并在该类(含继承链)中查找对应的
|
||||||
# dunder 方法。找到则生成方法调用 lhs.__dunder__(rhs),返回
|
# dunder 方法。找到则生成方法调用 lhs.__dunder__(rhs),返回
|
||||||
# 调用结果;未找到返回 None,调用方回退到原生运算。
|
# 调用结果;未找到返回 None,调用方回退到原生运算。
|
||||||
#
|
|
||||||
# Args:
|
|
||||||
# pool: 内存池
|
|
||||||
# builder: IRBuilder
|
|
||||||
# mod: LLVM 模块
|
|
||||||
# lhs: 左操作数 Value(已求值)
|
|
||||||
# rhs: 右操作数 Value(已求值)
|
|
||||||
# op: OpKind 运算符
|
|
||||||
# trans: Translator 对象
|
|
||||||
# is_compare: 0=BinOp, 1=Compare(决定 dunder 映射表)
|
|
||||||
#
|
|
||||||
# Returns:
|
|
||||||
# 方法调用的 Value(成功),None(未重载)
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
def try_operator_overload(pool: memhub.MemBuddy | t.CPtr,
|
def try_operator_overload(pool: memhub.MemBuddy | t.CPtr,
|
||||||
builder: llvmlite.IRBuilder | t.CPtr,
|
builder: llvmlite.IRBuilder | t.CPtr,
|
||||||
@@ -86,89 +87,12 @@ def try_operator_overload(pool: memhub.MemBuddy | t.CPtr,
|
|||||||
op: int,
|
op: int,
|
||||||
trans: HT.Translator | t.CPtr,
|
trans: HT.Translator | t.CPtr,
|
||||||
is_compare: int) -> llvmlite.Value | t.CPtr:
|
is_compare: int) -> llvmlite.Value | t.CPtr:
|
||||||
"""尝试运算符重载:lhs 是结构体指针时调用 dunder 方法,否则返回 None"""
|
"""尝试运算符重载:lhs 是结构体指针时调用 dunder 方法,否则返回 None(委托到 gen.try_operator_overload)"""
|
||||||
if lhs is None or rhs is None:
|
import lib.core.Gen.Generator as Generator
|
||||||
return None
|
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||||
|
if g is not None:
|
||||||
# 延迟导入避免循环依赖
|
return g.try_operator_overload(pool, builder, mod, lhs, rhs, op, trans, is_compare)
|
||||||
import lib.core.Handles.HandlesStruct as HandlesStruct
|
return None
|
||||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
|
||||||
|
|
||||||
# 映射运算符到 dunder 方法名
|
|
||||||
dunder: str = None
|
|
||||||
if is_compare != 0:
|
|
||||||
dunder = _cmpop_to_dunder(op)
|
|
||||||
else:
|
|
||||||
dunder = _binop_to_dunder(op)
|
|
||||||
if dunder is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 检查 lhs 是否为结构体指针
|
|
||||||
struct_ty: llvmlite.LLVMType | t.CPtr = HandlesStruct.get_struct_type_from_value(lhs)
|
|
||||||
if struct_ty is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 获取类名
|
|
||||||
class_name: str = HandlesStruct.get_class_name_by_type(pool, struct_ty)
|
|
||||||
if class_name is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 在继承链中查找 dunder 方法
|
|
||||||
lookup_name: t.CChar | t.CPtr = pool.alloc(128)
|
|
||||||
if lookup_name is None:
|
|
||||||
return None
|
|
||||||
viperlib.snprintf(lookup_name, 128, "%s.%s", class_name, dunder)
|
|
||||||
found_func: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module(mod, lookup_name)
|
|
||||||
|
|
||||||
search_class: str = class_name
|
|
||||||
if found_func is None:
|
|
||||||
# 多继承:沿 MRO 祖先链查找(先声明父类优先)
|
|
||||||
mro_ptr: t.CSizeT | t.CPtr = HandlesStruct.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)(t.CVoid(mro_ptr[mi], t.CPtr))
|
|
||||||
if anc is not None:
|
|
||||||
parent_lookup: t.CChar | t.CPtr = pool.alloc(128)
|
|
||||||
if parent_lookup is not None:
|
|
||||||
viperlib.snprintf(parent_lookup, 128, "%s.%s", anc, dunder)
|
|
||||||
parent_func: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module(mod, parent_lookup)
|
|
||||||
if parent_func is not None:
|
|
||||||
found_func = parent_func
|
|
||||||
search_class = anc
|
|
||||||
break
|
|
||||||
mi += 1
|
|
||||||
|
|
||||||
# 方法不在当前模块中时,检查类(含父类)是否有 SHA1(stub 可能未注入)
|
|
||||||
# 优先用类型指针定位 entry 获取 SHA1(规避跨模块同名 find_struct 找错)
|
|
||||||
cls_sha1: str = None
|
|
||||||
op_entry: HandlesStruct.StructEntry | t.CPtr = HandlesStruct.find_struct_by_type(struct_ty)
|
|
||||||
if op_entry is not None:
|
|
||||||
cls_sha1 = op_entry.ModuleSha1
|
|
||||||
if cls_sha1 is None:
|
|
||||||
cls_sha1 = HandlesStruct.get_struct_sha1(search_class)
|
|
||||||
if cls_sha1 is None:
|
|
||||||
mro_p: t.CSizeT | t.CPtr = HandlesStruct.get_mro_chain(pool, search_class)
|
|
||||||
mj: int = 1
|
|
||||||
while mro_p is not None and mro_p[mj] != 0 and cls_sha1 is None:
|
|
||||||
anc_p: str = (str | t.CPtr)(t.CVoid(mro_p[mj], t.CPtr))
|
|
||||||
if anc_p is not None:
|
|
||||||
cls_sha1 = HandlesStruct.get_struct_sha1(anc_p)
|
|
||||||
mj += 1
|
|
||||||
|
|
||||||
# 既无函数定义也无 SHA1 → 该类没有此 dunder 方法,返回 None 回退原生运算
|
|
||||||
if found_func is None and cls_sha1 is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 构建 extra_args 数组(仅含 rhs 一个参数)
|
|
||||||
extra_args: t.CSizeT | t.CPtr = pool.alloc(8)
|
|
||||||
if extra_args is None:
|
|
||||||
return None
|
|
||||||
extra_args[0] = t.CSizeT(rhs)
|
|
||||||
|
|
||||||
# 调用方法: lhs.__dunder__(rhs)
|
|
||||||
return HandlesExprCall._call_method_on_ptr(
|
|
||||||
pool, builder, mod, search_class, dunder,
|
|
||||||
lhs, extra_args, 1, trans)
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
@@ -184,77 +108,12 @@ def try_unary_operator_overload(pool: memhub.MemBuddy | t.CPtr,
|
|||||||
operand: llvmlite.Value | t.CPtr,
|
operand: llvmlite.Value | t.CPtr,
|
||||||
op: int,
|
op: int,
|
||||||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||||
"""尝试一元运算符重载:operand 是结构体指针时调用 dunder 方法,否则返回 None"""
|
"""尝试一元运算符重载:operand 是结构体指针时调用 dunder 方法,否则返回 None(委托到 gen.try_unary_operator_overload)"""
|
||||||
if operand is None:
|
import lib.core.Gen.Generator as Generator
|
||||||
return None
|
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||||
|
if g is not None:
|
||||||
# 延迟导入避免循环依赖
|
return g.try_unary_operator_overload(pool, builder, mod, operand, op, trans)
|
||||||
import lib.core.Handles.HandlesStruct as HandlesStruct
|
return None
|
||||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
|
||||||
|
|
||||||
dunder: str = _unaryop_to_dunder(op)
|
|
||||||
if dunder is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 检查 operand 是否为结构体指针
|
|
||||||
struct_ty: llvmlite.LLVMType | t.CPtr = HandlesStruct.get_struct_type_from_value(operand)
|
|
||||||
if struct_ty is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 获取类名
|
|
||||||
class_name: str = HandlesStruct.get_class_name_by_type(pool, struct_ty)
|
|
||||||
if class_name is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 在继承链中查找 dunder 方法
|
|
||||||
lookup_name: t.CChar | t.CPtr = pool.alloc(128)
|
|
||||||
if lookup_name is None:
|
|
||||||
return None
|
|
||||||
viperlib.snprintf(lookup_name, 128, "%s.%s", class_name, dunder)
|
|
||||||
found_func: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module(mod, lookup_name)
|
|
||||||
|
|
||||||
search_class: str = class_name
|
|
||||||
if found_func is None:
|
|
||||||
# 多继承:沿 MRO 祖先链查找(先声明父类优先)
|
|
||||||
mro_ptr: t.CSizeT | t.CPtr = HandlesStruct.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)(t.CVoid(mro_ptr[mi], t.CPtr))
|
|
||||||
if anc is not None:
|
|
||||||
parent_lookup: t.CChar | t.CPtr = pool.alloc(128)
|
|
||||||
if parent_lookup is not None:
|
|
||||||
viperlib.snprintf(parent_lookup, 128, "%s.%s", anc, dunder)
|
|
||||||
parent_func: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module(mod, parent_lookup)
|
|
||||||
if parent_func is not None:
|
|
||||||
found_func = parent_func
|
|
||||||
search_class = anc
|
|
||||||
break
|
|
||||||
mi += 1
|
|
||||||
|
|
||||||
# 方法不在当前模块中时,检查类(含父类)是否有 SHA1(stub 可能未注入)
|
|
||||||
cls_sha1: str = None
|
|
||||||
uop_entry: HandlesStruct.StructEntry | t.CPtr = HandlesStruct.find_struct_by_type(struct_ty)
|
|
||||||
if uop_entry is not None:
|
|
||||||
cls_sha1 = uop_entry.ModuleSha1
|
|
||||||
if cls_sha1 is None:
|
|
||||||
cls_sha1 = HandlesStruct.get_struct_sha1(search_class)
|
|
||||||
if cls_sha1 is None:
|
|
||||||
mro_p: t.CSizeT | t.CPtr = HandlesStruct.get_mro_chain(pool, search_class)
|
|
||||||
mj: int = 1
|
|
||||||
while mro_p is not None and mro_p[mj] != 0 and cls_sha1 is None:
|
|
||||||
anc_p: str = (str | t.CPtr)(t.CVoid(mro_p[mj], t.CPtr))
|
|
||||||
if anc_p is not None:
|
|
||||||
cls_sha1 = HandlesStruct.get_struct_sha1(anc_p)
|
|
||||||
mj += 1
|
|
||||||
|
|
||||||
# 既无函数定义也无 SHA1 → 该类没有此 dunder 方法,返回 None 回退原生运算
|
|
||||||
if found_func is None and cls_sha1 is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 一元方法无额外参数(extra_args 为空)
|
|
||||||
return HandlesExprCall._call_method_on_ptr(
|
|
||||||
pool, builder, mod, search_class, dunder,
|
|
||||||
operand, None, 0, trans)
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
@@ -265,136 +124,9 @@ def translate_binop(pool: memhub.MemBuddy | t.CPtr,
|
|||||||
mod: llvmlite.LLVMModule | t.CPtr,
|
mod: llvmlite.LLVMModule | t.CPtr,
|
||||||
node: ast.AST | t.CPtr,
|
node: ast.AST | t.CPtr,
|
||||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||||
"""翻译二元运算(自动类型提升)"""
|
"""翻译二元运算(自动类型提升)(委托到 gen.translate_binop)"""
|
||||||
binop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
|
import lib.core.Gen.Generator as Generator
|
||||||
if binop is None:
|
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||||
return None
|
if g is not None:
|
||||||
|
return g.translate_binop(pool, builder, mod, node, trans)
|
||||||
lhs_node: ast.AST | t.CPtr = binop.left
|
|
||||||
rhs_node: ast.AST | t.CPtr = binop.right
|
|
||||||
op: int = binop.op
|
|
||||||
|
|
||||||
# 先翻译 rhs(只翻译一次,避免副作用重复)
|
|
||||||
rhs: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
|
|
||||||
builder, pool, mod, rhs_node, None, 0, trans)
|
|
||||||
if rhs is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# === 运算符重载路径 1: lhs 是 Name 且对应结构体变量 ===
|
|
||||||
# 对于值类型变量(如 cnt: Counter),translate_value 会 load 返回 Struct 值,
|
|
||||||
# 但 dunder 方法需要 Ptr(Struct) 作为 self。直接用 alloca 指针尝试重载。
|
|
||||||
if lhs_node is not None and lhs_node.kind() == ast.ASTKind.Name and trans is not None:
|
|
||||||
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(lhs_node)
|
|
||||||
if nm is not None and nm.id is not None:
|
|
||||||
lhs_alloca: llvmlite.Value | t.CPtr = HandlesVar.lookup_var(
|
|
||||||
trans.SymTab, nm.id)
|
|
||||||
if lhs_alloca is not None:
|
|
||||||
ovl_result: llvmlite.Value | t.CPtr = try_operator_overload(
|
|
||||||
pool, builder, mod, lhs_alloca, rhs, op, trans, 0)
|
|
||||||
if ovl_result is not None:
|
|
||||||
return ovl_result
|
|
||||||
|
|
||||||
# 正常翻译 lhs
|
|
||||||
lhs: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
|
|
||||||
builder, pool, mod, lhs_node, None, 0, trans)
|
|
||||||
if lhs is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# === 运算符重载路径 2: lhs 是 Ptr(Struct)(如 Counter|t.CPtr 变量 load 后)===
|
|
||||||
ovl_result2: llvmlite.Value | t.CPtr = try_operator_overload(
|
|
||||||
pool, builder, mod, lhs, rhs, op, trans, 0)
|
|
||||||
if ovl_result2 is not None:
|
|
||||||
return ovl_result2
|
|
||||||
|
|
||||||
# 获取操作数类型信息
|
|
||||||
lhs_bits: int = HandlesExpr.get_llvm_type_bits(lhs.Ty)
|
|
||||||
rhs_bits: int = HandlesExpr.get_llvm_type_bits(rhs.Ty)
|
|
||||||
lhs_fbits: int = HandlesExpr.get_llvm_float_bits(lhs.Ty)
|
|
||||||
rhs_fbits: int = HandlesExpr.get_llvm_float_bits(rhs.Ty)
|
|
||||||
|
|
||||||
# 浮点运算: 任一操作数为浮点时,使用浮点指令(必须在指针算术之前检查,
|
|
||||||
# 因为 float 的 int bits 为 0,会被误认为指针)
|
|
||||||
if lhs_fbits != 0 or rhs_fbits != 0:
|
|
||||||
# 确定目标浮点类型(使用较大的位宽)
|
|
||||||
target_fbits: int = lhs_fbits
|
|
||||||
if rhs_fbits > target_fbits:
|
|
||||||
target_fbits = rhs_fbits
|
|
||||||
target_float_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Double(pool)
|
|
||||||
if target_fbits == 32:
|
|
||||||
target_float_ty = llvmlite.Float(pool)
|
|
||||||
# 将两个操作数转换为目标浮点类型(int→float via si2fp, float→float via fpext/fptrunc)
|
|
||||||
lhs = HandlesExpr.coerce_to_type(builder, lhs, target_float_ty, node)
|
|
||||||
rhs = HandlesExpr.coerce_to_type(builder, rhs, target_float_ty, node)
|
|
||||||
if op == ast.OpKind.Add:
|
|
||||||
return llvmlite.build_fadd(builder, lhs, rhs)
|
|
||||||
if op == ast.OpKind.Sub:
|
|
||||||
return llvmlite.build_fsub(builder, lhs, rhs)
|
|
||||||
if op == ast.OpKind.Mult:
|
|
||||||
return llvmlite.build_fmul(builder, lhs, rhs)
|
|
||||||
if op == ast.OpKind.Div:
|
|
||||||
return llvmlite.build_fdiv(builder, lhs, rhs)
|
|
||||||
if op == ast.OpKind.Mod:
|
|
||||||
return llvmlite.build_frem(builder, lhs, rhs)
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 指针算术: ptr + int / ptr - int / int + ptr → getelementptr(按元素大小缩放)
|
|
||||||
# 对齐 TPC ExprGen.emit_binary_op L50-67;int - ptr 无 GEP 形式(C 语义非法)
|
|
||||||
if (lhs_bits == 0 and rhs_bits != 0) or (lhs_bits != 0 and rhs_bits == 0):
|
|
||||||
if op == ast.OpKind.Add:
|
|
||||||
if lhs_bits == 0:
|
|
||||||
return HandlesExpr.translate_ptr_arith(pool, builder, lhs, rhs, op)
|
|
||||||
# int + ptr(交换)
|
|
||||||
return HandlesExpr.translate_ptr_arith(pool, builder, rhs, lhs, op)
|
|
||||||
if op == ast.OpKind.Sub and lhs_bits == 0:
|
|
||||||
return HandlesExpr.translate_ptr_arith(pool, builder, lhs, rhs, op)
|
|
||||||
|
|
||||||
if lhs_bits > rhs_bits:
|
|
||||||
if HandlesExpr.should_zext_widen(pool, rhs, lhs, rhs_node) != 0:
|
|
||||||
rhs = llvmlite.build_zext(builder, rhs, lhs.Ty)
|
|
||||||
else:
|
|
||||||
rhs = HandlesExpr.coerce_to_type(builder, rhs, lhs.Ty, node)
|
|
||||||
elif rhs_bits > lhs_bits:
|
|
||||||
if HandlesExpr.should_zext_widen(pool, lhs, rhs, lhs_node) != 0:
|
|
||||||
lhs = llvmlite.build_zext(builder, lhs, rhs.Ty)
|
|
||||||
else:
|
|
||||||
lhs = HandlesExpr.coerce_to_type(builder, lhs, rhs.Ty, node)
|
|
||||||
|
|
||||||
# 位运算类型安全检查:两边都是指针(lhs_bits==0 and rhs_bits==0)时,
|
|
||||||
# 位运算(BitOr/BitAnd/BitXor/LShift/RShift)非法,LLVM 要求整数操作数。
|
|
||||||
# 常见触发场景:CDefine 常量查找失败返回指针 null,与另一指针做 `|`。
|
|
||||||
if lhs_bits == 0 and rhs_bits == 0:
|
|
||||||
if op == ast.OpKind.BitOr or op == ast.OpKind.BitAnd or op == ast.OpKind.BitXor or op == ast.OpKind.LShift or op == ast.OpKind.RShift:
|
|
||||||
VLogger.error(
|
|
||||||
"位运算操作数类型非法: lhs/rhs 均为非整数类型(指针或结构体),无法执行位运算",
|
|
||||||
"BinOp")
|
|
||||||
return None
|
|
||||||
|
|
||||||
if op == ast.OpKind.Add:
|
|
||||||
return llvmlite.build_add(builder, lhs, rhs)
|
|
||||||
elif op == ast.OpKind.Sub:
|
|
||||||
return llvmlite.build_sub(builder, lhs, rhs)
|
|
||||||
elif op == ast.OpKind.Mult:
|
|
||||||
return llvmlite.build_mul(builder, lhs, rhs)
|
|
||||||
elif op == ast.OpKind.Div:
|
|
||||||
return llvmlite.build_sdiv(builder, lhs, rhs)
|
|
||||||
elif op == ast.OpKind.FloorDiv:
|
|
||||||
return llvmlite.build_sdiv(builder, lhs, rhs)
|
|
||||||
elif op == ast.OpKind.Mod:
|
|
||||||
return llvmlite.build_srem(builder, lhs, rhs)
|
|
||||||
elif op == ast.OpKind.BitAnd:
|
|
||||||
return llvmlite.build_and(builder, lhs, rhs)
|
|
||||||
elif op == ast.OpKind.BitOr:
|
|
||||||
return llvmlite.build_or(builder, lhs, rhs)
|
|
||||||
elif op == ast.OpKind.BitXor:
|
|
||||||
return llvmlite.build_xor(builder, lhs, rhs)
|
|
||||||
elif op == ast.OpKind.LShift:
|
|
||||||
return llvmlite.build_shl(builder, lhs, rhs)
|
|
||||||
elif op == ast.OpKind.RShift:
|
|
||||||
# 无符号 >> → lshr(逻辑右移),有符号 >> → ashr(算术右移)
|
|
||||||
# 对齐 TPC ExprGen.emit_binary_op:i8/i16 默认无符号;其余查操作数无符号性
|
|
||||||
if lhs_bits == 8 or lhs_bits == 16:
|
|
||||||
return llvmlite.build_lshr(builder, lhs, rhs)
|
|
||||||
if HandlesExpr._node_type_unsigned(pool, lhs_node, trans) != 0:
|
|
||||||
return llvmlite.build_lshr(builder, lhs, rhs)
|
|
||||||
return llvmlite.build_ashr(builder, lhs, rhs)
|
|
||||||
return None
|
return None
|
||||||
+6
-1
@@ -15,6 +15,8 @@ import lib
|
|||||||
import lib.core.VLogger as VLogger
|
import lib.core.VLogger as VLogger
|
||||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||||
import lib.core.Handles.HandlesStruct as HandlesStruct
|
import lib.core.Handles.HandlesStruct as HandlesStruct
|
||||||
|
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||||
|
import lib.core.Handles.HandlesExprOps as HandlesExprOps
|
||||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||||
import lib.core.Handles.HandlesType as HandlesType
|
import lib.core.Handles.HandlesType as HandlesType
|
||||||
import lib.core.BuildPipeline as BuildPipeline
|
import lib.core.BuildPipeline as BuildPipeline
|
||||||
@@ -87,9 +89,12 @@ def main() -> int:
|
|||||||
gen.__before_init__()
|
gen.__before_init__()
|
||||||
gen.__init__(mb)
|
gen.__init__(mb)
|
||||||
GenGenerator.set_global_gen(gen)
|
GenGenerator.set_global_gen(gen)
|
||||||
# P2: 注入 HandlesType/HandlesStruct 模块级单例(Phase1 阶段即调用其状态函数)
|
# P2/P3: 注入 HandlesType/HandlesStruct/HandlesExpr/HandlesExprOps 模块级单例
|
||||||
|
# (Phase1 阶段即调用其状态函数)
|
||||||
HandlesType.set_global_gen(gen)
|
HandlesType.set_global_gen(gen)
|
||||||
HandlesStruct.set_global_gen(gen)
|
HandlesStruct.set_global_gen(gen)
|
||||||
|
HandlesExpr.set_global_gen(gen)
|
||||||
|
HandlesExprOps.set_global_gen(gen)
|
||||||
|
|
||||||
# 初始化 VLogger 并打印启动日志
|
# 初始化 VLogger 并打印启动日志
|
||||||
log: VLogger.Logger | t.CPtr = VLogger.get_logger()
|
log: VLogger.Logger | t.CPtr = VLogger.get_logger()
|
||||||
|
|||||||
Reference in new issue
Block a user