158 lines
7.2 KiB
Python
158 lines
7.2 KiB
Python
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)
|