jaclang 0.8.1__py3-none-any.whl → 0.8.3__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 +21 -50
- jaclang/compiler/codeinfo.py +0 -1
- jaclang/compiler/constant.py +2 -0
- jaclang/compiler/jac.lark +17 -10
- jaclang/compiler/larkparse/jac_parser.py +2 -2
- jaclang/compiler/parser.py +34 -10
- jaclang/compiler/passes/main/__init__.py +2 -14
- jaclang/compiler/passes/main/annex_pass.py +2 -8
- jaclang/compiler/passes/main/cfg_build_pass.py +38 -12
- jaclang/compiler/passes/main/import_pass.py +3 -11
- jaclang/compiler/passes/main/pyast_gen_pass.py +246 -592
- jaclang/compiler/passes/main/sem_def_match_pass.py +67 -0
- jaclang/compiler/passes/main/sym_tab_build_pass.py +8 -0
- jaclang/compiler/passes/main/sym_tab_link_pass.py +2 -5
- jaclang/compiler/passes/main/tests/fixtures/sem_def_match.impl.jac +12 -0
- jaclang/compiler/passes/main/tests/fixtures/sem_def_match.jac +31 -0
- jaclang/compiler/passes/main/tests/test_cfg_build_pass.py +2 -8
- 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_sem_def_match_pass.py +38 -0
- 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 +259 -106
- 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/has_frmt.jac +13 -0
- 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 +25 -3
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +2 -2
- jaclang/compiler/program.py +23 -60
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/__init__.py +2 -8
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/__init__.py +1 -5
- jaclang/compiler/tests/test_importer.py +10 -13
- jaclang/compiler/unitree.py +88 -16
- jaclang/langserve/__init__.jac +1 -1
- jaclang/langserve/engine.jac +113 -108
- jaclang/langserve/server.jac +17 -2
- jaclang/langserve/tests/server_test/test_lang_serve.py +138 -46
- jaclang/langserve/tests/server_test/utils.py +35 -9
- jaclang/langserve/tests/test_sem_tokens.py +1 -1
- jaclang/langserve/tests/test_server.py +3 -7
- jaclang/runtimelib/archetype.py +127 -5
- jaclang/runtimelib/importer.py +51 -94
- jaclang/runtimelib/machine.py +391 -268
- 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/test_jaseci.py +3 -1
- 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/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/foo.jac +14 -22
- 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/unicode_strings.jac +24 -0
- jaclang/tests/fixtures/walker_update.jac +5 -7
- jaclang/tests/test_language.py +138 -140
- jaclang/tests/test_reference.py +9 -4
- jaclang/tests/test_typecheck.py +13 -26
- jaclang/utils/lang_tools.py +7 -5
- jaclang/utils/module_resolver.py +23 -0
- {jaclang-0.8.1.dist-info → jaclang-0.8.3.dist-info}/METADATA +1 -1
- {jaclang-0.8.1.dist-info → jaclang-0.8.3.dist-info}/RECORD +79 -72
- 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/tests/fixtures/deep/deeper/__init__.jac +0 -1
- {jaclang-0.8.1.dist-info → jaclang-0.8.3.dist-info}/WHEEL +0 -0
- {jaclang-0.8.1.dist-info → jaclang-0.8.3.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(
|
|
@@ -267,14 +310,10 @@ class PyastGenPass(UniPass):
|
|
|
267
310
|
attr_node: ast3.Name | ast3.Attribute = self.sync(
|
|
268
311
|
ast3.Name(id=attribute_list[0], ctx=ast3.Load()), sync_node_list[0]
|
|
269
312
|
)
|
|
270
|
-
for
|
|
271
|
-
if i == 0:
|
|
272
|
-
continue
|
|
313
|
+
for attr, sync_node in zip(attribute_list[1:], sync_node_list[1:]):
|
|
273
314
|
attr_node = self.sync(
|
|
274
|
-
ast3.Attribute(
|
|
275
|
-
|
|
276
|
-
),
|
|
277
|
-
sync_node_list[i],
|
|
315
|
+
ast3.Attribute(value=attr_node, attr=attr, ctx=ast3.Load()),
|
|
316
|
+
sync_node,
|
|
278
317
|
)
|
|
279
318
|
return attr_node
|
|
280
319
|
|
|
@@ -426,40 +465,8 @@ class PyastGenPass(UniPass):
|
|
|
426
465
|
)
|
|
427
466
|
|
|
428
467
|
def exit_import(self, node: uni.Import) -> None:
|
|
429
|
-
|
|
430
|
-
{node.from_loc.dot_path_str: None} if node.from_loc else {}
|
|
431
|
-
)
|
|
432
|
-
imp_from = {}
|
|
433
|
-
if node.items:
|
|
434
|
-
for item in node.items:
|
|
435
|
-
if isinstance(item, uni.ModuleItem):
|
|
436
|
-
imp_from[item.name.sym_name] = (
|
|
437
|
-
item.alias.sym_name if item.alias else None
|
|
438
|
-
)
|
|
439
|
-
elif isinstance(item, uni.ModulePath):
|
|
440
|
-
path_alias[item.dot_path_str] = (
|
|
441
|
-
item.alias.sym_name if item.alias else None
|
|
442
|
-
)
|
|
443
|
-
|
|
444
|
-
item_names: list[ast3.expr] = []
|
|
445
|
-
item_keys: list[ast3.Constant] = []
|
|
446
|
-
item_values: list[ast3.Constant] = []
|
|
447
|
-
for k, v in imp_from.items():
|
|
448
|
-
item_keys.append(self.sync(ast3.Constant(value=k)))
|
|
449
|
-
item_values.append(self.sync(ast3.Constant(value=v)))
|
|
450
|
-
item_names.append(
|
|
451
|
-
self.sync(
|
|
452
|
-
ast3.Name(
|
|
453
|
-
id=v or k,
|
|
454
|
-
ctx=ast3.Store(),
|
|
455
|
-
)
|
|
456
|
-
)
|
|
457
|
-
)
|
|
458
|
-
path_named_value: str
|
|
468
|
+
"""Exit import node."""
|
|
459
469
|
py_nodes: list[ast3.AST] = []
|
|
460
|
-
typecheck_nodes: list[ast3.AST] = []
|
|
461
|
-
runtime_nodes: list[ast3.AST] = []
|
|
462
|
-
|
|
463
470
|
if node.doc:
|
|
464
471
|
py_nodes.append(
|
|
465
472
|
self.sync(
|
|
@@ -468,255 +475,28 @@ class PyastGenPass(UniPass):
|
|
|
468
475
|
)
|
|
469
476
|
)
|
|
470
477
|
|
|
471
|
-
for path, alias in path_alias.items():
|
|
472
|
-
path_named_value = ("_jac_inc_" if node.is_absorb else "") + (
|
|
473
|
-
alias if alias else path
|
|
474
|
-
).lstrip(".").split(".")[0]
|
|
475
|
-
# target_named_value = ""
|
|
476
|
-
# for i in path.split("."):
|
|
477
|
-
# target_named_value += i if i else "."
|
|
478
|
-
# if i:
|
|
479
|
-
# break
|
|
480
|
-
|
|
481
|
-
args = [
|
|
482
|
-
self.sync(
|
|
483
|
-
ast3.Constant(value=path),
|
|
484
|
-
),
|
|
485
|
-
self.sync(
|
|
486
|
-
ast3.Name(
|
|
487
|
-
id="__file__",
|
|
488
|
-
ctx=ast3.Load(),
|
|
489
|
-
)
|
|
490
|
-
),
|
|
491
|
-
]
|
|
492
|
-
keywords = []
|
|
493
|
-
|
|
494
|
-
if node.is_absorb:
|
|
495
|
-
args.append(self.sync(ast3.Constant(value=node.is_absorb)))
|
|
496
|
-
|
|
497
|
-
if alias is not None:
|
|
498
|
-
keywords.append(
|
|
499
|
-
self.sync(
|
|
500
|
-
ast3.keyword(
|
|
501
|
-
arg="mdl_alias",
|
|
502
|
-
value=self.sync(
|
|
503
|
-
ast3.Constant(value=alias),
|
|
504
|
-
),
|
|
505
|
-
)
|
|
506
|
-
)
|
|
507
|
-
)
|
|
508
|
-
|
|
509
|
-
if item_keys and item_values:
|
|
510
|
-
keywords.append(
|
|
511
|
-
self.sync(
|
|
512
|
-
ast3.keyword(
|
|
513
|
-
arg="items",
|
|
514
|
-
value=self.sync(
|
|
515
|
-
ast3.Dict(
|
|
516
|
-
keys=cast(list[ast3.expr | None], item_keys),
|
|
517
|
-
values=cast(list[ast3.expr], item_values),
|
|
518
|
-
),
|
|
519
|
-
),
|
|
520
|
-
)
|
|
521
|
-
)
|
|
522
|
-
)
|
|
523
|
-
|
|
524
|
-
runtime_nodes.append(
|
|
525
|
-
self.sync(
|
|
526
|
-
ast3.Assign(
|
|
527
|
-
targets=(
|
|
528
|
-
[
|
|
529
|
-
self.sync(
|
|
530
|
-
ast3.Tuple(
|
|
531
|
-
elts=(
|
|
532
|
-
item_names
|
|
533
|
-
or [
|
|
534
|
-
self.sync(
|
|
535
|
-
ast3.Name(
|
|
536
|
-
id=path_named_value,
|
|
537
|
-
ctx=ast3.Store(),
|
|
538
|
-
)
|
|
539
|
-
)
|
|
540
|
-
]
|
|
541
|
-
),
|
|
542
|
-
ctx=ast3.Store(),
|
|
543
|
-
)
|
|
544
|
-
)
|
|
545
|
-
]
|
|
546
|
-
),
|
|
547
|
-
value=self.sync(
|
|
548
|
-
ast3.Call(
|
|
549
|
-
func=self.jaclib_obj("py_jac_import"),
|
|
550
|
-
args=args,
|
|
551
|
-
keywords=keywords,
|
|
552
|
-
)
|
|
553
|
-
),
|
|
554
|
-
),
|
|
555
|
-
),
|
|
556
|
-
)
|
|
557
|
-
if node.is_absorb:
|
|
558
|
-
absorb_exec = f"={path_named_value}.__dict__['"
|
|
559
|
-
runtime_nodes.append(
|
|
560
|
-
self.sync(
|
|
561
|
-
ast3.For(
|
|
562
|
-
target=self.sync(ast3.Name(id="i", ctx=ast3.Store())),
|
|
563
|
-
iter=self.sync(
|
|
564
|
-
ast3.IfExp(
|
|
565
|
-
test=self.sync(
|
|
566
|
-
ast3.Compare(
|
|
567
|
-
left=self.sync(ast3.Constant(value="__all__")),
|
|
568
|
-
ops=[self.sync(ast3.In())],
|
|
569
|
-
comparators=[
|
|
570
|
-
self.sync(
|
|
571
|
-
ast3.Attribute(
|
|
572
|
-
value=self.sync(
|
|
573
|
-
ast3.Name(
|
|
574
|
-
id=path_named_value,
|
|
575
|
-
ctx=ast3.Load(),
|
|
576
|
-
)
|
|
577
|
-
),
|
|
578
|
-
attr="__dict__",
|
|
579
|
-
ctx=ast3.Load(),
|
|
580
|
-
)
|
|
581
|
-
)
|
|
582
|
-
],
|
|
583
|
-
)
|
|
584
|
-
),
|
|
585
|
-
body=self.sync(
|
|
586
|
-
ast3.Attribute(
|
|
587
|
-
value=self.sync(
|
|
588
|
-
ast3.Name(
|
|
589
|
-
id=path_named_value, ctx=ast3.Load()
|
|
590
|
-
)
|
|
591
|
-
),
|
|
592
|
-
attr="__all__",
|
|
593
|
-
ctx=ast3.Load(),
|
|
594
|
-
)
|
|
595
|
-
),
|
|
596
|
-
orelse=self.sync(
|
|
597
|
-
ast3.Attribute(
|
|
598
|
-
value=self.sync(
|
|
599
|
-
ast3.Name(
|
|
600
|
-
id=path_named_value, ctx=ast3.Load()
|
|
601
|
-
)
|
|
602
|
-
),
|
|
603
|
-
attr="__dict__",
|
|
604
|
-
ctx=ast3.Load(),
|
|
605
|
-
)
|
|
606
|
-
),
|
|
607
|
-
)
|
|
608
|
-
),
|
|
609
|
-
body=[
|
|
610
|
-
self.sync(
|
|
611
|
-
ast3.If(
|
|
612
|
-
test=self.sync(
|
|
613
|
-
ast3.UnaryOp(
|
|
614
|
-
op=self.sync(ast3.Not()),
|
|
615
|
-
operand=self.sync(
|
|
616
|
-
ast3.Call(
|
|
617
|
-
func=self.sync(
|
|
618
|
-
ast3.Attribute(
|
|
619
|
-
value=self.sync(
|
|
620
|
-
ast3.Name(
|
|
621
|
-
id="i",
|
|
622
|
-
ctx=ast3.Load(),
|
|
623
|
-
)
|
|
624
|
-
),
|
|
625
|
-
attr="startswith",
|
|
626
|
-
ctx=ast3.Load(),
|
|
627
|
-
)
|
|
628
|
-
),
|
|
629
|
-
args=[
|
|
630
|
-
self.sync(
|
|
631
|
-
ast3.Constant(value="_")
|
|
632
|
-
)
|
|
633
|
-
],
|
|
634
|
-
keywords=[],
|
|
635
|
-
)
|
|
636
|
-
),
|
|
637
|
-
)
|
|
638
|
-
),
|
|
639
|
-
body=[
|
|
640
|
-
self.sync(
|
|
641
|
-
ast3.Expr(
|
|
642
|
-
value=self.sync(
|
|
643
|
-
ast3.Call(
|
|
644
|
-
func=self.sync(
|
|
645
|
-
ast3.Name(
|
|
646
|
-
id="exec",
|
|
647
|
-
ctx=ast3.Load(),
|
|
648
|
-
)
|
|
649
|
-
),
|
|
650
|
-
args=[
|
|
651
|
-
self.sync(
|
|
652
|
-
ast3.JoinedStr(
|
|
653
|
-
values=[
|
|
654
|
-
self.sync(
|
|
655
|
-
ast3.FormattedValue(
|
|
656
|
-
value=self.sync(
|
|
657
|
-
ast3.Name(
|
|
658
|
-
id="i",
|
|
659
|
-
ctx=ast3.Load(),
|
|
660
|
-
)
|
|
661
|
-
),
|
|
662
|
-
conversion=-1,
|
|
663
|
-
)
|
|
664
|
-
),
|
|
665
|
-
self.sync(
|
|
666
|
-
ast3.Constant(
|
|
667
|
-
value=absorb_exec
|
|
668
|
-
)
|
|
669
|
-
),
|
|
670
|
-
self.sync(
|
|
671
|
-
ast3.FormattedValue(
|
|
672
|
-
value=self.sync(
|
|
673
|
-
ast3.Name(
|
|
674
|
-
id="i",
|
|
675
|
-
ctx=ast3.Load(),
|
|
676
|
-
)
|
|
677
|
-
),
|
|
678
|
-
conversion=-1,
|
|
679
|
-
)
|
|
680
|
-
),
|
|
681
|
-
self.sync(
|
|
682
|
-
ast3.Constant(
|
|
683
|
-
value="']"
|
|
684
|
-
)
|
|
685
|
-
),
|
|
686
|
-
]
|
|
687
|
-
)
|
|
688
|
-
)
|
|
689
|
-
],
|
|
690
|
-
keywords=[],
|
|
691
|
-
)
|
|
692
|
-
)
|
|
693
|
-
)
|
|
694
|
-
)
|
|
695
|
-
],
|
|
696
|
-
orelse=[],
|
|
697
|
-
)
|
|
698
|
-
)
|
|
699
|
-
],
|
|
700
|
-
orelse=[],
|
|
701
|
-
)
|
|
702
|
-
)
|
|
703
|
-
)
|
|
704
478
|
if node.is_absorb:
|
|
479
|
+
# This is `include "module_name";` which becomes `from module_name import *`
|
|
705
480
|
source = node.items[0]
|
|
706
481
|
if not isinstance(source, uni.ModulePath):
|
|
707
482
|
raise self.ice()
|
|
708
|
-
|
|
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(
|
|
709
488
|
self.sync(
|
|
710
489
|
py_node=ast3.ImportFrom(
|
|
711
|
-
module=
|
|
490
|
+
module=module_name,
|
|
712
491
|
names=[self.sync(ast3.alias(name="*"), node)],
|
|
713
|
-
level=
|
|
492
|
+
level=source.level,
|
|
714
493
|
),
|
|
715
494
|
jac_node=node,
|
|
716
495
|
)
|
|
717
496
|
)
|
|
718
497
|
elif not node.from_loc:
|
|
719
|
-
|
|
498
|
+
# This is `import module1, module2 as alias;`
|
|
499
|
+
py_nodes.append(
|
|
720
500
|
self.sync(
|
|
721
501
|
ast3.Import(
|
|
722
502
|
names=[
|
|
@@ -728,32 +508,25 @@ class PyastGenPass(UniPass):
|
|
|
728
508
|
)
|
|
729
509
|
)
|
|
730
510
|
else:
|
|
731
|
-
|
|
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(
|
|
732
518
|
self.sync(
|
|
733
519
|
ast3.ImportFrom(
|
|
734
|
-
module=
|
|
735
|
-
node.from_loc.dot_path_str.lstrip(".")
|
|
736
|
-
if node.from_loc
|
|
737
|
-
else None
|
|
738
|
-
),
|
|
520
|
+
module=module_name,
|
|
739
521
|
names=[
|
|
740
522
|
cast(ast3.alias, i)
|
|
741
523
|
for item in node.items
|
|
742
524
|
for i in item.gen.py_ast
|
|
743
525
|
],
|
|
744
|
-
level=
|
|
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:
|
|
@@ -867,6 +640,17 @@ class PyastGenPass(UniPass):
|
|
|
867
640
|
if isinstance(node.body, uni.ImplDef):
|
|
868
641
|
self.traverse(node.body)
|
|
869
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
|
+
|
|
870
654
|
def gen_llm_body(self, node: uni.Ability) -> list[ast3.AST]:
|
|
871
655
|
"""Generate the by LLM body."""
|
|
872
656
|
# to Avoid circular import
|
|
@@ -988,11 +772,7 @@ class PyastGenPass(UniPass):
|
|
|
988
772
|
),
|
|
989
773
|
body=[cast(ast3.stmt, i) for i in body],
|
|
990
774
|
decorator_list=[cast(ast3.expr, i) for i in decorator_list],
|
|
991
|
-
returns=(
|
|
992
|
-
cast(ast3.expr, node.signature.return_type.gen.py_ast[0])
|
|
993
|
-
if node.signature and node.signature.return_type
|
|
994
|
-
else self.sync(ast3.Constant(value=None))
|
|
995
|
-
),
|
|
775
|
+
returns=self.sync(ast3.Constant(value=None)),
|
|
996
776
|
type_params=[],
|
|
997
777
|
)
|
|
998
778
|
)
|
|
@@ -1001,6 +781,9 @@ class PyastGenPass(UniPass):
|
|
|
1001
781
|
def exit_impl_def(self, node: uni.ImplDef) -> None:
|
|
1002
782
|
pass
|
|
1003
783
|
|
|
784
|
+
def exit_sem_def(self, node: uni.SemDef) -> None:
|
|
785
|
+
pass
|
|
786
|
+
|
|
1004
787
|
def exit_func_signature(self, node: uni.FuncSignature) -> None:
|
|
1005
788
|
params = (
|
|
1006
789
|
[self.sync(ast3.arg(arg="self", annotation=None))]
|
|
@@ -1829,25 +1612,9 @@ class PyastGenPass(UniPass):
|
|
|
1829
1612
|
]
|
|
1830
1613
|
|
|
1831
1614
|
def exit_await_expr(self, node: uni.AwaitExpr) -> None:
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
node.gen.py_ast = [
|
|
1836
|
-
self.sync(
|
|
1837
|
-
ast3.Await(value=cast(ast3.expr, node.target.gen.py_ast[0]))
|
|
1838
|
-
)
|
|
1839
|
-
]
|
|
1840
|
-
break
|
|
1841
|
-
else:
|
|
1842
|
-
node.gen.py_ast = [
|
|
1843
|
-
self.sync(
|
|
1844
|
-
ast3.Call(
|
|
1845
|
-
func=self.jaclib_obj("await_obj"),
|
|
1846
|
-
args=[cast(ast3.expr, node.target.gen.py_ast[0])],
|
|
1847
|
-
keywords=[],
|
|
1848
|
-
)
|
|
1849
|
-
)
|
|
1850
|
-
]
|
|
1615
|
+
node.gen.py_ast = [
|
|
1616
|
+
self.sync(ast3.Await(value=cast(ast3.expr, node.target.gen.py_ast[0])))
|
|
1617
|
+
]
|
|
1851
1618
|
|
|
1852
1619
|
def exit_global_stmt(self, node: uni.GlobalStmt) -> None:
|
|
1853
1620
|
py_nodes = []
|
|
@@ -2180,42 +1947,17 @@ class PyastGenPass(UniPass):
|
|
|
2180
1947
|
]
|
|
2181
1948
|
|
|
2182
1949
|
def exit_unary_expr(self, node: uni.UnaryExpr) -> None:
|
|
2183
|
-
|
|
1950
|
+
op_cls = UNARY_OP_MAP.get(node.op.name)
|
|
1951
|
+
if op_cls:
|
|
2184
1952
|
node.gen.py_ast = [
|
|
2185
1953
|
self.sync(
|
|
2186
1954
|
ast3.UnaryOp(
|
|
2187
|
-
op=self.sync(
|
|
2188
|
-
operand=cast(ast3.expr, node.operand.gen.py_ast[0]),
|
|
2189
|
-
)
|
|
2190
|
-
)
|
|
2191
|
-
]
|
|
2192
|
-
elif node.op.name == Tok.BW_NOT:
|
|
2193
|
-
node.gen.py_ast = [
|
|
2194
|
-
self.sync(
|
|
2195
|
-
ast3.UnaryOp(
|
|
2196
|
-
op=self.sync(ast3.Invert()),
|
|
2197
|
-
operand=cast(ast3.expr, node.operand.gen.py_ast[0]),
|
|
2198
|
-
)
|
|
2199
|
-
)
|
|
2200
|
-
]
|
|
2201
|
-
elif node.op.name == Tok.PLUS:
|
|
2202
|
-
node.gen.py_ast = [
|
|
2203
|
-
self.sync(
|
|
2204
|
-
ast3.UnaryOp(
|
|
2205
|
-
op=self.sync(ast3.UAdd()),
|
|
2206
|
-
operand=cast(ast3.expr, node.operand.gen.py_ast[0]),
|
|
2207
|
-
)
|
|
2208
|
-
)
|
|
2209
|
-
]
|
|
2210
|
-
elif node.op.name == Tok.MINUS:
|
|
2211
|
-
node.gen.py_ast = [
|
|
2212
|
-
self.sync(
|
|
2213
|
-
ast3.UnaryOp(
|
|
2214
|
-
op=self.sync(ast3.USub()),
|
|
1955
|
+
op=self.sync(op_cls()),
|
|
2215
1956
|
operand=cast(ast3.expr, node.operand.gen.py_ast[0]),
|
|
2216
1957
|
)
|
|
2217
1958
|
)
|
|
2218
1959
|
]
|
|
1960
|
+
return
|
|
2219
1961
|
elif node.op.name in [Tok.PIPE_FWD, Tok.KW_SPAWN, Tok.A_PIPE_FWD]:
|
|
2220
1962
|
node.gen.py_ast = [
|
|
2221
1963
|
self.sync(
|
|
@@ -2573,8 +2315,10 @@ class PyastGenPass(UniPass):
|
|
|
2573
2315
|
|
|
2574
2316
|
return JacMachineInterface.get_by_llm_call_args(self, node)
|
|
2575
2317
|
|
|
2576
|
-
def
|
|
2577
|
-
|
|
2318
|
+
def gen_call_args(
|
|
2319
|
+
self, node: uni.FuncCall
|
|
2320
|
+
) -> tuple[list[ast3.expr], list[ast3.keyword]]:
|
|
2321
|
+
"""Generate the arguments for a function call."""
|
|
2578
2322
|
args = []
|
|
2579
2323
|
keywords = []
|
|
2580
2324
|
if node.params:
|
|
@@ -2596,10 +2340,21 @@ class PyastGenPass(UniPass):
|
|
|
2596
2340
|
keywords.append(x.gen.py_ast[0])
|
|
2597
2341
|
else:
|
|
2598
2342
|
self.ice("Invalid Parameter")
|
|
2599
|
-
|
|
2343
|
+
return args, keywords
|
|
2344
|
+
|
|
2345
|
+
def exit_func_call(self, node: uni.FuncCall) -> None:
|
|
2346
|
+
if node.body_genai_call:
|
|
2347
|
+
node.gen.py_ast = self.gen_llm_call_override(node)
|
|
2348
|
+
|
|
2349
|
+
# TODO: This needs to be changed to only generate parameters no the body.
|
|
2350
|
+
elif node.genai_call:
|
|
2600
2351
|
by_llm_call_args = self.get_by_llm_call_args(node)
|
|
2601
2352
|
node.gen.py_ast = [self.sync(self.by_llm_call(**by_llm_call_args))]
|
|
2353
|
+
|
|
2602
2354
|
else:
|
|
2355
|
+
func = node.target.gen.py_ast[0]
|
|
2356
|
+
args, keywords = self.gen_call_args(node)
|
|
2357
|
+
|
|
2603
2358
|
node.gen.py_ast = [
|
|
2604
2359
|
self.sync(
|
|
2605
2360
|
ast3.Call(
|
|
@@ -2699,149 +2454,115 @@ class PyastGenPass(UniPass):
|
|
|
2699
2454
|
]
|
|
2700
2455
|
|
|
2701
2456
|
def exit_edge_ref_trailer(self, node: uni.EdgeRefTrailer) -> None:
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2457
|
+
origin = None
|
|
2458
|
+
cur = node.chain[0]
|
|
2459
|
+
chomp = [*node.chain[1:]]
|
|
2705
2460
|
from_visit = bool(isinstance(node.parent, uni.VisitStmt))
|
|
2706
|
-
if node.edges_only:
|
|
2707
|
-
for i in node.chain:
|
|
2708
|
-
if isinstance(i, uni.EdgeOpRef):
|
|
2709
|
-
last_edge = i
|
|
2710
|
-
while len(chomp):
|
|
2711
|
-
cur = chomp[0]
|
|
2712
|
-
chomp = chomp[1:]
|
|
2713
|
-
if len(chomp) == len(node.chain) - 1 and not isinstance(cur, uni.EdgeOpRef):
|
|
2714
|
-
continue
|
|
2715
|
-
next_i = chomp[0] if chomp else None
|
|
2716
|
-
if isinstance(cur, uni.EdgeOpRef) and (
|
|
2717
|
-
not next_i or not isinstance(next_i, uni.EdgeOpRef)
|
|
2718
|
-
):
|
|
2719
|
-
pynode = self.translate_edge_op_ref(
|
|
2720
|
-
loc=pynode,
|
|
2721
|
-
node=cur,
|
|
2722
|
-
targ=(
|
|
2723
|
-
next_i.gen.py_ast[0]
|
|
2724
|
-
if next_i and not isinstance(next_i, uni.FilterCompr)
|
|
2725
|
-
else None
|
|
2726
|
-
),
|
|
2727
|
-
edges_only=node.edges_only and cur == last_edge,
|
|
2728
|
-
from_visit=from_visit,
|
|
2729
|
-
)
|
|
2730
|
-
if next_i and isinstance(next_i, uni.FilterCompr):
|
|
2731
|
-
pynode = self.sync(
|
|
2732
|
-
ast3.Call(
|
|
2733
|
-
func=self.jaclib_obj("filter"),
|
|
2734
|
-
args=[],
|
|
2735
|
-
keywords=[
|
|
2736
|
-
self.sync(
|
|
2737
|
-
ast3.keyword(
|
|
2738
|
-
arg="items",
|
|
2739
|
-
value=cast(ast3.expr, pynode),
|
|
2740
|
-
)
|
|
2741
|
-
),
|
|
2742
|
-
self.sync(
|
|
2743
|
-
ast3.keyword(
|
|
2744
|
-
arg="func",
|
|
2745
|
-
value=cast(ast3.expr, next_i.gen.py_ast[0]),
|
|
2746
|
-
)
|
|
2747
|
-
),
|
|
2748
|
-
],
|
|
2749
|
-
)
|
|
2750
|
-
)
|
|
2751
|
-
chomp = chomp[1:] if next_i else chomp
|
|
2752
|
-
elif isinstance(cur, uni.EdgeOpRef) and isinstance(next_i, uni.EdgeOpRef):
|
|
2753
|
-
pynode = self.translate_edge_op_ref(
|
|
2754
|
-
pynode,
|
|
2755
|
-
cur,
|
|
2756
|
-
targ=None,
|
|
2757
|
-
edges_only=node.edges_only and cur == last_edge,
|
|
2758
|
-
from_visit=from_visit,
|
|
2759
|
-
)
|
|
2760
|
-
else:
|
|
2761
|
-
raise self.ice("Invalid edge ref trailer")
|
|
2762
|
-
|
|
2763
|
-
node.gen.py_ast = [pynode]
|
|
2764
|
-
|
|
2765
|
-
def exit_edge_op_ref(self, node: uni.EdgeOpRef) -> None:
|
|
2766
|
-
loc = self.sync(
|
|
2767
|
-
ast3.Name(id=Con.HERE.value, ctx=ast3.Load())
|
|
2768
|
-
if node.from_walker
|
|
2769
|
-
else ast3.Name(id="self", ctx=ast3.Load())
|
|
2770
|
-
)
|
|
2771
|
-
node.gen.py_ast = [loc]
|
|
2772
2461
|
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
node: uni.EdgeOpRef,
|
|
2777
|
-
targ: ast3.AST | None,
|
|
2778
|
-
edges_only: bool,
|
|
2779
|
-
from_visit: bool,
|
|
2780
|
-
) -> ast3.AST:
|
|
2781
|
-
"""Generate ast for edge op ref call."""
|
|
2782
|
-
keywords = [self.sync(ast3.keyword(arg="sources", value=cast(ast3.expr, loc)))]
|
|
2462
|
+
if not isinstance(cur, uni.EdgeOpRef):
|
|
2463
|
+
origin = cur.gen.py_ast[0]
|
|
2464
|
+
cur = cast(uni.EdgeOpRef, chomp.pop(0))
|
|
2783
2465
|
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
self.
|
|
2466
|
+
pynode = self.sync(
|
|
2467
|
+
ast3.Call(
|
|
2468
|
+
func=self.jaclib_obj("Path"),
|
|
2469
|
+
args=[cast(ast3.expr, origin or cur.gen.py_ast[0])],
|
|
2470
|
+
keywords=[],
|
|
2787
2471
|
)
|
|
2472
|
+
)
|
|
2788
2473
|
|
|
2789
|
-
|
|
2790
|
-
keywords
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
),
|
|
2474
|
+
while True:
|
|
2475
|
+
keywords = []
|
|
2476
|
+
if cur.filter_cond:
|
|
2477
|
+
keywords.append(
|
|
2478
|
+
self.sync(
|
|
2479
|
+
ast3.keyword(
|
|
2480
|
+
arg="edge",
|
|
2481
|
+
value=cast(
|
|
2482
|
+
ast3.expr, self.sync(cur.filter_cond.gen.py_ast[0])
|
|
2483
|
+
),
|
|
2484
|
+
)
|
|
2801
2485
|
)
|
|
2802
2486
|
)
|
|
2803
|
-
)
|
|
2804
2487
|
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
ast3.expr, self.sync(
|
|
2812
|
-
)
|
|
2488
|
+
if chomp and not isinstance(chomp[0], uni.EdgeOpRef):
|
|
2489
|
+
filt = chomp.pop(0)
|
|
2490
|
+
keywords.append(
|
|
2491
|
+
self.sync(
|
|
2492
|
+
ast3.keyword(
|
|
2493
|
+
arg="node",
|
|
2494
|
+
value=cast(ast3.expr, self.sync(filt.gen.py_ast[0])),
|
|
2495
|
+
)
|
|
2813
2496
|
)
|
|
2814
2497
|
)
|
|
2498
|
+
|
|
2499
|
+
pynode = self.sync(
|
|
2500
|
+
ast3.Call(
|
|
2501
|
+
func=self.sync(
|
|
2502
|
+
ast3.Attribute(
|
|
2503
|
+
value=pynode,
|
|
2504
|
+
attr=f"_{cur.edge_dir.name.lower()}",
|
|
2505
|
+
ctx=ast3.Load(),
|
|
2506
|
+
)
|
|
2507
|
+
),
|
|
2508
|
+
args=[],
|
|
2509
|
+
keywords=keywords,
|
|
2510
|
+
)
|
|
2815
2511
|
)
|
|
2816
2512
|
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2513
|
+
if chomp:
|
|
2514
|
+
cur = cast(uni.EdgeOpRef, chomp.pop(0))
|
|
2515
|
+
else:
|
|
2516
|
+
break
|
|
2517
|
+
|
|
2518
|
+
if node.edges_only:
|
|
2519
|
+
pynode = self.sync(
|
|
2520
|
+
ast3.Call(
|
|
2521
|
+
func=self.sync(
|
|
2522
|
+
ast3.Attribute(
|
|
2523
|
+
value=pynode,
|
|
2524
|
+
attr="edge",
|
|
2525
|
+
ctx=ast3.Load(),
|
|
2526
|
+
)
|
|
2527
|
+
),
|
|
2528
|
+
args=[],
|
|
2529
|
+
keywords=[],
|
|
2824
2530
|
)
|
|
2825
2531
|
)
|
|
2826
2532
|
|
|
2827
2533
|
if from_visit:
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2534
|
+
pynode = self.sync(
|
|
2535
|
+
ast3.Call(
|
|
2536
|
+
func=self.sync(
|
|
2537
|
+
ast3.Attribute(
|
|
2538
|
+
value=pynode,
|
|
2539
|
+
attr="visit",
|
|
2540
|
+
ctx=ast3.Load(),
|
|
2541
|
+
)
|
|
2542
|
+
),
|
|
2543
|
+
args=[],
|
|
2544
|
+
keywords=[],
|
|
2834
2545
|
)
|
|
2835
2546
|
)
|
|
2836
2547
|
|
|
2837
|
-
|
|
2548
|
+
pynode = self.sync(
|
|
2838
2549
|
ast3.Call(
|
|
2839
2550
|
func=self.jaclib_obj("refs"),
|
|
2840
|
-
args=[],
|
|
2841
|
-
keywords=
|
|
2551
|
+
args=[pynode],
|
|
2552
|
+
keywords=[],
|
|
2842
2553
|
)
|
|
2843
2554
|
)
|
|
2844
2555
|
|
|
2556
|
+
node.gen.py_ast = [pynode]
|
|
2557
|
+
|
|
2558
|
+
def exit_edge_op_ref(self, node: uni.EdgeOpRef) -> None:
|
|
2559
|
+
loc = self.sync(
|
|
2560
|
+
ast3.Name(id=Con.HERE.value, ctx=ast3.Load())
|
|
2561
|
+
if node.from_walker
|
|
2562
|
+
else ast3.Name(id="self", ctx=ast3.Load())
|
|
2563
|
+
)
|
|
2564
|
+
node.gen.py_ast = [loc]
|
|
2565
|
+
|
|
2845
2566
|
def exit_disconnect_op(self, node: uni.DisconnectOp) -> None:
|
|
2846
2567
|
node.gen.py_ast = node.edge_spec.gen.py_ast
|
|
2847
2568
|
|
|
@@ -3107,62 +2828,9 @@ class PyastGenPass(UniPass):
|
|
|
3107
2828
|
]
|
|
3108
2829
|
|
|
3109
2830
|
def exit_token(self, node: uni.Token) -> None:
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
node.gen.py_ast = [self.sync(ast3.Or())]
|
|
3114
|
-
elif node.name in [Tok.PLUS, Tok.ADD_EQ]:
|
|
3115
|
-
node.gen.py_ast = [self.sync(ast3.Add())]
|
|
3116
|
-
elif node.name in [Tok.BW_AND, Tok.BW_AND_EQ]:
|
|
3117
|
-
node.gen.py_ast = [self.sync(ast3.BitAnd())]
|
|
3118
|
-
elif node.name in [Tok.BW_OR, Tok.BW_OR_EQ]:
|
|
3119
|
-
node.gen.py_ast = [self.sync(ast3.BitOr())]
|
|
3120
|
-
elif node.name in [Tok.BW_XOR, Tok.BW_XOR_EQ]:
|
|
3121
|
-
node.gen.py_ast = [self.sync(ast3.BitXor())]
|
|
3122
|
-
elif node.name in [Tok.DIV, Tok.DIV_EQ]:
|
|
3123
|
-
node.gen.py_ast = [self.sync(ast3.Div())]
|
|
3124
|
-
elif node.name in [Tok.FLOOR_DIV, Tok.FLOOR_DIV_EQ]:
|
|
3125
|
-
node.gen.py_ast = [self.sync(ast3.FloorDiv())]
|
|
3126
|
-
elif node.name in [Tok.LSHIFT, Tok.LSHIFT_EQ]:
|
|
3127
|
-
node.gen.py_ast = [self.sync(ast3.LShift())]
|
|
3128
|
-
elif node.name in [Tok.MOD, Tok.MOD_EQ]:
|
|
3129
|
-
node.gen.py_ast = [self.sync(ast3.Mod())]
|
|
3130
|
-
elif node.name in [Tok.STAR_MUL, Tok.MUL_EQ]:
|
|
3131
|
-
node.gen.py_ast = [self.sync(ast3.Mult())]
|
|
3132
|
-
elif node.name in [Tok.DECOR_OP, Tok.MATMUL_EQ]:
|
|
3133
|
-
node.gen.py_ast = [self.sync(ast3.MatMult())]
|
|
3134
|
-
elif node.name in [Tok.STAR_POW, Tok.STAR_POW_EQ]:
|
|
3135
|
-
node.gen.py_ast = [self.sync(ast3.Pow())]
|
|
3136
|
-
elif node.name in [Tok.RSHIFT, Tok.RSHIFT_EQ]:
|
|
3137
|
-
node.gen.py_ast = [self.sync(ast3.RShift())]
|
|
3138
|
-
elif node.name in [Tok.MINUS, Tok.SUB_EQ]:
|
|
3139
|
-
node.gen.py_ast = [self.sync(ast3.Sub())]
|
|
3140
|
-
elif node.name in [Tok.BW_NOT, Tok.BW_NOT_EQ]:
|
|
3141
|
-
node.gen.py_ast = [self.sync(ast3.Invert())]
|
|
3142
|
-
elif node.name in [Tok.NOT]:
|
|
3143
|
-
node.gen.py_ast = [self.sync(ast3.Not())]
|
|
3144
|
-
elif node.name in [Tok.EQ]:
|
|
3145
|
-
node.gen.py_ast = [self.sync(ast3.NotEq())]
|
|
3146
|
-
elif node.name == Tok.EE:
|
|
3147
|
-
node.gen.py_ast = [self.sync(ast3.Eq())]
|
|
3148
|
-
elif node.name == Tok.GT:
|
|
3149
|
-
node.gen.py_ast = [self.sync(ast3.Gt())]
|
|
3150
|
-
elif node.name == Tok.GTE:
|
|
3151
|
-
node.gen.py_ast = [self.sync(ast3.GtE())]
|
|
3152
|
-
elif node.name == Tok.KW_IN:
|
|
3153
|
-
node.gen.py_ast = [self.sync(ast3.In())]
|
|
3154
|
-
elif node.name == Tok.KW_IS:
|
|
3155
|
-
node.gen.py_ast = [self.sync(ast3.Is())]
|
|
3156
|
-
elif node.name == Tok.KW_ISN:
|
|
3157
|
-
node.gen.py_ast = [self.sync(ast3.IsNot())]
|
|
3158
|
-
elif node.name == Tok.LT:
|
|
3159
|
-
node.gen.py_ast = [self.sync(ast3.Lt())]
|
|
3160
|
-
elif node.name == Tok.LTE:
|
|
3161
|
-
node.gen.py_ast = [self.sync(ast3.LtE())]
|
|
3162
|
-
elif node.name == Tok.NE:
|
|
3163
|
-
node.gen.py_ast = [self.sync(ast3.NotEq())]
|
|
3164
|
-
elif node.name == Tok.KW_NIN:
|
|
3165
|
-
node.gen.py_ast = [self.sync(ast3.NotIn())]
|
|
2831
|
+
op_cls = TOKEN_AST_MAP.get(node.name)
|
|
2832
|
+
if op_cls:
|
|
2833
|
+
node.gen.py_ast = [self.sync(op_cls())]
|
|
3166
2834
|
|
|
3167
2835
|
def exit_name(self, node: uni.Name) -> None:
|
|
3168
2836
|
node.gen.py_ast = [
|
|
@@ -3173,21 +2841,7 @@ class PyastGenPass(UniPass):
|
|
|
3173
2841
|
node.gen.py_ast = [self.sync(ast3.Constant(value=float(node.value)))]
|
|
3174
2842
|
|
|
3175
2843
|
def exit_int(self, node: uni.Int) -> None:
|
|
3176
|
-
|
|
3177
|
-
if value.startswith(("0x", "0X")):
|
|
3178
|
-
return int(value, 16)
|
|
3179
|
-
elif value.startswith(("0b", "0B")):
|
|
3180
|
-
return int(value, 2)
|
|
3181
|
-
elif value.startswith(("0o", "0O")):
|
|
3182
|
-
return int(value, 8)
|
|
3183
|
-
else:
|
|
3184
|
-
return int(value)
|
|
3185
|
-
|
|
3186
|
-
node.gen.py_ast = [
|
|
3187
|
-
self.sync(
|
|
3188
|
-
ast3.Constant(value=handle_node_value(str(node.value)), kind=None)
|
|
3189
|
-
)
|
|
3190
|
-
]
|
|
2844
|
+
node.gen.py_ast = [self.sync(ast3.Constant(value=int(node.value, 0)))]
|
|
3191
2845
|
|
|
3192
2846
|
def exit_string(self, node: uni.String) -> None:
|
|
3193
2847
|
node.gen.py_ast = [self.sync(ast3.Constant(value=node.lit_value))]
|