l0n0lc 0.8.6__tar.gz → 0.8.7__tar.gz

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-0.8.7/PKG-INFO ADDED
@@ -0,0 +1,233 @@
1
+ Metadata-Version: 2.4
2
+ Name: l0n0lc
3
+ Version: 0.8.7
4
+ Summary: 一个将python函数翻译为c++函数并运行的jit编译器
5
+ Classifier: Programming Language :: Python :: 3
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Dynamic: license-file
10
+
11
+
12
+ # 将python函数翻译为c++函数并运行
13
+ ## 1. 安装
14
+ ```
15
+ pip install l0n0lc
16
+ ```
17
+ ## 2. hello_world.py
18
+ ```python
19
+ import l0n0lc as lc
20
+ import math
21
+
22
+
23
+ @lc.映射函数(math.ceil, ['<cmath>'])
24
+ def cpp_ceil(v):
25
+ return f'std::ceil({lc.toCString(v)});'
26
+
27
+
28
+ @lc.映射函数(print, ['<iostream>'])
29
+ def cpp_cout(*args):
30
+ code = f'std::cout'
31
+ for arg in args:
32
+ code += f'<< {lc.toCString(arg)} << " "'
33
+ code += '<< std::endl;'
34
+ return code
35
+
36
+
37
+ def py_cin(v):
38
+ pass
39
+
40
+
41
+ @lc.映射函数(py_cin, ['<iostream>'])
42
+ def cpp_cin(v):
43
+ return f'std::cout << u8"请输入>>>"; std::cin >> {v};'
44
+
45
+
46
+ @lc.直接调用函数
47
+ def test_直接调用():
48
+ return 123
49
+
50
+
51
+ def test_other_fn(a: int, b: int) -> int:
52
+ return a - b
53
+
54
+
55
+ @lc.jit()
56
+ def test编译的函数(a: int, b: int) -> int:
57
+ return a * b
58
+
59
+
60
+ @lc.jit(每次运行都重新编译=True)
61
+ def test_add(a: int, b: int) -> int:
62
+ if a > 1:
63
+ return a + b
64
+ for i in range(1, 10, 2):
65
+ a += i
66
+ for i in [1, 2, 3]:
67
+ a += i
68
+ a = math.ceil(12.5)
69
+ cc = {'a': 1, 'b': 2}
70
+ cc['c'] = 3
71
+ print('输出map:')
72
+ for ii in cc:
73
+ print(ii.first, ii.second) # type: ignore
74
+ aa = [1, 3, 2]
75
+ aa[0] = 134
76
+ print('输出list:')
77
+ for i in range(3):
78
+ print(i, aa[i])
79
+ print('Hello World', a, b)
80
+ print('test_other_fn', test_other_fn(a, b))
81
+ print('test编译的函数', test编译的函数(a, b))
82
+ v = 0
83
+ vv = True and (False or 1)
84
+ print('vv:', vv)
85
+ while (vv):
86
+ py_cin(v)
87
+ if v > 100:
88
+ break
89
+ else:
90
+ print('输入的', v, '小于等于100')
91
+ return a + b + 1 + test_直接调用() + v
92
+
93
+
94
+ print('结果:', test_add(1, 3))
95
+
96
+ ```
97
+
98
+ ## 3. 运行hello_world.py
99
+ ```
100
+ uv run tests/hello_world.py
101
+ # 输入: b'1\n2\n100\n101\n'
102
+ ```
103
+ ```bash
104
+ 输出map:
105
+ c 3
106
+ a 1
107
+ b 2
108
+ 输出list:
109
+ 0 134
110
+ 1 3
111
+ 2 2
112
+ Hello World 13 3
113
+ test_other_fn 10
114
+ test编译的函数 39
115
+ vv: 1
116
+ 请输入>>>输入的 1 小于等于100
117
+ 请输入>>>输入的 2 小于等于100
118
+ 请输入>>>输入的 100 小于等于100
119
+ 请输入>>>结果: 241
120
+
121
+ ```
122
+
123
+ ## 4. 查看输出文件
124
+ ```bash
125
+ ls -al ./l0n0lcoutput
126
+
127
+ ```
128
+ ## 5. test_add_@ac596ca343e844de.cpp
129
+ ```c++
130
+ #include "test_add_@ac596ca343e844de.h"
131
+ extern "C" int16_t test_add (int16_t a, int16_t b)
132
+ {
133
+ if ((a > 1))
134
+ {
135
+ return a + b;
136
+ }
137
+
138
+ for (int64_t i = 1; i < 10; i += 2)
139
+ {
140
+ a = a + i;
141
+ }
142
+
143
+ for (auto i : {1,2,3})
144
+ {
145
+ a = a + i;
146
+ }
147
+
148
+ a = std::ceil(12.5);;
149
+ std::unordered_map<std::string, int16_t> cc = {{ u8"a", 1 },{ u8"b", 2 }};
150
+ cc[u8"c"] = 3;
151
+ std::cout<< u8"输出map:" << " "<< std::endl;
152
+ for (auto ii : cc)
153
+ {
154
+ std::cout<< ii.first << " "<< ii.second << " "<< std::endl;
155
+ }
156
+
157
+ int16_t aa[] = {1,3,2};
158
+ aa[0] = 134;
159
+ std::cout<< u8"输出list:" << " "<< std::endl;
160
+ for (int64_t i = 0; i < 3; ++i)
161
+ {
162
+ std::cout<< i << " "<< aa[i] << " "<< std::endl;
163
+ }
164
+
165
+ std::cout<< u8"Hello World" << " "<< a << " "<< b << " "<< std::endl;
166
+ std::cout<< u8"test_other_fn" << " "<< test_other_fn(a,b) << " "<< std::endl;
167
+ std::cout<< u8"test编译的函数" << " "<< function_74657374e7bc96e8af91e79a84e587bde695b0(a,b) << " "<< std::endl;
168
+ auto v = 0;
169
+ auto vv = true&&false||1;
170
+ std::cout<< u8"vv:" << " "<< vv << " "<< std::endl;
171
+ while (vv)
172
+ {
173
+ std::cout << u8"请输入>>>"; std::cin >> v;
174
+ if ((v > 100))
175
+ {
176
+ break;
177
+ }
178
+
179
+ else
180
+ {
181
+ std::cout<< u8"输入的" << " "<< v << " "<< u8"小于等于100" << " "<< std::endl;
182
+ }
183
+
184
+ }
185
+
186
+ return a + b + 1 + 123 + v;
187
+ }
188
+
189
+ ```
190
+ ## 6. test_add_@ac596ca343e844de.h
191
+ ```c++
192
+ #pragma once
193
+ #include "test_other_fn_@75fdd928ab58a8e3.h"
194
+ #include "test编译的函数_@3bf4501e0408a243.h"
195
+ #include <cmath>
196
+ #include <cstdint>
197
+ #include <iostream>
198
+ #include <string>
199
+ #include <unordered_map>
200
+ extern "C" int16_t test_add (int16_t a, int16_t b);
201
+ ```
202
+ ## 7. test_other_fn_@75fdd928ab58a8e3.cpp
203
+ ```c++
204
+ #include "test_other_fn_@75fdd928ab58a8e3.h"
205
+ extern "C" int16_t test_other_fn (int16_t a, int16_t b)
206
+ {
207
+ return a - b;
208
+ }
209
+
210
+ ```
211
+ ## 8. test_other_fn_@75fdd928ab58a8e3.h
212
+ ```c++
213
+ #pragma once
214
+ #include <cstdint>
215
+ #include <string>
216
+ extern "C" int16_t test_other_fn (int16_t a, int16_t b);
217
+ ```
218
+ ## 9. test编译的函数_@3bf4501e0408a243.cpp
219
+ ```c++
220
+ #include "test编译的函数_@3bf4501e0408a243.h"
221
+ extern "C" int16_t /*test编译的函数*/ function_74657374e7bc96e8af91e79a84e587bde695b0 (int16_t a, int16_t b)
222
+ {
223
+ return a * b;
224
+ }
225
+
226
+ ```
227
+ ## 10. test编译的函数_@3bf4501e0408a243.h
228
+ ```c++
229
+ #pragma once
230
+ #include <cstdint>
231
+ #include <string>
232
+ extern "C" int16_t /*test编译的函数*/ function_74657374e7bc96e8af91e79a84e587bde695b0 (int16_t a, int16_t b);
233
+ ```
l0n0lc-0.8.7/README.md ADDED
@@ -0,0 +1,223 @@
1
+
2
+ # 将python函数翻译为c++函数并运行
3
+ ## 1. 安装
4
+ ```
5
+ pip install l0n0lc
6
+ ```
7
+ ## 2. hello_world.py
8
+ ```python
9
+ import l0n0lc as lc
10
+ import math
11
+
12
+
13
+ @lc.映射函数(math.ceil, ['<cmath>'])
14
+ def cpp_ceil(v):
15
+ return f'std::ceil({lc.toCString(v)});'
16
+
17
+
18
+ @lc.映射函数(print, ['<iostream>'])
19
+ def cpp_cout(*args):
20
+ code = f'std::cout'
21
+ for arg in args:
22
+ code += f'<< {lc.toCString(arg)} << " "'
23
+ code += '<< std::endl;'
24
+ return code
25
+
26
+
27
+ def py_cin(v):
28
+ pass
29
+
30
+
31
+ @lc.映射函数(py_cin, ['<iostream>'])
32
+ def cpp_cin(v):
33
+ return f'std::cout << u8"请输入>>>"; std::cin >> {v};'
34
+
35
+
36
+ @lc.直接调用函数
37
+ def test_直接调用():
38
+ return 123
39
+
40
+
41
+ def test_other_fn(a: int, b: int) -> int:
42
+ return a - b
43
+
44
+
45
+ @lc.jit()
46
+ def test编译的函数(a: int, b: int) -> int:
47
+ return a * b
48
+
49
+
50
+ @lc.jit(每次运行都重新编译=True)
51
+ def test_add(a: int, b: int) -> int:
52
+ if a > 1:
53
+ return a + b
54
+ for i in range(1, 10, 2):
55
+ a += i
56
+ for i in [1, 2, 3]:
57
+ a += i
58
+ a = math.ceil(12.5)
59
+ cc = {'a': 1, 'b': 2}
60
+ cc['c'] = 3
61
+ print('输出map:')
62
+ for ii in cc:
63
+ print(ii.first, ii.second) # type: ignore
64
+ aa = [1, 3, 2]
65
+ aa[0] = 134
66
+ print('输出list:')
67
+ for i in range(3):
68
+ print(i, aa[i])
69
+ print('Hello World', a, b)
70
+ print('test_other_fn', test_other_fn(a, b))
71
+ print('test编译的函数', test编译的函数(a, b))
72
+ v = 0
73
+ vv = True and (False or 1)
74
+ print('vv:', vv)
75
+ while (vv):
76
+ py_cin(v)
77
+ if v > 100:
78
+ break
79
+ else:
80
+ print('输入的', v, '小于等于100')
81
+ return a + b + 1 + test_直接调用() + v
82
+
83
+
84
+ print('结果:', test_add(1, 3))
85
+
86
+ ```
87
+
88
+ ## 3. 运行hello_world.py
89
+ ```
90
+ uv run tests/hello_world.py
91
+ # 输入: b'1\n2\n100\n101\n'
92
+ ```
93
+ ```bash
94
+ 输出map:
95
+ c 3
96
+ a 1
97
+ b 2
98
+ 输出list:
99
+ 0 134
100
+ 1 3
101
+ 2 2
102
+ Hello World 13 3
103
+ test_other_fn 10
104
+ test编译的函数 39
105
+ vv: 1
106
+ 请输入>>>输入的 1 小于等于100
107
+ 请输入>>>输入的 2 小于等于100
108
+ 请输入>>>输入的 100 小于等于100
109
+ 请输入>>>结果: 241
110
+
111
+ ```
112
+
113
+ ## 4. 查看输出文件
114
+ ```bash
115
+ ls -al ./l0n0lcoutput
116
+
117
+ ```
118
+ ## 5. test_add_@ac596ca343e844de.cpp
119
+ ```c++
120
+ #include "test_add_@ac596ca343e844de.h"
121
+ extern "C" int16_t test_add (int16_t a, int16_t b)
122
+ {
123
+ if ((a > 1))
124
+ {
125
+ return a + b;
126
+ }
127
+
128
+ for (int64_t i = 1; i < 10; i += 2)
129
+ {
130
+ a = a + i;
131
+ }
132
+
133
+ for (auto i : {1,2,3})
134
+ {
135
+ a = a + i;
136
+ }
137
+
138
+ a = std::ceil(12.5);;
139
+ std::unordered_map<std::string, int16_t> cc = {{ u8"a", 1 },{ u8"b", 2 }};
140
+ cc[u8"c"] = 3;
141
+ std::cout<< u8"输出map:" << " "<< std::endl;
142
+ for (auto ii : cc)
143
+ {
144
+ std::cout<< ii.first << " "<< ii.second << " "<< std::endl;
145
+ }
146
+
147
+ int16_t aa[] = {1,3,2};
148
+ aa[0] = 134;
149
+ std::cout<< u8"输出list:" << " "<< std::endl;
150
+ for (int64_t i = 0; i < 3; ++i)
151
+ {
152
+ std::cout<< i << " "<< aa[i] << " "<< std::endl;
153
+ }
154
+
155
+ std::cout<< u8"Hello World" << " "<< a << " "<< b << " "<< std::endl;
156
+ std::cout<< u8"test_other_fn" << " "<< test_other_fn(a,b) << " "<< std::endl;
157
+ std::cout<< u8"test编译的函数" << " "<< function_74657374e7bc96e8af91e79a84e587bde695b0(a,b) << " "<< std::endl;
158
+ auto v = 0;
159
+ auto vv = true&&false||1;
160
+ std::cout<< u8"vv:" << " "<< vv << " "<< std::endl;
161
+ while (vv)
162
+ {
163
+ std::cout << u8"请输入>>>"; std::cin >> v;
164
+ if ((v > 100))
165
+ {
166
+ break;
167
+ }
168
+
169
+ else
170
+ {
171
+ std::cout<< u8"输入的" << " "<< v << " "<< u8"小于等于100" << " "<< std::endl;
172
+ }
173
+
174
+ }
175
+
176
+ return a + b + 1 + 123 + v;
177
+ }
178
+
179
+ ```
180
+ ## 6. test_add_@ac596ca343e844de.h
181
+ ```c++
182
+ #pragma once
183
+ #include "test_other_fn_@75fdd928ab58a8e3.h"
184
+ #include "test编译的函数_@3bf4501e0408a243.h"
185
+ #include <cmath>
186
+ #include <cstdint>
187
+ #include <iostream>
188
+ #include <string>
189
+ #include <unordered_map>
190
+ extern "C" int16_t test_add (int16_t a, int16_t b);
191
+ ```
192
+ ## 7. test_other_fn_@75fdd928ab58a8e3.cpp
193
+ ```c++
194
+ #include "test_other_fn_@75fdd928ab58a8e3.h"
195
+ extern "C" int16_t test_other_fn (int16_t a, int16_t b)
196
+ {
197
+ return a - b;
198
+ }
199
+
200
+ ```
201
+ ## 8. test_other_fn_@75fdd928ab58a8e3.h
202
+ ```c++
203
+ #pragma once
204
+ #include <cstdint>
205
+ #include <string>
206
+ extern "C" int16_t test_other_fn (int16_t a, int16_t b);
207
+ ```
208
+ ## 9. test编译的函数_@3bf4501e0408a243.cpp
209
+ ```c++
210
+ #include "test编译的函数_@3bf4501e0408a243.h"
211
+ extern "C" int16_t /*test编译的函数*/ function_74657374e7bc96e8af91e79a84e587bde695b0 (int16_t a, int16_t b)
212
+ {
213
+ return a * b;
214
+ }
215
+
216
+ ```
217
+ ## 10. test编译的函数_@3bf4501e0408a243.h
218
+ ```c++
219
+ #pragma once
220
+ #include <cstdint>
221
+ #include <string>
222
+ extern "C" int16_t /*test编译的函数*/ function_74657374e7bc96e8af91e79a84e587bde695b0 (int16_t a, int16_t b);
223
+ ```
@@ -41,27 +41,30 @@ def 执行额外函数(函数列表: List, *args):
41
41
 
42
42
 
43
43
  额外py转ctypes函数 = []
44
+ py2ctypes映射表 = {
45
+ int: ctypes.c_int64,
46
+ float: ctypes.c_float,
47
+ str: ctypes.c_char_p,
48
+ bool: ctypes.c_bool,
49
+ 指针: ctypes.c_void_p,
50
+ }
44
51
 
45
52
 
46
53
  def py类型转ctypes类型(类型):
47
54
  ret = 执行额外函数(额外py转ctypes函数, 类型)
48
55
  if ret is not None:
49
56
  return ret
50
-
51
- # 基础类型
52
- if 类型 is int:
53
- return ctypes.c_int64
54
- if 类型 is float:
55
- return ctypes.c_float
56
- if 类型 is str:
57
- return ctypes.c_char_p
58
- if 类型 is bool:
59
- return ctypes.c_bool
60
- if 类型 is 指针:
61
- return ctypes.c_void_p
57
+ return py2ctypes映射表.get(类型)
62
58
 
63
59
 
64
60
  额外py转c函数 = []
61
+ py2c类型映射表 = {
62
+ int: cpp类型.INT16_T,
63
+ float: cpp类型.FLOAT,
64
+ str: cpp类型.STRING,
65
+ bool: cpp类型.BOOL,
66
+ 指针: cpp类型.VOID_P,
67
+ }
65
68
 
66
69
 
67
70
  def py类型转c类型(类型):
@@ -70,16 +73,9 @@ def py类型转c类型(类型):
70
73
  return ret
71
74
 
72
75
  # 基础类型
73
- if 类型 is int:
74
- return cpp类型.INT64_T
75
- if 类型 is float:
76
- return cpp类型.FLOAT
77
- if 类型 is str:
78
- return cpp类型.STRING
79
- if 类型 is bool:
80
- return cpp类型.BOOL
81
- if 类型 is 指针:
82
- return cpp类型.VOID_P
76
+ ret = py2c类型映射表.get(类型)
77
+ if ret is not None:
78
+ return ret
83
79
 
84
80
  origin = get_origin(类型)
85
81
  args = get_args(类型)
@@ -119,17 +119,17 @@ class py2cpp编译器(ast.NodeVisitor):
119
119
  语法树 = ast.parse(self.源代码)
120
120
  self.visit(语法树)
121
121
  # 读取依赖函数
122
- cpps = [f'{通用信息.工作文件夹地址}/{self.获取cpp文件名()}']
122
+ cpps = set([f'{通用信息.工作文件夹地址}/{self.获取cpp文件名()}'])
123
123
  for b in self.依赖函数:
124
124
  self.include目录.add(f'"{b.获取h文件名()}"')
125
- cpps.append(f'{通用信息.工作文件夹地址}/{b.获取cpp文件名()}')
125
+ cpps.add(f'{通用信息.工作文件夹地址}/{b.获取cpp文件名()}')
126
126
 
127
127
  self.将代码保存到文件()
128
128
  self.c编译器.include目录列表 = list(self.include目录)
129
129
  self.c编译器.库目录列表 = list(self.库目录)
130
130
  self.c编译器.链接库 = list(self.链接库列表)
131
131
  输出路径 = f'{通用信息.工作文件夹地址}/{self.获取库文件名()}'
132
- self.c编译器.编译为动态库(cpps, 输出路径=输出路径)
132
+ self.c编译器.编译为动态库(list(cpps), 输出路径=输出路径)
133
133
 
134
134
  def 添加c代码(self, 代码: str):
135
135
  self.代码序列.append(c代码(代码, self.当前上下文层级))
@@ -255,7 +255,7 @@ class py2cpp编译器(ast.NodeVisitor):
255
255
  if isinstance(op, ast.NotEq):
256
256
  ret += f'{left} != {right}'
257
257
  if isinstance(op, ast.Lt):
258
- ret += f'{left} < {right})'
258
+ ret += f'{left} < {right}'
259
259
  if isinstance(op, ast.LtE):
260
260
  ret += f'{left} <= {right}'
261
261
  if isinstance(op, ast.Gt):
@@ -284,8 +284,6 @@ class py2cpp编译器(ast.NodeVisitor):
284
284
  return f'{left} / {right}'
285
285
  if isinstance(op, ast.Mod):
286
286
  return f'{left} % {right}'
287
- if isinstance(op, ast.Pow):
288
- return f'{left} ** {right}'
289
287
  if isinstance(op, ast.BitAnd):
290
288
  return f'{left} & {right}'
291
289
  if isinstance(op, ast.BitOr):
@@ -299,14 +297,29 @@ class py2cpp编译器(ast.NodeVisitor):
299
297
 
300
298
  self.抛出代码异常(f"暂不支持的运算符: {type(op).__name__}", node)
301
299
 
300
+ def 构建参数列表文本(self, args: List[ast.expr]):
301
+ 参数列表 = [str(self.获取值(arg)) for arg in args]
302
+ return ','.join(参数列表)
303
+
302
304
  def 调用Call(self, node: ast.Call):
303
- # 构建函数
305
+ # 获取函数
304
306
  fn = self.获取值(node.func)
307
+
308
+ # 如果是创建类型
309
+ if inspect.isclass(fn):
310
+ c类型 = py类型转c类型(fn)
311
+ if c类型 is None:
312
+ self.抛出代码异常(f'不支持的python类型{fn}', node)
313
+ 参数文本 = self.构建参数列表文本(node.args)
314
+ return c函数调用(c类型, 参数文本)
315
+
316
+ # 直接调用函数
305
317
  if fn in 通用信息.直接调用函数:
306
318
  参数列表 = [self.获取值(arg) for arg in node.args]
307
319
  self.正在调用直接函数 = True
308
320
  return fn(*参数列表)
309
321
 
322
+ # python函数对应的c++函数
310
323
  映射函数 = 通用信息.函数映射表.get(fn)
311
324
  if 映射函数 is not None:
312
325
  参数列表 = [self.获取值(arg) for arg in node.args]
@@ -323,19 +336,19 @@ class py2cpp编译器(ast.NodeVisitor):
323
336
  self.抛出代码异常(f'{ast.dump(node.func)} 没找到', node)
324
337
 
325
338
  if len(node.keywords) > 0:
326
- self.代码异常抛出器('暂不支持 keywords 函数调用', node)
327
-
328
- 参数列表 = [str(self.获取值(arg)) for arg in node.args]
329
- 参数字符串 = ','.join(参数列表)
339
+ self.抛出代码异常('暂不支持 keywords 函数调用', node)
330
340
 
341
+ 参数文本 = self.构建参数列表文本(node.args)
342
+ # 是否是编译好的函数
331
343
  if isinstance(fn, py2cpp编译器):
332
344
  self.依赖函数.append(fn)
333
- return c函数调用(fn.c函数名, 参数字符串)
345
+ return c函数调用(fn.c函数名, 参数文本)
346
+ # 编译该函数
334
347
  else:
335
348
  依赖函数编译器 = self.__class__(fn, self.c编译器)
336
349
  依赖函数编译器.编译()
337
350
  self.依赖函数.append(依赖函数编译器)
338
- return c函数调用(fn.__name__, 参数字符串)
351
+ return c函数调用(fn.__name__, 参数文本)
339
352
 
340
353
  def 获取Subscript(self, node: ast.Subscript):
341
354
  对象 = self.获取值(node.value)
@@ -557,7 +570,7 @@ class py2cpp编译器(ast.NodeVisitor):
557
570
  return '\n'.join(include代码列表)
558
571
 
559
572
  def 获取h代码(self):
560
- return self.获取includes() + '\n' + self.获取定义() + ';'
573
+ return '#pragma once\n' + self.获取includes() + '\n' + self.获取定义() + ';'
561
574
 
562
575
  def 获取无后缀文件名(self):
563
576
  return f'{self.文件前缀}{self.代码哈希值}'