Files
ViperC/App/lib/core/Handles/HandlesExpr.vp
T

954 lines
49 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import lib.core.Gen.ExprGenAttr as ExprGenAttr
import lib.core.Gen.ExprGenBase as ExprGenBase
import lib.core.Gen.ExprGenCdef as ExprGenCdef
import lib.core.Gen.ExprGenCls as ExprGenCls
import lib.core.Gen.ExprGenConst as ExprGenConst
import lib.core.Gen.ExprGenFstr as ExprGenFstr
import lib.core.Gen.ExprGenMixin as ExprGenMixin
import lib.core.Gen.ExprGenName as ExprGenName
import lib.core.Gen.ExprGenOps as ExprGenOps
import lib.core.Gen.FuncGenMixin as FuncGenMixin
import t, c
from stdint import *
import ast
import memhub
import string
import llvmlite
import stdlib
import stdio
import viperlib
import w32.fileio as fileio
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.Stub.StubMerger as StubMerger
import lib.core.VLogger as VLogger
import lib.Projectrans.Config as Config
import lib.Projectrans.Utils as Utils
import lib.core.Gen.Generator as Generator
# ============================================================
# HandlesExpr - 表达式处理(P3 对象化后的委托层)
#
# 全部模块级函数已迁移为 lib.core.Gen.ExprGenMixin 的方法
# (全局状态迁入 gen 字段),本模块保留同名模块级函数作为
# "一行委托":延迟 import Gen 取全局单例(BuildPipeline/main
# 创建后 set_global_gen 注册),再调用 gen 的对应方法。签名与
# 旧函数完全一致,调用方零改动。
#
# ExprHandle 类及其 NewExprHandle 工厂保留(translator handler 模式)。
# ============================================================
# ============================================================
# 全局 gen 单例(模块级镜像,同 HandlesType/HandlesStruct 模式)
# ============================================================
_g_gen: Generator.Generator | t.CPtr = None
# ============================================================
# 委托函数:延迟 import Gen 取全局单例 → 调 gen 方法
# (gen 未注册时正常流程不会发生;有返回值函数返回默认值)
# ============================================================
# ============================================================
# 从 AST 节点提取函数名
# ============================================================
def get_func_name(func_node: ast.AST | t.CPtr) -> str:
"""从函数节点提取函数名(委托到 gen.get_func_name)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase.get_func_name(func_node)
return None
# ============================================================
# 转义 LLVM IR 字符串字面量
# ============================================================
def escape_llvm_string(pool: memhub.MemBuddy | t.CPtr,
src: str) -> str:
"""将字符串转换为 LLVM IR 字符串字面量 c"...\\00"(委托到 gen.escape_llvm_string)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase.escape_llvm_string(pool, src)
return None
# ============================================================
# 获取 LLVM 整数类型的位宽
# ============================================================
def get_llvm_type_bits(ty: llvmlite.LLVMType | t.CPtr) -> int:
"""获取 LLVM 整数类型的位宽,非整数类型返回 0(委托到 gen.get_llvm_type_bits)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase.get_llvm_type_bits(ty)
return 0
# ============================================================
# 获取 LLVM 浮点类型的位宽
# ============================================================
def get_llvm_float_bits(ty: llvmlite.LLVMType | t.CPtr) -> int:
"""获取 LLVM 浮点类型的位宽,非浮点类型返回 0(委托到 gen.get_llvm_float_bits)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase.get_llvm_float_bits(ty)
return 0
# ============================================================
# is_ptr_type - 检查类型是否为 Ptr
#
# 返回 1=是, 0=否。作为类型检查工具函数被广泛使用(50+ 处调用)。
# ============================================================
def is_ptr_type(ty: llvmlite.LLVMType | t.CPtr) -> int:
"""检查 ty 是否是 Ptr 类型,返回 1=是, 0=否(委托到 gen.is_ptr_type)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase.is_ptr_type(ty)
return 0
# ============================================================
# get_ptr_level - 计算指针层级
#
# 返回值:
# 0 = 非指针(数值/结构体等)
# 1 = 一级指针(如 i8*, Struct*)
# 2 = 二级指针(如 i8**, Struct**)
# 3+ = 更高级指针
# ============================================================
def get_ptr_level(ty: llvmlite.LLVMType | t.CPtr) -> int:
"""计算指针层级,0=非指针, 1=一级指针, 2=二级指针...(委托到 gen.get_ptr_level)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase.get_ptr_level(ty)
return 0
# ============================================================
# is_array_type - 检查类型是否为 Array
#
# 返回 1=是, 0=否。类型检查工具函数。
# ============================================================
def is_array_type(ty: llvmlite.LLVMType | t.CPtr) -> int:
"""检查 ty 是否是 Array 类型,返回 1=是, 0=否(委托到 gen.is_array_type)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase.is_array_type(ty)
return 0
# ============================================================
# _zext_index_to_i32 - 数组下标索引零扩展
#
# LLVM GEP 对窄整数索引默认符号扩展:i8 0xE2(226) 会被当成 -30,
# 导致数组下标越界读(字节 >= 128 的乱码根因)。
# 数组下标语义为非负,<32 位整数索引一律 zext 到 i32。
# ============================================================
def _zext_index_to_i32(builder: llvmlite.IRBuilder | t.CPtr,
idx_val: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr:
"""将 <32 位整数下标零扩展到 i32(数组下标非负语义)(委托到 gen._zext_index_to_i32)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase._zext_index_to_i32(builder, idx_val)
return None
# ============================================================
# _get_custom_struct_cls_nm - 检查类型是否为已注册的自定义结构体
#
# 处理两种情况:
# - ty 直接是 Struct → 检查是否注册
# - ty 是 Ptr(Struct) → 检查 pointee 是否注册
# ============================================================
def _get_custom_struct_cls_nm(pool: memhub.MemBuddy | t.CPtr,
ty: llvmlite.LLVMType | t.CPtr) -> str:
"""检查 ty 或 ty 的 pointee 是否是已注册的自定义结构体,返回类名或 None(委托到 gen._get_custom_struct_cls_nm)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase._get_custom_struct_cls_nm(pool, ty)
return None
# ============================================================
# _is_list_subscript_base - 判断下标基座是否为 list[T] 变量
# ============================================================
def _is_list_subscript_base(pool: memhub.MemBuddy | t.CPtr,
trans: HT.Translator | t.CPtr,
sub_node: ast.AST | t.CPtr) -> int:
"""判断下标基座是否为 list[T] 变量(1=是)(委托到 gen._is_list_subscript_base)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase._is_list_subscript_base(pool, trans, sub_node)
return 0
# ============================================================
# _sub_base_class_name - 解析下标基座变量的结构体类名
# ============================================================
def _sub_base_class_name(pool: memhub.MemBuddy | t.CPtr,
trans: HT.Translator | t.CPtr,
sub_node: ast.AST | t.CPtr) -> str:
"""解析下标基座变量的结构体类名(无则 None)(委托到 gen._sub_base_class_name)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase._sub_base_class_name(pool, trans, sub_node)
return None
# ============================================================
# _sub_base_uses_getitem - 下标基座是否应走 __getitem__ 语义
# ============================================================
def _sub_base_uses_getitem(pool: memhub.MemBuddy | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
trans: HT.Translator | t.CPtr,
sub_node: ast.AST | t.CPtr) -> int:
"""下标基座应走 __getitem__ 语义时返回 1,否则 0(应走 GEP 地址语义)(委托到 gen._sub_base_uses_getitem)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase._sub_base_uses_getitem(pool, mod, trans, sub_node)
return 0
# ============================================================
# _deref_if_ptr_ptr - 如果 obj_ptr 是 Ptr(Ptr(...)),load 解引用
# ============================================================
def _deref_if_ptr_ptr(builder: llvmlite.IRBuilder | t.CPtr,
obj_ptr: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr:
"""如果 obj_ptr 是 Ptr(Ptr(...)),load 解引用获取内层指针(委托到 gen._deref_if_ptr_ptr)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase._deref_if_ptr_ptr(builder, obj_ptr)
return None
# ============================================================
# 类型强制转换:整数 sext/trunc,浮点 fpext/fptrunc,int↔float si2fp/fp2si
# ============================================================
def coerce_to_type(builder: llvmlite.IRBuilder | t.CPtr,
val: llvmlite.Value | t.CPtr,
target_ty: llvmlite.LLVMType | t.CPtr,
node: ast.AST | t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""将 val 强制转换为 target_ty(委托到 gen.coerce_to_type)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase.coerce_to_type(builder, val, target_ty, node)
return None
# ============================================================
# translate_ptr_arith - 指针算术: ptr + int / ptr - int
#
# 用 getelementptr(按 pointee 元素大小缩放索引),对齐 TPC
# ExprGen.emit_binary_op / HandlesAugAssign.py。
# ============================================================
def translate_ptr_arith(pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,
ptr_val: llvmlite.Value | t.CPtr,
int_val: llvmlite.Value | t.CPtr,
op: int) -> llvmlite.Value | t.CPtr:
"""指针算术: ptr + int / ptr - int → GEP(按元素大小缩放索引)(委托到 gen.translate_ptr_arith)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenBase.translate_ptr_arith(pool, builder, ptr_val, int_val, op)
return None
# ============================================================
# 创建全局字符串常量
# ============================================================
def create_global_string(builder: llvmlite.IRBuilder | t.CPtr,
pool: memhub.MemBuddy | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
str_val: str,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
"""创建全局字符串常量并返回 i8* bitcast(委托到 gen.create_global_string)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenConst.create_global_string(builder, pool, mod, str_val, trans)
return None
# ============================================================
# 模块引用 AST → 模块路径字符串(递归拼接 Attribute 链)
# ============================================================
def attr_module_path_str(pool: memhub.MemBuddy | t.CPtr,
node: ast.AST | t.CPtr) -> str:
"""把模块引用 AST 转成模块路径字符串(Name('sys')→"sys"、
Attribute(Attribute(Name('os'),'_win32'))→"os._win32";非模块引用形态返回 None)
跨 mixin 委托:CallGenMixin 等不能 self. 直接调用 ExprGenMixin 的方法
(@t.NoVTable 静态绑定会 mangle 成当前类名 → undefined reference)。
"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenAttr._attr_module_path_str(pool, node)
return None
# ============================================================
# 翻译常量表达式
# ============================================================
def translate_constant(builder: llvmlite.IRBuilder | t.CPtr,
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:
"""翻译常量(int/str/bool)(委托到 gen.translate_constant)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenConst.translate_constant(builder, pool, mod, node, trans)
return None
# ============================================================
# _infer_elem_type_from_value — 从 LLVM Value 推断 list 元素类型名
# ============================================================
def _infer_elem_type_from_value(pool: memhub.MemBuddy | t.CPtr,
value: llvmlite.Value | t.CPtr) -> str:
"""从 LLVM Value 的类型推断 list 元素类型名(委托到 gen._infer_elem_type_from_value)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenConst._infer_elem_type_from_value(pool, value)
return None
# ============================================================
# _find_pool_var — 查找上下文中的 pool 变量
#
# 依次尝试 "pool", "_mbuddy", "mbuddy", "mb"
# ============================================================
def _find_pool_var(trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
"""查找上下文中的 pool 变量,返回 alloca 或 None(委托到 gen._find_pool_var)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenConst._find_pool_var(trans)
return None
# ============================================================
# translate_list_literal — 翻译 list 字面量 [a, b, c]
#
# 将 list 字面量翻译为 list[T](pool) 构造 + append 调用序列
# ============================================================
def translate_list_literal(builder: llvmlite.IRBuilder | t.CPtr,
pool: memhub.MemBuddy | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
node: ast.AST | t.CPtr,
elem_type_name: str,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
"""翻译 list 字面量 [a, b, c] → list[T](pool) + append 序列(委托到 gen.translate_list_literal)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenConst.translate_list_literal(builder, pool, mod, node, elem_type_name, trans)
return None
# ============================================================
# 翻译值表达式(RHS 分派)— 模块级版本
# ============================================================
def translate_value(builder: llvmlite.IRBuilder | t.CPtr,
pool: memhub.MemBuddy | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
node: ast.AST | t.CPtr,
funcs_ptr: t.CPtr = None,
func_count: int = 0,
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""翻译值表达式为 LLVM Value(委托到 gen.translate_value)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGen.translate_value(builder, pool, mod, node, funcs_ptr, func_count, trans)
return None
# ============================================================
# 翻译 lambda 表达式 — 模块级委托
#
# translate_lambda 定义在 FuncGenMixin(跨 Mixin 方法),ExprGenMixin
# 不能 self. 直接调用(NoVTable 下方法 mangle 成定义类符号,跨 Mixin
# self 调用会解析失败),与 translate_value 同模式走模块级委托。
# ============================================================
def translate_lambda(builder: llvmlite.IRBuilder | t.CPtr,
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:
"""翻译 lambda 表达式,返回闭包指针(i8*)(委托到 gen.translate_lambda)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.FuncGen.translate_lambda(builder, pool, mod, node, trans)
return None
# ============================================================
# 翻译三元表达式 IfExp(test, body, orelse)
# ============================================================
def translate_ifexp(builder: llvmlite.IRBuilder | t.CPtr,
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:
"""翻译三元表达式 (body if test else orelse),返回 phi 结果 Value(委托到 gen.translate_ifexp)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenOps.translate_ifexp(builder, pool, mod, node, trans)
return None
# ============================================================
# 翻译比较表达式 Compare(left, ops, comparators)
# ============================================================
def should_zext_widen(pool: memhub.MemBuddy | t.CPtr,
narrow_val: llvmlite.Value | t.CPtr,
wide_val: llvmlite.Value | t.CPtr,
narrow_node: ast.AST | t.CPtr = None) -> int:
"""判断整数拓宽方向:1=zext(无符号语义),0=sext(委托到 gen.should_zext_widen)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenOps.should_zext_widen(pool, narrow_val, wide_val, narrow_node)
return 0
def _node_type_unsigned(pool: memhub.MemBuddy | t.CPtr,
node: ast.AST | t.CPtr,
trans: HT.Translator | t.CPtr = None) -> int:
"""轻量判断 AST 节点是否解析为无符号整数类型(1=是,0=否/未知)(委托到 gen._node_type_unsigned)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenOps._node_type_unsigned(pool, node, trans)
return 0
def _type_name_unsigned(type_name: str) -> int:
"""类型名是否为无符号整数类型(精确匹配,避免子串误伤如 nUIntCount)(委托到 gen._type_name_unsigned)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenOps._type_name_unsigned(type_name)
return 0
def translate_compare(builder: llvmlite.IRBuilder | t.CPtr,
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:
"""翻译比较表达式,返回 i1 结果(委托到 gen.translate_compare)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenOps.translate_compare(builder, pool, mod, node, trans)
return None
# ============================================================
# 翻译一元运算表达式 UnaryOp(op, operand)
# ============================================================
def translate_unaryop(builder: llvmlite.IRBuilder | t.CPtr,
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:
"""翻译一元运算(-x, +x, not x, ~x)(委托到 gen.translate_unaryop)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenOps.translate_unaryop(builder, pool, mod, node, trans)
return None
# ============================================================
# 翻译布尔运算 BoolOp(op, values) — 短路求值,返回 i1
# ============================================================
def translate_boolop(builder: llvmlite.IRBuilder | t.CPtr,
pool: memhub.MemBuddy | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
node: ast.AST | t.CPtr,
funcs_ptr: t.CPtr = None,
func_count: int = 0,
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""翻译布尔运算(and/or)的短路求值,返回 i1(委托到 gen.translate_boolop)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenOps.translate_boolop(builder, pool, mod, node, funcs_ptr, func_count, trans)
return None
# ============================================================
# _build_source_path_from_sha1 - 通过 SHA1 从存储器构建源 .vp/.py 文件路径
# ============================================================
def _build_source_path_from_sha1(sha1: str) -> str:
"""通过 SHA1 从全局存储器构建源 .py 文件路径(委托到 gen._build_source_path_from_sha1)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenCdef._build_source_path_from_sha1(sha1)
return None
# ============================================================
# _lookup_cross_module_cdefine - 跨模块查找 CDefine 常量
# ============================================================
def _lookup_cross_module_cdefine(pool: memhub.MemBuddy | t.CPtr,
name: str,
from_imports: str,
imported_modules: str = None,
depth: int = 0,
node: ast.AST | t.CPtr = None) -> t.CInt64T:
"""跨模块查找 CDefine 常量,返回值(64 位)或 -1(未找到)(委托到 gen._lookup_cross_module_cdefine)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenCdef._lookup_cross_module_cdefine(pool, name, from_imports, imported_modules, depth, node)
return 0
# ============================================================
# _is_cdefine_name_pattern - 检查名字是否符合 CDefine 命名约定
# ============================================================
def _is_cdefine_name_pattern(name: str) -> int:
"""检查名字是否符合 CDefine 命名约定(全大写+下划线+数字)(委托到 gen._is_cdefine_name_pattern)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenCdef._is_cdefine_name_pattern(name)
return 0
# ============================================================
# 翻译变量引用(Name 节点)→ load
# ============================================================
def translate_name_value(builder: llvmlite.IRBuilder | t.CPtr,
pool: memhub.MemBuddy | t.CPtr,
node: ast.AST | t.CPtr,
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""翻译变量引用(Name 节点)→ load(委托到 gen.translate_name_value)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenName.translate_name_value(builder, pool, node, trans)
return None
# ============================================================
# ExprHandle - 表达式处理器(Mixin 继承模式)
#
# HandleValue 提供 trans 接口,委托到模块级 translate_value
# ============================================================
@t.NoVTable
class ExprHandle(HandlesBase.Mixin):
"""表达式处理器:继承 Mixin 获得 Trans 回指针"""
def __init__(self, trans: HT.Translator | t.CPtr):
self.Trans = trans
# ============================================================
# HandleValue - 翻译值表达式为 LLVM Value
# ============================================================
def HandleValue(self, node: ast.AST | t.CPtr) -> llvmlite.Value | t.CPtr:
"""翻译值表达式,从 self.Trans 获取共享状态"""
return translate_value(
self.Trans._cur_builder, self.Trans.Pool, self.Trans.Module,
node,
self.Trans._funcs, self.Trans._func_count, self.Trans)
# ============================================================
# NewExprHandle - 工厂函数
# ============================================================
def NewExprHandle(pool: memhub.MemBuddy | t.CPtr,
trans: HT.Translator | t.CPtr) -> ExprHandle | t.CPtr:
h: ExprHandle | t.CPtr = pool.alloc(ExprHandle.__sizeof__())
if h is None:
return None
string.memset(h, 0, ExprHandle.__sizeof__())
h.Trans = trans
return h
# ============================================================
# list_getitem_inline — 内联生成 list[T] __getitem__ 逻辑
#
# list 结构布局 (6 字段 × 8 字节):
# __data__(0) __count__(8) __capacity__(16) __pool__(24) __elem_size__(32) __iter_index__(40)
# 返回元素地址 (i8*),调用方根据元素类型 load 正确的值
# ============================================================
def list_getitem_inline(builder: llvmlite.IRBuilder | t.CPtr,
pool: memhub.MemBuddy | t.CPtr,
lm_obj: llvmlite.Value | t.CPtr,
idx_val: llvmlite.Value | t.CPtr,
node: ast.AST | t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""内联生成 list __getitem__ 逻辑,返回元素地址 (i8*)(委托到 gen.list_getitem_inline)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenName.list_getitem_inline(builder, pool, lm_obj, idx_val, node)
return None
# ============================================================
# _list_elem_type_from_name — 从 list 类型名提取元素 LLVM 类型
# ============================================================
def _list_elem_type_from_name(pool: memhub.MemBuddy | t.CPtr,
struct_name: str) -> llvmlite.LLVMType | t.CPtr:
"""从 list 类型名提取元素 LLVM 类型(委托到 gen._list_elem_type_from_name)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenName._list_elem_type_from_name(pool, struct_name)
return None
# ============================================================
# list_setitem_inline — 内联生成 list[T] __setitem__ 逻辑
# ============================================================
def list_setitem_inline(builder: llvmlite.IRBuilder | t.CPtr,
pool: memhub.MemBuddy | t.CPtr,
lm_obj: llvmlite.Value | t.CPtr,
idx_val: llvmlite.Value | t.CPtr,
rhs_val: llvmlite.Value | t.CPtr,
node: ast.AST | t.CPtr = None) -> int:
"""内联生成 list __setitem__ 逻辑,返回 0(委托到 gen.list_setitem_inline)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenName.list_setitem_inline(builder, pool, lm_obj, idx_val, rhs_val, node)
return 0
# ============================================================
# is_list_subscript — 检查 Subscript 节点是否是 list[T] 类型
#
# 返回 list 对象指针 (Ptr(list[T])) 或 None
# ============================================================
def is_list_subscript(node: ast.AST | t.CPtr,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
"""检查 Subscript 节点是否是 list[T] 类型,返回 list 对象指针或 None(委托到 gen.is_list_subscript)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenName.is_list_subscript(node, trans)
return None
# ============================================================
# 翻译下标表达式 Subscript(value, slice, ctx) — ptr[i] / arr[i]
# ============================================================
def translate_subscript(builder: llvmlite.IRBuilder | t.CPtr,
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:
"""翻译下标表达式,返回加载的元素值(委托到 gen.translate_subscript)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenName.translate_subscript(builder, pool, mod, node, trans)
return None
# ============================================================
# find_global_in_module - 在模块全局变量链表中按名称查找
#
# 查找策略:
# 1. 精确匹配 (如 "_mbuddy" 匹配 @_mbuddy)
# 2. 后缀匹配 (如 "_mbuddy" 匹配 @"sha1._mbuddy")
# ============================================================
def find_global_in_module(mod: llvmlite.LLVMModule | t.CPtr,
name: str) -> llvmlite.GlobalVariable | t.CPtr:
"""在模块全局变量链表中按名称查找全局变量(委托到 gen.find_global_in_module)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenAttr.find_global_in_module(mod, name)
return None
# ============================================================
# make_global_ref - 创建全局变量引用 (@name,类型为 ty*)
# ============================================================
def make_global_ref(pool: memhub.MemBuddy | t.CPtr,
name: str,
ty: llvmlite.LLVMType | t.CPtr) -> llvmlite.Value | t.CPtr:
"""创建全局变量引用 (类型为 ty*,名称为 @name)(委托到 gen.make_global_ref)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenAttr.make_global_ref(pool, name, ty)
return None
# ============================================================
# _is_t_type_object_name - 检查 name 是否是 t.py 中的类型对象名
# ============================================================
def _is_t_type_object_name(name: str) -> int:
"""检查 name 是否是 t.py 中的类型对象名(CPtr/CInt/CDouble 等)(委托到 gen._is_t_type_object_name)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenAttr._is_t_type_object_name(name)
return 0
# ============================================================
# _resolve_module_attribute_global - 解析模块属性访问的全局变量引用
# ============================================================
def _resolve_module_attribute_global(pool: memhub.MemBuddy | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
trans: HT.Translator | t.CPtr,
at: ast.Attribute | t.CPtr,
ty_hint: llvmlite.LLVMType | t.CPtr) -> llvmlite.Value | t.CPtr:
"""解析模块属性访问,返回全局变量引用 (用于跨模块 global 访问)(委托到 gen._resolve_module_attribute_global)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenAttr._resolve_module_attribute_global(pool, mod, trans, at, ty_hint)
return None
# ============================================================
# _get_cderef_attr_base - c.Deref(ptr).attr 属性访问的 base 指针
# ============================================================
def _get_cderef_attr_base(builder: llvmlite.IRBuilder | t.CPtr,
pool: memhub.MemBuddy | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
at_value: ast.AST | t.CPtr,
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""检测 at.value 是否为 c.Deref(ptr) 调用,返回 ptr 指针(不做 load)(委托到 gen._get_cderef_attr_base)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenAttr._get_cderef_attr_base(builder, pool, mod, at_value, trans)
return None
# ============================================================
# 翻译属性访问 Attribute(value, attr, ctx) — obj.field
# ============================================================
def translate_attribute(builder: llvmlite.IRBuilder | t.CPtr,
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:
"""翻译属性访问,返回加载的字段值(委托到 gen.translate_attribute)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenAttr.translate_attribute(builder, pool, mod, node, trans)
return None
# ============================================================
# 获取下标表达式的元素指针(不加载值,用于赋值)
# ============================================================
def get_subscript_ptr(builder: llvmlite.IRBuilder | t.CPtr,
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:
"""获取下标表达式的元素指针(用于赋值 lhs)(委托到 gen.get_subscript_ptr)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenName.get_subscript_ptr(builder, pool, mod, node, trans)
return None
# ============================================================
# 获取属性访问的字段指针(不加载值,用于赋值)
# ============================================================
def get_attribute_ptr(builder: llvmlite.IRBuilder | t.CPtr,
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:
"""获取属性访问的字段指针(用于赋值 lhs)(委托到 gen.get_attribute_ptr)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenAttr.get_attribute_ptr(builder, pool, mod, node, trans)
return None
# ============================================================
# 翻译 f-string(JoinedStr → snprintf 生成 i8* 栈缓冲)— 模块级委托
# ============================================================
def translate_joined_str(builder: llvmlite.IRBuilder | t.CPtr,
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:
"""翻译 f-string(委托到 gen.translate_joined_str,定义于 ExprGenFstr)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenFstr.translate_joined_str(builder, pool, mod, node, trans)
return None
# ============================================================
# 翻译裸 FormattedValue(f"{expr:spec}" 无字面量)— 模块级委托
# ============================================================
def translate_formatted_value(builder: llvmlite.IRBuilder | t.CPtr,
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:
"""翻译裸 FormattedValue(委托到 gen.translate_formatted_value,定义于 ExprGenFstr)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenFstr.translate_formatted_value(builder, pool, mod, node, trans)
return None
# ============================================================
# CDefine 整数常量 → LLVM 常量(64 位升级规则)— 模块级委托
# ============================================================
def _const_int_for_cdefine(pool: memhub.MemBuddy | t.CPtr,
value: t.CInt64T) -> llvmlite.Value | t.CPtr:
"""CDefine 整数常量 → LLVM 常量(委托到 gen._const_int_for_cdefine,定义于 ExprGenCdef)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenCdef._const_int_for_cdefine(pool, value)
return None
# ============================================================
# 解析嵌套 Attribute 链的 docstring 归属 — 模块级委托
# ============================================================
def _resolve_doc_symbol_attr(trans: HT.Translator | t.CPtr,
at: ast.Attribute | t.CPtr,
out_mod: str, out_sym: str) -> int:
"""解析嵌套 Attribute 链的 docstring 归属(委托到 gen._resolve_doc_symbol_attr,定义于 ExprGenCls)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenCls._resolve_doc_symbol_attr(trans, at, out_mod, out_sym)
return 0
# ============================================================
# 解析 Name 符号的 docstring 归属 — 模块级委托
# ============================================================
def _resolve_doc_symbol_name(trans: HT.Translator | t.CPtr, name_id: str,
out_mod: str, out_sym: str) -> int:
"""解析 Name 符号的 docstring 归属(委托到 gen._resolve_doc_symbol_name,定义于 ExprGenCls)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenCls._resolve_doc_symbol_name(trans, name_id, out_mod, out_sym)
return 0
# ============================================================
# 查找 docstring 内容(key="{module_sha1}.{symbol}")— 模块级委托
# ============================================================
def lookup_docstring(module_sha1: str, symbol: str) -> str:
"""查找 docstring 内容(委托到 gen.lookup_docstring,定义于 ExprGenCls)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenCls.lookup_docstring(module_sha1, symbol)
return None
# ============================================================
# 解析属性链(a.b.c)中 c 字段的注解类名 — 模块级委托
# ============================================================
def _resolve_attr_field_class(pool: memhub.MemBuddy | t.CPtr,
trans: HT.Translator | t.CPtr,
attr_node: ast.AST | t.CPtr) -> str:
"""解析属性链最终字段的注解类名(委托到 gen._resolve_attr_field_class,定义于 ExprGenAttr)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenAttr._resolve_attr_field_class(pool, trans, attr_node)
return None
# ============================================================
# 翻译二元运算(自动类型提升)— 模块级委托
# ============================================================
def translate_binop(pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
node: ast.AST | t.CPtr,
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""翻译二元运算(委托到 gen.translate_binop,定义于 ExprGenOps)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenOps.translate_binop(pool, builder, mod, node, trans)
return None
# ============================================================
# binop op → dunder 方法名(如 Add → "__add__")— 模块级委托
# ============================================================
def _binop_to_dunder(op: int) -> str:
"""binop op → dunder 方法名(委托到 gen._binop_to_dunder,定义于 ExprGenOps)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenOps._binop_to_dunder(op)
return None
# ============================================================
# unaryop op → dunder 方法名(如 USub → "__neg__")— 模块级委托
# ============================================================
def _unaryop_to_dunder(op: int) -> str:
"""unaryop op → dunder 方法名(委托到 gen._unaryop_to_dunder,定义于 ExprGenOps)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenOps._unaryop_to_dunder(op)
return None
# ============================================================
# f-string 尾部:全局格式串 + 固定栈缓冲 + snprintf — 模块级委托
# ============================================================
def _fstr_finalize(builder: llvmlite.IRBuilder | t.CPtr,
pool: memhub.MemBuddy | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
fmt_buf: str,
arg_head: llvmlite.Value | t.CPtr,
arg_tail: llvmlite.Value | t.CPtr,
arg_count: int,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
"""f-string 尾部(委托到 gen._fstr_finalize,定义于 ExprGenFstr)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenFstr._fstr_finalize(builder, pool, mod, fmt_buf, arg_head, arg_tail, arg_count, trans)
return None
# ============================================================
# 追加字面量到格式串(% 转义)— 模块级委托
# ============================================================
def _fstr_append_literal(fmt_buf: str, lit: str) -> None:
"""追加字面量到格式串(委托到 gen._fstr_append_literal,定义于 ExprGenFstr)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
g.ExprGenFstr._fstr_append_literal(fmt_buf, lit)
# ============================================================
# Python format_spec → C printf 格式串 — 模块级委托
# ============================================================
def _fstr_parse_format_spec(pool: memhub.MemBuddy | t.CPtr,
spec_node: ast.AST | t.CPtr,
val: llvmlite.Value | t.CPtr,
arg_node: ast.AST | t.CPtr) -> str:
"""Python format_spec → C printf 格式串(委托到 gen._fstr_parse_format_spec,定义于 ExprGenFstr)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenFstr._fstr_parse_format_spec(pool, spec_node, val, arg_node)
return None
# ============================================================
# 无 format_spec 时按值类型推断 C printf 格式 — 模块级委托
# ============================================================
def _fstr_infer_c_fmt(pool: memhub.MemBuddy | t.CPtr,
val: llvmlite.Value | t.CPtr,
arg_node: ast.AST | t.CPtr,
trans: HT.Translator | t.CPtr) -> str:
"""按值类型推断 C printf 格式(委托到 gen._fstr_infer_c_fmt,定义于 ExprGenFstr)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenFstr._fstr_infer_c_fmt(pool, val, arg_node, trans)
return None
# ============================================================
# 按 C 格式转换值类型(i8/i16→i32、bool→i32、f32→f64)— 模块级委托
# ============================================================
def _fstr_cast_value(builder: llvmlite.IRBuilder | t.CPtr,
pool: memhub.MemBuddy | t.CPtr,
val: llvmlite.Value | t.CPtr,
c_fmt: str,
arg_node: ast.AST | t.CPtr,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
"""按 C 格式转换值类型(委托到 gen._fstr_cast_value,定义于 ExprGenFstr)"""
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ExprGenFstr._fstr_cast_value(builder, pool, val, c_fmt, arg_node, trans)
return None