jaclang 0.8.0__py3-none-any.whl → 0.8.2__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.
Potentially problematic release.
This version of jaclang might be problematic. Click here for more details.
- jaclang/__init__.py +6 -0
- jaclang/cli/cli.py +23 -50
- jaclang/compiler/codeinfo.py +0 -1
- jaclang/compiler/jac.lark +14 -22
- jaclang/compiler/larkparse/jac_parser.py +2 -2
- jaclang/compiler/parser.py +378 -531
- jaclang/compiler/passes/main/__init__.py +0 -14
- jaclang/compiler/passes/main/annex_pass.py +2 -8
- jaclang/compiler/passes/main/cfg_build_pass.py +39 -13
- jaclang/compiler/passes/main/def_impl_match_pass.py +14 -13
- jaclang/compiler/passes/main/def_use_pass.py +4 -7
- jaclang/compiler/passes/main/import_pass.py +6 -14
- jaclang/compiler/passes/main/inheritance_pass.py +2 -2
- jaclang/compiler/passes/main/pyast_gen_pass.py +428 -799
- jaclang/compiler/passes/main/pyast_load_pass.py +115 -311
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +8 -7
- jaclang/compiler/passes/main/sym_tab_build_pass.py +3 -3
- jaclang/compiler/passes/main/sym_tab_link_pass.py +6 -9
- jaclang/compiler/passes/main/tests/fixtures/symtab_link_tests/action/actions.jac +1 -5
- jaclang/compiler/passes/main/tests/fixtures/symtab_link_tests/main.jac +1 -8
- jaclang/compiler/passes/main/tests/test_cfg_build_pass.py +5 -9
- jaclang/compiler/passes/main/tests/test_decl_impl_match_pass.py +7 -8
- jaclang/compiler/passes/main/tests/test_import_pass.py +5 -18
- jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +2 -6
- jaclang/compiler/passes/main/tests/test_sub_node_pass.py +1 -3
- jaclang/compiler/passes/main/tests/test_sym_tab_link_pass.py +20 -17
- jaclang/compiler/passes/tool/doc_ir_gen_pass.py +425 -216
- jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -0
- jaclang/compiler/passes/tool/tests/fixtures/archetype_frmt.jac +14 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +5 -4
- jaclang/compiler/passes/tool/tests/fixtures/import_fmt.jac +6 -0
- jaclang/compiler/passes/tool/tests/fixtures/simple_walk_fmt.jac +3 -3
- jaclang/compiler/passes/tool/tests/fixtures/tagbreak.jac +9 -0
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +18 -3
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +2 -2
- jaclang/compiler/program.py +22 -66
- jaclang/compiler/tests/fixtures/fam.jac +2 -2
- jaclang/compiler/tests/fixtures/pkg_import_lib/__init__.jac +1 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib/sub/__init__.jac +1 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib/sub/helper.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib/tools.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/__init__.py +5 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/__init__.py +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/helper.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/tools.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_main.jac +10 -0
- jaclang/compiler/tests/fixtures/pkg_import_main_py.jac +11 -0
- jaclang/compiler/tests/test_importer.py +30 -13
- jaclang/compiler/tests/test_parser.py +1 -0
- jaclang/compiler/unitree.py +488 -320
- jaclang/langserve/__init__.jac +1 -0
- jaclang/langserve/engine.jac +503 -0
- jaclang/langserve/sem_manager.jac +309 -0
- jaclang/langserve/server.jac +201 -0
- jaclang/langserve/tests/server_test/test_lang_serve.py +139 -48
- jaclang/langserve/tests/server_test/utils.py +35 -6
- jaclang/langserve/tests/session.jac +294 -0
- jaclang/langserve/tests/test_sem_tokens.py +2 -2
- jaclang/langserve/tests/test_server.py +8 -7
- jaclang/langserve/utils.jac +51 -30
- jaclang/runtimelib/archetype.py +128 -6
- jaclang/runtimelib/builtin.py +17 -14
- jaclang/runtimelib/importer.py +51 -76
- jaclang/runtimelib/machine.py +469 -305
- jaclang/runtimelib/meta_importer.py +86 -0
- jaclang/runtimelib/tests/fixtures/graph_purger.jac +24 -26
- jaclang/runtimelib/tests/fixtures/other_root_access.jac +25 -16
- jaclang/runtimelib/tests/fixtures/traversing_save.jac +7 -5
- jaclang/runtimelib/tests/test_jaseci.py +3 -1
- jaclang/runtimelib/utils.py +3 -3
- jaclang/tests/fixtures/arch_rel_import_creation.jac +23 -23
- jaclang/tests/fixtures/async_ability.jac +43 -10
- jaclang/tests/fixtures/async_function.jac +18 -0
- jaclang/tests/fixtures/async_walker.jac +17 -12
- jaclang/tests/fixtures/backward_edge_visit.jac +31 -0
- jaclang/tests/fixtures/builtin_printgraph.jac +85 -0
- jaclang/tests/fixtures/builtin_printgraph_json.jac +21 -0
- jaclang/tests/fixtures/builtin_printgraph_mermaid.jac +16 -0
- jaclang/tests/fixtures/chandra_bugs2.jac +20 -13
- jaclang/tests/fixtures/concurrency.jac +1 -1
- jaclang/tests/fixtures/create_dynamic_archetype.jac +25 -28
- jaclang/tests/fixtures/deep/deeper/deep_outer_import.jac +7 -4
- jaclang/tests/fixtures/deep/deeper/snd_lev.jac +2 -2
- jaclang/tests/fixtures/deep/deeper/snd_lev_dup.jac +6 -0
- jaclang/tests/fixtures/deep/one_lev.jac +2 -2
- jaclang/tests/fixtures/deep/one_lev_dup.jac +4 -3
- jaclang/tests/fixtures/dynamic_archetype.jac +19 -12
- jaclang/tests/fixtures/edge_ability.jac +49 -0
- jaclang/tests/fixtures/foo.jac +14 -22
- jaclang/tests/fixtures/guess_game.jac +1 -1
- jaclang/tests/fixtures/here_usage_error.jac +21 -0
- jaclang/tests/fixtures/here_visitor_usage.jac +21 -0
- jaclang/tests/fixtures/jac_from_py.py +1 -1
- jaclang/tests/fixtures/jp_importer.jac +6 -6
- jaclang/tests/fixtures/jp_importer_auto.jac +5 -3
- jaclang/tests/fixtures/node_del.jac +30 -36
- jaclang/tests/fixtures/unicode_strings.jac +24 -0
- jaclang/tests/fixtures/visit_traversal.jac +47 -0
- jaclang/tests/fixtures/walker_update.jac +5 -7
- jaclang/tests/test_cli.py +12 -7
- jaclang/tests/test_language.py +218 -145
- jaclang/tests/test_reference.py +9 -4
- jaclang/tests/test_typecheck.py +13 -26
- jaclang/utils/helpers.py +14 -6
- jaclang/utils/lang_tools.py +9 -8
- jaclang/utils/module_resolver.py +23 -0
- jaclang/utils/tests/test_lang_tools.py +2 -1
- jaclang/utils/treeprinter.py +3 -4
- {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/METADATA +4 -3
- {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/RECORD +112 -94
- {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/WHEEL +1 -1
- jaclang/compiler/passes/main/tests/fixtures/main_err.jac +0 -6
- jaclang/compiler/passes/main/tests/fixtures/second_err.jac +0 -4
- jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +0 -644
- jaclang/compiler/passes/tool/tests/test_doc_ir_gen_pass.py +0 -29
- jaclang/langserve/__init__.py +0 -1
- jaclang/langserve/engine.py +0 -553
- jaclang/langserve/sem_manager.py +0 -383
- jaclang/langserve/server.py +0 -167
- jaclang/langserve/tests/session.py +0 -255
- jaclang/tests/fixtures/builtin_dotgen.jac +0 -42
- jaclang/tests/fixtures/builtin_dotgen_json.jac +0 -21
- jaclang/tests/fixtures/deep/deeper/__init__.jac +0 -1
- {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/entry_points.txt +0 -0
|
@@ -31,6 +31,63 @@ from jaclang.settings import settings
|
|
|
31
31
|
|
|
32
32
|
T = TypeVar("T", bound=ast3.AST)
|
|
33
33
|
|
|
34
|
+
# Mapping of Jac tokens to corresponding Python AST operator classes. This
|
|
35
|
+
# helps keep the implementation of ``exit_token`` concise and easier to
|
|
36
|
+
# maintain.
|
|
37
|
+
TOKEN_AST_MAP: dict[Tok, type[ast3.AST]] = {
|
|
38
|
+
Tok.KW_AND: ast3.And,
|
|
39
|
+
Tok.KW_OR: ast3.Or,
|
|
40
|
+
Tok.PLUS: ast3.Add,
|
|
41
|
+
Tok.ADD_EQ: ast3.Add,
|
|
42
|
+
Tok.BW_AND: ast3.BitAnd,
|
|
43
|
+
Tok.BW_AND_EQ: ast3.BitAnd,
|
|
44
|
+
Tok.BW_OR: ast3.BitOr,
|
|
45
|
+
Tok.BW_OR_EQ: ast3.BitOr,
|
|
46
|
+
Tok.BW_XOR: ast3.BitXor,
|
|
47
|
+
Tok.BW_XOR_EQ: ast3.BitXor,
|
|
48
|
+
Tok.DIV: ast3.Div,
|
|
49
|
+
Tok.DIV_EQ: ast3.Div,
|
|
50
|
+
Tok.FLOOR_DIV: ast3.FloorDiv,
|
|
51
|
+
Tok.FLOOR_DIV_EQ: ast3.FloorDiv,
|
|
52
|
+
Tok.LSHIFT: ast3.LShift,
|
|
53
|
+
Tok.LSHIFT_EQ: ast3.LShift,
|
|
54
|
+
Tok.MOD: ast3.Mod,
|
|
55
|
+
Tok.MOD_EQ: ast3.Mod,
|
|
56
|
+
Tok.STAR_MUL: ast3.Mult,
|
|
57
|
+
Tok.MUL_EQ: ast3.Mult,
|
|
58
|
+
Tok.DECOR_OP: ast3.MatMult,
|
|
59
|
+
Tok.MATMUL_EQ: ast3.MatMult,
|
|
60
|
+
Tok.STAR_POW: ast3.Pow,
|
|
61
|
+
Tok.STAR_POW_EQ: ast3.Pow,
|
|
62
|
+
Tok.RSHIFT: ast3.RShift,
|
|
63
|
+
Tok.RSHIFT_EQ: ast3.RShift,
|
|
64
|
+
Tok.MINUS: ast3.Sub,
|
|
65
|
+
Tok.SUB_EQ: ast3.Sub,
|
|
66
|
+
Tok.BW_NOT: ast3.Invert,
|
|
67
|
+
Tok.BW_NOT_EQ: ast3.Invert,
|
|
68
|
+
Tok.NOT: ast3.Not,
|
|
69
|
+
Tok.EQ: ast3.NotEq,
|
|
70
|
+
Tok.EE: ast3.Eq,
|
|
71
|
+
Tok.GT: ast3.Gt,
|
|
72
|
+
Tok.GTE: ast3.GtE,
|
|
73
|
+
Tok.KW_IN: ast3.In,
|
|
74
|
+
Tok.KW_IS: ast3.Is,
|
|
75
|
+
Tok.KW_ISN: ast3.IsNot,
|
|
76
|
+
Tok.LT: ast3.Lt,
|
|
77
|
+
Tok.LTE: ast3.LtE,
|
|
78
|
+
Tok.NE: ast3.NotEq,
|
|
79
|
+
Tok.KW_NIN: ast3.NotIn,
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# Mapping of unary operator tokens to their Python AST counterparts used in
|
|
83
|
+
# ``exit_unary_expr``.
|
|
84
|
+
UNARY_OP_MAP: dict[Tok, type[ast3.unaryop]] = {
|
|
85
|
+
Tok.NOT: ast3.Not,
|
|
86
|
+
Tok.BW_NOT: ast3.Invert,
|
|
87
|
+
Tok.PLUS: ast3.UAdd,
|
|
88
|
+
Tok.MINUS: ast3.USub,
|
|
89
|
+
}
|
|
90
|
+
|
|
34
91
|
|
|
35
92
|
class PyastGenPass(UniPass):
|
|
36
93
|
"""Jac blue transpilation to python pass."""
|
|
@@ -114,69 +171,55 @@ class PyastGenPass(UniPass):
|
|
|
114
171
|
)
|
|
115
172
|
)
|
|
116
173
|
|
|
117
|
-
def
|
|
118
|
-
"""
|
|
119
|
-
if
|
|
174
|
+
def _add_preamble_once(self, key: str, node: ast3.AST) -> None:
|
|
175
|
+
"""Append an import statement to the preamble once."""
|
|
176
|
+
if key in self.already_added:
|
|
120
177
|
return
|
|
121
|
-
self.preamble.append(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
jac_node=self.ir_out,
|
|
132
|
-
)
|
|
178
|
+
self.preamble.append(self.sync(node, jac_node=self.ir_out))
|
|
179
|
+
self.already_added.append(key)
|
|
180
|
+
|
|
181
|
+
def needs_typing(self) -> None:
|
|
182
|
+
"""Ensure typing is imported only once."""
|
|
183
|
+
self._add_preamble_once(
|
|
184
|
+
self.needs_typing.__name__,
|
|
185
|
+
ast3.Import(
|
|
186
|
+
names=[self.sync(ast3.alias(name="typing"), jac_node=self.ir_out)]
|
|
187
|
+
),
|
|
133
188
|
)
|
|
134
|
-
self.already_added.append(self.needs_typing.__name__)
|
|
135
189
|
|
|
136
190
|
def needs_enum(self) -> None:
|
|
137
|
-
"""
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
level=0,
|
|
149
|
-
),
|
|
150
|
-
jac_node=self.ir_out,
|
|
151
|
-
)
|
|
191
|
+
"""Ensure Enum utilities are imported only once."""
|
|
192
|
+
self._add_preamble_once(
|
|
193
|
+
self.needs_enum.__name__,
|
|
194
|
+
ast3.ImportFrom(
|
|
195
|
+
module="enum",
|
|
196
|
+
names=[
|
|
197
|
+
self.sync(ast3.alias(name="Enum", asname=None)),
|
|
198
|
+
self.sync(ast3.alias(name="auto", asname=None)),
|
|
199
|
+
],
|
|
200
|
+
level=0,
|
|
201
|
+
),
|
|
152
202
|
)
|
|
153
|
-
self.already_added.append(self.needs_enum.__name__)
|
|
154
203
|
|
|
155
204
|
def needs_future(self) -> None:
|
|
156
|
-
"""
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
ast3.
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
self.sync(ast3.alias(name="Future", asname=None)),
|
|
165
|
-
],
|
|
166
|
-
level=0,
|
|
167
|
-
),
|
|
168
|
-
jac_node=self.ir_out,
|
|
169
|
-
)
|
|
205
|
+
"""Ensure concurrent Future is imported only once."""
|
|
206
|
+
self._add_preamble_once(
|
|
207
|
+
self.needs_future.__name__,
|
|
208
|
+
ast3.ImportFrom(
|
|
209
|
+
module="concurrent.futures",
|
|
210
|
+
names=[self.sync(ast3.alias(name="Future", asname=None))],
|
|
211
|
+
level=0,
|
|
212
|
+
),
|
|
170
213
|
)
|
|
171
|
-
self.already_added.append(self.needs_future.__name__)
|
|
172
214
|
|
|
173
215
|
def flatten(self, body: list[T | list[T] | None]) -> list[T]:
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
216
|
+
"""Flatten a list of items or lists into a single list."""
|
|
217
|
+
new_body: list[T] = []
|
|
218
|
+
for item in body:
|
|
219
|
+
if isinstance(item, list):
|
|
220
|
+
new_body.extend(item)
|
|
221
|
+
elif item is not None:
|
|
222
|
+
new_body.append(item)
|
|
180
223
|
return new_body
|
|
181
224
|
|
|
182
225
|
def sync(
|
|
@@ -224,21 +267,15 @@ class PyastGenPass(UniPass):
|
|
|
224
267
|
|
|
225
268
|
def resolve_stmt_block(
|
|
226
269
|
self,
|
|
227
|
-
node:
|
|
228
|
-
uni.SubNodeList[uni.CodeBlockStmt]
|
|
229
|
-
| uni.SubNodeList[uni.ArchBlockStmt]
|
|
230
|
-
| uni.SubNodeList[uni.EnumBlockStmt]
|
|
231
|
-
| None
|
|
232
|
-
),
|
|
270
|
+
node: Sequence[uni.CodeBlockStmt] | Sequence[uni.EnumBlockStmt] | None,
|
|
233
271
|
doc: Optional[uni.String] = None,
|
|
234
272
|
) -> list[ast3.AST]:
|
|
235
273
|
"""Unwind codeblock."""
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
)
|
|
274
|
+
items = list(node) if node else []
|
|
275
|
+
valid_stmts = [i for i in items if not isinstance(i, uni.Semi)]
|
|
239
276
|
ret: list[ast3.AST] = (
|
|
240
|
-
[self.sync(ast3.Pass()
|
|
241
|
-
if isinstance(node,
|
|
277
|
+
[self.sync(ast3.Pass())]
|
|
278
|
+
if isinstance(node, Sequence) and not valid_stmts
|
|
242
279
|
else (
|
|
243
280
|
self.flatten(
|
|
244
281
|
[
|
|
@@ -247,7 +284,7 @@ class PyastGenPass(UniPass):
|
|
|
247
284
|
if not isinstance(x, uni.ImplDef)
|
|
248
285
|
]
|
|
249
286
|
)
|
|
250
|
-
if node
|
|
287
|
+
if node is not None
|
|
251
288
|
else []
|
|
252
289
|
)
|
|
253
290
|
)
|
|
@@ -273,23 +310,16 @@ class PyastGenPass(UniPass):
|
|
|
273
310
|
attr_node: ast3.Name | ast3.Attribute = self.sync(
|
|
274
311
|
ast3.Name(id=attribute_list[0], ctx=ast3.Load()), sync_node_list[0]
|
|
275
312
|
)
|
|
276
|
-
for
|
|
277
|
-
if i == 0:
|
|
278
|
-
continue
|
|
313
|
+
for attr, sync_node in zip(attribute_list[1:], sync_node_list[1:]):
|
|
279
314
|
attr_node = self.sync(
|
|
280
|
-
ast3.Attribute(
|
|
281
|
-
|
|
282
|
-
),
|
|
283
|
-
sync_node_list[i],
|
|
315
|
+
ast3.Attribute(value=attr_node, attr=attr, ctx=ast3.Load()),
|
|
316
|
+
sync_node,
|
|
284
317
|
)
|
|
285
318
|
return attr_node
|
|
286
319
|
|
|
287
320
|
def exit_sub_tag(self, node: uni.SubTag[uni.T]) -> None:
|
|
288
321
|
node.gen.py_ast = node.tag.gen.py_ast
|
|
289
322
|
|
|
290
|
-
def exit_sub_node_list(self, node: uni.SubNodeList[uni.T]) -> None:
|
|
291
|
-
node.gen.py_ast = self.flatten([i.gen.py_ast for i in node.items])
|
|
292
|
-
|
|
293
323
|
def exit_module(self, node: uni.Module) -> None:
|
|
294
324
|
clean_body = [i for i in node.body if not isinstance(i, uni.ImplDef)]
|
|
295
325
|
pre_body: list[uni.UniNode] = []
|
|
@@ -332,14 +362,15 @@ class PyastGenPass(UniPass):
|
|
|
332
362
|
ast3.Expr(value=cast(ast3.expr, node.doc.gen.py_ast[0])),
|
|
333
363
|
jac_node=node.doc,
|
|
334
364
|
)
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
)
|
|
338
|
-
|
|
365
|
+
assigns_ast: list[ast3.AST] = self.flatten(
|
|
366
|
+
[a.gen.py_ast for a in node.assignments]
|
|
367
|
+
)
|
|
368
|
+
if isinstance(doc, ast3.AST):
|
|
369
|
+
node.gen.py_ast = [doc] + assigns_ast
|
|
339
370
|
else:
|
|
340
371
|
raise self.ice()
|
|
341
372
|
else:
|
|
342
|
-
node.gen.py_ast =
|
|
373
|
+
node.gen.py_ast = self.flatten([a.gen.py_ast for a in node.assignments])
|
|
343
374
|
|
|
344
375
|
def exit_test(self, node: uni.Test) -> None:
|
|
345
376
|
test_name = node.name.sym_name
|
|
@@ -382,7 +413,7 @@ class PyastGenPass(UniPass):
|
|
|
382
413
|
ast3.keyword(
|
|
383
414
|
arg="file_loc",
|
|
384
415
|
value=self.sync(
|
|
385
|
-
ast3.Constant(value=node.
|
|
416
|
+
ast3.Constant(value=node.loc.mod_path)
|
|
386
417
|
),
|
|
387
418
|
)
|
|
388
419
|
),
|
|
@@ -434,40 +465,8 @@ class PyastGenPass(UniPass):
|
|
|
434
465
|
)
|
|
435
466
|
|
|
436
467
|
def exit_import(self, node: uni.Import) -> None:
|
|
437
|
-
|
|
438
|
-
{node.from_loc.dot_path_str: None} if node.from_loc else {}
|
|
439
|
-
)
|
|
440
|
-
imp_from = {}
|
|
441
|
-
if node.items:
|
|
442
|
-
for item in node.items.items:
|
|
443
|
-
if isinstance(item, uni.ModuleItem):
|
|
444
|
-
imp_from[item.name.sym_name] = (
|
|
445
|
-
item.alias.sym_name if item.alias else None
|
|
446
|
-
)
|
|
447
|
-
elif isinstance(item, uni.ModulePath):
|
|
448
|
-
path_alias[item.dot_path_str] = (
|
|
449
|
-
item.alias.sym_name if item.alias else None
|
|
450
|
-
)
|
|
451
|
-
|
|
452
|
-
item_names: list[ast3.expr] = []
|
|
453
|
-
item_keys: list[ast3.Constant] = []
|
|
454
|
-
item_values: list[ast3.Constant] = []
|
|
455
|
-
for k, v in imp_from.items():
|
|
456
|
-
item_keys.append(self.sync(ast3.Constant(value=k)))
|
|
457
|
-
item_values.append(self.sync(ast3.Constant(value=v)))
|
|
458
|
-
item_names.append(
|
|
459
|
-
self.sync(
|
|
460
|
-
ast3.Name(
|
|
461
|
-
id=v or k,
|
|
462
|
-
ctx=ast3.Store(),
|
|
463
|
-
)
|
|
464
|
-
)
|
|
465
|
-
)
|
|
466
|
-
path_named_value: str
|
|
468
|
+
"""Exit import node."""
|
|
467
469
|
py_nodes: list[ast3.AST] = []
|
|
468
|
-
typecheck_nodes: list[ast3.AST] = []
|
|
469
|
-
runtime_nodes: list[ast3.AST] = []
|
|
470
|
-
|
|
471
470
|
if node.doc:
|
|
472
471
|
py_nodes.append(
|
|
473
472
|
self.sync(
|
|
@@ -476,284 +475,58 @@ class PyastGenPass(UniPass):
|
|
|
476
475
|
)
|
|
477
476
|
)
|
|
478
477
|
|
|
479
|
-
for path, alias in path_alias.items():
|
|
480
|
-
path_named_value = ("_jac_inc_" if node.is_absorb else "") + (
|
|
481
|
-
alias if alias else path
|
|
482
|
-
).lstrip(".").split(".")[0]
|
|
483
|
-
# target_named_value = ""
|
|
484
|
-
# for i in path.split("."):
|
|
485
|
-
# target_named_value += i if i else "."
|
|
486
|
-
# if i:
|
|
487
|
-
# break
|
|
488
|
-
|
|
489
|
-
args = [
|
|
490
|
-
self.sync(
|
|
491
|
-
ast3.Constant(value=path),
|
|
492
|
-
),
|
|
493
|
-
self.sync(
|
|
494
|
-
ast3.Name(
|
|
495
|
-
id="__file__",
|
|
496
|
-
ctx=ast3.Load(),
|
|
497
|
-
)
|
|
498
|
-
),
|
|
499
|
-
]
|
|
500
|
-
keywords = []
|
|
501
|
-
|
|
502
|
-
if node.is_absorb:
|
|
503
|
-
args.append(self.sync(ast3.Constant(value=node.is_absorb)))
|
|
504
|
-
|
|
505
|
-
if alias is not None:
|
|
506
|
-
keywords.append(
|
|
507
|
-
self.sync(
|
|
508
|
-
ast3.keyword(
|
|
509
|
-
arg="mdl_alias",
|
|
510
|
-
value=self.sync(
|
|
511
|
-
ast3.Constant(value=alias),
|
|
512
|
-
),
|
|
513
|
-
)
|
|
514
|
-
)
|
|
515
|
-
)
|
|
516
|
-
|
|
517
|
-
if item_keys and item_values:
|
|
518
|
-
keywords.append(
|
|
519
|
-
self.sync(
|
|
520
|
-
ast3.keyword(
|
|
521
|
-
arg="items",
|
|
522
|
-
value=self.sync(
|
|
523
|
-
ast3.Dict(
|
|
524
|
-
keys=cast(list[ast3.expr | None], item_keys),
|
|
525
|
-
values=cast(list[ast3.expr], item_values),
|
|
526
|
-
),
|
|
527
|
-
),
|
|
528
|
-
)
|
|
529
|
-
)
|
|
530
|
-
)
|
|
531
|
-
|
|
532
|
-
runtime_nodes.append(
|
|
533
|
-
self.sync(
|
|
534
|
-
ast3.Assign(
|
|
535
|
-
targets=(
|
|
536
|
-
[
|
|
537
|
-
self.sync(
|
|
538
|
-
ast3.Tuple(
|
|
539
|
-
elts=(
|
|
540
|
-
item_names
|
|
541
|
-
or [
|
|
542
|
-
self.sync(
|
|
543
|
-
ast3.Name(
|
|
544
|
-
id=path_named_value,
|
|
545
|
-
ctx=ast3.Store(),
|
|
546
|
-
)
|
|
547
|
-
)
|
|
548
|
-
]
|
|
549
|
-
),
|
|
550
|
-
ctx=ast3.Store(),
|
|
551
|
-
)
|
|
552
|
-
)
|
|
553
|
-
]
|
|
554
|
-
),
|
|
555
|
-
value=self.sync(
|
|
556
|
-
ast3.Call(
|
|
557
|
-
func=self.jaclib_obj("py_jac_import"),
|
|
558
|
-
args=args,
|
|
559
|
-
keywords=keywords,
|
|
560
|
-
)
|
|
561
|
-
),
|
|
562
|
-
),
|
|
563
|
-
),
|
|
564
|
-
)
|
|
565
478
|
if node.is_absorb:
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
self.sync(
|
|
569
|
-
ast3.For(
|
|
570
|
-
target=self.sync(ast3.Name(id="i", ctx=ast3.Store())),
|
|
571
|
-
iter=self.sync(
|
|
572
|
-
ast3.IfExp(
|
|
573
|
-
test=self.sync(
|
|
574
|
-
ast3.Compare(
|
|
575
|
-
left=self.sync(ast3.Constant(value="__all__")),
|
|
576
|
-
ops=[self.sync(ast3.In())],
|
|
577
|
-
comparators=[
|
|
578
|
-
self.sync(
|
|
579
|
-
ast3.Attribute(
|
|
580
|
-
value=self.sync(
|
|
581
|
-
ast3.Name(
|
|
582
|
-
id=path_named_value,
|
|
583
|
-
ctx=ast3.Load(),
|
|
584
|
-
)
|
|
585
|
-
),
|
|
586
|
-
attr="__dict__",
|
|
587
|
-
ctx=ast3.Load(),
|
|
588
|
-
)
|
|
589
|
-
)
|
|
590
|
-
],
|
|
591
|
-
)
|
|
592
|
-
),
|
|
593
|
-
body=self.sync(
|
|
594
|
-
ast3.Attribute(
|
|
595
|
-
value=self.sync(
|
|
596
|
-
ast3.Name(
|
|
597
|
-
id=path_named_value, ctx=ast3.Load()
|
|
598
|
-
)
|
|
599
|
-
),
|
|
600
|
-
attr="__all__",
|
|
601
|
-
ctx=ast3.Load(),
|
|
602
|
-
)
|
|
603
|
-
),
|
|
604
|
-
orelse=self.sync(
|
|
605
|
-
ast3.Attribute(
|
|
606
|
-
value=self.sync(
|
|
607
|
-
ast3.Name(
|
|
608
|
-
id=path_named_value, ctx=ast3.Load()
|
|
609
|
-
)
|
|
610
|
-
),
|
|
611
|
-
attr="__dict__",
|
|
612
|
-
ctx=ast3.Load(),
|
|
613
|
-
)
|
|
614
|
-
),
|
|
615
|
-
)
|
|
616
|
-
),
|
|
617
|
-
body=[
|
|
618
|
-
self.sync(
|
|
619
|
-
ast3.If(
|
|
620
|
-
test=self.sync(
|
|
621
|
-
ast3.UnaryOp(
|
|
622
|
-
op=self.sync(ast3.Not()),
|
|
623
|
-
operand=self.sync(
|
|
624
|
-
ast3.Call(
|
|
625
|
-
func=self.sync(
|
|
626
|
-
ast3.Attribute(
|
|
627
|
-
value=self.sync(
|
|
628
|
-
ast3.Name(
|
|
629
|
-
id="i",
|
|
630
|
-
ctx=ast3.Load(),
|
|
631
|
-
)
|
|
632
|
-
),
|
|
633
|
-
attr="startswith",
|
|
634
|
-
ctx=ast3.Load(),
|
|
635
|
-
)
|
|
636
|
-
),
|
|
637
|
-
args=[
|
|
638
|
-
self.sync(
|
|
639
|
-
ast3.Constant(value="_")
|
|
640
|
-
)
|
|
641
|
-
],
|
|
642
|
-
keywords=[],
|
|
643
|
-
)
|
|
644
|
-
),
|
|
645
|
-
)
|
|
646
|
-
),
|
|
647
|
-
body=[
|
|
648
|
-
self.sync(
|
|
649
|
-
ast3.Expr(
|
|
650
|
-
value=self.sync(
|
|
651
|
-
ast3.Call(
|
|
652
|
-
func=self.sync(
|
|
653
|
-
ast3.Name(
|
|
654
|
-
id="exec",
|
|
655
|
-
ctx=ast3.Load(),
|
|
656
|
-
)
|
|
657
|
-
),
|
|
658
|
-
args=[
|
|
659
|
-
self.sync(
|
|
660
|
-
ast3.JoinedStr(
|
|
661
|
-
values=[
|
|
662
|
-
self.sync(
|
|
663
|
-
ast3.FormattedValue(
|
|
664
|
-
value=self.sync(
|
|
665
|
-
ast3.Name(
|
|
666
|
-
id="i",
|
|
667
|
-
ctx=ast3.Load(),
|
|
668
|
-
)
|
|
669
|
-
),
|
|
670
|
-
conversion=-1,
|
|
671
|
-
)
|
|
672
|
-
),
|
|
673
|
-
self.sync(
|
|
674
|
-
ast3.Constant(
|
|
675
|
-
value=absorb_exec
|
|
676
|
-
)
|
|
677
|
-
),
|
|
678
|
-
self.sync(
|
|
679
|
-
ast3.FormattedValue(
|
|
680
|
-
value=self.sync(
|
|
681
|
-
ast3.Name(
|
|
682
|
-
id="i",
|
|
683
|
-
ctx=ast3.Load(),
|
|
684
|
-
)
|
|
685
|
-
),
|
|
686
|
-
conversion=-1,
|
|
687
|
-
)
|
|
688
|
-
),
|
|
689
|
-
self.sync(
|
|
690
|
-
ast3.Constant(
|
|
691
|
-
value="']"
|
|
692
|
-
)
|
|
693
|
-
),
|
|
694
|
-
]
|
|
695
|
-
)
|
|
696
|
-
)
|
|
697
|
-
],
|
|
698
|
-
keywords=[],
|
|
699
|
-
)
|
|
700
|
-
)
|
|
701
|
-
)
|
|
702
|
-
)
|
|
703
|
-
],
|
|
704
|
-
orelse=[],
|
|
705
|
-
)
|
|
706
|
-
)
|
|
707
|
-
],
|
|
708
|
-
orelse=[],
|
|
709
|
-
)
|
|
710
|
-
)
|
|
711
|
-
)
|
|
712
|
-
if node.is_absorb:
|
|
713
|
-
source = node.items.items[0]
|
|
479
|
+
# This is `include "module_name";` which becomes `from module_name import *`
|
|
480
|
+
source = node.items[0]
|
|
714
481
|
if not isinstance(source, uni.ModulePath):
|
|
715
482
|
raise self.ice()
|
|
716
|
-
|
|
483
|
+
|
|
484
|
+
module_name_parts = [p.value for p in source.path] if source.path else []
|
|
485
|
+
module_name = ".".join(module_name_parts) if module_name_parts else None
|
|
486
|
+
|
|
487
|
+
py_nodes.append(
|
|
717
488
|
self.sync(
|
|
718
489
|
py_node=ast3.ImportFrom(
|
|
719
|
-
module=
|
|
490
|
+
module=module_name,
|
|
720
491
|
names=[self.sync(ast3.alias(name="*"), node)],
|
|
721
|
-
level=
|
|
492
|
+
level=source.level,
|
|
722
493
|
),
|
|
723
494
|
jac_node=node,
|
|
724
495
|
)
|
|
725
496
|
)
|
|
726
497
|
elif not node.from_loc:
|
|
727
|
-
|
|
498
|
+
# This is `import module1, module2 as alias;`
|
|
499
|
+
py_nodes.append(
|
|
728
500
|
self.sync(
|
|
729
501
|
ast3.Import(
|
|
730
|
-
names=[
|
|
502
|
+
names=[
|
|
503
|
+
cast(ast3.alias, x)
|
|
504
|
+
for item in node.items
|
|
505
|
+
for x in item.gen.py_ast
|
|
506
|
+
]
|
|
731
507
|
)
|
|
732
508
|
)
|
|
733
509
|
)
|
|
734
510
|
else:
|
|
735
|
-
|
|
511
|
+
# This is `from module import item1, item2 as alias;`
|
|
512
|
+
module_name_parts = (
|
|
513
|
+
[p.value for p in node.from_loc.path] if node.from_loc.path else []
|
|
514
|
+
)
|
|
515
|
+
module_name = ".".join(module_name_parts) if module_name_parts else None
|
|
516
|
+
|
|
517
|
+
py_nodes.append(
|
|
736
518
|
self.sync(
|
|
737
519
|
ast3.ImportFrom(
|
|
738
|
-
module=
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
level=
|
|
520
|
+
module=module_name,
|
|
521
|
+
names=[
|
|
522
|
+
cast(ast3.alias, i)
|
|
523
|
+
for item in node.items
|
|
524
|
+
for i in item.gen.py_ast
|
|
525
|
+
],
|
|
526
|
+
level=node.from_loc.level,
|
|
745
527
|
)
|
|
746
528
|
)
|
|
747
529
|
)
|
|
748
|
-
py_nodes.append(
|
|
749
|
-
self.sync(
|
|
750
|
-
ast3.If(
|
|
751
|
-
test=self.jaclib_obj("TYPE_CHECKING"),
|
|
752
|
-
body=[cast(ast3.stmt, node) for node in typecheck_nodes],
|
|
753
|
-
orelse=[cast(ast3.stmt, node) for node in runtime_nodes],
|
|
754
|
-
)
|
|
755
|
-
)
|
|
756
|
-
)
|
|
757
530
|
node.gen.py_ast = py_nodes
|
|
758
531
|
|
|
759
532
|
def exit_module_path(self, node: uni.ModulePath) -> None:
|
|
@@ -781,16 +554,19 @@ class PyastGenPass(UniPass):
|
|
|
781
554
|
self.traverse(node.body)
|
|
782
555
|
|
|
783
556
|
def exit_archetype(self, node: uni.Archetype) -> None:
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
if isinstance(node.body, uni.
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
)
|
|
793
|
-
|
|
557
|
+
inner = None
|
|
558
|
+
if isinstance(node.body, uni.ImplDef):
|
|
559
|
+
inner = (
|
|
560
|
+
node.body.body if not isinstance(node.body.body, uni.FuncCall) else None
|
|
561
|
+
)
|
|
562
|
+
elif not isinstance(node.body, uni.FuncCall):
|
|
563
|
+
inner = node.body
|
|
564
|
+
body = self.resolve_stmt_block(inner, doc=node.doc)
|
|
565
|
+
if not body and not isinstance(node.body, uni.FuncCall):
|
|
566
|
+
self.log_error(
|
|
567
|
+
"Archetype has no body. Perhaps an impl must be imported.", node
|
|
568
|
+
)
|
|
569
|
+
body = [self.sync(ast3.Pass(), node)]
|
|
794
570
|
if node.is_async:
|
|
795
571
|
body.insert(
|
|
796
572
|
0,
|
|
@@ -805,12 +581,11 @@ class PyastGenPass(UniPass):
|
|
|
805
581
|
)
|
|
806
582
|
|
|
807
583
|
decorators = (
|
|
808
|
-
|
|
809
|
-
if
|
|
584
|
+
[cast(ast3.expr, i.gen.py_ast[0]) for i in node.decorators]
|
|
585
|
+
if node.decorators
|
|
810
586
|
else []
|
|
811
587
|
)
|
|
812
|
-
|
|
813
|
-
base_classes = node.base_classes.gen.py_ast if node.base_classes else []
|
|
588
|
+
base_classes = [cast(ast3.expr, i.gen.py_ast[0]) for i in node.base_classes]
|
|
814
589
|
if node.arch_type.name != Tok.KW_CLASS:
|
|
815
590
|
base_classes.append(self.jaclib_obj(node.arch_type.value.capitalize()))
|
|
816
591
|
|
|
@@ -833,25 +608,21 @@ class PyastGenPass(UniPass):
|
|
|
833
608
|
|
|
834
609
|
def exit_enum(self, node: uni.Enum) -> None:
|
|
835
610
|
self.needs_enum()
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
if isinstance(node.body, uni.
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
)
|
|
611
|
+
inner = None
|
|
612
|
+
if isinstance(node.body, uni.ImplDef):
|
|
613
|
+
inner = (
|
|
614
|
+
node.body.body if not isinstance(node.body.body, uni.FuncCall) else None
|
|
615
|
+
)
|
|
616
|
+
elif not isinstance(node.body, uni.FuncCall):
|
|
617
|
+
inner = node.body
|
|
618
|
+
body = self.resolve_stmt_block(inner, doc=node.doc)
|
|
845
619
|
decorators = (
|
|
846
|
-
|
|
847
|
-
if
|
|
620
|
+
[cast(ast3.expr, i.gen.py_ast[0]) for i in node.decorators]
|
|
621
|
+
if node.decorators
|
|
848
622
|
else []
|
|
849
623
|
)
|
|
850
|
-
base_classes =
|
|
851
|
-
|
|
852
|
-
base_classes.append(self.sync(ast3.Name(id="Enum", ctx=ast3.Load())))
|
|
853
|
-
else:
|
|
854
|
-
raise self.ice()
|
|
624
|
+
base_classes = [cast(ast3.expr, i.gen.py_ast[0]) for i in node.base_classes]
|
|
625
|
+
base_classes.append(self.sync(ast3.Name(id="Enum", ctx=ast3.Load())))
|
|
855
626
|
node.gen.py_ast = [
|
|
856
627
|
self.sync(
|
|
857
628
|
ast3.ClassDef(
|
|
@@ -869,20 +640,42 @@ class PyastGenPass(UniPass):
|
|
|
869
640
|
if isinstance(node.body, uni.ImplDef):
|
|
870
641
|
self.traverse(node.body)
|
|
871
642
|
|
|
643
|
+
def gen_llm_call_override(self, node: uni.FuncCall) -> list[ast3.AST]:
|
|
644
|
+
"""Generate python ast nodes for llm function body override syntax.
|
|
645
|
+
|
|
646
|
+
example:
|
|
647
|
+
foo() by llm();
|
|
648
|
+
"""
|
|
649
|
+
# to Avoid circular import
|
|
650
|
+
from jaclang.runtimelib.machine import JacMachineInterface
|
|
651
|
+
|
|
652
|
+
return JacMachineInterface.gen_llm_call_override(self, node)
|
|
653
|
+
|
|
872
654
|
def gen_llm_body(self, node: uni.Ability) -> list[ast3.AST]:
|
|
873
655
|
"""Generate the by LLM body."""
|
|
874
656
|
# to Avoid circular import
|
|
875
657
|
from jaclang.runtimelib.machine import JacMachineInterface
|
|
876
658
|
|
|
877
|
-
|
|
659
|
+
body: list[ast3.AST] = JacMachineInterface.gen_llm_body(self, node)
|
|
660
|
+
if node.doc:
|
|
661
|
+
body.insert(
|
|
662
|
+
0,
|
|
663
|
+
self.sync(
|
|
664
|
+
ast3.Expr(value=cast(ast3.expr, node.doc.gen.py_ast[0])),
|
|
665
|
+
jac_node=node.doc,
|
|
666
|
+
),
|
|
667
|
+
)
|
|
668
|
+
return body
|
|
878
669
|
|
|
879
670
|
def exit_ability(self, node: uni.Ability) -> None:
|
|
880
671
|
func_type = ast3.AsyncFunctionDef if node.is_async else ast3.FunctionDef
|
|
881
672
|
body = (
|
|
882
673
|
self.gen_llm_body(node)
|
|
883
674
|
if isinstance(node.body, uni.FuncCall)
|
|
884
|
-
or
|
|
885
|
-
|
|
675
|
+
or (
|
|
676
|
+
isinstance(node.body, uni.ImplDef)
|
|
677
|
+
and isinstance(node.body.body, uni.FuncCall)
|
|
678
|
+
)
|
|
886
679
|
else (
|
|
887
680
|
[
|
|
888
681
|
self.sync(
|
|
@@ -899,8 +692,12 @@ class PyastGenPass(UniPass):
|
|
|
899
692
|
(
|
|
900
693
|
node.body.body
|
|
901
694
|
if isinstance(node.body, uni.ImplDef)
|
|
902
|
-
and isinstance(node.body.body, uni.
|
|
903
|
-
else
|
|
695
|
+
and not isinstance(node.body.body, uni.FuncCall)
|
|
696
|
+
else (
|
|
697
|
+
node.body
|
|
698
|
+
if not isinstance(node.body, uni.FuncCall)
|
|
699
|
+
else None
|
|
700
|
+
)
|
|
904
701
|
),
|
|
905
702
|
doc=node.doc,
|
|
906
703
|
)
|
|
@@ -912,7 +709,11 @@ class PyastGenPass(UniPass):
|
|
|
912
709
|
f"Abstract ability {node.sym_name} should not have a body.",
|
|
913
710
|
node,
|
|
914
711
|
)
|
|
915
|
-
decorator_list =
|
|
712
|
+
decorator_list = (
|
|
713
|
+
[cast(ast3.expr, i.gen.py_ast[0]) for i in node.decorators]
|
|
714
|
+
if node.decorators
|
|
715
|
+
else []
|
|
716
|
+
)
|
|
916
717
|
if isinstance(node.signature, uni.EventSignature):
|
|
917
718
|
decorator_list.append(
|
|
918
719
|
self.jaclib_obj(
|
|
@@ -971,11 +772,7 @@ class PyastGenPass(UniPass):
|
|
|
971
772
|
),
|
|
972
773
|
body=[cast(ast3.stmt, i) for i in body],
|
|
973
774
|
decorator_list=[cast(ast3.expr, i) for i in decorator_list],
|
|
974
|
-
returns=(
|
|
975
|
-
cast(ast3.expr, node.signature.return_type.gen.py_ast[0])
|
|
976
|
-
if node.signature and node.signature.return_type
|
|
977
|
-
else self.sync(ast3.Constant(value=None))
|
|
978
|
-
),
|
|
775
|
+
returns=self.sync(ast3.Constant(value=None)),
|
|
979
776
|
type_params=[],
|
|
980
777
|
)
|
|
981
778
|
)
|
|
@@ -995,23 +792,18 @@ class PyastGenPass(UniPass):
|
|
|
995
792
|
)
|
|
996
793
|
vararg = None
|
|
997
794
|
kwarg = None
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
(
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
defaults = (
|
|
1011
|
-
[x.value.gen.py_ast[0] for x in node.params.items if x.value]
|
|
1012
|
-
if node.params
|
|
1013
|
-
else []
|
|
1014
|
-
)
|
|
795
|
+
for i in node.params:
|
|
796
|
+
if i.unpack and i.unpack.value == "*":
|
|
797
|
+
vararg = i.gen.py_ast[0]
|
|
798
|
+
elif i.unpack and i.unpack.value == "**":
|
|
799
|
+
kwarg = i.gen.py_ast[0]
|
|
800
|
+
else:
|
|
801
|
+
(
|
|
802
|
+
params.append(i.gen.py_ast[0])
|
|
803
|
+
if isinstance(i.gen.py_ast[0], ast3.arg)
|
|
804
|
+
else self.ice("This list should only be Args")
|
|
805
|
+
)
|
|
806
|
+
defaults = [x.value.gen.py_ast[0] for x in node.params if x.value]
|
|
1015
807
|
node.gen.py_ast = [
|
|
1016
808
|
self.sync(
|
|
1017
809
|
ast3.arguments(
|
|
@@ -1027,9 +819,10 @@ class PyastGenPass(UniPass):
|
|
|
1027
819
|
]
|
|
1028
820
|
|
|
1029
821
|
def exit_event_signature(self, node: uni.EventSignature) -> None:
|
|
1030
|
-
|
|
822
|
+
arch_kw = Con.HERE.value if node.from_walker else Con.VISITOR.value
|
|
823
|
+
arch_arg = self.sync(
|
|
1031
824
|
ast3.arg(
|
|
1032
|
-
arg=f"{
|
|
825
|
+
arg=f"{arch_kw}",
|
|
1033
826
|
annotation=(
|
|
1034
827
|
cast(ast3.expr, node.arch_tag_info.gen.py_ast[0])
|
|
1035
828
|
if node.arch_tag_info
|
|
@@ -1043,10 +836,10 @@ class PyastGenPass(UniPass):
|
|
|
1043
836
|
ast3.arguments(
|
|
1044
837
|
posonlyargs=[],
|
|
1045
838
|
args=(
|
|
1046
|
-
[self.sync(ast3.arg(arg="self", annotation=None)),
|
|
839
|
+
[self.sync(ast3.arg(arg="self", annotation=None)), arch_arg]
|
|
1047
840
|
if (abl := node.find_parent_of_type(uni.Ability))
|
|
1048
841
|
and abl.is_method
|
|
1049
|
-
else [
|
|
842
|
+
else [arch_arg]
|
|
1050
843
|
),
|
|
1051
844
|
kwonlyargs=[],
|
|
1052
845
|
vararg=None,
|
|
@@ -1090,43 +883,31 @@ class PyastGenPass(UniPass):
|
|
|
1090
883
|
]
|
|
1091
884
|
|
|
1092
885
|
def exit_arch_has(self, node: uni.ArchHas) -> None:
|
|
886
|
+
vars_py: list[ast3.AST] = self.flatten([v.gen.py_ast for v in node.vars])
|
|
1093
887
|
if node.doc:
|
|
1094
888
|
doc = self.sync(
|
|
1095
889
|
ast3.Expr(value=cast(ast3.expr, node.doc.gen.py_ast[0])),
|
|
1096
890
|
jac_node=node.doc,
|
|
1097
891
|
)
|
|
1098
|
-
if isinstance(doc, ast3.AST)
|
|
1099
|
-
node.gen.py_ast = [doc] +
|
|
892
|
+
if isinstance(doc, ast3.AST):
|
|
893
|
+
node.gen.py_ast = [doc] + vars_py
|
|
1100
894
|
else:
|
|
1101
895
|
raise self.ice()
|
|
1102
896
|
else:
|
|
1103
|
-
node.gen.py_ast =
|
|
897
|
+
node.gen.py_ast = vars_py
|
|
1104
898
|
|
|
1105
899
|
def exit_has_var(self, node: uni.HasVar) -> None:
|
|
1106
900
|
annotation = node.type_tag.gen.py_ast[0] if node.type_tag else None
|
|
1107
901
|
|
|
1108
902
|
is_static_var = (
|
|
1109
|
-
node.
|
|
1110
|
-
and
|
|
1111
|
-
and
|
|
1112
|
-
and node.parent.parent.is_static
|
|
903
|
+
(haspar := node.find_parent_of_type(uni.ArchHas))
|
|
904
|
+
and haspar
|
|
905
|
+
and haspar.is_static
|
|
1113
906
|
)
|
|
1114
|
-
|
|
1115
907
|
is_in_class = (
|
|
1116
|
-
node.
|
|
1117
|
-
and
|
|
1118
|
-
and
|
|
1119
|
-
and (
|
|
1120
|
-
(
|
|
1121
|
-
isinstance(node.parent.parent.parent, uni.Archetype)
|
|
1122
|
-
and node.parent.parent.parent.arch_type.name == Tok.KW_CLASS
|
|
1123
|
-
)
|
|
1124
|
-
or (
|
|
1125
|
-
node.parent.parent.parent.parent
|
|
1126
|
-
and isinstance(node.parent.parent.parent.parent, uni.Archetype)
|
|
1127
|
-
and node.parent.parent.parent.parent.arch_type.name == Tok.KW_CLASS
|
|
1128
|
-
)
|
|
1129
|
-
)
|
|
908
|
+
(archpar := node.find_parent_of_type(uni.Archetype))
|
|
909
|
+
and archpar
|
|
910
|
+
and archpar.arch_type.name == Tok.KW_CLASS
|
|
1130
911
|
)
|
|
1131
912
|
|
|
1132
913
|
value = None
|
|
@@ -1313,11 +1094,9 @@ class PyastGenPass(UniPass):
|
|
|
1313
1094
|
self.sync(
|
|
1314
1095
|
ast3.Try(
|
|
1315
1096
|
body=cast(list[ast3.stmt], self.resolve_stmt_block(node.body)),
|
|
1316
|
-
handlers=
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
else []
|
|
1320
|
-
),
|
|
1097
|
+
handlers=[
|
|
1098
|
+
cast(ast3.ExceptHandler, i.gen.py_ast[0]) for i in node.excepts
|
|
1099
|
+
],
|
|
1321
1100
|
orelse=(
|
|
1322
1101
|
[cast(ast3.stmt, i) for i in node.else_body.gen.py_ast]
|
|
1323
1102
|
if node.else_body
|
|
@@ -1355,7 +1134,7 @@ class PyastGenPass(UniPass):
|
|
|
1355
1134
|
|
|
1356
1135
|
def exit_iter_for_stmt(self, node: uni.IterForStmt) -> None:
|
|
1357
1136
|
py_nodes: list[ast3.AST] = []
|
|
1358
|
-
body = node.body
|
|
1137
|
+
body = self.resolve_stmt_block(node.body)
|
|
1359
1138
|
if (
|
|
1360
1139
|
isinstance(body, list)
|
|
1361
1140
|
and isinstance(node.count_by.gen.py_ast[0], ast3.AST)
|
|
@@ -1419,7 +1198,9 @@ class PyastGenPass(UniPass):
|
|
|
1419
1198
|
node.gen.py_ast = [
|
|
1420
1199
|
self.sync(
|
|
1421
1200
|
with_node(
|
|
1422
|
-
items=[
|
|
1201
|
+
items=[
|
|
1202
|
+
cast(ast3.withitem, item.gen.py_ast[0]) for item in node.exprs
|
|
1203
|
+
],
|
|
1423
1204
|
body=[
|
|
1424
1205
|
cast(ast3.stmt, stmt)
|
|
1425
1206
|
for stmt in self.resolve_stmt_block(node.body)
|
|
@@ -1510,13 +1291,11 @@ class PyastGenPass(UniPass):
|
|
|
1510
1291
|
node: uni.FuncCall,
|
|
1511
1292
|
) -> CheckNodeIsinstanceCallResult:
|
|
1512
1293
|
|
|
1513
|
-
# Ensure the
|
|
1514
|
-
# since the type can be: Optional[SubNodeList[Expr | KWPair]].
|
|
1294
|
+
# Ensure the func call has exactly two expression parameters
|
|
1515
1295
|
if not (
|
|
1516
|
-
node.params
|
|
1517
|
-
and
|
|
1518
|
-
and isinstance(node.params
|
|
1519
|
-
and isinstance(node.params.items[1], uni.Expr)
|
|
1296
|
+
len(node.params) == 2
|
|
1297
|
+
and isinstance(node.params[0], uni.Expr)
|
|
1298
|
+
and isinstance(node.params[1], uni.Expr)
|
|
1520
1299
|
):
|
|
1521
1300
|
return CheckNodeIsinstanceCallResult()
|
|
1522
1301
|
|
|
@@ -1526,8 +1305,8 @@ class PyastGenPass(UniPass):
|
|
|
1526
1305
|
|
|
1527
1306
|
return CheckNodeIsinstanceCallResult(
|
|
1528
1307
|
True,
|
|
1529
|
-
node.params
|
|
1530
|
-
node.params
|
|
1308
|
+
node.params[0].gen.py_ast[0],
|
|
1309
|
+
node.params[1].gen.py_ast[0],
|
|
1531
1310
|
)
|
|
1532
1311
|
|
|
1533
1312
|
# By default the check expression will become assertTrue(<expr>), unless any pattern detected.
|
|
@@ -1613,9 +1392,8 @@ class PyastGenPass(UniPass):
|
|
|
1613
1392
|
if isinstance(func, uni.Name) and func.value == "almostEqual":
|
|
1614
1393
|
assert_func_name = "assertAlmostEqual"
|
|
1615
1394
|
assert_args_list = []
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
assert_args_list.append(param.gen.py_ast[0])
|
|
1395
|
+
for param in node.target.params:
|
|
1396
|
+
assert_args_list.append(param.gen.py_ast[0])
|
|
1619
1397
|
|
|
1620
1398
|
# assert_func_expr = "Con.JAC_CHECK.value.assertXXX"
|
|
1621
1399
|
assert_func_expr: ast3.Attribute = self.sync(
|
|
@@ -1746,7 +1524,7 @@ class PyastGenPass(UniPass):
|
|
|
1746
1524
|
walker = self.sync(
|
|
1747
1525
|
ast3.Name(id="self", ctx=ast3.Load())
|
|
1748
1526
|
if node.from_walker
|
|
1749
|
-
else ast3.Name(id=Con.
|
|
1527
|
+
else ast3.Name(id=Con.VISITOR.value, ctx=ast3.Load())
|
|
1750
1528
|
)
|
|
1751
1529
|
|
|
1752
1530
|
node.gen.py_ast = [
|
|
@@ -1769,7 +1547,7 @@ class PyastGenPass(UniPass):
|
|
|
1769
1547
|
loc = self.sync(
|
|
1770
1548
|
ast3.Name(id="self", ctx=ast3.Load())
|
|
1771
1549
|
if node.from_walker
|
|
1772
|
-
else ast3.Name(id=Con.
|
|
1550
|
+
else ast3.Name(id=Con.VISITOR.value, ctx=ast3.Load())
|
|
1773
1551
|
)
|
|
1774
1552
|
|
|
1775
1553
|
visit_call = self.sync(
|
|
@@ -1780,6 +1558,16 @@ class PyastGenPass(UniPass):
|
|
|
1780
1558
|
)
|
|
1781
1559
|
)
|
|
1782
1560
|
|
|
1561
|
+
if node.insert_loc is not None:
|
|
1562
|
+
visit_call.keywords.append(
|
|
1563
|
+
self.sync(
|
|
1564
|
+
ast3.keyword(
|
|
1565
|
+
arg="insert_loc",
|
|
1566
|
+
value=cast(ast3.expr, node.insert_loc.gen.py_ast[0]),
|
|
1567
|
+
)
|
|
1568
|
+
)
|
|
1569
|
+
)
|
|
1570
|
+
|
|
1783
1571
|
node.gen.py_ast = [
|
|
1784
1572
|
(
|
|
1785
1573
|
self.sync(
|
|
@@ -1803,7 +1591,7 @@ class PyastGenPass(UniPass):
|
|
|
1803
1591
|
loc = self.sync(
|
|
1804
1592
|
ast3.Name(id="self", ctx=ast3.Load())
|
|
1805
1593
|
if node.from_walker
|
|
1806
|
-
else ast3.Name(id=Con.
|
|
1594
|
+
else ast3.Name(id=Con.VISITOR.value, ctx=ast3.Load())
|
|
1807
1595
|
)
|
|
1808
1596
|
node.gen.py_ast = [
|
|
1809
1597
|
self.sync(
|
|
@@ -1821,29 +1609,13 @@ class PyastGenPass(UniPass):
|
|
|
1821
1609
|
]
|
|
1822
1610
|
|
|
1823
1611
|
def exit_await_expr(self, node: uni.AwaitExpr) -> None:
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
node.gen.py_ast = [
|
|
1828
|
-
self.sync(
|
|
1829
|
-
ast3.Await(value=cast(ast3.expr, node.target.gen.py_ast[0]))
|
|
1830
|
-
)
|
|
1831
|
-
]
|
|
1832
|
-
break
|
|
1833
|
-
else:
|
|
1834
|
-
node.gen.py_ast = [
|
|
1835
|
-
self.sync(
|
|
1836
|
-
ast3.Call(
|
|
1837
|
-
func=self.jaclib_obj("await_obj"),
|
|
1838
|
-
args=[cast(ast3.expr, node.target.gen.py_ast[0])],
|
|
1839
|
-
keywords=[],
|
|
1840
|
-
)
|
|
1841
|
-
)
|
|
1842
|
-
]
|
|
1612
|
+
node.gen.py_ast = [
|
|
1613
|
+
self.sync(ast3.Await(value=cast(ast3.expr, node.target.gen.py_ast[0])))
|
|
1614
|
+
]
|
|
1843
1615
|
|
|
1844
1616
|
def exit_global_stmt(self, node: uni.GlobalStmt) -> None:
|
|
1845
1617
|
py_nodes = []
|
|
1846
|
-
for x in node.target
|
|
1618
|
+
for x in node.target:
|
|
1847
1619
|
py_nodes.append(
|
|
1848
1620
|
self.sync(
|
|
1849
1621
|
ast3.Global(names=[x.sym_name]),
|
|
@@ -1854,7 +1626,7 @@ class PyastGenPass(UniPass):
|
|
|
1854
1626
|
|
|
1855
1627
|
def exit_non_local_stmt(self, node: uni.NonLocalStmt) -> None:
|
|
1856
1628
|
py_nodes = []
|
|
1857
|
-
for x in node.target
|
|
1629
|
+
for x in node.target:
|
|
1858
1630
|
py_nodes.append(
|
|
1859
1631
|
self.sync(
|
|
1860
1632
|
ast3.Nonlocal(names=[x.sym_name]),
|
|
@@ -1879,18 +1651,20 @@ class PyastGenPass(UniPass):
|
|
|
1879
1651
|
else None if node.type_tag else self.ice()
|
|
1880
1652
|
)
|
|
1881
1653
|
)
|
|
1654
|
+
targets_ast = [cast(ast3.expr, t.gen.py_ast[0]) for t in node.target]
|
|
1655
|
+
|
|
1882
1656
|
if node.type_tag:
|
|
1883
1657
|
node.gen.py_ast = [
|
|
1884
1658
|
self.sync(
|
|
1885
1659
|
ast3.AnnAssign(
|
|
1886
|
-
target=cast(ast3.Name,
|
|
1660
|
+
target=cast(ast3.Name, targets_ast[0]),
|
|
1887
1661
|
annotation=cast(ast3.expr, node.type_tag.gen.py_ast[0]),
|
|
1888
1662
|
value=(
|
|
1889
1663
|
cast(ast3.expr, node.value.gen.py_ast[0])
|
|
1890
1664
|
if node.value
|
|
1891
1665
|
else None
|
|
1892
1666
|
),
|
|
1893
|
-
simple=int(isinstance(
|
|
1667
|
+
simple=int(isinstance(targets_ast[0], ast3.Name)),
|
|
1894
1668
|
)
|
|
1895
1669
|
)
|
|
1896
1670
|
]
|
|
@@ -1898,7 +1672,7 @@ class PyastGenPass(UniPass):
|
|
|
1898
1672
|
node.gen.py_ast = [
|
|
1899
1673
|
self.sync(
|
|
1900
1674
|
ast3.AugAssign(
|
|
1901
|
-
target=cast(ast3.Name,
|
|
1675
|
+
target=cast(ast3.Name, targets_ast[0]),
|
|
1902
1676
|
op=cast(ast3.operator, node.aug_op.gen.py_ast[0]),
|
|
1903
1677
|
value=(
|
|
1904
1678
|
cast(ast3.expr, value)
|
|
@@ -1912,7 +1686,7 @@ class PyastGenPass(UniPass):
|
|
|
1912
1686
|
node.gen.py_ast = [
|
|
1913
1687
|
self.sync(
|
|
1914
1688
|
ast3.Assign(
|
|
1915
|
-
targets=cast(list[ast3.expr],
|
|
1689
|
+
targets=cast(list[ast3.expr], targets_ast),
|
|
1916
1690
|
value=(
|
|
1917
1691
|
cast(ast3.expr, value)
|
|
1918
1692
|
if isinstance(value, ast3.expr)
|
|
@@ -2078,11 +1852,9 @@ class PyastGenPass(UniPass):
|
|
|
2078
1852
|
func_node = uni.FuncCall(
|
|
2079
1853
|
target=node.right,
|
|
2080
1854
|
params=(
|
|
2081
|
-
node.left.values
|
|
2082
|
-
if isinstance(node.left, uni.TupleVal)
|
|
2083
|
-
else
|
|
2084
|
-
items=[node.left], delim=Tok.COMMA, kid=[node.left]
|
|
2085
|
-
)
|
|
1855
|
+
list(node.left.values)
|
|
1856
|
+
if isinstance(node.left, uni.TupleVal) and node.left.values
|
|
1857
|
+
else [node.left]
|
|
2086
1858
|
),
|
|
2087
1859
|
genai_call=None,
|
|
2088
1860
|
kid=node.kid,
|
|
@@ -2110,11 +1882,9 @@ class PyastGenPass(UniPass):
|
|
|
2110
1882
|
func_node = uni.FuncCall(
|
|
2111
1883
|
target=node.left,
|
|
2112
1884
|
params=(
|
|
2113
|
-
node.right.values
|
|
2114
|
-
if isinstance(node.right, uni.TupleVal)
|
|
2115
|
-
else
|
|
2116
|
-
items=[node.right], delim=Tok.COMMA, kid=[node.right]
|
|
2117
|
-
)
|
|
1885
|
+
list(node.right.values)
|
|
1886
|
+
if isinstance(node.right, uni.TupleVal) and node.right.values
|
|
1887
|
+
else [node.right]
|
|
2118
1888
|
),
|
|
2119
1889
|
genai_call=None,
|
|
2120
1890
|
kid=node.kid,
|
|
@@ -2174,42 +1944,17 @@ class PyastGenPass(UniPass):
|
|
|
2174
1944
|
]
|
|
2175
1945
|
|
|
2176
1946
|
def exit_unary_expr(self, node: uni.UnaryExpr) -> None:
|
|
2177
|
-
|
|
1947
|
+
op_cls = UNARY_OP_MAP.get(node.op.name)
|
|
1948
|
+
if op_cls:
|
|
2178
1949
|
node.gen.py_ast = [
|
|
2179
1950
|
self.sync(
|
|
2180
1951
|
ast3.UnaryOp(
|
|
2181
|
-
op=self.sync(
|
|
2182
|
-
operand=cast(ast3.expr, node.operand.gen.py_ast[0]),
|
|
2183
|
-
)
|
|
2184
|
-
)
|
|
2185
|
-
]
|
|
2186
|
-
elif node.op.name == Tok.BW_NOT:
|
|
2187
|
-
node.gen.py_ast = [
|
|
2188
|
-
self.sync(
|
|
2189
|
-
ast3.UnaryOp(
|
|
2190
|
-
op=self.sync(ast3.Invert()),
|
|
2191
|
-
operand=cast(ast3.expr, node.operand.gen.py_ast[0]),
|
|
2192
|
-
)
|
|
2193
|
-
)
|
|
2194
|
-
]
|
|
2195
|
-
elif node.op.name == Tok.PLUS:
|
|
2196
|
-
node.gen.py_ast = [
|
|
2197
|
-
self.sync(
|
|
2198
|
-
ast3.UnaryOp(
|
|
2199
|
-
op=self.sync(ast3.UAdd()),
|
|
2200
|
-
operand=cast(ast3.expr, node.operand.gen.py_ast[0]),
|
|
2201
|
-
)
|
|
2202
|
-
)
|
|
2203
|
-
]
|
|
2204
|
-
elif node.op.name == Tok.MINUS:
|
|
2205
|
-
node.gen.py_ast = [
|
|
2206
|
-
self.sync(
|
|
2207
|
-
ast3.UnaryOp(
|
|
2208
|
-
op=self.sync(ast3.USub()),
|
|
1952
|
+
op=self.sync(op_cls()),
|
|
2209
1953
|
operand=cast(ast3.expr, node.operand.gen.py_ast[0]),
|
|
2210
1954
|
)
|
|
2211
1955
|
)
|
|
2212
1956
|
]
|
|
1957
|
+
return
|
|
2213
1958
|
elif node.op.name in [Tok.PIPE_FWD, Tok.KW_SPAWN, Tok.A_PIPE_FWD]:
|
|
2214
1959
|
node.gen.py_ast = [
|
|
2215
1960
|
self.sync(
|
|
@@ -2274,9 +2019,11 @@ class PyastGenPass(UniPass):
|
|
|
2274
2019
|
if isinstance(i, uni.String):
|
|
2275
2020
|
pieces.append(i.lit_value)
|
|
2276
2021
|
elif isinstance(i, uni.FString):
|
|
2277
|
-
pieces.extend(get_pieces(i.parts
|
|
2022
|
+
pieces.extend(get_pieces(i.parts)) if i.parts else None
|
|
2278
2023
|
elif isinstance(i, uni.ExprStmt):
|
|
2279
2024
|
pieces.append(i.gen.py_ast[0])
|
|
2025
|
+
elif isinstance(i, uni.Token) and i.name in [Tok.LBRACE, Tok.RBRACE]:
|
|
2026
|
+
continue
|
|
2280
2027
|
else:
|
|
2281
2028
|
raise self.ice("Multi string made of something weird.")
|
|
2282
2029
|
return pieces
|
|
@@ -2313,62 +2060,30 @@ class PyastGenPass(UniPass):
|
|
|
2313
2060
|
node.gen.py_ast = [combined_multi[0]]
|
|
2314
2061
|
|
|
2315
2062
|
def exit_f_string(self, node: uni.FString) -> None:
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
)
|
|
2063
|
+
py_parts: list[list[ast3.AST]] = [
|
|
2064
|
+
cast(list[ast3.AST], p.gen.py_ast) for p in node.parts
|
|
2065
|
+
]
|
|
2066
|
+
parts = self.flatten(cast(list[list[ast3.AST] | ast3.AST | None], py_parts))
|
|
2067
|
+
node.gen.py_ast = parts if parts else [self.sync(ast3.Constant(value=""))]
|
|
2321
2068
|
|
|
2322
2069
|
def exit_list_val(self, node: uni.ListVal) -> None:
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
else []
|
|
2331
|
-
),
|
|
2332
|
-
ctx=ast3.Load(),
|
|
2333
|
-
)
|
|
2334
|
-
)
|
|
2335
|
-
]
|
|
2336
|
-
else:
|
|
2337
|
-
node.gen.py_ast = [
|
|
2338
|
-
self.sync(
|
|
2339
|
-
ast3.List(
|
|
2340
|
-
elts=(
|
|
2341
|
-
[cast(ast3.expr, item) for item in node.values.gen.py_ast]
|
|
2342
|
-
if node.values and node.values.gen.py_ast
|
|
2343
|
-
else []
|
|
2344
|
-
),
|
|
2345
|
-
ctx=cast(ast3.expr_context, node.py_ctx_func()),
|
|
2346
|
-
)
|
|
2347
|
-
)
|
|
2348
|
-
]
|
|
2070
|
+
elts = [cast(ast3.expr, v.gen.py_ast[0]) for v in node.values]
|
|
2071
|
+
ctx = (
|
|
2072
|
+
ast3.Load()
|
|
2073
|
+
if isinstance(node.py_ctx_func(), ast3.Load)
|
|
2074
|
+
else cast(ast3.expr_context, node.py_ctx_func())
|
|
2075
|
+
)
|
|
2076
|
+
node.gen.py_ast = [self.sync(ast3.List(elts=elts, ctx=ctx))]
|
|
2349
2077
|
|
|
2350
2078
|
def exit_set_val(self, node: uni.SetVal) -> None:
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
ast3.Set(
|
|
2354
|
-
elts=(
|
|
2355
|
-
[cast(ast3.expr, i) for i in node.values.gen.py_ast]
|
|
2356
|
-
if node.values
|
|
2357
|
-
else []
|
|
2358
|
-
),
|
|
2359
|
-
)
|
|
2360
|
-
)
|
|
2361
|
-
]
|
|
2079
|
+
elts = [cast(ast3.expr, i.gen.py_ast[0]) for i in node.values]
|
|
2080
|
+
node.gen.py_ast = [self.sync(ast3.Set(elts=elts))]
|
|
2362
2081
|
|
|
2363
2082
|
def exit_tuple_val(self, node: uni.TupleVal) -> None:
|
|
2364
2083
|
node.gen.py_ast = [
|
|
2365
2084
|
self.sync(
|
|
2366
2085
|
ast3.Tuple(
|
|
2367
|
-
elts=(
|
|
2368
|
-
cast(list[ast3.expr], node.values.gen.py_ast)
|
|
2369
|
-
if node.values
|
|
2370
|
-
else []
|
|
2371
|
-
),
|
|
2086
|
+
elts=[cast(ast3.expr, i.gen.py_ast[0]) for i in node.values],
|
|
2372
2087
|
ctx=cast(ast3.expr_context, node.py_ctx_func()),
|
|
2373
2088
|
)
|
|
2374
2089
|
)
|
|
@@ -2597,12 +2312,14 @@ class PyastGenPass(UniPass):
|
|
|
2597
2312
|
|
|
2598
2313
|
return JacMachineInterface.get_by_llm_call_args(self, node)
|
|
2599
2314
|
|
|
2600
|
-
def
|
|
2601
|
-
|
|
2315
|
+
def gen_call_args(
|
|
2316
|
+
self, node: uni.FuncCall
|
|
2317
|
+
) -> tuple[list[ast3.expr], list[ast3.keyword]]:
|
|
2318
|
+
"""Generate the arguments for a function call."""
|
|
2602
2319
|
args = []
|
|
2603
2320
|
keywords = []
|
|
2604
|
-
if node.params
|
|
2605
|
-
for x in node.params
|
|
2321
|
+
if node.params:
|
|
2322
|
+
for x in node.params:
|
|
2606
2323
|
if isinstance(x, uni.UnaryExpr) and x.op.name == Tok.STAR_POW:
|
|
2607
2324
|
keywords.append(
|
|
2608
2325
|
self.sync(
|
|
@@ -2620,10 +2337,21 @@ class PyastGenPass(UniPass):
|
|
|
2620
2337
|
keywords.append(x.gen.py_ast[0])
|
|
2621
2338
|
else:
|
|
2622
2339
|
self.ice("Invalid Parameter")
|
|
2623
|
-
|
|
2340
|
+
return args, keywords
|
|
2341
|
+
|
|
2342
|
+
def exit_func_call(self, node: uni.FuncCall) -> None:
|
|
2343
|
+
if node.body_genai_call:
|
|
2344
|
+
node.gen.py_ast = self.gen_llm_call_override(node)
|
|
2345
|
+
|
|
2346
|
+
# TODO: This needs to be changed to only generate parameters no the body.
|
|
2347
|
+
elif node.genai_call:
|
|
2624
2348
|
by_llm_call_args = self.get_by_llm_call_args(node)
|
|
2625
2349
|
node.gen.py_ast = [self.sync(self.by_llm_call(**by_llm_call_args))]
|
|
2350
|
+
|
|
2626
2351
|
else:
|
|
2352
|
+
func = node.target.gen.py_ast[0]
|
|
2353
|
+
args, keywords = self.gen_call_args(node)
|
|
2354
|
+
|
|
2627
2355
|
node.gen.py_ast = [
|
|
2628
2356
|
self.sync(
|
|
2629
2357
|
ast3.Call(
|
|
@@ -2723,135 +2451,115 @@ class PyastGenPass(UniPass):
|
|
|
2723
2451
|
]
|
|
2724
2452
|
|
|
2725
2453
|
def exit_edge_ref_trailer(self, node: uni.EdgeRefTrailer) -> None:
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
for i in node.chain:
|
|
2731
|
-
if isinstance(i, uni.EdgeOpRef):
|
|
2732
|
-
last_edge = i
|
|
2733
|
-
while len(chomp):
|
|
2734
|
-
cur = chomp[0]
|
|
2735
|
-
chomp = chomp[1:]
|
|
2736
|
-
if len(chomp) == len(node.chain) - 1 and not isinstance(cur, uni.EdgeOpRef):
|
|
2737
|
-
continue
|
|
2738
|
-
next_i = chomp[0] if chomp else None
|
|
2739
|
-
if isinstance(cur, uni.EdgeOpRef) and (
|
|
2740
|
-
not next_i or not isinstance(next_i, uni.EdgeOpRef)
|
|
2741
|
-
):
|
|
2742
|
-
pynode = self.translate_edge_op_ref(
|
|
2743
|
-
loc=pynode,
|
|
2744
|
-
node=cur,
|
|
2745
|
-
targ=(
|
|
2746
|
-
next_i.gen.py_ast[0]
|
|
2747
|
-
if next_i and not isinstance(next_i, uni.FilterCompr)
|
|
2748
|
-
else None
|
|
2749
|
-
),
|
|
2750
|
-
edges_only=node.edges_only and cur == last_edge,
|
|
2751
|
-
)
|
|
2752
|
-
if next_i and isinstance(next_i, uni.FilterCompr):
|
|
2753
|
-
pynode = self.sync(
|
|
2754
|
-
ast3.Call(
|
|
2755
|
-
func=self.jaclib_obj("filter"),
|
|
2756
|
-
args=[],
|
|
2757
|
-
keywords=[
|
|
2758
|
-
self.sync(
|
|
2759
|
-
ast3.keyword(
|
|
2760
|
-
arg="items",
|
|
2761
|
-
value=cast(ast3.expr, pynode),
|
|
2762
|
-
)
|
|
2763
|
-
),
|
|
2764
|
-
self.sync(
|
|
2765
|
-
ast3.keyword(
|
|
2766
|
-
arg="func",
|
|
2767
|
-
value=cast(ast3.expr, next_i.gen.py_ast[0]),
|
|
2768
|
-
)
|
|
2769
|
-
),
|
|
2770
|
-
],
|
|
2771
|
-
)
|
|
2772
|
-
)
|
|
2773
|
-
chomp = chomp[1:] if next_i else chomp
|
|
2774
|
-
elif isinstance(cur, uni.EdgeOpRef) and isinstance(next_i, uni.EdgeOpRef):
|
|
2775
|
-
pynode = self.translate_edge_op_ref(
|
|
2776
|
-
pynode,
|
|
2777
|
-
cur,
|
|
2778
|
-
targ=None,
|
|
2779
|
-
edges_only=node.edges_only and cur == last_edge,
|
|
2780
|
-
)
|
|
2781
|
-
else:
|
|
2782
|
-
raise self.ice("Invalid edge ref trailer")
|
|
2454
|
+
origin = None
|
|
2455
|
+
cur = node.chain[0]
|
|
2456
|
+
chomp = [*node.chain[1:]]
|
|
2457
|
+
from_visit = bool(isinstance(node.parent, uni.VisitStmt))
|
|
2783
2458
|
|
|
2784
|
-
|
|
2459
|
+
if not isinstance(cur, uni.EdgeOpRef):
|
|
2460
|
+
origin = cur.gen.py_ast[0]
|
|
2461
|
+
cur = cast(uni.EdgeOpRef, chomp.pop(0))
|
|
2785
2462
|
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2463
|
+
pynode = self.sync(
|
|
2464
|
+
ast3.Call(
|
|
2465
|
+
func=self.jaclib_obj("Path"),
|
|
2466
|
+
args=[cast(ast3.expr, origin or cur.gen.py_ast[0])],
|
|
2467
|
+
keywords=[],
|
|
2468
|
+
)
|
|
2791
2469
|
)
|
|
2792
|
-
node.gen.py_ast = [loc]
|
|
2793
2470
|
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
)
|
|
2471
|
+
while True:
|
|
2472
|
+
keywords = []
|
|
2473
|
+
if cur.filter_cond:
|
|
2474
|
+
keywords.append(
|
|
2475
|
+
self.sync(
|
|
2476
|
+
ast3.keyword(
|
|
2477
|
+
arg="edge",
|
|
2478
|
+
value=cast(
|
|
2479
|
+
ast3.expr, self.sync(cur.filter_cond.gen.py_ast[0])
|
|
2480
|
+
),
|
|
2481
|
+
)
|
|
2482
|
+
)
|
|
2483
|
+
)
|
|
2808
2484
|
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
ast3.
|
|
2816
|
-
|
|
2817
|
-
attr=node.edge_dir.name,
|
|
2818
|
-
ctx=ast3.Load(),
|
|
2819
|
-
)
|
|
2820
|
-
),
|
|
2485
|
+
if chomp and not isinstance(chomp[0], uni.EdgeOpRef):
|
|
2486
|
+
filt = chomp.pop(0)
|
|
2487
|
+
keywords.append(
|
|
2488
|
+
self.sync(
|
|
2489
|
+
ast3.keyword(
|
|
2490
|
+
arg="node",
|
|
2491
|
+
value=cast(ast3.expr, self.sync(filt.gen.py_ast[0])),
|
|
2492
|
+
)
|
|
2821
2493
|
)
|
|
2822
2494
|
)
|
|
2495
|
+
|
|
2496
|
+
pynode = self.sync(
|
|
2497
|
+
ast3.Call(
|
|
2498
|
+
func=self.sync(
|
|
2499
|
+
ast3.Attribute(
|
|
2500
|
+
value=pynode,
|
|
2501
|
+
attr=f"_{cur.edge_dir.name.lower()}",
|
|
2502
|
+
ctx=ast3.Load(),
|
|
2503
|
+
)
|
|
2504
|
+
),
|
|
2505
|
+
args=[],
|
|
2506
|
+
keywords=keywords,
|
|
2507
|
+
)
|
|
2823
2508
|
)
|
|
2824
2509
|
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2510
|
+
if chomp:
|
|
2511
|
+
cur = cast(uni.EdgeOpRef, chomp.pop(0))
|
|
2512
|
+
else:
|
|
2513
|
+
break
|
|
2514
|
+
|
|
2515
|
+
if node.edges_only:
|
|
2516
|
+
pynode = self.sync(
|
|
2517
|
+
ast3.Call(
|
|
2518
|
+
func=self.sync(
|
|
2519
|
+
ast3.Attribute(
|
|
2520
|
+
value=pynode,
|
|
2521
|
+
attr="edge",
|
|
2522
|
+
ctx=ast3.Load(),
|
|
2523
|
+
)
|
|
2524
|
+
),
|
|
2525
|
+
args=[],
|
|
2526
|
+
keywords=[],
|
|
2834
2527
|
)
|
|
2835
2528
|
)
|
|
2836
2529
|
|
|
2837
|
-
if
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2530
|
+
if from_visit:
|
|
2531
|
+
pynode = self.sync(
|
|
2532
|
+
ast3.Call(
|
|
2533
|
+
func=self.sync(
|
|
2534
|
+
ast3.Attribute(
|
|
2535
|
+
value=pynode,
|
|
2536
|
+
attr="visit",
|
|
2537
|
+
ctx=ast3.Load(),
|
|
2538
|
+
)
|
|
2539
|
+
),
|
|
2540
|
+
args=[],
|
|
2541
|
+
keywords=[],
|
|
2844
2542
|
)
|
|
2845
2543
|
)
|
|
2846
2544
|
|
|
2847
|
-
|
|
2545
|
+
pynode = self.sync(
|
|
2848
2546
|
ast3.Call(
|
|
2849
2547
|
func=self.jaclib_obj("refs"),
|
|
2850
|
-
args=[],
|
|
2851
|
-
keywords=
|
|
2548
|
+
args=[pynode],
|
|
2549
|
+
keywords=[],
|
|
2852
2550
|
)
|
|
2853
2551
|
)
|
|
2854
2552
|
|
|
2553
|
+
node.gen.py_ast = [pynode]
|
|
2554
|
+
|
|
2555
|
+
def exit_edge_op_ref(self, node: uni.EdgeOpRef) -> None:
|
|
2556
|
+
loc = self.sync(
|
|
2557
|
+
ast3.Name(id=Con.HERE.value, ctx=ast3.Load())
|
|
2558
|
+
if node.from_walker
|
|
2559
|
+
else ast3.Name(id="self", ctx=ast3.Load())
|
|
2560
|
+
)
|
|
2561
|
+
node.gen.py_ast = [loc]
|
|
2562
|
+
|
|
2855
2563
|
def exit_disconnect_op(self, node: uni.DisconnectOp) -> None:
|
|
2856
2564
|
node.gen.py_ast = node.edge_spec.gen.py_ast
|
|
2857
2565
|
|
|
@@ -2949,7 +2657,7 @@ class PyastGenPass(UniPass):
|
|
|
2949
2657
|
),
|
|
2950
2658
|
jac_node=x,
|
|
2951
2659
|
)
|
|
2952
|
-
for x in
|
|
2660
|
+
for x in node.compares
|
|
2953
2661
|
if isinstance(x.gen.py_ast[0], ast3.Compare)
|
|
2954
2662
|
and isinstance(x.gen.py_ast[0].left, ast3.Name)
|
|
2955
2663
|
)
|
|
@@ -2984,7 +2692,7 @@ class PyastGenPass(UniPass):
|
|
|
2984
2692
|
def exit_assign_compr(self, node: uni.AssignCompr) -> None:
|
|
2985
2693
|
keys = []
|
|
2986
2694
|
values = []
|
|
2987
|
-
for i in node.assigns
|
|
2695
|
+
for i in node.assigns:
|
|
2988
2696
|
if i.key: # TODO: add support for **kwargs in assign_compr
|
|
2989
2697
|
keys.append(self.sync(ast3.Constant(i.key.sym_name)))
|
|
2990
2698
|
values.append(i.value.gen.py_ast[0])
|
|
@@ -3099,92 +2807,27 @@ class PyastGenPass(UniPass):
|
|
|
3099
2807
|
self.sync(
|
|
3100
2808
|
ast3.MatchClass(
|
|
3101
2809
|
cls=cast(ast3.expr, node.name.gen.py_ast[0]),
|
|
3102
|
-
patterns=
|
|
3103
|
-
[
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
]
|
|
3116
|
-
if node.kw_patterns
|
|
3117
|
-
else []
|
|
3118
|
-
),
|
|
3119
|
-
kwd_patterns=(
|
|
3120
|
-
[
|
|
3121
|
-
cast(ast3.pattern, x.value.gen.py_ast[0])
|
|
3122
|
-
for x in node.kw_patterns.items
|
|
3123
|
-
]
|
|
3124
|
-
if node.kw_patterns
|
|
3125
|
-
else []
|
|
3126
|
-
),
|
|
2810
|
+
patterns=[
|
|
2811
|
+
cast(ast3.pattern, x.gen.py_ast[0])
|
|
2812
|
+
for x in (node.arg_patterns or [])
|
|
2813
|
+
],
|
|
2814
|
+
kwd_attrs=[
|
|
2815
|
+
x.key.sym_name
|
|
2816
|
+
for x in (node.kw_patterns or [])
|
|
2817
|
+
if isinstance(x.key, uni.NameAtom)
|
|
2818
|
+
],
|
|
2819
|
+
kwd_patterns=[
|
|
2820
|
+
cast(ast3.pattern, x.value.gen.py_ast[0])
|
|
2821
|
+
for x in (node.kw_patterns or [])
|
|
2822
|
+
],
|
|
3127
2823
|
)
|
|
3128
2824
|
)
|
|
3129
2825
|
]
|
|
3130
2826
|
|
|
3131
2827
|
def exit_token(self, node: uni.Token) -> None:
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
node.gen.py_ast = [self.sync(ast3.Or())]
|
|
3136
|
-
elif node.name in [Tok.PLUS, Tok.ADD_EQ]:
|
|
3137
|
-
node.gen.py_ast = [self.sync(ast3.Add())]
|
|
3138
|
-
elif node.name in [Tok.BW_AND, Tok.BW_AND_EQ]:
|
|
3139
|
-
node.gen.py_ast = [self.sync(ast3.BitAnd())]
|
|
3140
|
-
elif node.name in [Tok.BW_OR, Tok.BW_OR_EQ]:
|
|
3141
|
-
node.gen.py_ast = [self.sync(ast3.BitOr())]
|
|
3142
|
-
elif node.name in [Tok.BW_XOR, Tok.BW_XOR_EQ]:
|
|
3143
|
-
node.gen.py_ast = [self.sync(ast3.BitXor())]
|
|
3144
|
-
elif node.name in [Tok.DIV, Tok.DIV_EQ]:
|
|
3145
|
-
node.gen.py_ast = [self.sync(ast3.Div())]
|
|
3146
|
-
elif node.name in [Tok.FLOOR_DIV, Tok.FLOOR_DIV_EQ]:
|
|
3147
|
-
node.gen.py_ast = [self.sync(ast3.FloorDiv())]
|
|
3148
|
-
elif node.name in [Tok.LSHIFT, Tok.LSHIFT_EQ]:
|
|
3149
|
-
node.gen.py_ast = [self.sync(ast3.LShift())]
|
|
3150
|
-
elif node.name in [Tok.MOD, Tok.MOD_EQ]:
|
|
3151
|
-
node.gen.py_ast = [self.sync(ast3.Mod())]
|
|
3152
|
-
elif node.name in [Tok.STAR_MUL, Tok.MUL_EQ]:
|
|
3153
|
-
node.gen.py_ast = [self.sync(ast3.Mult())]
|
|
3154
|
-
elif node.name in [Tok.DECOR_OP, Tok.MATMUL_EQ]:
|
|
3155
|
-
node.gen.py_ast = [self.sync(ast3.MatMult())]
|
|
3156
|
-
elif node.name in [Tok.STAR_POW, Tok.STAR_POW_EQ]:
|
|
3157
|
-
node.gen.py_ast = [self.sync(ast3.Pow())]
|
|
3158
|
-
elif node.name in [Tok.RSHIFT, Tok.RSHIFT_EQ]:
|
|
3159
|
-
node.gen.py_ast = [self.sync(ast3.RShift())]
|
|
3160
|
-
elif node.name in [Tok.MINUS, Tok.SUB_EQ]:
|
|
3161
|
-
node.gen.py_ast = [self.sync(ast3.Sub())]
|
|
3162
|
-
elif node.name in [Tok.BW_NOT, Tok.BW_NOT_EQ]:
|
|
3163
|
-
node.gen.py_ast = [self.sync(ast3.Invert())]
|
|
3164
|
-
elif node.name in [Tok.NOT]:
|
|
3165
|
-
node.gen.py_ast = [self.sync(ast3.Not())]
|
|
3166
|
-
elif node.name in [Tok.EQ]:
|
|
3167
|
-
node.gen.py_ast = [self.sync(ast3.NotEq())]
|
|
3168
|
-
elif node.name == Tok.EE:
|
|
3169
|
-
node.gen.py_ast = [self.sync(ast3.Eq())]
|
|
3170
|
-
elif node.name == Tok.GT:
|
|
3171
|
-
node.gen.py_ast = [self.sync(ast3.Gt())]
|
|
3172
|
-
elif node.name == Tok.GTE:
|
|
3173
|
-
node.gen.py_ast = [self.sync(ast3.GtE())]
|
|
3174
|
-
elif node.name == Tok.KW_IN:
|
|
3175
|
-
node.gen.py_ast = [self.sync(ast3.In())]
|
|
3176
|
-
elif node.name == Tok.KW_IS:
|
|
3177
|
-
node.gen.py_ast = [self.sync(ast3.Is())]
|
|
3178
|
-
elif node.name == Tok.KW_ISN:
|
|
3179
|
-
node.gen.py_ast = [self.sync(ast3.IsNot())]
|
|
3180
|
-
elif node.name == Tok.LT:
|
|
3181
|
-
node.gen.py_ast = [self.sync(ast3.Lt())]
|
|
3182
|
-
elif node.name == Tok.LTE:
|
|
3183
|
-
node.gen.py_ast = [self.sync(ast3.LtE())]
|
|
3184
|
-
elif node.name == Tok.NE:
|
|
3185
|
-
node.gen.py_ast = [self.sync(ast3.NotEq())]
|
|
3186
|
-
elif node.name == Tok.KW_NIN:
|
|
3187
|
-
node.gen.py_ast = [self.sync(ast3.NotIn())]
|
|
2828
|
+
op_cls = TOKEN_AST_MAP.get(node.name)
|
|
2829
|
+
if op_cls:
|
|
2830
|
+
node.gen.py_ast = [self.sync(op_cls())]
|
|
3188
2831
|
|
|
3189
2832
|
def exit_name(self, node: uni.Name) -> None:
|
|
3190
2833
|
node.gen.py_ast = [
|
|
@@ -3195,21 +2838,7 @@ class PyastGenPass(UniPass):
|
|
|
3195
2838
|
node.gen.py_ast = [self.sync(ast3.Constant(value=float(node.value)))]
|
|
3196
2839
|
|
|
3197
2840
|
def exit_int(self, node: uni.Int) -> None:
|
|
3198
|
-
|
|
3199
|
-
if value.startswith(("0x", "0X")):
|
|
3200
|
-
return int(value, 16)
|
|
3201
|
-
elif value.startswith(("0b", "0B")):
|
|
3202
|
-
return int(value, 2)
|
|
3203
|
-
elif value.startswith(("0o", "0O")):
|
|
3204
|
-
return int(value, 8)
|
|
3205
|
-
else:
|
|
3206
|
-
return int(value)
|
|
3207
|
-
|
|
3208
|
-
node.gen.py_ast = [
|
|
3209
|
-
self.sync(
|
|
3210
|
-
ast3.Constant(value=handle_node_value(str(node.value)), kind=None)
|
|
3211
|
-
)
|
|
3212
|
-
]
|
|
2841
|
+
node.gen.py_ast = [self.sync(ast3.Constant(value=int(node.value, 0)))]
|
|
3213
2842
|
|
|
3214
2843
|
def exit_string(self, node: uni.String) -> None:
|
|
3215
2844
|
node.gen.py_ast = [self.sync(ast3.Constant(value=node.lit_value))]
|