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:
TermiNexus committed 2026-08-10 02:11:26 +08:00
1 parent 34a37358c9
commit 24c1aada30
6 files changed
+4396 -3573

No files matched your search

+6 -2
View File
@@ -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
+2 -1
View File
@@ -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):
File diff suppressed because it is too large. Load diff
+59 -327
View File
@@ -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
View File
@@ -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()