Files
TransPyC/lib/core/Translator/BaseTranslator.py
2026-07-18 19:25:40 +08:00

158 lines
7.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from __future__ import annotations
import ast
from typing import Any, Callable, Dict, TYPE_CHECKING
from lib.core.Exportable import Exportable
if TYPE_CHECKING:
import llvmlite.ir as ir
from lib.core.Handles import (
IfHandle, ForHandle, WhileHandle,
AnnAssignHandle,
HandlesTypeMerge, ExprHandle, BodyHandle,
ReturnHandle, AssignHandle, AugAssignHandle, DeleteHandle,
WithHandle, TryHandle, AssertHandle, RaiseHandle, MatchHandle,
ExprUtils, ExprOpsHandle, ExprAttrHandle, ExprBuiltinHandle,
ExprAsmHandle, ExprFormatHandle, ExprLambdaHandle, ExprCallHandle,
CSpecialCallHandle, TSpecialCallHandle,
ClassHandle,
FunctionHandle,
ImportHandle
)
from lib.core.Handles.HandlesBase import CTypeInfo
from lib.core.SymbolTable import SymbolTable
from lib.core.SymbolNode import SymbolNode
from lib.constants.config import mode as _ConfigMode
from lib.core.VLogger import get_logger as _vlog
def _StrictLog(logger: Callable[[str], None], msg: str) -> None:
"""在 strict 模式下记录异常日志"""
if _ConfigMode == "strict":
logger(msg)
class BaseTranslatorMixin:
"""代码转换器基础 Mixin
提供 __init__、日志、调试输出与表达式处理等基础能力。
"""
def __init__(self) -> None:
self.VarScopes: list[Dict[str, SymbolNode]] = [{}] # 跟踪变量作用域,第一个是全局作用域
self.FunctionReturnTypes: Dict[str, CTypeInfo] = {} # 记录函数名和其返回类型
self.CurrentCReturnTypes: list[CTypeInfo] | None = None # 当前函数的 CReturn 类型列表
self._CurrentCpythonObjectClass: str | None = None # 当前正在处理的 CPython 对象类名
self.FunctionDefCache: dict = {} # 函数定义缓存
self.OriginalLines: list[str] = [] # 原始代码行
self.Content: str = ''
self.DebugFile: str | None = None # 调试输出文件路径
self.IsHeader: bool = False # 是否生成头文件(仅处理定义、宏、导入等,忽略函数体)
self.AnnotationModules: set[str] = set() # 注解模块集合,用于识别类型定义模块
self.Warnings: list[str] = [] # 警告日志
self._ErrorStack: list[tuple[str, str, str]] = [] # 错误栈,按顺序收集错误位置
self.Errors: list[dict[str, str | None]] = [] # 错误日志
self.SliceCount: int = 0 # 切片计数
self.SliceInfos: list = [] # 切片信息列表
self.SliceLevel: int = 3 # 切片优化级别
self.GeneratedTypes: set[str] = set() # 在当前代码中生成的类型struct/typedef
self.EmbeddedAssignments: dict[str, list] = {} # {ClassName: [var1, var2, ...]} 嵌入的实例化变量
self.TypedefAssignments: dict[str, list] = {} # {ClassName: [(var1, IsPtr), ...]} 嵌入的 typedef/指针变量
self.ChainAssignmentArrays: list = [] # 链式赋值数组形式 [(ClassName, VarName, ArraySize_node), ...]
self.tree: ast.AST | None = None # 保存解析后的 AST 树
self.LibraryPaths: list[str] = ['.'] # 库搜索路径列表,默认包含当前目录
self.InClass: bool = False # 是否正在处理 class 定义
self._UserTypeModules: dict = {}
self._source_module_sig_files: dict = {}
self._global_function_default_args: dict = {}
self._global_function_param_names: dict = {}
self.exception_registry: dict = {}
self.exception_parents: dict = {}
self._next_exception_code: int = 100
# 以下属性原先在外部懒注入,此处显式初始化以避免 hasattr/getattr 动态反射
self.config: Any = None
self._ImportedModules: set[str] | None = None
self._t_c_imported_names: dict = {}
# 导出表
self.Exportable = Exportable(filename='')
self.SymbolTable = SymbolTable(self)
self.IfHandler = IfHandle(self)
self.ForHandler = ForHandle(self)
self.WhileHandler = WhileHandle(self)
self.AnnAssignHandler = AnnAssignHandle(self)
self.TypeMergeHandler = HandlesTypeMerge(self)
self.ExprHandler = ExprHandle(self)
self.ExprUtils = ExprUtils(self)
self.ExprOpsHandle = ExprOpsHandle(self)
self.ExprAttrHandle = ExprAttrHandle(self)
self.ExprBuiltinHandle = ExprBuiltinHandle(self)
self.ExprAsmHandle = ExprAsmHandle(self)
self.ExprFormatHandle = ExprFormatHandle(self)
self.ExprLambdaHandle = ExprLambdaHandle(self)
self.ExprCallHandle = ExprCallHandle(self)
self.CSpecialCallHandle = CSpecialCallHandle(self)
self.TSpecialCallHandle = TSpecialCallHandle(self)
self.ClassHandler = ClassHandle(self)
self.FunctionHandler = FunctionHandle(self)
self.ImportHandler = ImportHandle(self)
self.BodyHandler = BodyHandle(self)
self.ReturnHandler = ReturnHandle(self)
self.AssignHandler = AssignHandle(self)
self.AugAssignHandler = AugAssignHandle(self)
self.DeleteHandler = DeleteHandle(self)
self.WithHandler = WithHandle(self)
self.TryHandler = TryHandle(self)
self.AssertHandler = AssertHandle(self)
self.RaiseHandler = RaiseHandle(self)
self.MatchHandler = MatchHandle(self)
def LogWarning(self, message: str, LineNum: int | None = None) -> None:
"""记录警告
Args:
message: 警告消息
LineNum: 行号(可选)
"""
warning = f"Warning: {message}"
if LineNum is not None:
warning += f" (line {LineNum})"
self.Warnings.append(warning)
def LogError(self, message: str, LineNum: int | None = None) -> None:
"""记录错误
Args:
message: 错误消息
LineNum: 行号
"""
_vlog().error(message)
entry: dict[str, str | int | None] = {'message': message, 'line': LineNum}
self.Errors.append(entry)
# 检查 config 中是否有 debug 文件
DebugFile: str | None = None
if hasattr(self, 'config') and self.config:
DebugFile = getattr(self.config, 'debug', None)
if DebugFile:
with open(DebugFile, 'a', encoding='utf-8') as f:
LineInfo: str = f' line {LineNum}' if LineNum else ''
f.write(f'[ERROR]{LineInfo}: {message}\n')
def SetDebugFile(self, FilePath: str) -> None:
"""设置调试输出文件"""
self.DebugFile = FilePath
def DebugPrint(self, *args: Any, **kwargs: Any) -> None:
"""输出调试信息到文件"""
if self.DebugFile:
with open(self.DebugFile, 'a', encoding='utf-8') as f:
print(*args, file=f, **kwargs)
def HandleExpr(self, Node: ast.AST, UseSingleQuote: bool = False, VarType: ir.Type | None = None) -> Any:
return self.ExprHandler.HandleExpr(Node, UseSingleQuote, VarType)