jaclang 0.7.13__py3-none-any.whl → 0.7.16__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/cli/cli.py +15 -10
- jaclang/cli/cmdreg.py +9 -12
- jaclang/compiler/__init__.py +19 -53
- jaclang/compiler/absyntree.py +95 -17
- jaclang/compiler/jac.lark +4 -3
- jaclang/compiler/parser.py +35 -23
- jaclang/compiler/passes/ir_pass.py +4 -13
- jaclang/compiler/passes/main/access_modifier_pass.py +1 -1
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +4 -5
- jaclang/compiler/passes/main/import_pass.py +19 -23
- jaclang/compiler/passes/main/pyast_gen_pass.py +308 -567
- jaclang/compiler/passes/main/pyast_load_pass.py +33 -6
- jaclang/compiler/passes/main/registry_pass.py +37 -3
- jaclang/compiler/passes/main/sym_tab_build_pass.py +1 -1
- jaclang/compiler/passes/main/tests/__init__.py +1 -1
- jaclang/compiler/passes/main/tests/test_import_pass.py +5 -1
- jaclang/compiler/passes/main/type_check_pass.py +7 -0
- jaclang/compiler/passes/tool/fuse_comments_pass.py +14 -2
- jaclang/compiler/passes/tool/jac_formatter_pass.py +144 -94
- jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +0 -1
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/architype_test.jac +13 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/comment_alignment.jac +11 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/comments.jac +13 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/decorator_stack.jac +37 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/esc_keywords.jac +5 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/long_names.jac +19 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +6 -0
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +11 -0
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +33 -39
- jaclang/compiler/passes/transform.py +4 -0
- jaclang/compiler/semtable.py +31 -7
- jaclang/compiler/tests/test_importer.py +12 -5
- jaclang/langserve/engine.py +82 -143
- jaclang/langserve/sem_manager.py +379 -0
- jaclang/langserve/server.py +8 -10
- jaclang/langserve/tests/fixtures/base_module_structure.jac +27 -6
- jaclang/langserve/tests/fixtures/circle.jac +3 -3
- jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
- jaclang/langserve/tests/fixtures/circle_pure.test.jac +3 -3
- jaclang/langserve/tests/fixtures/import_include_statements.jac +1 -1
- jaclang/langserve/tests/test_sem_tokens.py +277 -0
- jaclang/langserve/tests/test_server.py +96 -16
- jaclang/langserve/utils.py +163 -96
- jaclang/plugin/builtin.py +1 -1
- jaclang/plugin/default.py +214 -24
- jaclang/plugin/feature.py +59 -11
- jaclang/plugin/spec.py +58 -6
- jaclang/{core → runtimelib}/architype.py +1 -1
- jaclang/{core → runtimelib}/context.py +8 -1
- jaclang/runtimelib/importer.py +361 -0
- jaclang/runtimelib/machine.py +94 -0
- jaclang/{core → runtimelib}/utils.py +13 -5
- jaclang/settings.py +4 -1
- jaclang/tests/fixtures/abc.jac +3 -3
- jaclang/tests/fixtures/blankwithentry.jac +3 -0
- jaclang/tests/fixtures/byllmissue.jac +1 -5
- jaclang/tests/fixtures/chandra_bugs2.jac +11 -10
- jaclang/tests/fixtures/cls_method.jac +41 -0
- jaclang/tests/fixtures/dblhello.jac +6 -0
- jaclang/tests/fixtures/deep/one_lev.jac +3 -3
- jaclang/tests/fixtures/deep/one_lev_dup.jac +2 -3
- jaclang/tests/fixtures/deep_import_mods.jac +13 -0
- jaclang/tests/fixtures/err.impl.jac +3 -0
- jaclang/tests/fixtures/err.jac +4 -2
- jaclang/tests/fixtures/err.test.jac +3 -0
- jaclang/tests/fixtures/err_runtime.jac +15 -0
- jaclang/tests/fixtures/game1.jac +1 -1
- jaclang/tests/fixtures/hello.jac +4 -0
- jaclang/tests/fixtures/impl_grab.impl.jac +2 -1
- jaclang/tests/fixtures/impl_grab.jac +4 -1
- jaclang/tests/fixtures/jp_importer_auto.jac +14 -0
- jaclang/tests/fixtures/maxfail_run_test.jac +4 -4
- jaclang/tests/fixtures/needs_import.jac +2 -2
- jaclang/tests/fixtures/pyfunc_2.py +3 -0
- jaclang/tests/fixtures/registry.jac +9 -0
- jaclang/tests/fixtures/run_test.jac +4 -4
- jaclang/tests/fixtures/semstr.jac +1 -4
- jaclang/tests/fixtures/simple_archs.jac +1 -1
- jaclang/tests/test_cli.py +65 -2
- jaclang/tests/test_language.py +83 -7
- jaclang/tests/test_man_code.py +17 -0
- jaclang/tests/test_reference.py +6 -0
- jaclang/utils/helpers.py +45 -21
- jaclang/utils/test.py +9 -0
- jaclang/utils/treeprinter.py +0 -4
- {jaclang-0.7.13.dist-info → jaclang-0.7.16.dist-info}/METADATA +3 -2
- {jaclang-0.7.13.dist-info → jaclang-0.7.16.dist-info}/RECORD +93 -77
- jaclang/core/importer.py +0 -344
- jaclang/tests/fixtures/aott_raise.jac +0 -25
- jaclang/tests/fixtures/package_import.jac +0 -6
- /jaclang/{core → runtimelib}/__init__.py +0 -0
- /jaclang/{core → runtimelib}/constructs.py +0 -0
- /jaclang/{core → runtimelib}/memory.py +0 -0
- /jaclang/{core → runtimelib}/test.py +0 -0
- {jaclang-0.7.13.dist-info → jaclang-0.7.16.dist-info}/WHEEL +0 -0
- {jaclang-0.7.13.dist-info → jaclang-0.7.16.dist-info}/entry_points.txt +0 -0
|
@@ -6,12 +6,12 @@ in each node. Module nodes contain the entire module code.
|
|
|
6
6
|
|
|
7
7
|
import ast as ast3
|
|
8
8
|
import textwrap
|
|
9
|
+
from dataclasses import dataclass
|
|
9
10
|
from typing import Optional, Sequence, TypeVar
|
|
10
11
|
|
|
11
12
|
import jaclang.compiler.absyntree as ast
|
|
12
13
|
from jaclang.compiler.constant import Constants as Con, EdgeDir, Tokens as Tok
|
|
13
14
|
from jaclang.compiler.passes import Pass
|
|
14
|
-
from jaclang.core.utils import extract_params, extract_type, get_sem_scope
|
|
15
15
|
|
|
16
16
|
T = TypeVar("T", bound=ast3.AST)
|
|
17
17
|
|
|
@@ -19,24 +19,25 @@ T = TypeVar("T", bound=ast3.AST)
|
|
|
19
19
|
class PyastGenPass(Pass):
|
|
20
20
|
"""Jac blue transpilation to python pass."""
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
22
|
+
# TODO: This should live in utils and perhaps a test added using it
|
|
23
|
+
# @staticmethod
|
|
24
|
+
# def node_compilable_test(node: ast3.AST) -> None:
|
|
25
|
+
# """Convert any AST node to a compilable module node."""
|
|
26
|
+
# if isinstance(node, ast3.Module):
|
|
27
|
+
# pass
|
|
28
|
+
# elif isinstance(node, (ast3.Expr, ast3.stmt)):
|
|
29
|
+
# node = ast3.Module(body=[node], type_ignores=[])
|
|
30
|
+
# elif isinstance(node, list) and all(isinstance(n, ast3.stmt) for n in node):
|
|
31
|
+
# node = ast3.Module(body=node, type_ignores=[])
|
|
32
|
+
# else:
|
|
33
|
+
# node = ast3.Module(body=[], type_ignores=[])
|
|
34
|
+
# try:
|
|
35
|
+
# compile(node, "<ast>", "exec")
|
|
36
|
+
# except TypeError as e:
|
|
37
|
+
# print(ast3.dump(node, indent=2))
|
|
38
|
+
# raise e
|
|
39
|
+
# except Exception:
|
|
40
|
+
# pass
|
|
40
41
|
|
|
41
42
|
def before_pass(self) -> None:
|
|
42
43
|
"""Initialize pass."""
|
|
@@ -51,14 +52,6 @@ class PyastGenPass(Pass):
|
|
|
51
52
|
),
|
|
52
53
|
jac_node=self.ir,
|
|
53
54
|
),
|
|
54
|
-
self.sync(
|
|
55
|
-
ast3.ImportFrom(
|
|
56
|
-
module="typing",
|
|
57
|
-
names=[self.sync(ast3.alias(name="TYPE_CHECKING", asname=None))],
|
|
58
|
-
level=0,
|
|
59
|
-
),
|
|
60
|
-
jac_node=self.ir,
|
|
61
|
-
),
|
|
62
55
|
]
|
|
63
56
|
|
|
64
57
|
def enter_node(self, node: ast.AstNode) -> None:
|
|
@@ -80,7 +73,7 @@ class PyastGenPass(Pass):
|
|
|
80
73
|
|
|
81
74
|
def needs_jac_import(self) -> None:
|
|
82
75
|
"""Check if import is needed."""
|
|
83
|
-
if
|
|
76
|
+
if self.needs_jac_import.__name__ in self.already_added:
|
|
84
77
|
return
|
|
85
78
|
self.preamble.append(
|
|
86
79
|
self.sync(
|
|
@@ -96,11 +89,11 @@ class PyastGenPass(Pass):
|
|
|
96
89
|
jac_node=self.ir,
|
|
97
90
|
)
|
|
98
91
|
)
|
|
99
|
-
self.already_added.append(
|
|
92
|
+
self.already_added.append(self.needs_jac_import.__name__)
|
|
100
93
|
|
|
101
94
|
def needs_typing(self) -> None:
|
|
102
95
|
"""Check if enum is needed."""
|
|
103
|
-
if
|
|
96
|
+
if self.needs_typing.__name__ in self.already_added:
|
|
104
97
|
return
|
|
105
98
|
self.preamble.append(
|
|
106
99
|
self.sync(
|
|
@@ -115,11 +108,30 @@ class PyastGenPass(Pass):
|
|
|
115
108
|
jac_node=self.ir,
|
|
116
109
|
)
|
|
117
110
|
)
|
|
118
|
-
self.already_added.append(
|
|
111
|
+
self.already_added.append(self.needs_typing.__name__)
|
|
112
|
+
|
|
113
|
+
def needs_abc(self) -> None:
|
|
114
|
+
"""Check if enum is needed."""
|
|
115
|
+
if self.needs_abc.__name__ in self.already_added:
|
|
116
|
+
return
|
|
117
|
+
self.preamble.append(
|
|
118
|
+
self.sync(
|
|
119
|
+
ast3.Import(
|
|
120
|
+
names=[
|
|
121
|
+
self.sync(
|
|
122
|
+
ast3.alias(name="abc", asname="_jac_abc"),
|
|
123
|
+
jac_node=self.ir,
|
|
124
|
+
),
|
|
125
|
+
]
|
|
126
|
+
),
|
|
127
|
+
jac_node=self.ir,
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
self.already_added.append(self.needs_abc.__name__)
|
|
119
131
|
|
|
120
132
|
def needs_enum(self) -> None:
|
|
121
133
|
"""Check if enum is needed."""
|
|
122
|
-
if
|
|
134
|
+
if self.needs_enum.__name__ in self.already_added:
|
|
123
135
|
return
|
|
124
136
|
self.preamble.append(
|
|
125
137
|
self.sync(
|
|
@@ -134,11 +146,11 @@ class PyastGenPass(Pass):
|
|
|
134
146
|
jac_node=self.ir,
|
|
135
147
|
)
|
|
136
148
|
)
|
|
137
|
-
self.already_added.append(
|
|
149
|
+
self.already_added.append(self.needs_enum.__name__)
|
|
138
150
|
|
|
139
151
|
def needs_jac_feature(self) -> None:
|
|
140
152
|
"""Check if enum is needed."""
|
|
141
|
-
if
|
|
153
|
+
if self.needs_jac_feature.__name__ in self.already_added:
|
|
142
154
|
return
|
|
143
155
|
self.preamble.append(
|
|
144
156
|
self.sync(
|
|
@@ -164,11 +176,11 @@ class PyastGenPass(Pass):
|
|
|
164
176
|
jac_node=self.ir,
|
|
165
177
|
)
|
|
166
178
|
)
|
|
167
|
-
self.already_added.append(
|
|
179
|
+
self.already_added.append(self.needs_jac_feature.__name__)
|
|
168
180
|
|
|
169
181
|
def needs_dataclass(self) -> None:
|
|
170
182
|
"""Check if enum is needed."""
|
|
171
|
-
if
|
|
183
|
+
if self.needs_dataclass.__name__ in self.already_added:
|
|
172
184
|
return
|
|
173
185
|
self.preamble.append(
|
|
174
186
|
self.sync(
|
|
@@ -184,11 +196,11 @@ class PyastGenPass(Pass):
|
|
|
184
196
|
jac_node=self.ir,
|
|
185
197
|
)
|
|
186
198
|
)
|
|
187
|
-
self.already_added.append(
|
|
199
|
+
self.already_added.append(self.needs_dataclass.__name__)
|
|
188
200
|
|
|
189
201
|
def needs_dataclass_field(self) -> None:
|
|
190
202
|
"""Check if enum is needed."""
|
|
191
|
-
if
|
|
203
|
+
if self.needs_dataclass_field.__name__ in self.already_added:
|
|
192
204
|
return
|
|
193
205
|
self.preamble.append(
|
|
194
206
|
self.sync(
|
|
@@ -202,7 +214,7 @@ class PyastGenPass(Pass):
|
|
|
202
214
|
jac_node=self.ir,
|
|
203
215
|
)
|
|
204
216
|
)
|
|
205
|
-
self.already_added.append(
|
|
217
|
+
self.already_added.append(self.needs_dataclass_field.__name__)
|
|
206
218
|
|
|
207
219
|
def flatten(self, body: list[T | list[T] | None]) -> list[T]:
|
|
208
220
|
"""Flatten ast list."""
|
|
@@ -425,6 +437,33 @@ class PyastGenPass(Pass):
|
|
|
425
437
|
type_params=[],
|
|
426
438
|
),
|
|
427
439
|
)
|
|
440
|
+
if node.loc.mod_path != self.ir.loc.mod_path:
|
|
441
|
+
func.decorator_list.append(
|
|
442
|
+
self.sync(
|
|
443
|
+
ast3.Call(
|
|
444
|
+
func=self.sync(
|
|
445
|
+
ast3.Attribute(
|
|
446
|
+
value=self.sync(
|
|
447
|
+
ast3.Name(id=Con.JAC_FEATURE.value, ctx=ast3.Load())
|
|
448
|
+
),
|
|
449
|
+
attr="impl_patch_filename",
|
|
450
|
+
ctx=ast3.Load(),
|
|
451
|
+
)
|
|
452
|
+
),
|
|
453
|
+
args=[],
|
|
454
|
+
keywords=[
|
|
455
|
+
self.sync(
|
|
456
|
+
ast3.keyword(
|
|
457
|
+
arg="file_loc",
|
|
458
|
+
value=self.sync(
|
|
459
|
+
ast3.Constant(value=node.body.loc.mod_path)
|
|
460
|
+
),
|
|
461
|
+
)
|
|
462
|
+
),
|
|
463
|
+
],
|
|
464
|
+
)
|
|
465
|
+
)
|
|
466
|
+
)
|
|
428
467
|
node.gen.py_ast = [func]
|
|
429
468
|
|
|
430
469
|
def exit_module_code(self, node: ast.ModuleCode) -> None:
|
|
@@ -434,14 +473,7 @@ class PyastGenPass(Pass):
|
|
|
434
473
|
body: SubNodeList[CodeBlockStmt],
|
|
435
474
|
doc: Optional[String],
|
|
436
475
|
"""
|
|
437
|
-
|
|
438
|
-
doc = self.sync(ast3.Expr(value=node.doc.gen.py_ast[0]), jac_node=node.doc)
|
|
439
|
-
if isinstance(node.body.gen.py_ast, list):
|
|
440
|
-
node.gen.py_ast = [doc] + node.body.gen.py_ast
|
|
441
|
-
else:
|
|
442
|
-
raise self.ice()
|
|
443
|
-
else:
|
|
444
|
-
node.gen.py_ast = node.body.gen.py_ast
|
|
476
|
+
node.gen.py_ast = self.resolve_stmt_block(node.body, doc=node.doc)
|
|
445
477
|
if node.name:
|
|
446
478
|
node.gen.py_ast = [
|
|
447
479
|
self.sync(
|
|
@@ -599,23 +631,12 @@ class PyastGenPass(Pass):
|
|
|
599
631
|
),
|
|
600
632
|
)
|
|
601
633
|
),
|
|
602
|
-
self.sync(
|
|
603
|
-
ast3.keyword(
|
|
604
|
-
arg="mod_bundle",
|
|
605
|
-
value=self.sync(
|
|
606
|
-
ast3.Name(
|
|
607
|
-
id="__name__",
|
|
608
|
-
ctx=ast3.Load(),
|
|
609
|
-
)
|
|
610
|
-
),
|
|
611
|
-
)
|
|
612
|
-
),
|
|
613
634
|
self.sync(
|
|
614
635
|
ast3.keyword(
|
|
615
636
|
arg="lng",
|
|
616
637
|
value=self.sync(
|
|
617
638
|
ast3.Constant(
|
|
618
|
-
value=node.
|
|
639
|
+
value="py" if node.is_py else "jac"
|
|
619
640
|
),
|
|
620
641
|
node.hint,
|
|
621
642
|
),
|
|
@@ -830,10 +851,17 @@ class PyastGenPass(Pass):
|
|
|
830
851
|
)
|
|
831
852
|
)
|
|
832
853
|
)
|
|
854
|
+
self.needs_typing()
|
|
833
855
|
py_nodes.append(
|
|
834
856
|
self.sync(
|
|
835
857
|
ast3.If(
|
|
836
|
-
test=self.sync(
|
|
858
|
+
test=self.sync(
|
|
859
|
+
ast3.Attribute(
|
|
860
|
+
value=self.sync(ast3.Name(id="_jac_typ", ctx=ast3.Load())),
|
|
861
|
+
attr="TYPE_CHECKING",
|
|
862
|
+
ctx=ast3.Load(),
|
|
863
|
+
)
|
|
864
|
+
),
|
|
837
865
|
body=typecheck_nodes,
|
|
838
866
|
orelse=runtime_nodes,
|
|
839
867
|
)
|
|
@@ -906,6 +934,7 @@ class PyastGenPass(Pass):
|
|
|
906
934
|
if isinstance(node.decorators, ast.SubNodeList)
|
|
907
935
|
else []
|
|
908
936
|
)
|
|
937
|
+
|
|
909
938
|
ds_on_entry, ds_on_exit = self.collect_events(node)
|
|
910
939
|
if node.arch_type.name != Tok.KW_CLASS:
|
|
911
940
|
self.needs_jac_feature()
|
|
@@ -978,19 +1007,11 @@ class PyastGenPass(Pass):
|
|
|
978
1007
|
)
|
|
979
1008
|
)
|
|
980
1009
|
if node.is_abstract:
|
|
981
|
-
self.
|
|
1010
|
+
self.needs_abc()
|
|
982
1011
|
base_classes.append(
|
|
983
1012
|
self.sync(
|
|
984
1013
|
ast3.Attribute(
|
|
985
|
-
value=self.sync(
|
|
986
|
-
ast3.Attribute(
|
|
987
|
-
value=self.sync(
|
|
988
|
-
ast3.Name(id=Con.JAC_FEATURE.value, ctx=ast3.Load())
|
|
989
|
-
),
|
|
990
|
-
attr="abc",
|
|
991
|
-
ctx=ast3.Load(),
|
|
992
|
-
)
|
|
993
|
-
),
|
|
1014
|
+
value=self.sync(ast3.Name(id="_jac_abc", ctx=ast3.Load())),
|
|
994
1015
|
attr="ABC",
|
|
995
1016
|
ctx=ast3.Load(),
|
|
996
1017
|
)
|
|
@@ -1140,6 +1161,13 @@ class PyastGenPass(Pass):
|
|
|
1140
1161
|
if isinstance(node.body, ast.AstImplOnlyNode):
|
|
1141
1162
|
self.traverse(node.body)
|
|
1142
1163
|
|
|
1164
|
+
def gen_llm_body(self, node: ast.Ability) -> list[ast3.AST]:
|
|
1165
|
+
"""Generate the by LLM body."""
|
|
1166
|
+
# to Avoid circular import
|
|
1167
|
+
from jaclang.plugin.feature import JacFeature
|
|
1168
|
+
|
|
1169
|
+
return JacFeature.gen_llm_body(self, node)
|
|
1170
|
+
|
|
1143
1171
|
def exit_ability(self, node: ast.Ability) -> None:
|
|
1144
1172
|
"""Sub objects.
|
|
1145
1173
|
|
|
@@ -1186,20 +1214,40 @@ class PyastGenPass(Pass):
|
|
|
1186
1214
|
node,
|
|
1187
1215
|
)
|
|
1188
1216
|
decorator_list = node.decorators.gen.py_ast if node.decorators else []
|
|
1189
|
-
if node.
|
|
1217
|
+
if isinstance(node.body, ast.AstImplOnlyNode):
|
|
1190
1218
|
self.needs_jac_feature()
|
|
1191
1219
|
decorator_list.append(
|
|
1192
1220
|
self.sync(
|
|
1193
|
-
ast3.
|
|
1194
|
-
|
|
1221
|
+
ast3.Call(
|
|
1222
|
+
func=self.sync(
|
|
1195
1223
|
ast3.Attribute(
|
|
1196
1224
|
value=self.sync(
|
|
1197
1225
|
ast3.Name(id=Con.JAC_FEATURE.value, ctx=ast3.Load())
|
|
1198
1226
|
),
|
|
1199
|
-
attr="
|
|
1227
|
+
attr="impl_patch_filename",
|
|
1200
1228
|
ctx=ast3.Load(),
|
|
1201
1229
|
)
|
|
1202
1230
|
),
|
|
1231
|
+
args=[],
|
|
1232
|
+
keywords=[
|
|
1233
|
+
self.sync(
|
|
1234
|
+
ast3.keyword(
|
|
1235
|
+
arg="file_loc",
|
|
1236
|
+
value=self.sync(
|
|
1237
|
+
ast3.Constant(value=node.body.loc.mod_path)
|
|
1238
|
+
),
|
|
1239
|
+
)
|
|
1240
|
+
),
|
|
1241
|
+
],
|
|
1242
|
+
)
|
|
1243
|
+
)
|
|
1244
|
+
)
|
|
1245
|
+
if node.is_abstract:
|
|
1246
|
+
self.needs_abc()
|
|
1247
|
+
decorator_list.append(
|
|
1248
|
+
self.sync(
|
|
1249
|
+
ast3.Attribute(
|
|
1250
|
+
value=self.sync(ast3.Name(id="_jac_abc", ctx=ast3.Load())),
|
|
1203
1251
|
attr="abstractmethod",
|
|
1204
1252
|
ctx=ast3.Load(),
|
|
1205
1253
|
)
|
|
@@ -1241,289 +1289,6 @@ class PyastGenPass(Pass):
|
|
|
1241
1289
|
)
|
|
1242
1290
|
]
|
|
1243
1291
|
|
|
1244
|
-
def gen_llm_body(self, node: ast.Ability) -> list[ast3.AST]:
|
|
1245
|
-
"""Generate llm body."""
|
|
1246
|
-
self.needs_jac_feature()
|
|
1247
|
-
if isinstance(node.body, ast.FuncCall):
|
|
1248
|
-
model = node.body.target.gen.py_ast[0]
|
|
1249
|
-
extracted_type = (
|
|
1250
|
-
"".join(extract_type(node.signature.return_type))
|
|
1251
|
-
if isinstance(node.signature, ast.FuncSignature)
|
|
1252
|
-
and node.signature.return_type
|
|
1253
|
-
else None
|
|
1254
|
-
)
|
|
1255
|
-
scope = self.sync(ast3.Constant(value=str(get_sem_scope(node))))
|
|
1256
|
-
model_params, include_info, exclude_info = extract_params(node.body)
|
|
1257
|
-
inputs = (
|
|
1258
|
-
[
|
|
1259
|
-
self.sync(
|
|
1260
|
-
ast3.Tuple(
|
|
1261
|
-
elts=[
|
|
1262
|
-
(
|
|
1263
|
-
self.sync(
|
|
1264
|
-
ast3.Constant(
|
|
1265
|
-
value=(
|
|
1266
|
-
param.semstr.lit_value
|
|
1267
|
-
if param.semstr
|
|
1268
|
-
else None
|
|
1269
|
-
)
|
|
1270
|
-
)
|
|
1271
|
-
)
|
|
1272
|
-
),
|
|
1273
|
-
(
|
|
1274
|
-
param.type_tag.tag.gen.py_ast[0]
|
|
1275
|
-
if param.type_tag
|
|
1276
|
-
else None
|
|
1277
|
-
),
|
|
1278
|
-
self.sync(ast3.Constant(value=param.name.value)),
|
|
1279
|
-
self.sync(
|
|
1280
|
-
ast3.Name(
|
|
1281
|
-
id=param.name.value,
|
|
1282
|
-
ctx=ast3.Load(),
|
|
1283
|
-
)
|
|
1284
|
-
),
|
|
1285
|
-
],
|
|
1286
|
-
ctx=ast3.Load(),
|
|
1287
|
-
)
|
|
1288
|
-
)
|
|
1289
|
-
for param in node.signature.params.items
|
|
1290
|
-
]
|
|
1291
|
-
if isinstance(node.signature, ast.FuncSignature)
|
|
1292
|
-
and node.signature.params
|
|
1293
|
-
else []
|
|
1294
|
-
)
|
|
1295
|
-
outputs = (
|
|
1296
|
-
[
|
|
1297
|
-
(
|
|
1298
|
-
self.sync(
|
|
1299
|
-
ast3.Constant(
|
|
1300
|
-
value=(
|
|
1301
|
-
node.signature.semstr.lit_value
|
|
1302
|
-
if node.signature.semstr
|
|
1303
|
-
else ""
|
|
1304
|
-
)
|
|
1305
|
-
)
|
|
1306
|
-
)
|
|
1307
|
-
),
|
|
1308
|
-
(self.sync(ast3.Constant(value=(extracted_type)))),
|
|
1309
|
-
]
|
|
1310
|
-
if isinstance(node.signature, ast.FuncSignature)
|
|
1311
|
-
else []
|
|
1312
|
-
)
|
|
1313
|
-
action = (
|
|
1314
|
-
node.semstr.gen.py_ast[0]
|
|
1315
|
-
if node.semstr
|
|
1316
|
-
else self.sync(ast3.Constant(value=node.name_ref.sym_name))
|
|
1317
|
-
)
|
|
1318
|
-
return [
|
|
1319
|
-
self.sync(
|
|
1320
|
-
ast3.Assign(
|
|
1321
|
-
targets=[self.sync(ast3.Name(id="output", ctx=ast3.Store()))],
|
|
1322
|
-
value=self.by_llm_call(
|
|
1323
|
-
model,
|
|
1324
|
-
model_params,
|
|
1325
|
-
scope,
|
|
1326
|
-
inputs,
|
|
1327
|
-
outputs,
|
|
1328
|
-
action,
|
|
1329
|
-
include_info,
|
|
1330
|
-
exclude_info,
|
|
1331
|
-
),
|
|
1332
|
-
)
|
|
1333
|
-
),
|
|
1334
|
-
self.sync(
|
|
1335
|
-
ast3.Try(
|
|
1336
|
-
body=[
|
|
1337
|
-
self.sync(
|
|
1338
|
-
ast3.Return(
|
|
1339
|
-
value=self.sync(
|
|
1340
|
-
ast3.Call(
|
|
1341
|
-
func=self.sync(
|
|
1342
|
-
ast3.Name(id="eval", ctx=ast3.Load())
|
|
1343
|
-
),
|
|
1344
|
-
args=[
|
|
1345
|
-
self.sync(
|
|
1346
|
-
ast3.Name(
|
|
1347
|
-
id="output", ctx=ast3.Load()
|
|
1348
|
-
)
|
|
1349
|
-
)
|
|
1350
|
-
],
|
|
1351
|
-
keywords=[],
|
|
1352
|
-
)
|
|
1353
|
-
)
|
|
1354
|
-
)
|
|
1355
|
-
)
|
|
1356
|
-
],
|
|
1357
|
-
handlers=[
|
|
1358
|
-
self.sync(
|
|
1359
|
-
ast3.ExceptHandler(
|
|
1360
|
-
type=None,
|
|
1361
|
-
name=None,
|
|
1362
|
-
body=[
|
|
1363
|
-
self.sync(
|
|
1364
|
-
ast3.Return(
|
|
1365
|
-
value=self.sync(
|
|
1366
|
-
ast3.Name(
|
|
1367
|
-
id="output", ctx=ast3.Load()
|
|
1368
|
-
)
|
|
1369
|
-
)
|
|
1370
|
-
)
|
|
1371
|
-
)
|
|
1372
|
-
],
|
|
1373
|
-
)
|
|
1374
|
-
)
|
|
1375
|
-
],
|
|
1376
|
-
orelse=[],
|
|
1377
|
-
finalbody=[],
|
|
1378
|
-
)
|
|
1379
|
-
),
|
|
1380
|
-
]
|
|
1381
|
-
else:
|
|
1382
|
-
return []
|
|
1383
|
-
|
|
1384
|
-
def by_llm_call(
|
|
1385
|
-
self,
|
|
1386
|
-
model: ast3.AST,
|
|
1387
|
-
model_params: dict[str, ast.Expr],
|
|
1388
|
-
scope: ast3.AST,
|
|
1389
|
-
inputs: Sequence[Optional[ast3.AST]],
|
|
1390
|
-
outputs: Sequence[Optional[ast3.AST]] | ast3.Call,
|
|
1391
|
-
action: Optional[ast3.AST],
|
|
1392
|
-
include_info: list[tuple[str, ast3.AST]],
|
|
1393
|
-
exclude_info: list[tuple[str, ast3.AST]],
|
|
1394
|
-
) -> ast3.Call:
|
|
1395
|
-
"""Return the LLM Call, e.g. _Jac.with_llm()."""
|
|
1396
|
-
return self.sync(
|
|
1397
|
-
ast3.Call(
|
|
1398
|
-
func=self.sync(
|
|
1399
|
-
ast3.Attribute(
|
|
1400
|
-
value=self.sync(
|
|
1401
|
-
ast3.Name(
|
|
1402
|
-
id=Con.JAC_FEATURE.value,
|
|
1403
|
-
ctx=ast3.Load(),
|
|
1404
|
-
)
|
|
1405
|
-
),
|
|
1406
|
-
attr="with_llm",
|
|
1407
|
-
ctx=ast3.Load(),
|
|
1408
|
-
)
|
|
1409
|
-
),
|
|
1410
|
-
args=[],
|
|
1411
|
-
keywords=[
|
|
1412
|
-
self.sync(
|
|
1413
|
-
ast3.keyword(
|
|
1414
|
-
arg="file_loc",
|
|
1415
|
-
value=self.sync(ast3.Name(id="__file__", ctx=ast3.Load())),
|
|
1416
|
-
)
|
|
1417
|
-
),
|
|
1418
|
-
self.sync(
|
|
1419
|
-
ast3.keyword(
|
|
1420
|
-
arg="model",
|
|
1421
|
-
value=model,
|
|
1422
|
-
)
|
|
1423
|
-
),
|
|
1424
|
-
self.sync(
|
|
1425
|
-
ast3.keyword(
|
|
1426
|
-
arg="model_params",
|
|
1427
|
-
value=self.sync(
|
|
1428
|
-
ast3.Dict(
|
|
1429
|
-
keys=[
|
|
1430
|
-
self.sync(ast3.Constant(value=key))
|
|
1431
|
-
for key in model_params.keys()
|
|
1432
|
-
],
|
|
1433
|
-
values=[
|
|
1434
|
-
value.gen.py_ast[0]
|
|
1435
|
-
for value in model_params.values()
|
|
1436
|
-
],
|
|
1437
|
-
)
|
|
1438
|
-
),
|
|
1439
|
-
)
|
|
1440
|
-
),
|
|
1441
|
-
self.sync(
|
|
1442
|
-
ast3.keyword(
|
|
1443
|
-
arg="scope",
|
|
1444
|
-
value=scope,
|
|
1445
|
-
)
|
|
1446
|
-
),
|
|
1447
|
-
self.sync(
|
|
1448
|
-
ast3.keyword(
|
|
1449
|
-
arg="incl_info",
|
|
1450
|
-
value=self.sync(
|
|
1451
|
-
ast3.List(
|
|
1452
|
-
elts=[
|
|
1453
|
-
self.sync(
|
|
1454
|
-
ast3.Tuple(
|
|
1455
|
-
elts=[
|
|
1456
|
-
self.sync(ast3.Constant(value=key)),
|
|
1457
|
-
value,
|
|
1458
|
-
],
|
|
1459
|
-
ctx=ast3.Load(),
|
|
1460
|
-
)
|
|
1461
|
-
)
|
|
1462
|
-
for key, value in include_info
|
|
1463
|
-
],
|
|
1464
|
-
ctx=ast3.Load(),
|
|
1465
|
-
)
|
|
1466
|
-
),
|
|
1467
|
-
)
|
|
1468
|
-
),
|
|
1469
|
-
self.sync(
|
|
1470
|
-
ast3.keyword(
|
|
1471
|
-
arg="excl_info",
|
|
1472
|
-
value=self.sync(
|
|
1473
|
-
ast3.List(
|
|
1474
|
-
elts=[
|
|
1475
|
-
self.sync(
|
|
1476
|
-
ast3.Tuple(
|
|
1477
|
-
elts=[
|
|
1478
|
-
self.sync(ast3.Constant(value=key)),
|
|
1479
|
-
value,
|
|
1480
|
-
],
|
|
1481
|
-
ctx=ast3.Load(),
|
|
1482
|
-
)
|
|
1483
|
-
)
|
|
1484
|
-
for key, value in exclude_info
|
|
1485
|
-
],
|
|
1486
|
-
ctx=ast3.Load(),
|
|
1487
|
-
)
|
|
1488
|
-
),
|
|
1489
|
-
),
|
|
1490
|
-
),
|
|
1491
|
-
self.sync(
|
|
1492
|
-
ast3.keyword(
|
|
1493
|
-
arg="inputs",
|
|
1494
|
-
value=self.sync(
|
|
1495
|
-
ast3.List(
|
|
1496
|
-
elts=inputs,
|
|
1497
|
-
ctx=ast3.Load(),
|
|
1498
|
-
)
|
|
1499
|
-
),
|
|
1500
|
-
)
|
|
1501
|
-
),
|
|
1502
|
-
self.sync(
|
|
1503
|
-
ast3.keyword(
|
|
1504
|
-
arg="outputs",
|
|
1505
|
-
value=(
|
|
1506
|
-
self.sync(
|
|
1507
|
-
ast3.Tuple(
|
|
1508
|
-
elts=outputs,
|
|
1509
|
-
ctx=ast3.Load(),
|
|
1510
|
-
)
|
|
1511
|
-
)
|
|
1512
|
-
if not isinstance(outputs, ast3.Call)
|
|
1513
|
-
else outputs
|
|
1514
|
-
),
|
|
1515
|
-
)
|
|
1516
|
-
),
|
|
1517
|
-
self.sync(
|
|
1518
|
-
ast3.keyword(
|
|
1519
|
-
arg="action",
|
|
1520
|
-
value=action,
|
|
1521
|
-
)
|
|
1522
|
-
),
|
|
1523
|
-
],
|
|
1524
|
-
)
|
|
1525
|
-
)
|
|
1526
|
-
|
|
1527
1292
|
def exit_ability_def(self, node: ast.AbilityDef) -> None:
|
|
1528
1293
|
"""Sub objects.
|
|
1529
1294
|
|
|
@@ -1542,7 +1307,7 @@ class PyastGenPass(Pass):
|
|
|
1542
1307
|
"""
|
|
1543
1308
|
params = (
|
|
1544
1309
|
[self.sync(ast3.arg(arg="self", annotation=None))]
|
|
1545
|
-
if node.is_method and not node.is_static
|
|
1310
|
+
if node.is_method and not node.is_static and not node.is_in_py_class
|
|
1546
1311
|
else []
|
|
1547
1312
|
)
|
|
1548
1313
|
vararg = None
|
|
@@ -2087,33 +1852,160 @@ class PyastGenPass(Pass):
|
|
|
2087
1852
|
|
|
2088
1853
|
target: ExprType,
|
|
2089
1854
|
"""
|
|
1855
|
+
# TODO: Here is the list of assertions which are not implemented instead a simpler version of them will work.
|
|
1856
|
+
# ie. [] == [] will be assertEqual instead of assertListEqual. However I don't think this is needed since it can
|
|
1857
|
+
# only detected if both operand are compile time literal list or type inferable.
|
|
1858
|
+
#
|
|
1859
|
+
# assertAlmostEqual
|
|
1860
|
+
# assertNotAlmostEqual
|
|
1861
|
+
# assertSequenceEqual
|
|
1862
|
+
# assertListEqual
|
|
1863
|
+
# assertTupleEqual
|
|
1864
|
+
# assertSetEqual
|
|
1865
|
+
# assertDictEqual
|
|
1866
|
+
# assertCountEqual
|
|
1867
|
+
# assertMultiLineEqual
|
|
1868
|
+
# assertRaisesRegex
|
|
1869
|
+
# assertWarnsRegex
|
|
1870
|
+
# assertRegex
|
|
1871
|
+
# assertNotRegex
|
|
1872
|
+
|
|
1873
|
+
# The return type "struct" for the bellow check_node_isinstance_call.
|
|
1874
|
+
@dataclass
|
|
1875
|
+
class CheckNodeIsinstanceCallResult:
|
|
1876
|
+
isit: bool = False
|
|
1877
|
+
inst: ast3.AST | None = None
|
|
1878
|
+
clss: ast3.AST | None = None
|
|
1879
|
+
|
|
1880
|
+
# This will check if a node is `isinstance(<expr>, <expr>)`, we're
|
|
1881
|
+
# using a function because it's reusable to check not isinstance(<expr>, <expr>).
|
|
1882
|
+
def check_node_isinstance_call(
|
|
1883
|
+
node: ast.FuncCall,
|
|
1884
|
+
) -> CheckNodeIsinstanceCallResult:
|
|
1885
|
+
|
|
1886
|
+
# Ensure the type of the FuncCall node is SubNodeList[Expr]
|
|
1887
|
+
# since the type can be: Optional[SubNodeList[Expr | KWPair]].
|
|
1888
|
+
if not (
|
|
1889
|
+
node.params is not None
|
|
1890
|
+
and len(node.params.items) == 2
|
|
1891
|
+
and isinstance(node.params.items[0], ast.Expr)
|
|
1892
|
+
and isinstance(node.params.items[1], ast.Expr)
|
|
1893
|
+
):
|
|
1894
|
+
return CheckNodeIsinstanceCallResult()
|
|
1895
|
+
|
|
1896
|
+
func = node.target.gen.py_ast[0]
|
|
1897
|
+
if not (isinstance(func, ast3.Name) and func.id == "isinstance"):
|
|
1898
|
+
return CheckNodeIsinstanceCallResult()
|
|
1899
|
+
|
|
1900
|
+
return CheckNodeIsinstanceCallResult(
|
|
1901
|
+
True,
|
|
1902
|
+
node.params.items[0].gen.py_ast[0],
|
|
1903
|
+
node.params.items[1].gen.py_ast[0],
|
|
1904
|
+
)
|
|
1905
|
+
|
|
1906
|
+
# By default the check expression will become assertTrue(<expr>), unless any pattern detected.
|
|
1907
|
+
assert_func_name = "assertTrue"
|
|
1908
|
+
assert_args_list = node.target.gen.py_ast
|
|
1909
|
+
|
|
1910
|
+
# Compare operations. Note that We're only considering the compare
|
|
1911
|
+
# operation with a single operation ie. a < b < c is ignored here.
|
|
1912
|
+
if (
|
|
1913
|
+
isinstance(node.target, ast.CompareExpr)
|
|
1914
|
+
and isinstance(node.target.gen.py_ast[0], ast3.Compare)
|
|
1915
|
+
and len(node.target.ops) == 1
|
|
1916
|
+
):
|
|
1917
|
+
expr: ast.CompareExpr = node.target
|
|
1918
|
+
opty: ast.Token = expr.ops[0]
|
|
1919
|
+
|
|
1920
|
+
optype2fn = {
|
|
1921
|
+
Tok.EE.name: "assertEqual",
|
|
1922
|
+
Tok.NE.name: "assertNotEqual",
|
|
1923
|
+
Tok.LT.name: "assertLess",
|
|
1924
|
+
Tok.LTE.name: "assertLessEqual",
|
|
1925
|
+
Tok.GT.name: "assertGreater",
|
|
1926
|
+
Tok.GTE.name: "assertGreaterEqual",
|
|
1927
|
+
Tok.KW_IN.name: "assertIn",
|
|
1928
|
+
Tok.KW_NIN.name: "assertNotIn",
|
|
1929
|
+
Tok.KW_IS.name: "assertIs",
|
|
1930
|
+
Tok.KW_ISN.name: "assertIsNot",
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
if opty.name in optype2fn:
|
|
1934
|
+
assert_func_name = optype2fn[opty.name]
|
|
1935
|
+
assert_args_list = [
|
|
1936
|
+
expr.left.gen.py_ast[0],
|
|
1937
|
+
expr.rights[0].gen.py_ast[0],
|
|
1938
|
+
]
|
|
1939
|
+
|
|
1940
|
+
# Override for <expr> is None.
|
|
1941
|
+
if opty.name == Tok.KW_IS and isinstance(expr.rights[0], ast.Null):
|
|
1942
|
+
assert_func_name = "assertIsNone"
|
|
1943
|
+
assert_args_list.pop()
|
|
1944
|
+
|
|
1945
|
+
# Override for <expr> is not None.
|
|
1946
|
+
elif opty.name == Tok.KW_ISN and isinstance(expr.rights[0], ast.Null):
|
|
1947
|
+
assert_func_name = "assertIsNotNone"
|
|
1948
|
+
assert_args_list.pop()
|
|
1949
|
+
|
|
1950
|
+
# Check if 'isinstance' is called.
|
|
1951
|
+
elif isinstance(node.target, ast.FuncCall) and isinstance(
|
|
1952
|
+
node.target.gen.py_ast[0], ast3.Call
|
|
1953
|
+
):
|
|
1954
|
+
res = check_node_isinstance_call(node.target)
|
|
1955
|
+
if res.isit:
|
|
1956
|
+
# These assertions will make mypy happy.
|
|
1957
|
+
assert isinstance(res.inst, ast3.AST)
|
|
1958
|
+
assert isinstance(res.clss, ast3.AST)
|
|
1959
|
+
assert_func_name = "assertIsInstance"
|
|
1960
|
+
assert_args_list = [res.inst, res.clss]
|
|
1961
|
+
|
|
1962
|
+
# Check if 'not isinstance(<expr>, <expr>)' is called.
|
|
1963
|
+
elif (
|
|
1964
|
+
isinstance(node.target, ast.UnaryExpr)
|
|
1965
|
+
and isinstance(node.target, ast.UnaryExpr)
|
|
1966
|
+
and isinstance(node.target.operand, ast.FuncCall)
|
|
1967
|
+
and isinstance(node.target.operand, ast.UnaryExpr)
|
|
1968
|
+
):
|
|
1969
|
+
res = check_node_isinstance_call(node.target.operand)
|
|
1970
|
+
if res.isit:
|
|
1971
|
+
# These assertions will make mypy happy.
|
|
1972
|
+
assert isinstance(res.inst, ast3.AST)
|
|
1973
|
+
assert isinstance(res.clss, ast3.AST)
|
|
1974
|
+
assert_func_name = "assertIsNotInstance"
|
|
1975
|
+
assert_args_list = [res.inst, res.clss]
|
|
1976
|
+
|
|
1977
|
+
# NOTE That the almost equal is NOT a builtin function of jaclang and won't work outside of the
|
|
1978
|
+
# check statement. And we're hacking the node here. Not sure if this is a hacky workaround to support
|
|
1979
|
+
# the almost equal functionality (snice there is no almost equal operator in jac and never needed ig.).
|
|
1980
|
+
|
|
1981
|
+
# Check if 'almostEqual' is called.
|
|
2090
1982
|
if isinstance(node.target, ast.FuncCall) and isinstance(
|
|
2091
1983
|
node.target.gen.py_ast[0], ast3.Call
|
|
2092
1984
|
):
|
|
2093
|
-
func = node.target.target
|
|
2094
|
-
if isinstance(func,
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
)
|
|
2109
|
-
]
|
|
2110
|
-
return
|
|
2111
|
-
self.error(
|
|
2112
|
-
"For now, check statements must be function calls "
|
|
2113
|
-
"in the style of assertTrue(), assertEqual(), etc.",
|
|
2114
|
-
node,
|
|
1985
|
+
func = node.target.target
|
|
1986
|
+
if isinstance(func, ast.Name) and func.value == "almostEqual":
|
|
1987
|
+
assert_func_name = "assertAlmostEqual"
|
|
1988
|
+
assert_args_list = []
|
|
1989
|
+
if node.target.params is not None:
|
|
1990
|
+
for param in node.target.params.items:
|
|
1991
|
+
assert_args_list.append(param.gen.py_ast[0])
|
|
1992
|
+
|
|
1993
|
+
# assert_func_expr = "_jac_check.assertXXX"
|
|
1994
|
+
assert_func_expr: ast3.Attribute = self.sync(
|
|
1995
|
+
ast3.Attribute(
|
|
1996
|
+
value=self.sync(ast3.Name(id="_jac_check", ctx=ast3.Load())),
|
|
1997
|
+
attr=assert_func_name,
|
|
1998
|
+
ctx=ast3.Load(),
|
|
1999
|
+
)
|
|
2115
2000
|
)
|
|
2116
2001
|
|
|
2002
|
+
# assert_call_expr = "(_jac_check.assertXXX)(args)"
|
|
2003
|
+
assert_call_expr: ast3.Call = self.sync(
|
|
2004
|
+
ast3.Call(func=assert_func_expr, args=assert_args_list, keywords=[])
|
|
2005
|
+
)
|
|
2006
|
+
|
|
2007
|
+
node.gen.py_ast = [self.sync(ast3.Expr(assert_call_expr))]
|
|
2008
|
+
|
|
2117
2009
|
def exit_ctrl_stmt(self, node: ast.CtrlStmt) -> None:
|
|
2118
2010
|
"""Sub objects.
|
|
2119
2011
|
|
|
@@ -3080,6 +2972,40 @@ class PyastGenPass(Pass):
|
|
|
3080
2972
|
"""
|
|
3081
2973
|
node.gen.py_ast = node.value.gen.py_ast
|
|
3082
2974
|
|
|
2975
|
+
def by_llm_call(
|
|
2976
|
+
self,
|
|
2977
|
+
model: ast3.AST,
|
|
2978
|
+
model_params: dict[str, ast.Expr],
|
|
2979
|
+
scope: ast3.AST,
|
|
2980
|
+
inputs: Sequence[Optional[ast3.AST]],
|
|
2981
|
+
outputs: Sequence[Optional[ast3.AST]] | ast3.Call,
|
|
2982
|
+
action: Optional[ast3.AST],
|
|
2983
|
+
include_info: list[tuple[str, ast3.AST]],
|
|
2984
|
+
exclude_info: list[tuple[str, ast3.AST]],
|
|
2985
|
+
) -> ast3.Call:
|
|
2986
|
+
"""Return the LLM Call, e.g. _Jac.with_llm()."""
|
|
2987
|
+
# to avoid circular import
|
|
2988
|
+
from jaclang.plugin.feature import JacFeature
|
|
2989
|
+
|
|
2990
|
+
return JacFeature.by_llm_call(
|
|
2991
|
+
self,
|
|
2992
|
+
model,
|
|
2993
|
+
model_params,
|
|
2994
|
+
scope,
|
|
2995
|
+
inputs,
|
|
2996
|
+
outputs,
|
|
2997
|
+
action,
|
|
2998
|
+
include_info,
|
|
2999
|
+
exclude_info,
|
|
3000
|
+
)
|
|
3001
|
+
|
|
3002
|
+
def get_by_llm_call_args(self, node: ast.FuncCall) -> dict:
|
|
3003
|
+
"""Get the arguments for the by_llm_call."""
|
|
3004
|
+
# to avoid circular import
|
|
3005
|
+
from jaclang.plugin.feature import JacFeature
|
|
3006
|
+
|
|
3007
|
+
return JacFeature.get_by_llm_call_args(self, node)
|
|
3008
|
+
|
|
3083
3009
|
def exit_func_call(self, node: ast.FuncCall) -> None:
|
|
3084
3010
|
"""Sub objects.
|
|
3085
3011
|
|
|
@@ -3105,193 +3031,8 @@ class PyastGenPass(Pass):
|
|
|
3105
3031
|
self.ice("Invalid Parameter")
|
|
3106
3032
|
if node.genai_call:
|
|
3107
3033
|
self.needs_jac_feature()
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
action = self.sync(
|
|
3111
|
-
ast3.Constant(
|
|
3112
|
-
value="Create an object of the specified type, using the specifically "
|
|
3113
|
-
" provided input value(s) and look up any missing attributes from reliable"
|
|
3114
|
-
" online sources to fill them in accurately."
|
|
3115
|
-
)
|
|
3116
|
-
)
|
|
3117
|
-
_output_ = "".join(extract_type(node.target))
|
|
3118
|
-
include_info.append(
|
|
3119
|
-
(
|
|
3120
|
-
_output_.split(".")[0],
|
|
3121
|
-
self.sync(ast3.Name(id=_output_.split(".")[0], ctx=ast3.Load())),
|
|
3122
|
-
)
|
|
3123
|
-
)
|
|
3124
|
-
scope = self.sync(
|
|
3125
|
-
ast3.Call(
|
|
3126
|
-
func=self.sync(
|
|
3127
|
-
ast3.Attribute(
|
|
3128
|
-
value=self.sync(
|
|
3129
|
-
ast3.Name(
|
|
3130
|
-
id=Con.JAC_FEATURE.value,
|
|
3131
|
-
ctx=ast3.Load(),
|
|
3132
|
-
)
|
|
3133
|
-
),
|
|
3134
|
-
attr="obj_scope",
|
|
3135
|
-
ctx=ast3.Load(),
|
|
3136
|
-
)
|
|
3137
|
-
),
|
|
3138
|
-
args=[
|
|
3139
|
-
self.sync(
|
|
3140
|
-
ast3.Name(
|
|
3141
|
-
id="__file__",
|
|
3142
|
-
ctx=ast3.Load(),
|
|
3143
|
-
)
|
|
3144
|
-
),
|
|
3145
|
-
self.sync(ast3.Constant(value=_output_)),
|
|
3146
|
-
],
|
|
3147
|
-
keywords=[],
|
|
3148
|
-
)
|
|
3149
|
-
)
|
|
3150
|
-
outputs = self.sync(
|
|
3151
|
-
ast3.Call(
|
|
3152
|
-
func=self.sync(
|
|
3153
|
-
ast3.Attribute(
|
|
3154
|
-
value=self.sync(
|
|
3155
|
-
ast3.Name(
|
|
3156
|
-
id=Con.JAC_FEATURE.value,
|
|
3157
|
-
ctx=ast3.Load(),
|
|
3158
|
-
)
|
|
3159
|
-
),
|
|
3160
|
-
attr="get_sem_type",
|
|
3161
|
-
ctx=ast3.Load(),
|
|
3162
|
-
)
|
|
3163
|
-
),
|
|
3164
|
-
args=[
|
|
3165
|
-
self.sync(
|
|
3166
|
-
ast3.Name(
|
|
3167
|
-
id="__file__",
|
|
3168
|
-
ctx=ast3.Load(),
|
|
3169
|
-
)
|
|
3170
|
-
),
|
|
3171
|
-
self.sync(ast3.Constant(value=str(_output_))),
|
|
3172
|
-
],
|
|
3173
|
-
keywords=[],
|
|
3174
|
-
)
|
|
3175
|
-
)
|
|
3176
|
-
if node.params and node.params.items:
|
|
3177
|
-
inputs = [
|
|
3178
|
-
self.sync(
|
|
3179
|
-
ast3.Tuple(
|
|
3180
|
-
elts=[
|
|
3181
|
-
self.sync(
|
|
3182
|
-
ast3.Call(
|
|
3183
|
-
func=self.sync(
|
|
3184
|
-
ast3.Attribute(
|
|
3185
|
-
value=self.sync(
|
|
3186
|
-
ast3.Name(
|
|
3187
|
-
id=Con.JAC_FEATURE.value,
|
|
3188
|
-
ctx=ast3.Load(),
|
|
3189
|
-
)
|
|
3190
|
-
),
|
|
3191
|
-
attr="get_semstr_type",
|
|
3192
|
-
ctx=ast3.Load(),
|
|
3193
|
-
)
|
|
3194
|
-
),
|
|
3195
|
-
args=[
|
|
3196
|
-
self.sync(
|
|
3197
|
-
ast3.Name(
|
|
3198
|
-
id="__file__", ctx=ast3.Load()
|
|
3199
|
-
)
|
|
3200
|
-
),
|
|
3201
|
-
scope,
|
|
3202
|
-
self.sync(
|
|
3203
|
-
ast3.Constant(
|
|
3204
|
-
value=(
|
|
3205
|
-
kw_pair.key.value
|
|
3206
|
-
if isinstance(
|
|
3207
|
-
kw_pair.key, ast.Name
|
|
3208
|
-
)
|
|
3209
|
-
else None
|
|
3210
|
-
)
|
|
3211
|
-
)
|
|
3212
|
-
),
|
|
3213
|
-
self.sync(ast3.Constant(value=True)),
|
|
3214
|
-
],
|
|
3215
|
-
keywords=[],
|
|
3216
|
-
)
|
|
3217
|
-
),
|
|
3218
|
-
self.sync(
|
|
3219
|
-
ast3.Call(
|
|
3220
|
-
func=self.sync(
|
|
3221
|
-
ast3.Attribute(
|
|
3222
|
-
value=self.sync(
|
|
3223
|
-
ast3.Name(
|
|
3224
|
-
id=Con.JAC_FEATURE.value,
|
|
3225
|
-
ctx=ast3.Load(),
|
|
3226
|
-
)
|
|
3227
|
-
),
|
|
3228
|
-
attr="get_semstr_type",
|
|
3229
|
-
ctx=ast3.Load(),
|
|
3230
|
-
)
|
|
3231
|
-
),
|
|
3232
|
-
args=[
|
|
3233
|
-
self.sync(
|
|
3234
|
-
ast3.Name(
|
|
3235
|
-
id="__file__", ctx=ast3.Load()
|
|
3236
|
-
)
|
|
3237
|
-
),
|
|
3238
|
-
scope,
|
|
3239
|
-
self.sync(
|
|
3240
|
-
ast3.Constant(
|
|
3241
|
-
value=(
|
|
3242
|
-
kw_pair.key.value
|
|
3243
|
-
if isinstance(
|
|
3244
|
-
kw_pair.key, ast.Name
|
|
3245
|
-
)
|
|
3246
|
-
else None
|
|
3247
|
-
)
|
|
3248
|
-
)
|
|
3249
|
-
),
|
|
3250
|
-
self.sync(ast3.Constant(value=False)),
|
|
3251
|
-
],
|
|
3252
|
-
keywords=[],
|
|
3253
|
-
)
|
|
3254
|
-
),
|
|
3255
|
-
self.sync(
|
|
3256
|
-
ast3.Constant(
|
|
3257
|
-
value=(
|
|
3258
|
-
kw_pair.key.value
|
|
3259
|
-
if isinstance(kw_pair.key, ast.Name)
|
|
3260
|
-
else None
|
|
3261
|
-
)
|
|
3262
|
-
)
|
|
3263
|
-
),
|
|
3264
|
-
kw_pair.value.gen.py_ast[0],
|
|
3265
|
-
],
|
|
3266
|
-
ctx=ast3.Load(),
|
|
3267
|
-
)
|
|
3268
|
-
)
|
|
3269
|
-
for kw_pair in node.params.items
|
|
3270
|
-
if isinstance(kw_pair, ast.KWPair)
|
|
3271
|
-
]
|
|
3272
|
-
else:
|
|
3273
|
-
inputs = []
|
|
3274
|
-
|
|
3275
|
-
node.gen.py_ast = [
|
|
3276
|
-
self.sync(
|
|
3277
|
-
ast3.Call(
|
|
3278
|
-
func=self.sync(ast3.Name(id="eval", ctx=ast3.Load())),
|
|
3279
|
-
args=[
|
|
3280
|
-
self.by_llm_call(
|
|
3281
|
-
model,
|
|
3282
|
-
model_params,
|
|
3283
|
-
scope,
|
|
3284
|
-
inputs,
|
|
3285
|
-
outputs,
|
|
3286
|
-
action,
|
|
3287
|
-
include_info,
|
|
3288
|
-
exclude_info,
|
|
3289
|
-
),
|
|
3290
|
-
],
|
|
3291
|
-
keywords=[],
|
|
3292
|
-
)
|
|
3293
|
-
)
|
|
3294
|
-
]
|
|
3034
|
+
by_llm_call_args = self.get_by_llm_call_args(node)
|
|
3035
|
+
node.gen.py_ast = [self.sync(self.by_llm_call(**by_llm_call_args))]
|
|
3295
3036
|
else:
|
|
3296
3037
|
node.gen.py_ast = [
|
|
3297
3038
|
self.sync(ast3.Call(func=func, args=args, keywords=keywords))
|