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.HandlesStruct as HandlesStruct
|
||||
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.StubMerger as StubMerger
|
||||
import lib.StubGen.Converter as StubConverter
|
||||
@@ -142,10 +144,12 @@ def TranslateFileGetTrans(mb: memhub.MemBuddy | t.CPtr, file_path: str,
|
||||
gen.__before_init__()
|
||||
gen.__init__(mb)
|
||||
GenGenerator.set_global_gen(gen)
|
||||
# P2: 注入 HandlesType/HandlesStruct 模块级单例(委托函数经本地 _g_gen 访问,
|
||||
# 避免函数体 import 包模块与 Generator 类/模块名歧义)
|
||||
# P2/P3: 注入 HandlesType/HandlesStruct/HandlesExpr/HandlesExprOps 模块级单例
|
||||
# (委托函数经本地 _g_gen 访问,避免函数体 import 包模块与类/模块名歧义)
|
||||
HandlesType.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)
|
||||
# 同步到 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.TypeGenMixin as TypeGenMixin
|
||||
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.HandlesExprCall as HandlesExprCall
|
||||
|
||||
@@ -23,7 +24,7 @@ import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class Generator(BaseGenMixin.BaseGenMixin, TypeGenMixin.TypeGenMixin,
|
||||
StructGenMixin.StructGenMixin):
|
||||
StructGenMixin.StructGenMixin, ExprGenMixin.ExprGenMixin):
|
||||
"""生成器:多继承 Mixin 组合(对象化迁移宿主)"""
|
||||
|
||||
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 是结构体指针时,检查该类是否定义了
|
||||
# 对应的 dunder 方法(如 __add__、__eq__),若有则生成方法调用
|
||||
# 而非原生算术/比较指令。
|
||||
# 由 BuildPipeline/main 在 gen 创建后调用 set_global_gen 注入。
|
||||
# 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 方法名
|
||||
def _binop_to_dunder(op: int) -> str:
|
||||
"""将 BinOp 运算符映射到 dunder 方法名,无映射时返回 None"""
|
||||
if op == ast.OpKind.Add: return "__add__"
|
||||
if op == ast.OpKind.Sub: return "__sub__"
|
||||
if op == ast.OpKind.Mult: return "__mul__"
|
||||
if op == ast.OpKind.Div: return "__div__"
|
||||
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__"
|
||||
"""将 BinOp 运算符映射到 dunder 方法名,无映射时返回 None(委托到 gen._binop_to_dunder)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g._binop_to_dunder(op)
|
||||
return None
|
||||
|
||||
|
||||
# Compare 运算符 → dunder 方法名
|
||||
def _cmpop_to_dunder(op: int) -> str:
|
||||
"""将 Compare 运算符映射到 dunder 方法名,无映射时返回 None"""
|
||||
if op == ast.OpKind.Eq: return "__eq__"
|
||||
if op == ast.OpKind.Ne: return "__ne__"
|
||||
if op == ast.OpKind.Lt: return "__lt__"
|
||||
if op == ast.OpKind.Le: return "__le__"
|
||||
if op == ast.OpKind.Gt: return "__gt__"
|
||||
if op == ast.OpKind.Ge: return "__ge__"
|
||||
"""将 Compare 运算符映射到 dunder 方法名,无映射时返回 None(委托到 gen._cmpop_to_dunder)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g._cmpop_to_dunder(op)
|
||||
return None
|
||||
|
||||
|
||||
# UnaryOp 运算符 → dunder 方法名
|
||||
def _unaryop_to_dunder(op: int) -> str:
|
||||
"""将 UnaryOp 运算符映射到 dunder 方法名,无映射时返回 None"""
|
||||
if op == ast.OpKind.USub: return "__neg__"
|
||||
if op == ast.OpKind.UAdd: return "__pos__"
|
||||
if op == ast.OpKind.Invert: return "__invert__"
|
||||
"""将 UnaryOp 运算符映射到 dunder 方法名,无映射时返回 None(委托到 gen._unaryop_to_dunder)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g._unaryop_to_dunder(op)
|
||||
return None
|
||||
|
||||
|
||||
@@ -64,19 +78,6 @@ def _unaryop_to_dunder(op: int) -> str:
|
||||
# 检查 lhs 是否为结构体指针,并在该类(含继承链)中查找对应的
|
||||
# dunder 方法。找到则生成方法调用 lhs.__dunder__(rhs),返回
|
||||
# 调用结果;未找到返回 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,
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
@@ -86,89 +87,12 @@ def try_operator_overload(pool: memhub.MemBuddy | t.CPtr,
|
||||
op: int,
|
||||
trans: HT.Translator | t.CPtr,
|
||||
is_compare: int) -> llvmlite.Value | t.CPtr:
|
||||
"""尝试运算符重载:lhs 是结构体指针时调用 dunder 方法,否则返回 None"""
|
||||
if lhs is None or rhs is None:
|
||||
return None
|
||||
|
||||
# 延迟导入避免循环依赖
|
||||
import lib.core.Handles.HandlesStruct as HandlesStruct
|
||||
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)
|
||||
"""尝试运算符重载:lhs 是结构体指针时调用 dunder 方法,否则返回 None(委托到 gen.try_operator_overload)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
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)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -184,77 +108,12 @@ def try_unary_operator_overload(pool: memhub.MemBuddy | t.CPtr,
|
||||
operand: llvmlite.Value | t.CPtr,
|
||||
op: int,
|
||||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""尝试一元运算符重载:operand 是结构体指针时调用 dunder 方法,否则返回 None"""
|
||||
if operand is None:
|
||||
return None
|
||||
|
||||
# 延迟导入避免循环依赖
|
||||
import lib.core.Handles.HandlesStruct as HandlesStruct
|
||||
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)
|
||||
"""尝试一元运算符重载:operand 是结构体指针时调用 dunder 方法,否则返回 None(委托到 gen.try_unary_operator_overload)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
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)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -265,136 +124,9 @@ def translate_binop(pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译二元运算(自动类型提升)"""
|
||||
binop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
|
||||
if binop is None:
|
||||
return None
|
||||
|
||||
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)
|
||||
"""翻译二元运算(自动类型提升)(委托到 gen.translate_binop)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.translate_binop(pool, builder, mod, node, trans)
|
||||
return None
|
||||
+6
-1
@@ -15,6 +15,8 @@ import lib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
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.HandlesType as HandlesType
|
||||
import lib.core.BuildPipeline as BuildPipeline
|
||||
@@ -87,9 +89,12 @@ def main() -> int:
|
||||
gen.__before_init__()
|
||||
gen.__init__(mb)
|
||||
GenGenerator.set_global_gen(gen)
|
||||
# P2: 注入 HandlesType/HandlesStruct 模块级单例(Phase1 阶段即调用其状态函数)
|
||||
# P2/P3: 注入 HandlesType/HandlesStruct/HandlesExpr/HandlesExprOps 模块级单例
|
||||
# (Phase1 阶段即调用其状态函数)
|
||||
HandlesType.set_global_gen(gen)
|
||||
HandlesStruct.set_global_gen(gen)
|
||||
HandlesExpr.set_global_gen(gen)
|
||||
HandlesExprOps.set_global_gen(gen)
|
||||
|
||||
# 初始化 VLogger 并打印启动日志
|
||||
log: VLogger.Logger | t.CPtr = VLogger.get_logger()
|
||||
|
||||
Reference in new issue
Block a user