l0n0lc 0.8.4__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- l0n0lc/Py/350/275/254Cpp/350/275/254/350/257/221/345/231/250.py +579 -0
- l0n0lc/__init__.py +75 -6
- l0n0lc/aot/347/274/226/350/257/221.py +679 -0
- l0n0lc/ast/350/256/277/351/227/256/350/200/205.py +599 -0
- l0n0lc/cpp/347/261/273/345/236/213.py +330 -0
- l0n0lc/cpp/347/274/226/350/257/221/345/231/250.py +317 -0
- l0n0lc/simd/344/274/230/345/214/226.py +260 -0
- l0n0lc/std_map.py +153 -0
- l0n0lc/std_set.py +185 -0
- l0n0lc/std_vector.py +96 -0
- l0n0lc//344/273/243/347/240/201/344/274/230/345/214/226.py +302 -0
- l0n0lc//344/273/243/347/240/201/347/224/237/346/210/220.py +546 -0
- l0n0lc//344/276/235/350/265/226/346/263/250/345/205/245.py +155 -0
- l0n0lc//345/215/263/346/227/266/347/274/226/350/257/221.py +192 -0
- l0n0lc//345/217/230/351/207/217/347/256/241/347/220/206/345/231/250.py +123 -0
- l0n0lc//345/237/272/347/241/200/346/230/240/345/260/204.py +103 -0
- l0n0lc//345/237/272/347/241/200/346/267/267/345/205/245.py +147 -0
- l0n0lc//345/256/271/345/231/250/346/236/204/345/273/272/345/231/250.py +214 -0
- l0n0lc//345/267/245/345/205/267.py +285 -0
- l0n0lc//345/271/266/350/241/214/347/274/226/350/257/221/345/231/250.py +412 -0
- l0n0lc//345/274/202/345/270/270.py +474 -0
- l0n0lc//346/225/260/347/273/204/345/257/271/350/261/241/346/261/240.py +248 -0
- l0n0lc//346/226/207/344/273/266/347/256/241/347/220/206/345/231/250.py +286 -0
- l0n0lc//346/227/245/345/277/227/345/267/245/345/205/267.py +152 -0
- l0n0lc//347/261/273/345/236/213/346/216/250/346/226/255/345/267/245/345/205/267.py +352 -0
- l0n0lc//347/261/273/345/236/213/350/275/254/346/215/242.py +210 -0
- l0n0lc//347/261/273/346/224/257/346/214/201.py +372 -0
- l0n0lc//347/274/226/350/257/221/344/270/212/344/270/213/346/226/207.py +132 -0
- l0n0lc//347/274/226/350/257/221/347/256/241/347/220/206/345/231/250.py +171 -0
- l0n0lc//350/241/250/350/276/276/345/274/217/345/244/204/347/220/206.py +462 -0
- l0n0lc//350/275/254/350/257/221/345/231/250/345/267/245/345/205/267.py +49 -0
- l0n0lc//350/277/220/350/241/214/346/227/266/345/212/240/350/275/275.py +217 -0
- l0n0lc//351/200/232/347/224/250/345/267/245/345/205/267.py +149 -0
- l0n0lc-1.0.0.dist-info/METADATA +363 -0
- l0n0lc-1.0.0.dist-info/RECORD +39 -0
- {l0n0lc-0.8.4.dist-info → l0n0lc-1.0.0.dist-info}/WHEEL +1 -1
- l0n0lc-1.0.0.dist-info/entry_points.txt +2 -0
- {l0n0lc-0.8.4.dist-info → l0n0lc-1.0.0.dist-info}/licenses/LICENSE +0 -0
- l0n0lc/StdList.py +0 -24
- l0n0lc/StdMap.py +0 -21
- l0n0lc/c/345/237/272/347/241/200/345/244/204/347/220/206.py +0 -207
- l0n0lc/jit.py +0 -604
- l0n0lc//347/274/226/350/257/221.py +0 -58
- l0n0lc//351/200/232/347/224/250.py +0 -134
- l0n0lc-0.8.4.dist-info/METADATA +0 -241
- l0n0lc-0.8.4.dist-info/RECORD +0 -12
- {l0n0lc-0.8.4.dist-info → l0n0lc-1.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import ast
|
|
2
|
+
import inspect
|
|
3
|
+
import sys
|
|
4
|
+
import traceback
|
|
5
|
+
from .工具 import 全局上下文
|
|
6
|
+
from .cpp类型 import C变量
|
|
7
|
+
from .异常 import Jit错误
|
|
8
|
+
from .代码生成 import 代码生成器, 参数处理器
|
|
9
|
+
from .基础混入 import 错误处理混入, 类型处理混入
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class 类支持处理器(错误处理混入, 类型处理混入):
|
|
13
|
+
"""处理类定义相关的功能"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, transpiler):
|
|
16
|
+
self.transpiler = transpiler
|
|
17
|
+
|
|
18
|
+
def 处理类定义(self, node: ast.ClassDef):
|
|
19
|
+
"""处理类定义"""
|
|
20
|
+
if node.name != self.transpiler.函数名:
|
|
21
|
+
self.抛出错误(f"Nested classes not supported: {node.name}", node)
|
|
22
|
+
|
|
23
|
+
# 0. 处理基类(继承)
|
|
24
|
+
self.处理基类(node)
|
|
25
|
+
|
|
26
|
+
# 1. 扫描成员变量(支持默认值)
|
|
27
|
+
self.扫描成员变量(node)
|
|
28
|
+
|
|
29
|
+
# 2. 访问方法
|
|
30
|
+
self.处理类方法(node)
|
|
31
|
+
|
|
32
|
+
def 处理基类(self, node: ast.ClassDef):
|
|
33
|
+
"""处理基类继承"""
|
|
34
|
+
if node.bases:
|
|
35
|
+
for base in node.bases:
|
|
36
|
+
if isinstance(base, ast.Name):
|
|
37
|
+
base_class = self.transpiler.获取值(base)
|
|
38
|
+
if base_class and inspect.isclass(base_class):
|
|
39
|
+
self.transpiler.类基类列表.append(base_class)
|
|
40
|
+
# 将基类添加到依赖中
|
|
41
|
+
try:
|
|
42
|
+
base_transpiler = type(self.transpiler)(
|
|
43
|
+
base_class, self.transpiler.编译器
|
|
44
|
+
)
|
|
45
|
+
base_transpiler.编译() # 需要编译基类以生成头文件和实现
|
|
46
|
+
self.transpiler.依赖函数.append(base_transpiler)
|
|
47
|
+
except Exception as e:
|
|
48
|
+
# 如果基类无法编译,记录警告但不阻止编译
|
|
49
|
+
print(
|
|
50
|
+
f"Warning: Failed to compile base class '{base_class.__name__}': {str(e)}",
|
|
51
|
+
file=sys.stderr,
|
|
52
|
+
)
|
|
53
|
+
if traceback.format_exc():
|
|
54
|
+
print(
|
|
55
|
+
f"Base class compilation traceback:\n{traceback.format_exc()}",
|
|
56
|
+
file=sys.stderr,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def 扫描成员变量(self, node: ast.ClassDef):
|
|
60
|
+
"""扫描类的成员变量"""
|
|
61
|
+
for stmt in node.body:
|
|
62
|
+
if isinstance(stmt, ast.AnnAssign) and isinstance(stmt.target, ast.Name):
|
|
63
|
+
self.处理注解赋值(stmt)
|
|
64
|
+
|
|
65
|
+
# 检测类变量(以'_'开头的变量,视为静态成员)
|
|
66
|
+
elif isinstance(stmt, ast.Assign):
|
|
67
|
+
self.处理赋值语句(stmt)
|
|
68
|
+
|
|
69
|
+
def 处理注解赋值(self, stmt: ast.AnnAssign):
|
|
70
|
+
"""处理带有类型注解的赋值语句"""
|
|
71
|
+
from .表达式处理 import 表达式访问者
|
|
72
|
+
|
|
73
|
+
expr_visitor = 表达式访问者(self.transpiler)
|
|
74
|
+
|
|
75
|
+
py_type = expr_visitor.获取值(stmt.annotation)
|
|
76
|
+
c_type = self.解析类型(py_type)
|
|
77
|
+
# 类型注解:我们已经检查过stmt.target是ast.Name类型
|
|
78
|
+
member_name = stmt.target.id # type: ignore[attr-defined]
|
|
79
|
+
|
|
80
|
+
# 检查是否是以'_'开头的静态成员
|
|
81
|
+
if member_name.startswith("_"):
|
|
82
|
+
# 这是静态成员
|
|
83
|
+
static_type = str(c_type)
|
|
84
|
+
static_value = 0 # 默认值,如果没有显式赋值的话
|
|
85
|
+
if stmt.value is not None:
|
|
86
|
+
static_value = expr_visitor.获取值(stmt.value)
|
|
87
|
+
self.transpiler.类静态成员[member_name] = (static_type, static_value)
|
|
88
|
+
else:
|
|
89
|
+
# 这是普通实例成员
|
|
90
|
+
self.transpiler.类成员变量[member_name] = str(c_type)
|
|
91
|
+
|
|
92
|
+
# 检查是否有默认值
|
|
93
|
+
if stmt.value is not None:
|
|
94
|
+
default_val = expr_visitor.获取值(stmt.value)
|
|
95
|
+
self.transpiler.类成员默认值[member_name] = default_val
|
|
96
|
+
|
|
97
|
+
def 处理赋值语句(self, stmt: ast.Assign):
|
|
98
|
+
"""处理赋值语句(用于类变量)"""
|
|
99
|
+
from .表达式处理 import 表达式访问者
|
|
100
|
+
|
|
101
|
+
expr_visitor = 表达式访问者(self.transpiler)
|
|
102
|
+
|
|
103
|
+
for target in stmt.targets:
|
|
104
|
+
if isinstance(target, ast.Name):
|
|
105
|
+
# 检查变量名是否以'_'开头
|
|
106
|
+
static_name = target.id # type: ignore[attr-defined]
|
|
107
|
+
if static_name.startswith("_"):
|
|
108
|
+
# 这是一个静态成员
|
|
109
|
+
static_value = expr_visitor.获取值(stmt.value)
|
|
110
|
+
# 尝试推断类型
|
|
111
|
+
if isinstance(static_value, bool):
|
|
112
|
+
static_type = "bool"
|
|
113
|
+
elif isinstance(static_value, int):
|
|
114
|
+
static_type = "int64_t"
|
|
115
|
+
elif isinstance(static_value, float):
|
|
116
|
+
static_type = "double"
|
|
117
|
+
elif isinstance(static_value, str):
|
|
118
|
+
static_type = "const char*"
|
|
119
|
+
else:
|
|
120
|
+
static_type = "auto"
|
|
121
|
+
self.transpiler.类静态成员[static_name] = (
|
|
122
|
+
static_type,
|
|
123
|
+
static_value,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
def 处理类方法(self, node: ast.ClassDef):
|
|
127
|
+
"""处理类方法"""
|
|
128
|
+
for stmt in node.body:
|
|
129
|
+
if isinstance(stmt, ast.FunctionDef):
|
|
130
|
+
self.处理单个方法(stmt)
|
|
131
|
+
|
|
132
|
+
def 处理单个方法(self, node: ast.FunctionDef):
|
|
133
|
+
"""处理单个类方法"""
|
|
134
|
+
# 设置当前方法名
|
|
135
|
+
self.transpiler.当前方法名 = node.name
|
|
136
|
+
# 重置当前方法参数,避免方法间干扰
|
|
137
|
+
self.transpiler.当前方法参数 = {}
|
|
138
|
+
# 同时清空列表参数映射
|
|
139
|
+
self.transpiler.列表参数映射 = {}
|
|
140
|
+
|
|
141
|
+
# 处理方法
|
|
142
|
+
self.访问方法节点(node)
|
|
143
|
+
|
|
144
|
+
def 访问方法节点(self, node: ast.FunctionDef):
|
|
145
|
+
"""访问方法节点(类似于原visit_FunctionDef但针对类方法)"""
|
|
146
|
+
is_init = node.name == "__init__"
|
|
147
|
+
|
|
148
|
+
# 检测装饰器
|
|
149
|
+
decorators = []
|
|
150
|
+
for decorator in node.decorator_list:
|
|
151
|
+
if isinstance(decorator, ast.Name):
|
|
152
|
+
decorators.append(decorator.id)
|
|
153
|
+
if decorator.id == "classmethod":
|
|
154
|
+
self.抛出错误("@classmethod is not supported", decorator)
|
|
155
|
+
|
|
156
|
+
is_static = "staticmethod" in decorators
|
|
157
|
+
is_property = "property" in decorators
|
|
158
|
+
|
|
159
|
+
# 检测运算符重载
|
|
160
|
+
operator_map = {
|
|
161
|
+
"__add__": "operator+",
|
|
162
|
+
"__sub__": "operator-",
|
|
163
|
+
"__mul__": "operator*",
|
|
164
|
+
"__truediv__": "operator/",
|
|
165
|
+
"__mod__": "operator%",
|
|
166
|
+
"__eq__": "operator==",
|
|
167
|
+
"__ne__": "operator!=",
|
|
168
|
+
"__lt__": "operator<",
|
|
169
|
+
"__le__": "operator<=",
|
|
170
|
+
"__gt__": "operator>",
|
|
171
|
+
"__ge__": "operator>=",
|
|
172
|
+
"__getitem__": "operator[]",
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
is_operator = node.name in operator_map
|
|
176
|
+
method_name = operator_map.get(node.name, node.name)
|
|
177
|
+
|
|
178
|
+
# 构造函数名为类名
|
|
179
|
+
if is_init:
|
|
180
|
+
method_name = self.transpiler.函数名
|
|
181
|
+
|
|
182
|
+
c_ret_type = ""
|
|
183
|
+
|
|
184
|
+
# 创建临时代码缓冲区用于方法体(使用 StringIO 优化性能)
|
|
185
|
+
import io
|
|
186
|
+
方法缓冲区 = io.StringIO()
|
|
187
|
+
|
|
188
|
+
# 保存原始的参数变量字典(用于恢复)
|
|
189
|
+
original_param_vars = self.transpiler.参数变量
|
|
190
|
+
self.transpiler.参数变量 = {} # 临时清空,让 visit_arguments 填充到这里
|
|
191
|
+
|
|
192
|
+
# 参数处理
|
|
193
|
+
args_node = node.args
|
|
194
|
+
original_args = list(args_node.args)
|
|
195
|
+
|
|
196
|
+
# 检查第一个参数 (self/cls)
|
|
197
|
+
first_arg_name = None
|
|
198
|
+
first_arg_type = None
|
|
199
|
+
|
|
200
|
+
if not is_static and original_args:
|
|
201
|
+
first_arg = original_args[0]
|
|
202
|
+
first_arg_name = first_arg.arg
|
|
203
|
+
|
|
204
|
+
# 实例方法:第一个参数是 self
|
|
205
|
+
first_arg_type = f"{self.transpiler.函数名}*"
|
|
206
|
+
|
|
207
|
+
# 从参数列表中移除 self,使其不出现在 C++ 参数签名中
|
|
208
|
+
args_node.args = original_args[1:]
|
|
209
|
+
|
|
210
|
+
# 为方法体创建新的作用域
|
|
211
|
+
# 临时替换全局缓冲区为方法缓冲区
|
|
212
|
+
原始缓冲区 = self.transpiler.代码缓冲区
|
|
213
|
+
self.transpiler.代码缓冲区 = 方法缓冲区
|
|
214
|
+
|
|
215
|
+
with self.transpiler.代码块上下文:
|
|
216
|
+
# 注册 self 变量 (作为 this 指针)
|
|
217
|
+
if first_arg_name and not is_static and first_arg_type:
|
|
218
|
+
self_var = C变量(first_arg_type, first_arg_name, False)
|
|
219
|
+
self_var.C名称 = "this" # 实例方法映射到 C++ this
|
|
220
|
+
self.transpiler.添加C变量(self_var)
|
|
221
|
+
|
|
222
|
+
# 处理方法参数
|
|
223
|
+
|
|
224
|
+
param_processor = 参数处理器(self.transpiler)
|
|
225
|
+
param_processor.处理参数列表(args_node)
|
|
226
|
+
|
|
227
|
+
# 将参数从 self.参数变量 复制到 self.当前方法参数
|
|
228
|
+
self.transpiler.当前方法参数 = dict(self.transpiler.参数变量)
|
|
229
|
+
|
|
230
|
+
for stmt in node.body:
|
|
231
|
+
self.transpiler.visit(stmt)
|
|
232
|
+
|
|
233
|
+
# 获取生成的代码块(从临时缓冲区)
|
|
234
|
+
method_body = 方法缓冲区.getvalue().strip().split('\n') if 方法缓冲区.getvalue().strip() else []
|
|
235
|
+
|
|
236
|
+
# 恢复原始缓冲区和参数变量
|
|
237
|
+
self.transpiler.代码缓冲区 = 原始缓冲区
|
|
238
|
+
self.transpiler.参数变量 = original_param_vars
|
|
239
|
+
|
|
240
|
+
# 确定返回类型
|
|
241
|
+
c_ret_type = self.推断返回类型(node, is_init)
|
|
242
|
+
|
|
243
|
+
# 存储方法信息
|
|
244
|
+
self.transpiler.类方法列表.append(
|
|
245
|
+
{
|
|
246
|
+
"name": method_name,
|
|
247
|
+
"ret_type": c_ret_type,
|
|
248
|
+
"body": method_body,
|
|
249
|
+
"is_init": is_init,
|
|
250
|
+
"is_static": is_static,
|
|
251
|
+
"is_property": is_property,
|
|
252
|
+
"is_operator": is_operator,
|
|
253
|
+
"params": self._构建当前参数列表字符串(),
|
|
254
|
+
}
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
def 推断返回类型(self, node: ast.FunctionDef, is_init: bool):
|
|
258
|
+
"""推断方法的返回类型"""
|
|
259
|
+
if is_init:
|
|
260
|
+
return "" # 构造函数无返回类型部分
|
|
261
|
+
|
|
262
|
+
from .表达式处理 import 表达式访问者
|
|
263
|
+
|
|
264
|
+
expr_visitor = 表达式访问者(self.transpiler)
|
|
265
|
+
|
|
266
|
+
ret_py_type = expr_visitor.获取值(node.returns, is_type_annotation=True)
|
|
267
|
+
|
|
268
|
+
if isinstance(node.returns, ast.Name):
|
|
269
|
+
# 处理名称类型注解(如 int, str, float 等)
|
|
270
|
+
# 处理自定义类类型
|
|
271
|
+
if inspect.isclass(ret_py_type):
|
|
272
|
+
# 首先检查是否有类型映射
|
|
273
|
+
mapped_type = 全局上下文.类型映射表.get(ret_py_type)
|
|
274
|
+
if mapped_type:
|
|
275
|
+
# 使用映射的类型
|
|
276
|
+
c_ret_type = mapped_type.目标类型
|
|
277
|
+
# 添加需要包含的头文件
|
|
278
|
+
if mapped_type.包含目录:
|
|
279
|
+
self.transpiler.包含头文件.update(mapped_type.包含目录)
|
|
280
|
+
elif ret_py_type.__module__ == "builtins":
|
|
281
|
+
c_ret_type = str(self.解析类型(ret_py_type))
|
|
282
|
+
else:
|
|
283
|
+
# 用户自定义类
|
|
284
|
+
c_ret_type = ret_py_type.__name__
|
|
285
|
+
else:
|
|
286
|
+
c_ret_type = str(self.解析类型(ret_py_type))
|
|
287
|
+
elif isinstance(node.returns, ast.Constant):
|
|
288
|
+
# 处理字符串类型注解(如 'Vector2D')
|
|
289
|
+
if isinstance(ret_py_type, str) and ret_py_type not in [
|
|
290
|
+
"int",
|
|
291
|
+
"float",
|
|
292
|
+
"str",
|
|
293
|
+
"bool",
|
|
294
|
+
"void",
|
|
295
|
+
]:
|
|
296
|
+
# 尝试从全局变量中查找对应的类
|
|
297
|
+
if ret_py_type in self.transpiler.全局变量:
|
|
298
|
+
potential_class = self.transpiler.全局变量[ret_py_type]
|
|
299
|
+
if inspect.isclass(potential_class):
|
|
300
|
+
ret_py_type = potential_class
|
|
301
|
+
|
|
302
|
+
# 处理自定义类类型
|
|
303
|
+
if inspect.isclass(ret_py_type):
|
|
304
|
+
# 首先检查是否有类型映射
|
|
305
|
+
mapped_type = 全局上下文.类型映射表.get(ret_py_type)
|
|
306
|
+
if mapped_type:
|
|
307
|
+
# 使用映射的类型
|
|
308
|
+
c_ret_type = mapped_type.目标类型
|
|
309
|
+
# 添加需要包含的头文件
|
|
310
|
+
if mapped_type.包含目录:
|
|
311
|
+
self.transpiler.包含头文件.update(mapped_type.包含目录)
|
|
312
|
+
elif ret_py_type.__module__ == "builtins":
|
|
313
|
+
c_ret_type = str(self.解析类型(ret_py_type))
|
|
314
|
+
else:
|
|
315
|
+
# 用户自定义类
|
|
316
|
+
c_ret_type = ret_py_type.__name__
|
|
317
|
+
else:
|
|
318
|
+
c_ret_type = str(self.解析类型(ret_py_type))
|
|
319
|
+
|
|
320
|
+
elif node.returns is None:
|
|
321
|
+
# 没有类型注解,需要根据函数体推断返回类型
|
|
322
|
+
# 检查函数体中是否有返回语句
|
|
323
|
+
return_stmt = None
|
|
324
|
+
for stmt in node.body:
|
|
325
|
+
if isinstance(stmt, ast.Return):
|
|
326
|
+
return_stmt = stmt
|
|
327
|
+
break
|
|
328
|
+
|
|
329
|
+
if return_stmt and return_stmt.value is not None:
|
|
330
|
+
# 有返回语句但没有类型注解,尝试推断返回值类型
|
|
331
|
+
if isinstance(return_stmt.value, ast.Call):
|
|
332
|
+
# 检查函数调用
|
|
333
|
+
call_node = return_stmt.value
|
|
334
|
+
if isinstance(call_node.func, ast.Name):
|
|
335
|
+
# 函数调用,如 Vector2D()
|
|
336
|
+
func_name = call_node.func.id
|
|
337
|
+
# 检查是否是当前类的构造函数调用
|
|
338
|
+
if func_name == self.transpiler.函数名:
|
|
339
|
+
# 构造函数调用返回当前类类型
|
|
340
|
+
c_ret_type = self.transpiler.函数名
|
|
341
|
+
else:
|
|
342
|
+
# 其他函数使用auto
|
|
343
|
+
c_ret_type = "auto"
|
|
344
|
+
else:
|
|
345
|
+
# 其他类型的调用使用auto
|
|
346
|
+
c_ret_type = "auto"
|
|
347
|
+
elif isinstance(return_stmt.value, ast.Constant):
|
|
348
|
+
# 常量返回值
|
|
349
|
+
if isinstance(return_stmt.value.value, bool):
|
|
350
|
+
c_ret_type = "bool"
|
|
351
|
+
elif isinstance(return_stmt.value.value, int):
|
|
352
|
+
c_ret_type = "int64_t"
|
|
353
|
+
elif isinstance(return_stmt.value.value, float):
|
|
354
|
+
c_ret_type = "double"
|
|
355
|
+
else:
|
|
356
|
+
c_ret_type = "auto"
|
|
357
|
+
else:
|
|
358
|
+
# 其他表达式使用auto
|
|
359
|
+
c_ret_type = "auto"
|
|
360
|
+
else:
|
|
361
|
+
# 没有返回语句或返回值为None,设为void
|
|
362
|
+
c_ret_type = "void"
|
|
363
|
+
else:
|
|
364
|
+
c_ret_type = "auto"
|
|
365
|
+
|
|
366
|
+
return c_ret_type
|
|
367
|
+
|
|
368
|
+
def _构建当前参数列表字符串(self):
|
|
369
|
+
"""构建方法的参数列表字符串"""
|
|
370
|
+
|
|
371
|
+
generator = 代码生成器(self.transpiler)
|
|
372
|
+
return generator.构建当前参数列表字符串()
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"""
|
|
2
|
+
编译上下文模块
|
|
3
|
+
|
|
4
|
+
提供编译实例的上下文,代替部分全局状态。
|
|
5
|
+
每个转译器实例拥有独立的编译上下文,避免全局状态滥用。
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Set, Dict, Any
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class 编译上下文:
|
|
12
|
+
"""
|
|
13
|
+
编译实例的上下文
|
|
14
|
+
|
|
15
|
+
每个转译器实例拥有独立的编译上下文,用于管理:
|
|
16
|
+
- 编译栈:防止循环编译
|
|
17
|
+
- 变量ID生成
|
|
18
|
+
- 包含头文件
|
|
19
|
+
- 链接库
|
|
20
|
+
|
|
21
|
+
相比全局上下文,这些状态应该是实例级别的,而不是全局的。
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, 工作目录: str = "./l0n0lcoutput"):
|
|
25
|
+
"""
|
|
26
|
+
初始化编译上下文
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
工作目录: 编译输出目录
|
|
30
|
+
"""
|
|
31
|
+
self.工作目录 = 工作目录
|
|
32
|
+
self.编译栈: Set[str] = set() # 防止循环编译的栈
|
|
33
|
+
self.最大变量ID = 0 # 变量ID生成器
|
|
34
|
+
self.包含头文件: Set[str] = set() # 需要包含的头文件
|
|
35
|
+
self.链接库: Set[str] = set() # 需要链接的库
|
|
36
|
+
self.库搜索目录: Set[str] = set() # 库搜索目录
|
|
37
|
+
|
|
38
|
+
def 生成变量ID(self) -> int:
|
|
39
|
+
"""
|
|
40
|
+
生成唯一的变量ID
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
新的变量ID
|
|
44
|
+
"""
|
|
45
|
+
self.最大变量ID += 1
|
|
46
|
+
return self.最大变量ID
|
|
47
|
+
|
|
48
|
+
def 添加包含头文件(self, 头文件: str):
|
|
49
|
+
"""
|
|
50
|
+
添加需要包含的头文件
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
头文件: 头文件路径,如 <stdint.h> 或 "myheader.h"
|
|
54
|
+
"""
|
|
55
|
+
self.包含头文件.add(头文件)
|
|
56
|
+
|
|
57
|
+
def 添加链接库(self, 库名: str):
|
|
58
|
+
"""
|
|
59
|
+
添加需要链接的库
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
库名: 库名称,如 "m" (数学库)
|
|
63
|
+
"""
|
|
64
|
+
self.链接库.add(库名)
|
|
65
|
+
|
|
66
|
+
def 添加库搜索目录(self, 目录: str):
|
|
67
|
+
"""
|
|
68
|
+
添加库搜索目录
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
目录: 库搜索目录路径
|
|
72
|
+
"""
|
|
73
|
+
self.库搜索目录.add(目录)
|
|
74
|
+
|
|
75
|
+
def 入栈编译(self, 标识: str):
|
|
76
|
+
"""
|
|
77
|
+
将函数标识压入编译栈
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
标识: 函数的唯一标识
|
|
81
|
+
|
|
82
|
+
Raises:
|
|
83
|
+
RuntimeError: 如果检测到循环编译
|
|
84
|
+
"""
|
|
85
|
+
if 标识 in self.编译栈:
|
|
86
|
+
raise RuntimeError(f"检测到循环编译: {标识}")
|
|
87
|
+
self.编译栈.add(标识)
|
|
88
|
+
|
|
89
|
+
def 出栈编译(self, 标识: str):
|
|
90
|
+
"""
|
|
91
|
+
将函数标识从编译栈弹出
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
标识: 函数的唯一标识
|
|
95
|
+
"""
|
|
96
|
+
self.编译栈.discard(标识)
|
|
97
|
+
|
|
98
|
+
def 是否正在编译(self, 标识: str) -> bool:
|
|
99
|
+
"""
|
|
100
|
+
检查函数是否正在编译
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
标识: 函数的唯一标识
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
是否正在编译
|
|
107
|
+
"""
|
|
108
|
+
return 标识 in self.编译栈
|
|
109
|
+
|
|
110
|
+
def 重置(self):
|
|
111
|
+
"""重置编译上下文(用于重复使用)"""
|
|
112
|
+
self.编译栈.clear()
|
|
113
|
+
self.最大变量ID = 0
|
|
114
|
+
self.包含头文件.clear()
|
|
115
|
+
self.链接库.clear()
|
|
116
|
+
self.库搜索目录.clear()
|
|
117
|
+
|
|
118
|
+
def 获取状态摘要(self) -> Dict[str, Any]:
|
|
119
|
+
"""
|
|
120
|
+
获取编译上下文的当前状态摘要
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
包含当前状态的字典
|
|
124
|
+
"""
|
|
125
|
+
return {
|
|
126
|
+
"工作目录": self.工作目录,
|
|
127
|
+
"编译栈大小": len(self.编译栈),
|
|
128
|
+
"最大变量ID": self.最大变量ID,
|
|
129
|
+
"包含头文件数量": len(self.包含头文件),
|
|
130
|
+
"链接库数量": len(self.链接库),
|
|
131
|
+
"库搜索目录数量": len(self.库搜索目录),
|
|
132
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"""
|
|
2
|
+
编译管理器模块
|
|
3
|
+
|
|
4
|
+
负责管理编译过程、缓存管理和清理操作。
|
|
5
|
+
从 Py转Cpp转译器 中分离出来,实现单一职责原则。
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import List, Optional, Callable, Any
|
|
9
|
+
from .文件管理器 import 文件管理器
|
|
10
|
+
from .编译上下文 import 编译上下文
|
|
11
|
+
from .cpp编译器 import Cpp编译器
|
|
12
|
+
from .日志工具 import 日志
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class 编译管理器:
|
|
16
|
+
"""
|
|
17
|
+
编译管理器
|
|
18
|
+
|
|
19
|
+
负责:
|
|
20
|
+
- 编译过程管理
|
|
21
|
+
- 缓存验证和清理
|
|
22
|
+
- 依赖管理
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
文件管理器: 文件管理器,
|
|
28
|
+
编译器: Cpp编译器,
|
|
29
|
+
编译上下文: 编译上下文
|
|
30
|
+
):
|
|
31
|
+
"""
|
|
32
|
+
初始化编译管理器
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
文件管理器: 文件管理器实例
|
|
36
|
+
编译器: C++ 编译器实例
|
|
37
|
+
编译上下文: 编译上下文实例
|
|
38
|
+
"""
|
|
39
|
+
self.文件管理器 = 文件管理器
|
|
40
|
+
self.编译器 = 编译器
|
|
41
|
+
self.编译上下文 = 编译上下文
|
|
42
|
+
|
|
43
|
+
def 检查缓存完整性(self, 获取文件名列表) -> List[str]:
|
|
44
|
+
"""
|
|
45
|
+
检查缓存文件的完整性
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
获取文件名列表: 返回 (cpp文件名, 头文件名, 库文件名) 的函数
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
问题列表,如果为空表示缓存完整
|
|
52
|
+
"""
|
|
53
|
+
try:
|
|
54
|
+
cpp_file名, 头文件名, 库文件名 = 获取文件名列表()
|
|
55
|
+
|
|
56
|
+
issues = []
|
|
57
|
+
|
|
58
|
+
# 检查源文件是否存在且可读
|
|
59
|
+
if self.文件管理器.文件是否存在(cpp_file名):
|
|
60
|
+
if not self.文件管理器.文件是否可读(cpp_file名):
|
|
61
|
+
issues.append(f"源文件不可读: {cpp_file名}")
|
|
62
|
+
else:
|
|
63
|
+
issues.append(f"源文件不存在: {cpp_file名}")
|
|
64
|
+
|
|
65
|
+
# 检查头文件
|
|
66
|
+
if self.文件管理器.文件是否存在(头文件名):
|
|
67
|
+
if not self.文件管理器.文件是否可读(头文件名):
|
|
68
|
+
issues.append(f"头文件不可读: {头文件名}")
|
|
69
|
+
|
|
70
|
+
# 检查库文件
|
|
71
|
+
if self.文件管理器.文件是否存在(库文件名):
|
|
72
|
+
if not self.文件管理器.文件是否可读(库文件名):
|
|
73
|
+
issues.append(f"库文件不可读: {库文件名}")
|
|
74
|
+
|
|
75
|
+
return issues
|
|
76
|
+
|
|
77
|
+
except Exception as e:
|
|
78
|
+
return [f"缓存完整性检查失败: {str(e)}"]
|
|
79
|
+
|
|
80
|
+
def 清理编译文件(self, 文件名列表: List[str]):
|
|
81
|
+
"""
|
|
82
|
+
清理编译文件
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
文件名列表: 需要清理的文件名列表
|
|
86
|
+
"""
|
|
87
|
+
try:
|
|
88
|
+
self.文件管理器.清理编译文件(文件名列表)
|
|
89
|
+
|
|
90
|
+
# 清理临时文件(使用第一个文件名的基础名称)
|
|
91
|
+
if 文件名列表:
|
|
92
|
+
基础名称 = 文件名列表[0].rsplit('.', 1)[0] if '.' in 文件名列表[0] else 文件名列表[0]
|
|
93
|
+
self.文件管理器.清理临时文件(基础名称)
|
|
94
|
+
|
|
95
|
+
except (OSError, IOError) as e:
|
|
96
|
+
# 清理过程中的错误不应该掩盖原始错误
|
|
97
|
+
日志.调试(f"清理文件时出错: {e}")
|
|
98
|
+
except Exception as e:
|
|
99
|
+
# 其他未预期的异常
|
|
100
|
+
日志.警告(f"清理文件时发生未预期错误: {e}")
|
|
101
|
+
|
|
102
|
+
def 清理所有缓存(self) -> int:
|
|
103
|
+
"""
|
|
104
|
+
清理所有缓存文件
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
清理的文件数量
|
|
108
|
+
"""
|
|
109
|
+
try:
|
|
110
|
+
return self.文件管理器.清理所有缓存()
|
|
111
|
+
except (OSError, IOError) as e:
|
|
112
|
+
日志.调试(f"清理缓存时出错: {e}")
|
|
113
|
+
return 0
|
|
114
|
+
except Exception as e:
|
|
115
|
+
日志.警告(f"清理缓存时发生未预期错误: {e}")
|
|
116
|
+
return 0
|
|
117
|
+
|
|
118
|
+
def 配置编译器(
|
|
119
|
+
self,
|
|
120
|
+
库目录列表: Optional[List[str]] = None,
|
|
121
|
+
链接库列表: Optional[List[str]] = None
|
|
122
|
+
):
|
|
123
|
+
"""
|
|
124
|
+
配置编译器
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
库目录列表: 库搜索目录列表
|
|
128
|
+
链接库列表: 需要链接的库列表
|
|
129
|
+
"""
|
|
130
|
+
if 库目录列表:
|
|
131
|
+
self.编译器.添加库目录(库目录列表)
|
|
132
|
+
|
|
133
|
+
if 链接库列表:
|
|
134
|
+
self.编译器.添加库(链接库列表)
|
|
135
|
+
|
|
136
|
+
def 执行编译(
|
|
137
|
+
self,
|
|
138
|
+
源文件列表: List[str],
|
|
139
|
+
输出路径: str,
|
|
140
|
+
是否为可执行文件: bool = False,
|
|
141
|
+
编译选项: Optional[List[str]] = None
|
|
142
|
+
):
|
|
143
|
+
"""
|
|
144
|
+
执行编译
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
源文件列表: 源文件路径列表
|
|
148
|
+
输出路径: 输出文件路径
|
|
149
|
+
是否为可执行文件: 是否编译为可执行文件
|
|
150
|
+
编译选项: 额外的编译选项
|
|
151
|
+
"""
|
|
152
|
+
if 编译选项:
|
|
153
|
+
for option in 编译选项:
|
|
154
|
+
self.编译器.添加编译选项(option)
|
|
155
|
+
|
|
156
|
+
if 是否为可执行文件:
|
|
157
|
+
self.编译器.编译文件(源文件列表, 输出路径)
|
|
158
|
+
else:
|
|
159
|
+
self.编译器.编译共享库(源文件列表, 输出路径)
|
|
160
|
+
|
|
161
|
+
def 获取状态摘要(self) -> dict:
|
|
162
|
+
"""
|
|
163
|
+
获取编译管理器的状态摘要
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
包含当前状态的字典
|
|
167
|
+
"""
|
|
168
|
+
return {
|
|
169
|
+
"文件管理器状态": self.文件管理器.获取状态摘要() if hasattr(self.文件管理器, '获取状态摘要') else {},
|
|
170
|
+
"编译上下文状态": self.编译上下文.获取状态摘要(),
|
|
171
|
+
}
|