refactor(tpv): 删除 Handles 目录,核心逻辑合并进 Gen

- 新建 Gen/Translator.vp:Translator 类 + Mixin + 常量 + _mbuddy 自 HandlesTranslator 迁入(删 7 个委托壳与 _g_gen)

- GenApi 下沉 7 个 global/nonlocal 管理委托(add/is_global_name、add/is_nonlocal_name、get_nonlocal_type/index、clear_scope_names)+ update_global_func_typestr

- CallGenLeafKit 并入 ExprCallHandle 类,NewExprCallHandle 改本地引用

- 删除 Handles/HandlesExpr/ExprCallTable/HandlesBase(60+ 委托零消费者/纯委托壳)与 Handles 目录整体

- 全 App 56 文件 import 改指 lib.core.Gen.*,清理死 import,委托调用改 GenApi,main/BuildPipeline _g_gen 注入删除
This commit is contained in:
TermiNexus committed 2026-08-28 14:29:25 +08:00
1 parent d99b6268de
commit 24ae2dc966
64 files changed
+11434 -13008

No files matched your search

+1 -6
View File
@@ -16,9 +16,7 @@ import subprocess
import viperlib
import ast
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HandlesTranslator
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HandlesTranslator
import lib.Stub.StubMerger as StubMerger
import lib.Stub.StubGen.Converter as StubConverter
import lib.Projectrans.Config as Config
@@ -154,9 +152,6 @@ def TranslateFileGetTrans(mb: memhub.MemBuddy | t.CPtr, file_path: str,
# P2-P5: 注入各 Handles 模块级单例(委托函数经本地 _g_gen 访问,
# 避免函数体 import 包模块与类/模块名歧义)
GenApi._g_gen = gen
HandlesTranslator._g_gen = gen
HandlesExpr._g_gen = gen
HandlesExprCall._g_gen = gen
# P6: 注入语句/赋值/变量/导入/翻译驱动模块的单例
# 设置当前文件名(供报错使用)
GenApi.set_current_file_type(file_path)
+1 -2
View File
@@ -9,8 +9,7 @@ import w32.win32base
import ast
import llvmlite
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HandlesTranslator
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HandlesTranslator
import lib.core.IncludesScanner as IncludesScanner
import lib.Stub.StubMerger as StubMerger
import lib.core.Gen.Generator as GenGenerator
+1 -2
View File
@@ -11,8 +11,7 @@ import w32.win32base
import ast
import llvmlite
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HandlesTranslator
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HandlesTranslator
import lib.core.IncludesScanner as IncludesScanner
import lib.Stub.StubMerger as StubMerger
import lib.core.Gen.Generator as GenGenerator
+1 -2
View File
@@ -10,8 +10,7 @@ import w32.win32base
import ast
import llvmlite
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HandlesTranslator
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HandlesTranslator
import lib.core.IncludesScanner as IncludesScanner
import lib.Stub.StubMerger as StubMerger
import lib.core.Gen.Generator as GenGenerator
+1 -2
View File
@@ -15,8 +15,7 @@ import llvmlite
import subprocess
import argparse
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HandlesTranslator
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HandlesTranslator
import lib.Phase.BuildPipeline as BuildPipeline
import lib.core.IncludesScanner as IncludesScanner
import lib.core.CompilerFactory as CompilerFactory
+3 -5
View File
@@ -13,10 +13,8 @@ import llvmlite
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
import lib.core.Handles.ExprCallTable as ExprCallTable
# ============================================================
@@ -1959,7 +1957,7 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr,
# 补全全局函数表 TypeStr(参数已全部添加,对齐 FuncGenDef L211 行为):
# vpi 注入路径若不补全,跨模块 vtable/调用解析 find_func_entry_global()
# 时 TypeStr 为空 → "vtable 方法找不到函数实现"(依赖模块晚于本模块编译时必现)
ExprCallTable.update_global_func_typestr(pool, fd.name, func)
GenApi.update_global_func_typestr(pool, fd.name, func)
# ============================================================
@@ -2152,7 +2150,7 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr,
# vpi 注入的方法声明若不补全 TypeStr,跨模块继承 vtable 生成时
# find_func_entry_global().TypeStr 为空 → "vtable 方法找不到函数实现"
# (astaux.vp 先于 ast.base.vp 编译时必现:AST.accept 仅有 vpi 注入条目)
ExprCallTable.update_global_func_typestr(pool, lookup_name, func)
GenApi.update_global_func_typestr(pool, lookup_name, func)
# ============================================================
+1 -1
View File
@@ -13,7 +13,7 @@ import sys
import ast
import lib.core.VLogger as VLogger
import lib.core.IncludesScanner as IncludesScanner
import lib.core.Handles.HandlesTranslator as HandlesTranslator
import lib.core.Gen.Translator as HandlesTranslator
import lib.Phase.BuildPipeline as BuildPipeline
import lib.Stub.StubGen.VpiReader as VpiReader
import lib.Projectrans.Utils as Utils
+1 -1
View File
@@ -12,7 +12,7 @@ import sys
import ast
import lib.core.VLogger as VLogger
import lib.core.IncludesScanner as IncludesScanner
import lib.core.Handles.HandlesTranslator as HandlesTranslator
import lib.core.Gen.Translator as HandlesTranslator
import lib.Phase.BuildPipeline as BuildPipeline
import lib.Stub.StubGen.VpiReader as VpiReader
import lib.Projectrans.Utils as Utils
+1 -1
View File
@@ -13,7 +13,7 @@ import sys
import ast
import lib.core.VLogger as VLogger
import lib.core.IncludesScanner as IncludesScanner
import lib.core.Handles.HandlesTranslator as HandlesTranslator
import lib.core.Gen.Translator as HandlesTranslator
import lib.Phase.BuildPipeline as BuildPipeline
import lib.Stub.StubGen.VpiReader as VpiReader
import lib.Projectrans.Utils as Utils
+1 -1
View File
@@ -12,7 +12,7 @@ import sys
import ast
import lib.core.VLogger as VLogger
import lib.core.IncludesScanner as IncludesScanner
import lib.core.Handles.HandlesTranslator as HandlesTranslator
import lib.core.Gen.Translator as HandlesTranslator
import lib.Phase.BuildPipeline as BuildPipeline
import lib.Stub.StubGen.VpiReader as VpiReader
import lib.Projectrans.Utils as Utils
+1 -1
View File
@@ -12,7 +12,7 @@ import sys
import ast
import lib.core.VLogger as VLogger
import lib.core.IncludesScanner as IncludesScanner
import lib.core.Handles.HandlesTranslator as HandlesTranslator
import lib.core.Gen.Translator as HandlesTranslator
import lib.Phase.BuildPipeline as BuildPipeline
import lib.Stub.StubGen.VpiReader as VpiReader
import lib.Projectrans.Utils as Utils
+1 -1
View File
@@ -12,7 +12,7 @@ import sys
import ast
import lib.core.VLogger as VLogger
import lib.core.IncludesScanner as IncludesScanner
import lib.core.Handles.HandlesTranslator as HandlesTranslator
import lib.core.Gen.Translator as HandlesTranslator
import lib.Phase.BuildPipeline as BuildPipeline
import lib.Stub.StubGen.VpiReader as VpiReader
import lib.Projectrans.Utils as Utils
+10 -10
View File
@@ -9,12 +9,12 @@ import stdlib
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
import lib.core.Gen.GenTypes as GenTypes
import lib.core.Gen.Generator as Generator
import lib.Stub.StubGen.VpiReader as VpiReader
import lib.core.Gen.GenApi as GenApi
# ============================================================
# AssignGenMixin - 赋值翻译 Mixin(P6 方法化)
@@ -789,9 +789,9 @@ class AssignGenMixin:
# 1. 确定变量作用域类型: 0=local, 1=global, 2=nonlocal
scope_type: int = 0
if HT.is_global_name(trans, nm.id) != 0:
if GenApi.is_global_name(trans, nm.id) != 0:
scope_type = 1
elif HT.is_nonlocal_name(trans, nm.id) != 0:
elif GenApi.is_nonlocal_name(trans, nm.id) != 0:
scope_type = 2
# 2. 加载当前值
@@ -999,9 +999,9 @@ class AssignGenMixin:
return 0
# global/nonlocal 变量不需要局部 alloca
if HT.is_global_name(trans, nm.id) != 0:
if GenApi.is_global_name(trans, nm.id) != 0:
return 0
if HT.is_nonlocal_name(trans, nm.id) != 0:
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
return 0
# 模块级全局变量已由 handle_module_level_var 注册到模块作用域。
@@ -1161,7 +1161,7 @@ class AssignGenMixin:
self.Gen.CallGenLeafKit.register_func_ptr_sig(nm.id, callable_ret)
# global 变量:写入模块作用域中的全局变量
if HT.is_global_name(trans, nm.id) != 0:
if GenApi.is_global_name(trans, nm.id) != 0:
mod_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
trans.SymTab, nm.id)
if mod_alloca is not None and aa.value is not None:
@@ -1178,7 +1178,7 @@ class AssignGenMixin:
return 0
# nonlocal 变量:通过闭包 env 写入
if HT.is_nonlocal_name(trans, nm.id) != 0:
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
if aa.value is not None:
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
builder, pool, mod, aa.value,
@@ -1821,7 +1821,7 @@ class AssignGenMixin:
if nm.id is None:
continue
# global 变量:写入模块作用域中的全局变量
if HT.is_global_name(trans, nm.id) != 0:
if GenApi.is_global_name(trans, nm.id) != 0:
mod_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
trans.SymTab, nm.id)
if mod_alloca is None:
@@ -1839,7 +1839,7 @@ class AssignGenMixin:
continue
# nonlocal 变量:通过闭包 env 写入
if HT.is_nonlocal_name(trans, nm.id) != 0:
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
nl_ptr: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
trans, nm.id)
if nl_ptr is None:
File diff suppressed because it is too large. Load diff
-1
View File
@@ -4,7 +4,6 @@ import t, c
from stdint import *
import memhub
import llvmlite
import lib.core.Handles.HandlesExprCall as HandlesExprCall
# ============================================================
+1 -4
View File
@@ -12,11 +12,8 @@ import sys
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.CompilerFactory as CompilerFactory
import lib.Stub.StubMerger.StubMergerCollect as StubMergerCollect
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
+5 -7
View File
@@ -11,14 +11,12 @@ import sys
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Gen.Call.CallGenBase as CallGenBase
import lib.core.Gen.GenApi as GenApi
# ============================================================
@@ -259,7 +257,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
if a_node is not None and a_node.kind() == ast.ASTKind.Name and trans is not None:
nm_set: ast.Name | t.CPtr = (ast.Name | t.CPtr)(a_node)
if nm_set.id is not None:
if HT.is_global_name(trans, nm_set.id) != 0:
if GenApi.is_global_name(trans, nm_set.id) != 0:
mod_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
trans.SymTab, nm_set.id)
if mod_alloca is not None:
@@ -271,7 +269,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
sv = self.Gen.ExprGenBase.coerce_to_type(builder, b_val, tg_ty, a_node)
llvmlite.build_store(builder, sv, mod_alloca)
return b_val
if HT.is_nonlocal_name(trans, nm_set.id) != 0:
if GenApi.is_nonlocal_name(trans, nm_set.id) != 0:
nl_ptr: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
trans, nm_set.id)
if nl_ptr is not None:
@@ -357,7 +355,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
# 不能 lookup_var 跨函数命中父函数 alloca(SSA 编号错乱崩溃)。
# 与普通局部 c.Addr(obj) 返回对象指针(load 一次)语义一致。
if trans is not None:
if HT.is_nonlocal_name(trans, nm.id) != 0:
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
nl_addr: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.load_nonlocal_var(
trans, nm.id)
if nl_addr is not None:
+3 -7
View File
@@ -11,15 +11,11 @@ import sys
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Gen.Call.CallGenBase as CallGenBase
import lib.core.Handles.ExprCallTable as ExprCallTable
# ============================================================
@@ -417,7 +413,7 @@ class CallGenCall(CallGenBase.CallGenBase):
mdf_default_count: int = 0
mdf_param_count: int = 0
if trans is not None and trans._funcs is not None:
mdf_entry: GenTypes.FuncEntry | t.CPtr = ExprCallTable.find_func_entry_in_table(
mdf_entry: GenTypes.FuncEntry | t.CPtr = self.Gen.CallGenLeafKit.find_func_entry_in_table(
trans._funcs, trans._func_count, lookup_name)
if mdf_entry is not None:
mdf_defaults = mdf_entry.Defaults
@@ -1370,7 +1366,7 @@ class CallGenCall(CallGenBase.CallGenBase):
mdf_default_count: int = 0
mdf_param_count: int = 0
if trans is not None and trans._funcs is not None:
mdf_entry: GenTypes.FuncEntry | t.CPtr = ExprCallTable.find_func_entry_in_table(
mdf_entry: GenTypes.FuncEntry | t.CPtr = self.Gen.CallGenLeafKit.find_func_entry_in_table(
trans._funcs, trans._func_count, lookup_name)
if mdf_entry is not None:
mdf_defaults = mdf_entry.Defaults
+1 -5
View File
@@ -11,15 +11,11 @@ import sys
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Gen.Call.CallGenBase as CallGenBase
import lib.core.Handles.ExprCallTable as ExprCallTable
# ============================================================
File diff suppressed because it is too large. Load diff
+1 -4
View File
@@ -11,11 +11,8 @@ import sys
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Gen.Call.CallGenBase as CallGenBase
+47 -7
View File
@@ -11,11 +11,9 @@ import sys
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Gen.GenApi as GenApi
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Gen.Call.CallGenCBuiltin as CallGenCBuiltin
@@ -1293,11 +1291,53 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
def NewExprCallHandle(self, pool: memhub.MemBuddy | t.CPtr,
trans: HT.Translator | t.CPtr) -> HandlesExprCall.ExprCallHandle | t.CPtr:
h: HandlesExprCall.ExprCallHandle | t.CPtr = pool.alloc(HandlesExprCall.ExprCallHandle.__sizeof__())
trans: HT.Translator | t.CPtr) -> ExprCallHandle | t.CPtr:
h: ExprCallHandle | t.CPtr = pool.alloc(ExprCallHandle.__sizeof__())
if h is None:
return None
string.memset(h, 0, HandlesExprCall.ExprCallHandle.__sizeof__())
string.memset(h, 0, ExprCallHandle.__sizeof__())
h.Trans = trans
return h
# ============================================================
# ExprCallHandle - 函数调用处理器(自 HandlesExprCall 迁入)
#
# HandleCall / HandlePrintfCall / HandlePrintCall 提供 trans 接口,
# 内部委托 GenApi.translate_call 等。
# ============================================================
@t.NoVTable
class ExprCallHandle(HT.Mixin):
"""函数调用处理器:继承 Mixin 获得 Trans 回指针"""
def __init__(self, trans: HT.Translator | t.CPtr):
self.Trans = trans
# ============================================================
# HandleCall - 翻译函数调用,返回 call 结果 Value
# ============================================================
def HandleCall(self, node: ast.AST | t.CPtr) -> llvmlite.Value | t.CPtr:
"""翻译函数调用,从 self.Trans 获取共享状态"""
return GenApi.translate_call(
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
node,
self.Trans._funcs, self.Trans._func_count, self.Trans)
# ============================================================
# HandlePrintfCall - 翻译 printf 调用
# ============================================================
def HandlePrintfCall(self, cl: ast.Call | t.CPtr):
"""翻译 printf 调用,从 self.Trans 获取共享状态"""
GenApi.translate_printf_call(
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
cl, self.Trans)
# ============================================================
# HandlePrintCall - 翻译 print 调用
# ============================================================
def HandlePrintCall(self, cl: ast.Call | t.CPtr):
"""翻译 print 调用(类型感知格式化 + 默认换行)"""
GenApi.translate_print_call(
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
cl, self.Trans)
+1 -4
View File
@@ -10,11 +10,8 @@ import sys
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Gen.Call.CallGenBase as CallGenBase
File diff suppressed because it is too large. Load diff
+1 -4
View File
@@ -11,11 +11,8 @@ import sys
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Gen.Call.CallGenBase as CallGenBase
+1 -4
View File
@@ -10,11 +10,8 @@ import sys
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Gen.Call.CallGenBase as CallGenBase
+1 -4
View File
@@ -13,11 +13,8 @@ import sys
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Gen.Call.CallGenBase as CallGenBase
+1 -1
View File
@@ -10,7 +10,7 @@ import stdio
import stdlib
import viperlib
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.CompilerFactory as CompilerFactory
+1 -1
View File
@@ -9,7 +9,7 @@ import stdio
import stdlib
import viperlib
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.CompilerFactory as CompilerFactory
+1 -1
View File
@@ -9,7 +9,7 @@ import stdio
import stdlib
import viperlib
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.CompilerFactory as CompilerFactory
+1 -1
View File
@@ -9,7 +9,7 @@ import stdio
import stdlib
import viperlib
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.CompilerFactory as CompilerFactory
+1 -1
View File
@@ -8,7 +8,7 @@ import stdio
import stdlib
import viperlib
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Gen.Class.ClassGenBase as ClassGenBase
File diff suppressed because it is too large. Load diff
+6 -8
View File
@@ -10,10 +10,7 @@ import stdlib
import viperlib
import w32.fileio as fileio
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
import lib.Stub.StubMerger.StubMergerBuild as StubMergerBuild
@@ -23,6 +20,7 @@ import lib.Projectrans.Utils as Utils
import lib.core.Gen.Expr.ExprGenBase as ExprGenBase
import lib.core.Gen.GenApi as GenApi
# ============================================================
# ExprGenAttr - ExprGenMixin 拆分(阶段 D):Attribute/属性访问/全局引用
@@ -721,11 +719,11 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
if at.value.kind() == ast.ASTKind.Name and trans is not None:
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(at.value)
if nm.id is not None:
if HT.is_nonlocal_name(trans, nm.id) != 0:
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
raw_nl_a: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl._load_raw_var_ptr(
trans, nm.id)
if raw_nl_a is not None:
nl_ty_a: llvmlite.LLVMType | t.CPtr = HT.get_nonlocal_type(
nl_ty_a: llvmlite.LLVMType | t.CPtr = GenApi.get_nonlocal_type(
trans, nm.id)
if nl_ty_a is not None:
# 对象即指针:Struct/Array 类型直接用堆地址(bitcast 后
@@ -1044,11 +1042,11 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
if at.value.kind() == ast.ASTKind.Name and trans is not None:
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(at.value)
if nm.id is not None:
if HT.is_nonlocal_name(trans, nm.id) != 0:
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
raw_nl_a: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl._load_raw_var_ptr(
trans, nm.id)
if raw_nl_a is not None:
nl_ty_a: llvmlite.LLVMType | t.CPtr = HT.get_nonlocal_type(
nl_ty_a: llvmlite.LLVMType | t.CPtr = GenApi.get_nonlocal_type(
trans, nm.id)
if nl_ty_a is not None:
# 对象即指针:Struct/Array 类型直接用堆地址(bitcast 后
+1 -4
View File
@@ -10,10 +10,7 @@ import stdlib
import viperlib
import w32.fileio as fileio
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.VLogger as VLogger
import lib.Projectrans.Config as Config
+1 -4
View File
@@ -9,10 +9,7 @@ import stdlib
import viperlib
import w32.fileio as fileio
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.VLogger as VLogger
import lib.Projectrans.Config as Config
+1 -4
View File
@@ -12,10 +12,7 @@ import stdlib
import viperlib
import w32.fileio as fileio
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.VLogger as VLogger
import lib.Projectrans.Config as Config
+1 -4
View File
@@ -10,10 +10,7 @@ import stdlib
import viperlib
import w32.fileio as fileio
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.VLogger as VLogger
import lib.Projectrans.Config as Config
+1 -4
View File
@@ -9,10 +9,7 @@ import stdlib
import viperlib
import w32.fileio as fileio
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.VLogger as VLogger
import lib.Projectrans.Config as Config
+1 -4
View File
@@ -9,10 +9,7 @@ import stdio
import viperlib
import w32.fileio as fileio
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.VLogger as VLogger
import lib.Projectrans.Config as Config
+7 -9
View File
@@ -10,10 +10,7 @@ import stdlib
import viperlib
import w32.fileio as fileio
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
import lib.core.VLogger as VLogger
@@ -22,6 +19,7 @@ import lib.Projectrans.Utils as Utils
import lib.core.Gen.Expr.ExprGenBase as ExprGenBase
import lib.core.Gen.GenApi as GenApi
# ============================================================
# ExprGenName - ExprGenMixin 拆分(阶段 D):Name/Subscript/下标访问
@@ -157,7 +155,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
# global 变量:从模块作用域查找(global 声明优先级最高)
if trans is not None:
if HT.is_global_name(trans, nm_id) != 0:
if GenApi.is_global_name(trans, nm_id) != 0:
mod_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
trans.SymTab, nm_id)
if mod_alloca is not None:
@@ -181,7 +179,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
return llvmlite.build_load(builder, load_ty, mod_alloca)
# nonlocal 变量:通过闭包 env 访问
if HT.is_nonlocal_name(trans, nm_id) != 0:
if GenApi.is_nonlocal_name(trans, nm_id) != 0:
return self.Gen.StmtGenDecl.load_nonlocal_var(trans, nm_id)
# *args va_list:变量名直接解析为指向 24 字节 va_list 缓冲区的 i8* 地址
@@ -587,7 +585,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
"""nonlocal 数组/指针下标:从 env 读堆地址 → bitcast → GEP,返回元素指针"""
if trans is None or nm_id is None or idx_val is None:
return None
nl_ty: llvmlite.LLVMType | t.CPtr = HT.get_nonlocal_type(trans, nm_id)
nl_ty: llvmlite.LLVMType | t.CPtr = GenApi.get_nonlocal_type(trans, nm_id)
if nl_ty is None:
return None
raw_nl: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl._load_raw_var_ptr(trans, nm_id)
@@ -702,7 +700,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
# nonlocal 数组/指针:从 env 读共享堆地址(提升函数内不能
# lookup_var 外层 alloca——SSA 编号跨函数错乱崩溃)
# 读路径:元素指针 load 出元素值
if HT.is_nonlocal_name(trans, nm.id) != 0:
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
nl_ptr_r: llvmlite.Value | t.CPtr = self._nonlocal_subscript_ptr(
builder, pool, trans, nm.id, idx_val)
if nl_ptr_r is not None and nl_ptr_r.Ty is not None:
@@ -1002,7 +1000,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
if nm.id is not None and trans is not None:
# nonlocal 数组/指针:从 env 读共享堆地址(提升函数内不能
# lookup_var 外层 alloca——SSA 编号跨函数错乱崩溃)
if HT.is_nonlocal_name(trans, nm.id) != 0:
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
return self._nonlocal_subscript_ptr(
builder, pool, trans, nm.id, idx_val)
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
+1 -4
View File
@@ -10,10 +10,7 @@ import stdlib
import viperlib
import w32.fileio as fileio
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.VLogger as VLogger
import lib.Projectrans.Config as Config
+1 -3
View File
@@ -8,9 +8,7 @@ import viperlib
import stdio
import stdlib
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.core.Gen.Call.CallGenBase as CallGenBase
# ============================================================
+3 -5
View File
@@ -10,11 +10,9 @@ import viperlib
import stdio
import stdlib
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Handles.ExprCallTable as ExprCallTable
import lib.core.Gen.Translator as HT
import lib.core.Gen.Call.CallGenBase as CallGenBase
import lib.core.Gen.GenApi as GenApi
# ============================================================
@@ -800,7 +798,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
trans._cur_func = func
trans._cur_builder = func_builder
# 清空 global/nonlocal 名称集合(新函数作用域)
HT.clear_scope_names(trans)
GenApi.clear_scope_names(trans)
# 重置链内 nonlocal 堆预建标志(每函数只建一次;多嵌套函数定义
# 共享同一堆,防重复 malloc + 二次重定向 VarEntry)
trans._nl_chain_done = 0
File diff suppressed because it is too large. Load diff
+82 -1
View File
@@ -14,7 +14,7 @@ import viperlib
import w32.fileio as fileio
import lib.core.Gen.GenTypes as GenTypes
import lib.core.Gen.Generator as Generator
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Gen.Translator as HT
# ============================================================
@@ -603,3 +603,84 @@ def translate_print_call(pool: memhub.MemBuddy | t.CPtr, builder: llvmlite.IRBui
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit.translate_print_call(pool, builder, mod, cl, trans)
# ---------------- add_global_name(委托 TranslatorGenMixin.add_global_name) ----------------
def add_global_name(trans: HT.Translator | t.CPtr, name: str) -> None:
"""委托到 gen.TranslatorGen.add_global_name(原 Handles 壳)"""
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.TranslatorGen.add_global_name(trans, name)
# ---------------- is_global_name(委托 TranslatorGenMixin.is_global_name) ----------------
def is_global_name(trans: HT.Translator | t.CPtr, name: str) -> int:
"""委托到 gen.TranslatorGen.is_global_name(原 Handles 壳)"""
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.TranslatorGen.is_global_name(trans, name)
return 0
# ---------------- add_nonlocal_name(委托 TranslatorGenMixin.add_nonlocal_name) ----------------
def add_nonlocal_name(trans: HT.Translator | t.CPtr, name: str,
var_ty: llvmlite.LLVMType | t.CPtr = None) -> None:
"""委托到 gen.TranslatorGen.add_nonlocal_name(原 Handles 壳)"""
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.TranslatorGen.add_nonlocal_name(trans, name, var_ty)
# ---------------- get_nonlocal_type(委托 TranslatorGenMixin.get_nonlocal_type) ----------------
def get_nonlocal_type(trans: HT.Translator | t.CPtr,
name: str) -> llvmlite.LLVMType | t.CPtr:
"""委托到 gen.TranslatorGen.get_nonlocal_type(原 Handles 壳)"""
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.TranslatorGen.get_nonlocal_type(trans, name)
return None
# ---------------- is_nonlocal_name(委托 TranslatorGenMixin.is_nonlocal_name) ----------------
def is_nonlocal_name(trans: HT.Translator | t.CPtr, name: str) -> int:
"""委托到 gen.TranslatorGen.is_nonlocal_name(原 Handles 壳)"""
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.TranslatorGen.is_nonlocal_name(trans, name)
return 0
# ---------------- get_nonlocal_index(委托 TranslatorGenMixin.get_nonlocal_index) ----------------
def get_nonlocal_index(trans: HT.Translator | t.CPtr, name: str) -> int:
"""委托到 gen.TranslatorGen.get_nonlocal_index(原 Handles 壳)"""
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.TranslatorGen.get_nonlocal_index(trans, name)
return 0
# ---------------- clear_scope_names(委托 TranslatorGenMixin.clear_scope_names) ----------------
def clear_scope_names(trans: HT.Translator | t.CPtr) -> None:
"""委托到 gen.TranslatorGen.clear_scope_names(原 Handles 壳)"""
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.TranslatorGen.clear_scope_names(trans)
# ---------------- update_global_func_typestr(委托 CallGenLeafKit.update_global_func_typestr) ----------------
def update_global_func_typestr(pool: memhub.MemBuddy | t.CPtr,
name: str,
func: llvmlite.Function | t.CPtr) -> int:
"""委托到 gen.CallGenLeafKit.update_global_func_typestr(原 ExprCallTable 壳)"""
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.CallGenLeafKit.update_global_func_typestr(pool, name, func)
return 0
+1 -1
View File
@@ -11,7 +11,7 @@ import sys
import w32.fileio as fileio
import lib.Stub.StubMerger as StubMerger
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
File diff suppressed because it is too large. Load diff
+1 -3
View File
@@ -10,9 +10,7 @@ import stdlib
import stdio
import viperlib
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.core.CompilerFactory as CompilerFactory
import lib.Projectrans.Config as Config
# ============================================================
+7 -8
View File
@@ -9,12 +9,11 @@ import stdlib
import stdio
import viperlib
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.core.CompilerFactory as CompilerFactory
import lib.Projectrans.Config as Config
import lib.core.Gen.Stmt.StmtGenCifMixin as StmtGenCifMixin
import lib.core.Gen.GenApi as GenApi
# ============================================================
@@ -56,7 +55,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
if nm_node is not None and nm_node.kind() == ast.ASTKind.Name:
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(nm_node)
if nm.id is not None:
HT.add_global_name(trans, nm.id)
GenApi.add_global_name(trans, nm.id)
return 0
def translate_nonlocal(self, trans: HT.Translator | t.CPtr,
@@ -92,7 +91,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
self.Gen.TypeGenErr.fatal_error(nm_node, f"nonlocal 变量 '{nm.id}' 类型无效(Void/无法解析)", "TypeError")
case _:
pass
HT.add_nonlocal_name(trans, nm.id, var_ty)
GenApi.add_nonlocal_name(trans, nm.id, var_ty)
return 0
def translate_expr_stmt(self, trans: HT.Translator | t.CPtr,
@@ -330,7 +329,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
返回 i8* 类型的 Value,调用方需 bitcast 为具体类型指针后 load/store。
"""
idx: int = HT.get_nonlocal_index(trans, name)
idx: int = GenApi.get_nonlocal_index(trans, name)
if idx < 0:
return None
@@ -374,7 +373,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
# 获取变量类型(从注册时存储的类型信息)
var_ty: llvmlite.LLVMType | t.CPtr = HT.get_nonlocal_type(trans, name)
var_ty: llvmlite.LLVMType | t.CPtr = GenApi.get_nonlocal_type(trans, name)
if var_ty is None or self._is_void_type(var_ty) != 0:
# 类型缺失/无效直接报错终止(fail-fast),避免生成 "load void, void*" 非法 IR
self.Gen.TypeGenErr.fatal_error(None, f"nonlocal 变量 '{name}' 类型缺失,无法 load", "TypeError")
@@ -400,7 +399,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
# 获取变量类型
var_ty: llvmlite.LLVMType | t.CPtr = HT.get_nonlocal_type(trans, name)
var_ty: llvmlite.LLVMType | t.CPtr = GenApi.get_nonlocal_type(trans, name)
if var_ty is None or self._is_void_type(var_ty) != 0:
# 类型缺失/无效直接报错终止(fail-fast),避免生成 "bitcast ... to void*" 非法 IR
self.Gen.TypeGenErr.fatal_error(None, f"nonlocal 变量 '{name}' 类型缺失,无法 load", "TypeError")
+1 -3
View File
@@ -11,9 +11,7 @@ import stdlib
import stdio
import viperlib
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.core.CompilerFactory as CompilerFactory
import lib.Projectrans.Config as Config
import lib.core.Gen.Stmt.StmtGenDeclMixin as StmtGenDeclMixin
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -7,7 +7,7 @@ import memhub
import string
import viperlib
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Gen.Translator as HT
import lib.core.Gen.GenTypes as GenTypes
+1 -4
View File
@@ -8,10 +8,7 @@ import viperlib
import stdio
import stdlib
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.CompilerFactory as CompilerFactory
+1 -6
View File
@@ -8,10 +8,7 @@ import viperlib
import stdio
import stdlib
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.core.CompilerFactory as CompilerFactory
@@ -322,7 +319,6 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
# ExprGenMixin 方法,TypeGenMixin 直接调用会生成未定义引用)
if (from_imports is not None or imported_modules is not None) \
and pool is not None:
import lib.core.Handles.HandlesExpr as HandlesExpr
x_val: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(
pool, nm.id, from_imports, imported_modules)
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
@@ -355,7 +351,6 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
for mi in range(mod_len):
fi_buf[2 + mi] = at_mod.id[mi]
fi_buf[2 + mod_len] = '\0'
import lib.core.Handles.HandlesExpr as HandlesExpr
av: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(
pool, at.attr, fi_buf, imported_modules)
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
+395 -395
View File
@@ -1,396 +1,396 @@
import lib.core.Gen.GenTypes as GenTypes
import lib.core.Gen.Generator as Generator
import t, c
from stdint import *
import ast
import llvmlite
import memhub
import string
import viperlib
import stdio
import stdlib
import sys
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.Stub.StubMerger as StubMerger
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Gen.Type.TypeGenBase as TypeGenBase
# ============================================================
# TypeGenErr - TypeGenMixin 拆分(阶段 D):错误上报/源行读取/类型推断(fatal_error/infer_* 等)
#
# 继承 TypeGenBase(1 级,TPV self 调用仅支持 1 级父类)。
# 跨 Mixin 调用统一走 HandlesType 委托(经 _g_gen)。
# @t.NoVTable:静态绑定。
# ============================================================
@t.NoVTable
class TypeGenErr(TypeGenBase.TypeGenBase):
"""错误上报/源行读取/类型推断(fatal_error/infer_* 等)"""
def _read_source_line(self, file_path: str, lineno: int) -> str:
"""从源文件读取第 lineno 行内容"""
if file_path is None or lineno <= 0:
return None
f: fileio.File | t.CPtr = fileio.File(file_path, fileio.MODE.R)
if f.closed:
return None
# 按文件实际大小分配缓冲区:固定 256KB 会截断大源文件,末尾行号读不到 →
# 误报"文件不存在或行号超出范围"(如 CallGenMixin.vp 555KB/9236 行的第
# 8390 行)。64MB 上限防御异常超大文件整体读取。
fsize: LONGLONG = f.size()
if fsize <= 0 or fsize > 67108864:
f.close()
return None
src_size: t.CSizeT = t.CSizeT(fsize)
buf: bytes = stdlib.malloc(src_size + 1)
if buf is None:
f.close()
return None
bytes_read: LONG = f.read_all(buf, ULONG(src_size + 1))
f.close()
if bytes_read <= 0:
stdlib.free(buf)
return None
# 逐行查找第 lineno 行
cur_line: int = 1
line_start: t.CSizeT = 0
for i in range(bytes_read):
if buf[i] == '\n':
if cur_line == lineno:
line_len: t.CSizeT = i - line_start
if line_len > 0 and buf[line_start + line_len - 1] == '\r':
line_len -= 1
line_buf: bytes = stdlib.malloc(line_len + 1)
if line_buf is not None:
string.strncpy(line_buf, buf + line_start, line_len)
line_buf[line_len] = '\0'
stdlib.free(buf)
return line_buf
stdlib.free(buf)
return None
cur_line += 1
line_start = i + 1
stdlib.free(buf)
return None
def read_source_line(self, file_path: str, lineno: int) -> str:
"""公开包装:从源文件读取第 lineno 行内容(供 traceback 展示)"""
return self._read_source_line(file_path, lineno)
def dump_parse_traceback(self, file_path: str) -> None:
"""解析失败时以 Python 风格输出 traceback(仿 fatal_error)"""
err_line: int = ast.get_parse_err_line()
err_col: int = ast.get_parse_err_col()
err_msg: str = ast.get_parse_err_msg()
stdio.printf("Traceback (most recent call last):\n")
if file_path is None or file_path[0] == 0:
file_path = "<unknown>"
if err_line > 0:
stdio.printf(' File "%s", line %d\n', file_path, err_line)
src: str = self._read_source_line(file_path, err_line)
if src is not None:
stdio.printf(" %s\n", src)
# 列标记:在出错 token 起始列下方标 ^(parser 的 col_offset 是 0-based,
# 前缀 4 空格 + err_col 个空格后落点恰好是该 token 首字符)
if err_col > 0:
stdio.printf(" ")
c: int
for c in range(err_col):
stdio.printf(" ")
stdio.printf("^\n")
stdlib.free(src)
else:
stdio.printf(' File "%s"\n', file_path)
if err_msg is None or err_msg[0] == 0:
err_msg = "语法错误"
stdio.printf("SyntaxError: %s\n", err_msg)
def fatal_error(self, node: ast.AST | t.CPtr, msg: str,
err_type: str = "SyntaxError",
col_start: int = 0, col_end: int = 0):
"""以 Python 风格报错并退出(支持多帧、错误类型、列范围)
向后兼容:err_type/col_start/col_end 有默认值,旧调用 fatal_error(node, msg) 仍可用。
"""
stdio.printf("Traceback (most recent call last):\n")
# 输出调用栈帧(从底到顶)
i: int
for i in range(self.Gen.TypeGenBase.TraceCount):
frame: GenTypes.TraceFrame | t.CPtr = self.Gen.TypeGenBase._get_trace_frame(i)
if frame is not None and frame.file_name is not None:
if frame.lineno > 0:
stdio.printf(' File "%s", line %d\n', frame.file_name, frame.lineno)
src: str = self._read_source_line(frame.file_name, frame.lineno)
if src is not None:
stdio.printf(" %s\n", src)
stdlib.free(src)
else:
stdio.printf(' File "%s"\n', frame.file_name)
# 输出当前帧(node 对应的位置)
lineno: int = 0
if node is not None:
lineno = node.lineno
file_name: str = self.Gen.TypeGenResolve.get_current_file()
if file_name is None:
file_name = "<unknown>"
# 行号兜底:克隆/构造节点 lineno 可能为 0(如泛型特化 _clone_arguments 的
# ast.Arg 构造器硬编码 0,astaux.vp L139)。此时回退到 trace 栈最后一个
# 有效帧(文件+行号)作为出错位置,避免输出误导性的 "line 0"。
if lineno <= 0 and self.Gen.TypeGenBase.TraceCount > 0:
ti_b: int = self.Gen.TypeGenBase.TraceCount - 1
while ti_b >= 0:
tfb: GenTypes.TraceFrame | t.CPtr = self.Gen.TypeGenBase._get_trace_frame(ti_b)
if tfb is not None and tfb.file_name is not None and tfb.lineno > 0:
file_name = tfb.file_name
lineno = tfb.lineno
break
ti_b -= 1
# 行号合理性防御:先读取该行源码,验证 node.lineno 是否落在当前文件内。
# 若读不到(文件不存在或行号超出范围),说明文件/行号归属不可信
# (如 AST 树被内存复用/串扰后跨文件报错),打印警告而非误导性行号。
src_line: str = None
line_ok: int = 1
if lineno > 0 and string.strcmp(file_name, "<unknown>") != 0:
src_line = self._read_source_line(file_name, lineno)
if src_line is None:
line_ok = 0
if line_ok == 0:
stdio.printf(' File "%s", line %d (!! 无法读取该行源码:文件不存在或行号超出范围,错误可能来自被复用的 AST 树,请以错误消息为准)\n',
file_name, lineno)
else:
stdio.printf(' File "%s", line %d\n', file_name, lineno)
if src_line is not None:
stdio.printf(" %s\n", src_line)
# 列范围标记:在源代码行下方用 ^ 标记出错范围
if col_start > 0 and col_end >= col_start:
stdio.printf(" ")
j: int
for j in range(col_end):
if j >= col_start - 1 and j < col_end:
stdio.printf("^")
else:
stdio.printf(" ")
stdio.printf("\n")
stdlib.free(src_line)
# 输出错误类型 + 消息
if err_type is None or err_type[0] == 0:
err_type = "SyntaxError"
stdio.printf("%s: %s\n", err_type, msg)
sys.exit(1)
def fatal_type_error(self, node: ast.AST | t.CPtr, msg: str,
col_start: int = 0, col_end: int = 0):
"""以 Python 风格报错并退出(TypeError 版本)"""
self.fatal_error(node, msg, "TypeError", col_start, col_end)
def try_extract_callable_ret(self, pool: memhub.MemBuddy | t.CPtr,
annot: ast.AST | t.CPtr,
imported_modules: str,
from_imports: str,
trans: HT.Translator | t.CPtr) -> llvmlite.LLVMType | t.CPtr:
"""提取 t.Callable 注解的返回类型 LLVMType;非 Callable 注解返回 None"""
if annot is None or annot.kind() != ast.ASTKind.Subscript:
return None
sub_cr: ast.Subscript | t.CPtr = (ast.Subscript | t.CPtr)(annot)
if sub_cr.value is None or sub_cr.value.kind() != ast.ASTKind.Attribute:
return None
at_cr: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(sub_cr.value)
if at_cr.attr is None or string.strcmp(at_cr.attr, "Callable") != 0:
return None
# slice 必须是 Tuple(elts=[args_list, ret_node])
if sub_cr.slice is None or sub_cr.slice.kind() != ast.ASTKind.Tuple:
return None
tp_cr: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(sub_cr.slice)
if tp_cr.elts is None or len(tp_cr.elts) != 2:
return None
ret_node_cr: ast.AST | t.CPtr = tp_cr.elts.get(1)
if ret_node_cr is None:
return None
return self.Gen.TypeGenResolve.resolve_annotation_type(pool, ret_node_cr, imported_modules, from_imports, trans, 0)
def has_decorator_marker(self, node: ast.AST | t.CPtr,
marker_name: str,
depth: int = 0) -> int:
"""检测类型注解中是否包含指定的装饰器标记"""
if node is None or marker_name is None:
return 0
# 递归深度守卫:vpi stub 注入时对每个函数 returns 调用本函数,
# vpi tree 深层节点可能被覆盖损坏成回指环(VpiReader L810-813),
# BinOp 递归无守卫会无限递归直至栈耗尽。fail-fast 终止。
if depth > 128:
self.fatal_type_error(node, "装饰器标记检测递归过深(AST 环或嵌套超过 128 层)")
k: int = node.kind()
# Attribute 节点: t.CExtern, t.State, t.CExport, t.CInline
if k == ast.ASTKind.Attribute:
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(node)
if at.attr is not None:
if string.strcmp(at.attr, marker_name) == 0:
return 1
return 0
# BinOp 节点: int | t.CExtern(递归检测左右子节点)
if k == ast.ASTKind.BinOp:
bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
if self.has_decorator_marker(bop.left, marker_name, depth + 1) != 0:
return 1
if self.has_decorator_marker(bop.right, marker_name, depth + 1) != 0:
return 1
return 0
return 0
def is_pass_body(self, body: list[ast.AST | t.CPtr] | t.CPtr) -> int:
"""检测函数体是否为 pass(空体或仅含 pass 语句)"""
if body is None:
return 1
bn: t.CSizeT = len(body)
if bn == 0:
return 1
if bn == 1:
stmt: ast.AST | t.CPtr = body.get(0)
if stmt is not None and stmt.kind() == ast.ASTKind.Pass:
return 1
return 0
def get_llvm_type_bits(self, ty: llvmlite.LLVMType | t.CPtr) -> int:
"""获取 LLVM 整数类型的位宽,非整数类型返回 0"""
if ty is None:
return 0
match ty:
case llvmlite.LLVMType.Int(bits):
return bits
case _:
return 0
def infer_expr_type(self, pool: memhub.MemBuddy | t.CPtr,
node: ast.AST | t.CPtr,
param_types: str) -> llvmlite.LLVMType | t.CPtr:
"""推断表达式的 LLVM 类型
param_types 格式: "name:bits,name:bits,..."
"""
if node is None:
return llvmlite.Int32(pool)
k: int = node.kind()
if k == ast.ASTKind.Constant:
return llvmlite.Int32(pool)
elif k == ast.ASTKind.Name:
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(node)
if nm.id is not None and param_types is not None:
# 在 param_types 中查找: "name:bits" 格式
search_key: str = pool.alloc(64)
if search_key is not None:
viperlib.snprintf(search_key, 64, "%s:", nm.id)
found: str = string.strstr(param_types, search_key)
if found is not None:
colon_pos: t.CSizeT = string.strlen(nm.id) + 1
bits_str: str = found + colon_pos
bits: int = 0
for bi in range(4):
ch: t.CChar = bits_str[bi]
if ch >= '0' and ch <= '9':
bits = bits * 10 + (ch - '0')
else:
break
if bits == 64:
return llvmlite.Int64(pool)
elif bits == 16:
return llvmlite.Int16(pool)
elif bits == 8:
return llvmlite.Int8(pool)
return llvmlite.Int32(pool)
elif k == ast.ASTKind.BinOp:
binop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
lhs_ty: llvmlite.LLVMType | t.CPtr = self.infer_expr_type(
pool, binop.left, param_types)
rhs_ty: llvmlite.LLVMType | t.CPtr = self.infer_expr_type(
pool, binop.right, param_types)
lhs_bits: int = self.get_llvm_type_bits(lhs_ty)
rhs_bits: int = self.get_llvm_type_bits(rhs_ty)
if lhs_bits >= rhs_bits:
return lhs_ty
return rhs_ty
return llvmlite.Int32(pool)
def infer_return_type(self, pool: memhub.MemBuddy | t.CPtr,
body: list[ast.AST | t.CPtr] | t.CPtr,
param_types: str) -> llvmlite.LLVMType | t.CPtr:
"""扫描函数体中的 return 语句,推断返回类型"""
if body is None:
return llvmlite.Int32(pool)
ret_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
bn: t.CSizeT = len(body)
for bi in range(bn):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None and stmt.kind() == ast.ASTKind.Return:
rt: ast.Return | t.CPtr = (ast.Return | t.CPtr)(stmt)
if rt.value is not None:
expr_ty: llvmlite.LLVMType | t.CPtr = self.infer_expr_type(
pool, rt.value, param_types)
if expr_ty is not None:
cur_bits: int = self.get_llvm_type_bits(ret_ty)
new_bits: int = self.get_llvm_type_bits(expr_ty)
if new_bits > cur_bits:
ret_ty = expr_ty
return ret_ty
def build_param_types_str(self, pool: memhub.MemBuddy | t.CPtr,
args_node: ast.AST | t.CPtr) -> str:
"""构建参数类型编码字符串 "name:bits,name:bits,..." """
if args_node is None:
return None
ags: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(args_node)
if ags.args is None:
return None
alist: list[ast.AST | t.CPtr] | t.CPtr = ags.args
an: t.CSizeT = len(alist)
if an == 0:
return None
buf_size: t.CSizeT = an * 32 + 1
buf: str = pool.alloc(buf_size)
if buf is None:
return None
buf[0] = '\0'
i32_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
for ai in range(an):
arg: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(alist.get(ai))
if arg is not None and arg.arg is not None:
param_ty: llvmlite.LLVMType | t.CPtr = i32_ty
if arg.annotation is not None:
# 直接调用 map_t_type 解析 Attribute 注解
if arg.annotation.kind() == ast.ASTKind.Attribute:
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(arg.annotation)
if at.attr is not None:
resolved: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.map_t_type(pool, at.attr)
if resolved is not None:
param_ty = resolved
bits: int = self.get_llvm_type_bits(param_ty)
if bits == 0:
bits = 32
tmp: str = pool.alloc(32)
if tmp is not None:
viperlib.snprintf(tmp, 32, "%s:%d", arg.arg, bits)
if ai > 0:
self._strappend(buf, buf_size, ",")
self._strappend(buf, buf_size, tmp)
return buf
def _strappend(self, dst: str, dst_size: t.CSizeT, src: str):
"""将 src 追加到 dst 末尾"""
if dst is None or src is None:
return
dlen: t.CSizeT = string.strlen(dst)
slen: t.CSizeT = string.strlen(src)
remain: t.CSizeT = dst_size - dlen
if remain <= 0:
return
# 内联 min(slen, remain - 1) 避免 builtin min 未定义(TransPyV 无 builtin min)
limit: t.CSizeT = slen
cap: t.CSizeT = remain - 1
if cap < limit:
limit = cap
for i in range(limit):
dst[dlen + i] = src[i]
import lib.core.Gen.GenTypes as GenTypes
import lib.core.Gen.Generator as Generator
import t, c
from stdint import *
import ast
import llvmlite
import memhub
import string
import viperlib
import stdio
import stdlib
import sys
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.Stub.StubMerger as StubMerger
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Gen.Translator as HT
import lib.core.Gen.Type.TypeGenBase as TypeGenBase
# ============================================================
# TypeGenErr - TypeGenMixin 拆分(阶段 D):错误上报/源行读取/类型推断(fatal_error/infer_* 等)
#
# 继承 TypeGenBase(1 级,TPV self 调用仅支持 1 级父类)。
# 跨 Mixin 调用统一走 HandlesType 委托(经 _g_gen)。
# @t.NoVTable:静态绑定。
# ============================================================
@t.NoVTable
class TypeGenErr(TypeGenBase.TypeGenBase):
"""错误上报/源行读取/类型推断(fatal_error/infer_* 等)"""
def _read_source_line(self, file_path: str, lineno: int) -> str:
"""从源文件读取第 lineno 行内容"""
if file_path is None or lineno <= 0:
return None
f: fileio.File | t.CPtr = fileio.File(file_path, fileio.MODE.R)
if f.closed:
return None
# 按文件实际大小分配缓冲区:固定 256KB 会截断大源文件,末尾行号读不到 →
# 误报"文件不存在或行号超出范围"(如 CallGenMixin.vp 555KB/9236 行的第
# 8390 行)。64MB 上限防御异常超大文件整体读取。
fsize: LONGLONG = f.size()
if fsize <= 0 or fsize > 67108864:
f.close()
return None
src_size: t.CSizeT = t.CSizeT(fsize)
buf: bytes = stdlib.malloc(src_size + 1)
if buf is None:
f.close()
return None
bytes_read: LONG = f.read_all(buf, ULONG(src_size + 1))
f.close()
if bytes_read <= 0:
stdlib.free(buf)
return None
# 逐行查找第 lineno 行
cur_line: int = 1
line_start: t.CSizeT = 0
for i in range(bytes_read):
if buf[i] == '\n':
if cur_line == lineno:
line_len: t.CSizeT = i - line_start
if line_len > 0 and buf[line_start + line_len - 1] == '\r':
line_len -= 1
line_buf: bytes = stdlib.malloc(line_len + 1)
if line_buf is not None:
string.strncpy(line_buf, buf + line_start, line_len)
line_buf[line_len] = '\0'
stdlib.free(buf)
return line_buf
stdlib.free(buf)
return None
cur_line += 1
line_start = i + 1
stdlib.free(buf)
return None
def read_source_line(self, file_path: str, lineno: int) -> str:
"""公开包装:从源文件读取第 lineno 行内容(供 traceback 展示)"""
return self._read_source_line(file_path, lineno)
def dump_parse_traceback(self, file_path: str) -> None:
"""解析失败时以 Python 风格输出 traceback(仿 fatal_error)"""
err_line: int = ast.get_parse_err_line()
err_col: int = ast.get_parse_err_col()
err_msg: str = ast.get_parse_err_msg()
stdio.printf("Traceback (most recent call last):\n")
if file_path is None or file_path[0] == 0:
file_path = "<unknown>"
if err_line > 0:
stdio.printf(' File "%s", line %d\n', file_path, err_line)
src: str = self._read_source_line(file_path, err_line)
if src is not None:
stdio.printf(" %s\n", src)
# 列标记:在出错 token 起始列下方标 ^(parser 的 col_offset 是 0-based,
# 前缀 4 空格 + err_col 个空格后落点恰好是该 token 首字符)
if err_col > 0:
stdio.printf(" ")
c: int
for c in range(err_col):
stdio.printf(" ")
stdio.printf("^\n")
stdlib.free(src)
else:
stdio.printf(' File "%s"\n', file_path)
if err_msg is None or err_msg[0] == 0:
err_msg = "语法错误"
stdio.printf("SyntaxError: %s\n", err_msg)
def fatal_error(self, node: ast.AST | t.CPtr, msg: str,
err_type: str = "SyntaxError",
col_start: int = 0, col_end: int = 0):
"""以 Python 风格报错并退出(支持多帧、错误类型、列范围)
向后兼容:err_type/col_start/col_end 有默认值,旧调用 fatal_error(node, msg) 仍可用。
"""
stdio.printf("Traceback (most recent call last):\n")
# 输出调用栈帧(从底到顶)
i: int
for i in range(self.Gen.TypeGenBase.TraceCount):
frame: GenTypes.TraceFrame | t.CPtr = self.Gen.TypeGenBase._get_trace_frame(i)
if frame is not None and frame.file_name is not None:
if frame.lineno > 0:
stdio.printf(' File "%s", line %d\n', frame.file_name, frame.lineno)
src: str = self._read_source_line(frame.file_name, frame.lineno)
if src is not None:
stdio.printf(" %s\n", src)
stdlib.free(src)
else:
stdio.printf(' File "%s"\n', frame.file_name)
# 输出当前帧(node 对应的位置)
lineno: int = 0
if node is not None:
lineno = node.lineno
file_name: str = self.Gen.TypeGenResolve.get_current_file()
if file_name is None:
file_name = "<unknown>"
# 行号兜底:克隆/构造节点 lineno 可能为 0(如泛型特化 _clone_arguments 的
# ast.Arg 构造器硬编码 0,astaux.vp L139)。此时回退到 trace 栈最后一个
# 有效帧(文件+行号)作为出错位置,避免输出误导性的 "line 0"。
if lineno <= 0 and self.Gen.TypeGenBase.TraceCount > 0:
ti_b: int = self.Gen.TypeGenBase.TraceCount - 1
while ti_b >= 0:
tfb: GenTypes.TraceFrame | t.CPtr = self.Gen.TypeGenBase._get_trace_frame(ti_b)
if tfb is not None and tfb.file_name is not None and tfb.lineno > 0:
file_name = tfb.file_name
lineno = tfb.lineno
break
ti_b -= 1
# 行号合理性防御:先读取该行源码,验证 node.lineno 是否落在当前文件内。
# 若读不到(文件不存在或行号超出范围),说明文件/行号归属不可信
# (如 AST 树被内存复用/串扰后跨文件报错),打印警告而非误导性行号。
src_line: str = None
line_ok: int = 1
if lineno > 0 and string.strcmp(file_name, "<unknown>") != 0:
src_line = self._read_source_line(file_name, lineno)
if src_line is None:
line_ok = 0
if line_ok == 0:
stdio.printf(' File "%s", line %d (!! 无法读取该行源码:文件不存在或行号超出范围,错误可能来自被复用的 AST 树,请以错误消息为准)\n',
file_name, lineno)
else:
stdio.printf(' File "%s", line %d\n', file_name, lineno)
if src_line is not None:
stdio.printf(" %s\n", src_line)
# 列范围标记:在源代码行下方用 ^ 标记出错范围
if col_start > 0 and col_end >= col_start:
stdio.printf(" ")
j: int
for j in range(col_end):
if j >= col_start - 1 and j < col_end:
stdio.printf("^")
else:
stdio.printf(" ")
stdio.printf("\n")
stdlib.free(src_line)
# 输出错误类型 + 消息
if err_type is None or err_type[0] == 0:
err_type = "SyntaxError"
stdio.printf("%s: %s\n", err_type, msg)
sys.exit(1)
def fatal_type_error(self, node: ast.AST | t.CPtr, msg: str,
col_start: int = 0, col_end: int = 0):
"""以 Python 风格报错并退出(TypeError 版本)"""
self.fatal_error(node, msg, "TypeError", col_start, col_end)
def try_extract_callable_ret(self, pool: memhub.MemBuddy | t.CPtr,
annot: ast.AST | t.CPtr,
imported_modules: str,
from_imports: str,
trans: HT.Translator | t.CPtr) -> llvmlite.LLVMType | t.CPtr:
"""提取 t.Callable 注解的返回类型 LLVMType;非 Callable 注解返回 None"""
if annot is None or annot.kind() != ast.ASTKind.Subscript:
return None
sub_cr: ast.Subscript | t.CPtr = (ast.Subscript | t.CPtr)(annot)
if sub_cr.value is None or sub_cr.value.kind() != ast.ASTKind.Attribute:
return None
at_cr: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(sub_cr.value)
if at_cr.attr is None or string.strcmp(at_cr.attr, "Callable") != 0:
return None
# slice 必须是 Tuple(elts=[args_list, ret_node])
if sub_cr.slice is None or sub_cr.slice.kind() != ast.ASTKind.Tuple:
return None
tp_cr: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(sub_cr.slice)
if tp_cr.elts is None or len(tp_cr.elts) != 2:
return None
ret_node_cr: ast.AST | t.CPtr = tp_cr.elts.get(1)
if ret_node_cr is None:
return None
return self.Gen.TypeGenResolve.resolve_annotation_type(pool, ret_node_cr, imported_modules, from_imports, trans, 0)
def has_decorator_marker(self, node: ast.AST | t.CPtr,
marker_name: str,
depth: int = 0) -> int:
"""检测类型注解中是否包含指定的装饰器标记"""
if node is None or marker_name is None:
return 0
# 递归深度守卫:vpi stub 注入时对每个函数 returns 调用本函数,
# vpi tree 深层节点可能被覆盖损坏成回指环(VpiReader L810-813),
# BinOp 递归无守卫会无限递归直至栈耗尽。fail-fast 终止。
if depth > 128:
self.fatal_type_error(node, "装饰器标记检测递归过深(AST 环或嵌套超过 128 层)")
k: int = node.kind()
# Attribute 节点: t.CExtern, t.State, t.CExport, t.CInline
if k == ast.ASTKind.Attribute:
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(node)
if at.attr is not None:
if string.strcmp(at.attr, marker_name) == 0:
return 1
return 0
# BinOp 节点: int | t.CExtern(递归检测左右子节点)
if k == ast.ASTKind.BinOp:
bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
if self.has_decorator_marker(bop.left, marker_name, depth + 1) != 0:
return 1
if self.has_decorator_marker(bop.right, marker_name, depth + 1) != 0:
return 1
return 0
return 0
def is_pass_body(self, body: list[ast.AST | t.CPtr] | t.CPtr) -> int:
"""检测函数体是否为 pass(空体或仅含 pass 语句)"""
if body is None:
return 1
bn: t.CSizeT = len(body)
if bn == 0:
return 1
if bn == 1:
stmt: ast.AST | t.CPtr = body.get(0)
if stmt is not None and stmt.kind() == ast.ASTKind.Pass:
return 1
return 0
def get_llvm_type_bits(self, ty: llvmlite.LLVMType | t.CPtr) -> int:
"""获取 LLVM 整数类型的位宽,非整数类型返回 0"""
if ty is None:
return 0
match ty:
case llvmlite.LLVMType.Int(bits):
return bits
case _:
return 0
def infer_expr_type(self, pool: memhub.MemBuddy | t.CPtr,
node: ast.AST | t.CPtr,
param_types: str) -> llvmlite.LLVMType | t.CPtr:
"""推断表达式的 LLVM 类型
param_types 格式: "name:bits,name:bits,..."
"""
if node is None:
return llvmlite.Int32(pool)
k: int = node.kind()
if k == ast.ASTKind.Constant:
return llvmlite.Int32(pool)
elif k == ast.ASTKind.Name:
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(node)
if nm.id is not None and param_types is not None:
# 在 param_types 中查找: "name:bits" 格式
search_key: str = pool.alloc(64)
if search_key is not None:
viperlib.snprintf(search_key, 64, "%s:", nm.id)
found: str = string.strstr(param_types, search_key)
if found is not None:
colon_pos: t.CSizeT = string.strlen(nm.id) + 1
bits_str: str = found + colon_pos
bits: int = 0
for bi in range(4):
ch: t.CChar = bits_str[bi]
if ch >= '0' and ch <= '9':
bits = bits * 10 + (ch - '0')
else:
break
if bits == 64:
return llvmlite.Int64(pool)
elif bits == 16:
return llvmlite.Int16(pool)
elif bits == 8:
return llvmlite.Int8(pool)
return llvmlite.Int32(pool)
elif k == ast.ASTKind.BinOp:
binop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
lhs_ty: llvmlite.LLVMType | t.CPtr = self.infer_expr_type(
pool, binop.left, param_types)
rhs_ty: llvmlite.LLVMType | t.CPtr = self.infer_expr_type(
pool, binop.right, param_types)
lhs_bits: int = self.get_llvm_type_bits(lhs_ty)
rhs_bits: int = self.get_llvm_type_bits(rhs_ty)
if lhs_bits >= rhs_bits:
return lhs_ty
return rhs_ty
return llvmlite.Int32(pool)
def infer_return_type(self, pool: memhub.MemBuddy | t.CPtr,
body: list[ast.AST | t.CPtr] | t.CPtr,
param_types: str) -> llvmlite.LLVMType | t.CPtr:
"""扫描函数体中的 return 语句,推断返回类型"""
if body is None:
return llvmlite.Int32(pool)
ret_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
bn: t.CSizeT = len(body)
for bi in range(bn):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None and stmt.kind() == ast.ASTKind.Return:
rt: ast.Return | t.CPtr = (ast.Return | t.CPtr)(stmt)
if rt.value is not None:
expr_ty: llvmlite.LLVMType | t.CPtr = self.infer_expr_type(
pool, rt.value, param_types)
if expr_ty is not None:
cur_bits: int = self.get_llvm_type_bits(ret_ty)
new_bits: int = self.get_llvm_type_bits(expr_ty)
if new_bits > cur_bits:
ret_ty = expr_ty
return ret_ty
def build_param_types_str(self, pool: memhub.MemBuddy | t.CPtr,
args_node: ast.AST | t.CPtr) -> str:
"""构建参数类型编码字符串 "name:bits,name:bits,..." """
if args_node is None:
return None
ags: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(args_node)
if ags.args is None:
return None
alist: list[ast.AST | t.CPtr] | t.CPtr = ags.args
an: t.CSizeT = len(alist)
if an == 0:
return None
buf_size: t.CSizeT = an * 32 + 1
buf: str = pool.alloc(buf_size)
if buf is None:
return None
buf[0] = '\0'
i32_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
for ai in range(an):
arg: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(alist.get(ai))
if arg is not None and arg.arg is not None:
param_ty: llvmlite.LLVMType | t.CPtr = i32_ty
if arg.annotation is not None:
# 直接调用 map_t_type 解析 Attribute 注解
if arg.annotation.kind() == ast.ASTKind.Attribute:
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(arg.annotation)
if at.attr is not None:
resolved: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.map_t_type(pool, at.attr)
if resolved is not None:
param_ty = resolved
bits: int = self.get_llvm_type_bits(param_ty)
if bits == 0:
bits = 32
tmp: str = pool.alloc(32)
if tmp is not None:
viperlib.snprintf(tmp, 32, "%s:%d", arg.arg, bits)
if ai > 0:
self._strappend(buf, buf_size, ",")
self._strappend(buf, buf_size, tmp)
return buf
def _strappend(self, dst: str, dst_size: t.CSizeT, src: str):
"""将 src 追加到 dst 末尾"""
if dst is None or src is None:
return
dlen: t.CSizeT = string.strlen(dst)
slen: t.CSizeT = string.strlen(src)
remain: t.CSizeT = dst_size - dlen
if remain <= 0:
return
# 内联 min(slen, remain - 1) 避免 builtin min 未定义(TransPyV 无 builtin min)
limit: t.CSizeT = slen
cap: t.CSizeT = remain - 1
if cap < limit:
limit = cap
for i in range(limit):
dst[dlen + i] = src[i]
dst[dlen + i] = '\0' # i 退出值存疑
+1 -1
View File
@@ -11,7 +11,7 @@ import viperlib
import w32.fileio as fileio
import lib.core.CompilerFactory as CompilerFactory
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Gen.Translator as HT
import lib.core.Gen.Type.TypeGenBase as TypeGenBase
+1 -4
View File
@@ -11,10 +11,7 @@ import string
import viperlib
import stdlib
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HT
import lib.Stub.StubMerger as StubMerger
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
import lib.core.CompilerFactory as CompilerFactory
-197
View File
@@ -1,197 +0,0 @@
import lib.core.Gen.GenTypes as GenTypes
import lib.core.Gen.Call.CallGenLeafKit as CallGenLeafKit
import t, c
from stdint import *
import ast
import llvmlite
import memhub
import string
import stdio
import stdlib
import sys
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.Stub.StubMerger as StubMerger
import lib.core.Handles.HandlesExprCall as HandlesExprCall
# ============================================================
# ExprCallTable - HandlesExprCall 拆分(阶段 E):ExprCallTable
#
# 直接移动模式:委托函数迁至此模块,原 HandlesExprCall.vp 仅
# 保留 _g_gen/常量/类;调用方经本模块前缀访问。
# ============================================================
# ============================================================
# 初始化函数表
# ============================================================
def init_func_table(pool: memhub.MemBuddy | t.CPtr,
max_count: int) -> GenTypes.FuncEntry | t.CPtr:
"""分配并清零函数表数组(委托到 gen.init_func_table)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit.init_func_table(pool, max_count)
return None
# ============================================================
# 查找函数
# ============================================================
def find_func_in_table(funcs: GenTypes.FuncEntry | t.CPtr,
func_count: int,
name: str) -> llvmlite.Function | t.CPtr:
"""在函数表中按名称查找,返回 Function 指针或 None(委托到 gen.find_func_in_table)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit.find_func_in_table(funcs, func_count, name)
return None
# ============================================================
# 添加函数到函数表
# ============================================================
def add_func_to_table(funcs: GenTypes.FuncEntry | t.CPtr,
func_count: int,
name: str,
func: llvmlite.Function | t.CPtr,
max_count: int,
defaults: t.CVoid | t.CPtr = None,
default_count: int = 0,
param_count: int = 0,
pool: memhub.MemBuddy | t.CPtr = None) -> int:
"""添加函数到函数表,返回 0 成功(委托到 gen.add_func_to_table)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit.add_func_to_table(funcs, func_count, name, func, max_count,
defaults, default_count, param_count, pool)
return 0
# ============================================================
# 全局函数注册表(跨模块函数查找)
#
# 所有模块翻译的函数都会注册到此表(通过 add_func_to_table 自动注册)。
# 主要用途: vtable 初始化时查找跨模块继承方法的 Function 对象,
# 以获取函数类型信息构造 bitcast 字符串。
# ============================================================
GLOBAL_FUNC_MAX: t.CDefine = 8192
def _init_global_func_table() -> int:
"""初始化全局函数表(用 stdlib.malloc 分配,生命周期=整个程序)(委托到 gen._init_global_func_table)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit._init_global_func_table()
return 0
# _build_func_type_str — 从 Function 对象生成函数类型文本(stdlib 存储)
#
# 格式: ret_ty(param1_ty, param2_ty, ...),与 vtable bitcast 需要一致。
# 用 stdlib.malloc 分配返回,跨文件永久存活(1b reset 不回收)。
# 返回 None 表示失败。
def _build_func_type_str(pool: memhub.MemBuddy | t.CPtr,
func: llvmlite.Function | t.CPtr) -> str:
"""生成函数类型文本(stdlib 分配)(委托到 gen._build_func_type_str)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit._build_func_type_str(pool, func)
return None
def _register_global_func(name: str, func: llvmlite.Function | t.CPtr,
pool: memhub.MemBuddy | t.CPtr = None) -> int:
"""注册函数到全局表(已存在则跳过),返回 0 成功(委托到 gen._register_global_func)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit._register_global_func(name, func, pool)
return 0
def update_global_func_typestr(pool: memhub.MemBuddy | t.CPtr,
name: str,
func: llvmlite.Function | t.CPtr) -> int:
"""更新全局函数表的 TypeStr(在函数参数全部添加完成后调用)(委托到 gen.update_global_func_typestr)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit.update_global_func_typestr(pool, name, func)
return 0
def find_func_global(name: str) -> llvmlite.Function | t.CPtr:
"""在全局函数表中按名称查找,返回 Function 指针或 None(委托到 gen.find_func_global)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit.find_func_global(name)
return None
def find_func_entry_global(name: str) -> GenTypes.FuncEntry | t.CPtr:
"""在全局函数表中按名称查找,返回完整 GenTypes.FuncEntry(含 TypeStr)或 None(委托到 gen.find_func_entry_global)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit.find_func_entry_global(name)
return None
# ============================================================
# 全局默认参数注册表(跨模块默认参数填充)
#
# 独立于 _global_funcs,因为 _register_global_func 可能在
# add_func_to_table 之前被调用(如 stub 注入),此时 defaults 还不可用。
# ============================================================
GLOBAL_DEFAULTS_MAX: t.CDefine = 4096
def _init_global_defaults_table() -> int:
"""初始化全局默认参数表(委托到 gen._init_global_defaults_table)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit._init_global_defaults_table()
return 0
def _register_global_defaults(name: str,
defaults: t.CVoid | t.CPtr,
default_count: int,
param_count: int) -> int:
"""注册函数默认参数到全局表,返回 0 成功(委托到 gen._register_global_defaults)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit._register_global_defaults(name, defaults, default_count, param_count)
return 0
def find_func_defaults(name: str) -> GenTypes.FuncDefaultsEntry | t.CPtr:
"""按函数名查找默认参数信息,返回 GenTypes.FuncDefaultsEntry 或 None(委托到 gen.find_func_defaults)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit.find_func_defaults(name)
return None
# _build_const_from_snapshot — 从常量快照重建常量 IR 值
#
# 用于跨模块默认参数填充:gd_entry.Defaults(pool 内 AST)可能已被 reset 回收,
# 改用注册时提取的 stdlib 常量快照(ConstKinds/ConstInts/ConstStrs)重建常量 IR。
# 返回 llvmlite.Value*,失败返回 None。
def _build_const_from_snapshot(pool: memhub.MemBuddy | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
gd_entry: GenTypes.FuncDefaultsEntry | t.CPtr,
di: int,
trans: HT.Translator | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr) -> llvmlite.Value | t.CPtr:
"""从快照重建第 di 个默认值常量 IR(委托到 gen._build_const_from_snapshot)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit._build_const_from_snapshot(pool, mod, gd_entry, di, trans, builder)
return None
def find_func_entry_in_table(funcs: GenTypes.FuncEntry | t.CPtr,
func_count: int,
name: str) -> GenTypes.FuncEntry | t.CPtr:
"""在函数表中按名称查找,返回完整 GenTypes.FuncEntry 或 None"""
if name is None or funcs is None:
return None
entry_size: t.CSizeT = GenTypes.FuncEntry.__sizeof__()
i: int = 0
while i < func_count:
entry_addr: t.CUInt64T = t.CUInt64T(funcs) + i * entry_size
entry: GenTypes.FuncEntry | t.CPtr = (GenTypes.FuncEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry.Name is not None:
if string.strcmp(entry.Name, name) == 0:
return entry
i += 1
return None
-262
View File
@@ -1,262 +0,0 @@
import t, c
from stdint import *
import string
import viperlib
import memhub
import hashtable
import lib.core.Handles.HandlesTranslator as HT
# ============================================================
# TypeKind - 类型种类枚举
#
# 替代 TransPyC 中 CType.position frozenset 的元属性系统。
# 每个 TypeInfo 通过 Kind 字段标记其种类,避免 Python ClassVar 反射。
# ============================================================
class TypeKind(t.CEnum):
Basic: t.State # 基本类型(int/char/float/double/bool 等)
Pointer: t.State # 指针(T*)— 指针层数由 TypeInfo.PtrCount 表达
Struct: t.State # 结构体/类
Union: t.State # 联合体
Enum: t.State # 枚举
Typedef: t.State # 类型别名
Function: t.State # 函数指针
Array: t.State # 数组 T[N]
Void: t.State # void
# ============================================================
# TypeInfo - 类型信息结构
#
# 设计原则(相对 TransPyC CTypeInfo 的简化):
# - POD 数据结构,无虚函数,无 Python 元特性(ClassVar/Generic/frozenset)
# - 通过 mbuddy 分配,调用方管理生命周期(参考 llvmlite Module 模式)
# - 通过 Kind 枚举代替 position frozenset
# - PtrCount 表达指针层数(0=非指针, 1=T*, 2=T**)
# - IsSigned 三态:-1=不适用(void/float), 0=unsigned, 1=signed
#
# 字段布局(8 字段):
# Kind : i32 类型种类(TypeKind 枚举值)
# Name : i8* 类型名(如 'int', 'CInt', 'MyStruct'),可能为 None
# Size : i32 位宽(0=void/未知;int=32, char=8, double=64, long long=64)
# Align : i32 对齐字节数(0=默认)
# IsSigned : i32 -1=N/A, 0=unsigned, 1=signed
# PtrCount : i32 指针层数
# IsConst : i32 const 限定符(0/1)
# IsVolatile : i32 volatile 限定符(0/1)
#
# 注意:Size 使用位宽(bit width)而非字节数,与 LLVM IR 的 i{N} 和
# TransPyC CType.Size 约定一致(CInt.Size=32, CChar.Size=8)。
# ============================================================
@t.NoVTable
class TypeInfo:
Kind: int
Name: str
Size: int
Align: int
IsSigned: int
PtrCount: int
IsConst: int
IsVolatile: int
# ============================================================
# TypeRegistry - 类型注册表
#
# 维护 name(str) → TypeInfo* 映射,基于 HashTable 实现 O(1) 查找。
# 替代 TransPyC CTypeRegistry 的 _name_to_class dict。
# 内置基本类型(int/char/void/...)由 InitBasicTypes 注册。
# ============================================================
class TypeRegistry:
_ht: hashtable.HashTable | t.CPtr
__mbuddy__: memhub.MemBuddy | t.CPtr
def Register(self, ti: TypeInfo | t.CPtr) -> int:
"""注册一个 TypeInfo。ti.Name 字段必须已设置。
Returns:
1 表示成功,0 表示失败(ti 为 None 或 Name 为 None)
"""
if ti is None:
return 0
if ti.Name is None:
return 0
self._ht[ti.Name] = ti
return 1
def Lookup(self, name: str) -> TypeInfo | t.CPtr:
"""按名称查找 TypeInfo。
Returns:
找到返回 TypeInfo*,找不到返回 None
"""
if name is None:
return None
return self._ht[name]
def Has(self, name: str) -> int:
"""检查类型是否已注册。"""
if name is None:
return 0
return name in self._ht
# ============================================================
# NewTypeInfo - 工厂函数:分配并初始化一个 TypeInfo
#
# 默认值:Kind=Basic, IsSigned=-1, 其余=0/None
# ============================================================
def NewTypeInfo(pool: memhub.MemBuddy | t.CPtr) -> TypeInfo | t.CPtr:
ptr: TypeInfo | t.CPtr = pool.alloc(TypeInfo.__sizeof__())
if ptr is None:
return None
string.memset(ptr, 0, TypeInfo.__sizeof__())
ptr.Kind = TypeKind.Basic
ptr.IsSigned = -1
return ptr
# ============================================================
# NewTypeRegistry - 工厂函数:创建类型注册表
# ============================================================
def NewTypeRegistry(pool: memhub.MemBuddy | t.CPtr) -> TypeRegistry | t.CPtr:
ptr: TypeRegistry | t.CPtr = pool.alloc(TypeRegistry.__sizeof__())
if ptr is None:
return None
string.memset(ptr, 0, TypeRegistry.__sizeof__())
ptr.__mbuddy__ = pool
ptr._ht = hashtable.HashTable(pool)
return ptr
# ============================================================
# TypeToLLVM - 将 TypeInfo 转换为 LLVM IR 类型字符串
#
# 规则:
# - Kind == Void 或 (Size==0 且 IsSigned==-1 且 PtrCount==0) → "void"
# - void 有 PtrCount > 0 → "i8" + PtrCount 个 "*"
# - IsSigned == -1 且 Size > 0 → 浮点: half/float/double/fp128
# - IsSigned != -1 且 Size > 0 → 整数: i{Size}
# - 未知 → "i8*"
#
# Args:
# buf: 输出缓冲区(i8*)
# buf_size: 缓冲区容量
# ti: TypeInfo 指针
#
# Returns:
# 写入的字符数(不含 NUL),失败返回 -1
# ============================================================
def TypeToLLVM(buf: str, buf_size: t.CSizeT,
ti: TypeInfo | t.CPtr) -> int:
if buf is None:
return -1
if ti is None:
return -1
if buf_size == 0:
return -1
# 判定 void
is_void: int = 0
if ti.Kind == TypeKind.Void:
is_void = 1
elif ti.Size == 0 and ti.IsSigned == -1 and ti.PtrCount == 0:
is_void = 1
# 写入 base 类型字符串到 buf
base_len: int = 0
if is_void == 1:
if ti.PtrCount == 0:
# "void"
if buf_size < 5:
return -1
string.strcpy(buf, "void")
base_len = 4
else:
# void* → i8*(LLVM 中 void* 表示为 i8*)
if buf_size < 4:
return -1
string.strcpy(buf, "i8")
base_len = 2
elif ti.IsSigned == -1:
# 浮点
if ti.Size == 16:
if buf_size < 5:
return -1
string.strcpy(buf, "half")
base_len = 4
elif ti.Size == 32:
if buf_size < 6:
return -1
string.strcpy(buf, "float")
base_len = 5
elif ti.Size == 64:
if buf_size < 7:
return -1
string.strcpy(buf, "double")
base_len = 6
elif ti.Size == 128:
if buf_size < 6:
return -1
string.strcpy(buf, "fp128")
base_len = 5
else:
# 未知浮点尺寸 → double 兜底
if buf_size < 7:
return -1
string.strcpy(buf, "double")
base_len = 6
else:
# 整数: i{Size},用 snprintf 安全写入
if ti.Size <= 0:
# 无效尺寸 → i8 兜底
if buf_size < 4:
return -1
string.strcpy(buf, "i8")
base_len = 2
else:
viperlib.snprintf(buf, buf_size, "i%d", ti.Size)
base_len = string.strlen(buf)
# 追加 PtrCount 个 "*"
if base_len + ti.PtrCount + 1 > buf_size:
return -1
pos: int = base_len
for i in range(ti.PtrCount):
buf[pos] = '*'
pos += 1
buf[pos] = 0
return pos
# ============================================================
# Mixin - 所有 Handle 的非多态基类(对应 TransPyC 的 BaseHandle)
#
# @t.NoVTable 继承:字段展平嵌入子类,无 vtable 开销(对应 C++ 非多态继承)。
# 子类继承 Trans 字段 + 共享工具方法,编译器自动生成子类方法包装
# (self bitcast 为父类指针后调用),子类可直接调用继承的方法。
#
# 用法:
# @t.NoVTable
# class AssignHandle(Mixin):
# _CurrentClass: str
# def __init__(self, trans):
# self.InitMixin(trans)
# self._CurrentClass = None
# def Handle(self, node) -> int:
# rhs = self.Trans.ExprH.HandleValue(node.value)
# ...
# ============================================================
@t.NoVTable
class Mixin:
"""所有 Handle 的非多态基类:持有 Translator 回指针 + 共享委托方法"""
Trans: HT.Translator | t.CPtr
def InitMixin(self, trans: HT.Translator | t.CPtr) -> int:
"""初始化 Mixin 字段(子类 __init__ 中调用)"""
self.Trans = trans
return 0
# 全局 mbuddy 指针
_mbuddy: t.CVoid | t.CPtr
-953
View File
@@ -1,953 +0,0 @@
import lib.core.Gen.Expr.ExprGenAttr as ExprGenAttr
import lib.core.Gen.Expr.ExprGenBase as ExprGenBase
import lib.core.Gen.Expr.ExprGenCdef as ExprGenCdef
import lib.core.Gen.Expr.ExprGenCls as ExprGenCls
import lib.core.Gen.Expr.ExprGenConst as ExprGenConst
import lib.core.Gen.Expr.ExprGenFstr as ExprGenFstr
import lib.core.Gen.Expr.ExprGenMixin as ExprGenMixin
import lib.core.Gen.Expr.ExprGenName as ExprGenName
import lib.core.Gen.Expr.ExprGenOps as ExprGenOps
import lib.core.Gen.Func.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
-137
View File
@@ -1,137 +0,0 @@
import lib.core.Gen.GenApi as GenApi
import t, c
from stdint import *
import ast
import llvmlite
import memhub
import string
import stdio
import stdlib
import sys
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HT
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.Stub.StubMerger as StubMerger
import lib.core.Gen.Generator as Generator
# ============================================================
# 全局 gen 单例(模块级镜像,同 HandlesType/HandlesStruct 模式)
# ============================================================
_g_gen: Generator.Generator | t.CPtr = None
# ============================================================
# 本地常量(阶段 E 拆分时随函数块误删,补回;子模块经 HandlesExprCall.常量 引用)
# ============================================================
_CEXPORT_MAX: t.CDefine = 256
ASM_MAX_OPERANDS: t.CDefine = 16
ASM_TEXT_BUF_SIZE: t.CDefine = 2048
ASM_CONST_BUF_SIZE: t.CDefine = 512
ASM_ARGS_BUF_SIZE: t.CDefine = 512
ASM_LINE_BUF_SIZE: t.CDefine = 4096
LLVMIR_MAX_OPS: t.CDefine = 16
LLVMIR_TEMPLATE_BUF: t.CDefine = 512
MAX_CLOSURE_NAMES: t.CDefine = 128
MAX_FUNC_PTR_SIGS: t.CDefine = 64
GLOBAL_FUNC_MAX: t.CDefine = 8192
GLOBAL_DEFAULTS_MAX: t.CDefine = 4096
# ============================================================
# AsmOperand - 内联汇编操作数条目
# ============================================================
@t.NoVTable
class AsmOperand:
"""内联汇编操作数条目"""
Value: llvmlite.Value | t.CPtr # 输入值或输出 alloca
Constraint: str # 约束字符串 (如 "r", "=r")
IsOutput: int # 1=输出, 0=输入
# ============================================================
# FuncEntry 结构体(用于函数表)
# ============================================================
@t.NoVTable
class FuncEntry:
"""函数表条目"""
Name: str
Func: llvmlite.Function | t.CPtr
Defaults: t.CVoid | t.CPtr # defaults 列表节点指针 (list[AST | CPtr]),None=无默认值
DefaultCount: int # 默认值数量
ParamCount: int # 形参数量(不含 self)
# TypeStr: 函数类型文本(stdlib 深拷贝,跨文件安全)
# 1b 每文件 reset_to(mark1) 回收 pool 内 Function 对象后,
# vtable 生成 find_func_global 读类型改用此文本,避免悬空。
TypeStr: str
@t.NoVTable
class FuncDefaultsEntry:
"""默认参数表条目"""
Name: str
Defaults: t.CVoid | t.CPtr # defaults 列表节点指针 (list[AST | CPtr])(pool 内,可能被 reset)
DefaultCount: int
ParamCount: int # 形参数量(不含 self)
# 常量快照(stdlib 分配,跨文件永久存活):
# 注册时提取每个默认值 Constant 的值,跨模块调用时优先用快照重建常量 IR,
# 避免读取已被 1b reset_to(mark1) 回收的 pool 内 AST。
ConstKinds: t.CInt | t.CPtr # const_kind 数组(DefaultCount 个 i32)
ConstInts: t.CInt64T | t.CPtr # int_val 数组(DefaultCount 个 i64)
ConstStrs: t.CSizeT | t.CPtr # str_val 指针数组(DefaultCount 个 i8*)
# ============================================================
# ExprCallHandle - 函数调用处理器(Mixin 继承模式)
#
# HandleCall / HandlePrintfCall 提供 trans 接口
# ============================================================
@t.NoVTable
class ExprCallHandle(HandlesBase.Mixin):
"""函数调用处理器:继承 Mixin 获得 Trans 回指针"""
def __init__(self, trans: HT.Translator | t.CPtr):
self.Trans = trans
# ============================================================
# HandleCall - 翻译函数调用,返回 call 结果 Value
# ============================================================
def HandleCall(self, node: ast.AST | t.CPtr) -> llvmlite.Value | t.CPtr:
"""翻译函数调用,从 self.Trans 获取共享状态"""
return GenApi.translate_call(
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
node,
self.Trans._funcs, self.Trans._func_count, self.Trans)
# ============================================================
# HandlePrintfCall - 翻译 printf 调用
# ============================================================
def HandlePrintfCall(self, cl: ast.Call | t.CPtr):
"""翻译 printf 调用,从 self.Trans 获取共享状态"""
GenApi.translate_printf_call(
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
cl, self.Trans)
# ============================================================
# HandlePrintCall - 翻译 print 调用
# ============================================================
def HandlePrintCall(self, cl: ast.Call | t.CPtr):
"""翻译 print 调用(类型感知格式化 + 默认换行)"""
GenApi.translate_print_call(
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
cl, self.Trans)
-9
View File
@@ -1,9 +0,0 @@
import t, c
from stdint import *
# Handles 实体模块(去除委托层后保留:数据类/Translator/实体逻辑)
import lib.core.Handles.HandlesBase as HandlesBase
import lib.core.Handles.HandlesTranslator as HandlesTranslator
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Handles.ExprCallTable as ExprCallTable
+1 -6
View File
@@ -1,8 +1,6 @@
import lib.core.Gen.GenApi as GenApi
import lib.core.VLogger as VLogger
import lib.core.Handles.HandlesTranslator as HandlesTranslator
import lib.core.Handles.HandlesExpr as HandlesExpr
import lib.core.Handles.HandlesExprCall as HandlesExprCall
import lib.core.Gen.Translator as HandlesTranslator
import lib.Phase.BuildPipeline as BuildPipeline
import lib.core.IncludesScanner as IncludesScanner
import lib.Stub.StubMerger as StubMerger
@@ -118,9 +116,6 @@ def main() -> int:
# 种子 TPC 时代用裸名 @_g_gen(全局共享),遗漏三个 Handles 模块无感,
# 自举后 HT/HE/HEC 委托读各自 _g_gen=None 恒失效(is_global_name 恒 0 误报)
GenApi._g_gen = gen
HandlesTranslator._g_gen = gen
HandlesExpr._g_gen = gen
HandlesExprCall._g_gen = gen
# P6: 注入语句/赋值/变量/导入/翻译驱动模块的单例
# 初始化 VLogger 并打印启动日志