128 lines
7.8 KiB
Plaintext
128 lines
7.8 KiB
Plaintext
import t, c
|
||
from stdint import *
|
||
import ast
|
||
import memhub
|
||
import llvmlite
|
||
import lib.core.Gen.Translator as HT
|
||
import lib.core.Gen.Expr.ExprGenBase as ExprGenBase
|
||
|
||
|
||
# ============================================================
|
||
# docstring 登记表容量(__doc__ 魔法属性支持)
|
||
#
|
||
# DOC_MAX: 登记条目上限(预注册阶段所有 App/includes 文件的
|
||
# 函数/类/方法 docstring,幂等查重)
|
||
# DOC_KEY_SZ: key "{module_sha1}.{symbol}" 缓冲宽度
|
||
# DOC_VAL_SZ: docstring 内容缓冲宽度
|
||
# ============================================================
|
||
define DOC_MAX = 512
|
||
define DOC_KEY_SZ = 192
|
||
define DOC_VAL_SZ = 4096
|
||
|
||
# ============================================================
|
||
# f-string 翻译常量(对齐 TPC HandlesExprFormat)
|
||
#
|
||
# FSTR_BUF_SIZE: 运行时栈缓冲大小(snprintf 结果缓冲)
|
||
# FSTR_SPEC_MAX: 编译期 format_spec 解析缓冲宽度
|
||
# FSTR_FMT_MAX: 编译期 C printf 格式串缓冲宽度
|
||
# ============================================================
|
||
define FSTR_BUF_SIZE = 1024
|
||
define FSTR_SPEC_MAX = 64
|
||
define FSTR_FMT_MAX = 64
|
||
|
||
|
||
# ============================================================
|
||
# ExprGenMixin - 表达式处理 Mixin(对象化 P3)
|
||
# ============================================================
|
||
|
||
|
||
# ============================================================
|
||
# ExprGenMixin - 表达式/常量/下标/属性访问/运算符
|
||
# ============================================================
|
||
novirtual class ExprGenMixin(ExprGenBase.ExprGenBase):
|
||
"""表达式处理 Mixin(纯方法化迁移,无状态字段)"""
|
||
|
||
# ============================================================
|
||
# 翻译值表达式(RHS 分派)— 模块级版本
|
||
# ============================================================
|
||
def translate_value(self, builder: llvmlite.IRBuilder*,
|
||
pool: memhub.MemBuddy*,
|
||
mod: llvmlite.LLVMModule*,
|
||
node: ast.AST*,
|
||
funcs_ptr: t.CPtr = None,
|
||
func_count: int = 0,
|
||
trans: HT.Translator* = None,
|
||
target_ty: llvmlite.LLVMType* = None,
|
||
use_ctx: str = None) -> llvmlite.Value*:
|
||
"""翻译值表达式为 LLVM Value(深度守卫包装器,原逻辑见 _translate_value_impl)
|
||
|
||
target_ty: 目标类型上下文(如调用形参类型/赋值目标类型),用于单引号
|
||
单字符字面量(CONST_CHAR)在字符串目标下物化为 1 字符字符串(对齐 TPC)。
|
||
use_ctx: 使用处**真实站点种类**标签("局部变量注解" / "模块级全局" /
|
||
"形参" / "返回注解" …),只被 CDefine 使用处宽度不足报文读取;不参与判定。
|
||
"""
|
||
if trans is not None:
|
||
if trans.TranslateDepth >= HT.TRANSLATE_MAX_DEPTH:
|
||
self.Gen.TypeGenErr.fatal_error(node, "表达式翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError")
|
||
trans.TranslateDepth += 1
|
||
rv: llvmlite.Value* = self._translate_value_impl(builder, pool, mod, node, funcs_ptr, func_count, trans, target_ty, use_ctx)
|
||
if trans is not None:
|
||
trans.TranslateDepth -= 1
|
||
return rv
|
||
|
||
def _translate_value_impl(self, builder: llvmlite.IRBuilder*,
|
||
pool: memhub.MemBuddy*,
|
||
mod: llvmlite.LLVMModule*,
|
||
node: ast.AST*,
|
||
funcs_ptr: t.CPtr = None,
|
||
func_count: int = 0,
|
||
trans: HT.Translator* = None,
|
||
target_ty: llvmlite.LLVMType* = None,
|
||
use_ctx: str = None) -> llvmlite.Value*:
|
||
"""翻译值表达式为 LLVM Value"""
|
||
if node is None:
|
||
return None
|
||
k: int = node.kind()
|
||
if k == ast.ASTKind.Constant:
|
||
rv: llvmlite.Value* = self.Gen.ExprGenConst.translate_constant(builder, pool, mod, node, trans, target_ty)
|
||
return rv
|
||
elif k == ast.ASTKind.Name: return self.Gen.ExprGenName.translate_name_value(builder, pool, node, trans, target_ty, use_ctx)
|
||
elif k == ast.ASTKind.BinOp: return self.Gen.ExprGenOps.translate_binop(pool, builder, mod, node, trans)
|
||
elif k == ast.ASTKind.Call: return self.Gen.CallGen.translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans)
|
||
elif k == ast.ASTKind.Compare: return self.Gen.ExprGenOps.translate_compare(builder, pool, mod, node, trans)
|
||
elif k == ast.ASTKind.UnaryOp: return self.Gen.ExprGenOps.translate_unaryop(builder, pool, mod, node, trans)
|
||
elif k == ast.ASTKind.BoolOp: return self.Gen.ExprGenOps.translate_boolop(builder, pool, mod, node, funcs_ptr, func_count, trans)
|
||
elif k == ast.ASTKind.Subscript: return self.Gen.ExprGenName.translate_subscript(builder, pool, mod, node, trans)
|
||
elif k == ast.ASTKind.Attribute: return self.Gen.ExprGenAttr.translate_attribute(builder, pool, mod, node, trans)
|
||
elif k == ast.ASTKind.List: return self.Gen.ExprGenConst.translate_list_literal(builder, pool, mod, node, None, trans)
|
||
elif k == ast.ASTKind.IfExp: return self.Gen.ExprGenOps.translate_ifexp(builder, pool, mod, node, trans)
|
||
elif k == ast.ASTKind.Lambda: return self.Gen.FuncGen.translate_lambda(builder, pool, mod, node, trans)
|
||
elif k == ast.ASTKind.JoinedStr: return self.Gen.ExprGenFstr.translate_joined_str(builder, pool, mod, node, trans)
|
||
elif k == ast.ASTKind.FormattedValue: return self.Gen.ExprGenFstr.translate_formatted_value(builder, pool, mod, node, trans)
|
||
elif k == ast.ASTKind.Await:
|
||
# 协程 await(TPV-M1):await 目标是 async 函数调用时内联翻译
|
||
# (子帧创建 + resume 到 DONE + 取子帧 ret 存父帧 await 槽 + 父挂起),
|
||
# 返回子协程 ret 值(i32)。顶层 await(AnnAssign/Assign 的 value 直接
|
||
# 是 Await)由 AsyncGen 段翻译特判处理,本分支覆盖表达式上下文中的
|
||
# await(M1 覆盖有限场景,详见 AsyncGenMixin._emit_await)。
|
||
aw: rawptr[ast.Await] = rawptr[ast.Await](node)
|
||
if aw is not None and aw.value is not None and aw.value.kind() == ast.ASTKind.Call:
|
||
aw_cl: ast.Call* = ast.Call*(aw.value)
|
||
if aw_cl.func is not None and aw_cl.func.kind() == ast.ASTKind.Name:
|
||
aw_nm: ast.Name* = ast.Name*(aw_cl.func)
|
||
if aw_nm.id is not None and trans is not None:
|
||
if self.Gen.AsyncGen.is_async_func(trans, aw_nm.id) != 0:
|
||
return self.Gen.AsyncGen._emit_await(builder, pool, mod, trans, aw, aw_nm.id)
|
||
return None
|
||
elif k == ast.ASTKind.Starred:
|
||
# *x 在值上下文(如 printf("%d", *k) 实参):解析器把调用参数位的
|
||
# '*' 按 Python *args 解包语义归类为 Starred,但 Viper 未实现解包,
|
||
# 全代码库无调用点使用;按 C 语义视为单目解引用(*ptr → load pointee,
|
||
# 对齐 UnaryOp(Deref))。构造 Deref UnaryOp 复用既有翻译/错误路径。
|
||
st: rawptr[ast.Starred] = rawptr[ast.Starred](node)
|
||
if st is None or st.value is None: return None
|
||
deref_node: ast.AST* = ast.UnaryOp(pool, ast.OpKind.Deref, st.value)
|
||
if deref_node is None: return None
|
||
return self.Gen.ExprGenOps.translate_unaryop(builder, pool, mod, deref_node, trans)
|
||
return None
|