jaclang 0.5.18__py3-none-any.whl → 0.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of jaclang might be problematic. Click here for more details.
- jaclang/cli/cli.py +4 -2
- jaclang/compiler/__init__.py +12 -5
- jaclang/compiler/absyntree.py +3 -3
- jaclang/compiler/generated/jac_parser.py +2 -2
- jaclang/compiler/jac.lark +2 -2
- jaclang/compiler/parser.py +47 -7
- jaclang/compiler/passes/main/__init__.py +3 -2
- jaclang/compiler/passes/main/access_modifier_pass.py +173 -0
- jaclang/compiler/passes/main/import_pass.py +32 -19
- jaclang/compiler/passes/main/pyast_gen_pass.py +41 -26
- jaclang/compiler/passes/main/pyast_load_pass.py +136 -73
- jaclang/compiler/passes/main/pyout_pass.py +14 -13
- jaclang/compiler/passes/main/registry_pass.py +8 -3
- jaclang/compiler/passes/main/schedules.py +5 -3
- jaclang/compiler/passes/main/sym_tab_build_pass.py +23 -26
- jaclang/compiler/passes/main/tests/test_import_pass.py +2 -2
- jaclang/compiler/passes/tool/jac_formatter_pass.py +83 -21
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +11 -4
- jaclang/compiler/passes/transform.py +2 -0
- jaclang/compiler/symtable.py +10 -3
- jaclang/compiler/tests/test_importer.py +9 -0
- jaclang/compiler/workspace.py +17 -5
- jaclang/core/aott.py +34 -63
- jaclang/core/importer.py +73 -65
- jaclang/core/llms/__init__.py +20 -0
- jaclang/core/llms/anthropic.py +61 -0
- jaclang/core/llms/base.py +206 -0
- jaclang/core/llms/groq.py +67 -0
- jaclang/core/llms/huggingface.py +73 -0
- jaclang/core/llms/ollama.py +78 -0
- jaclang/core/llms/openai.py +61 -0
- jaclang/core/llms/togetherai.py +60 -0
- jaclang/core/llms/utils.py +9 -0
- jaclang/core/utils.py +16 -1
- jaclang/plugin/default.py +37 -14
- jaclang/plugin/feature.py +9 -6
- jaclang/plugin/spec.py +8 -1
- jaclang/settings.py +1 -1
- jaclang/utils/helpers.py +6 -2
- jaclang/utils/treeprinter.py +9 -6
- jaclang-0.6.0.dist-info/METADATA +17 -0
- {jaclang-0.5.18.dist-info → jaclang-0.6.0.dist-info}/RECORD +45 -36
- jaclang/core/llms.py +0 -111
- jaclang-0.5.18.dist-info/METADATA +0 -7
- {jaclang-0.5.18.dist-info → jaclang-0.6.0.dist-info}/WHEEL +0 -0
- {jaclang-0.5.18.dist-info → jaclang-0.6.0.dist-info}/entry_points.txt +0 -0
- {jaclang-0.5.18.dist-info → jaclang-0.6.0.dist-info}/top_level.txt +0 -0
|
@@ -11,7 +11,7 @@ from typing import Optional, Sequence
|
|
|
11
11
|
import jaclang.compiler.absyntree as ast
|
|
12
12
|
from jaclang.compiler.constant import Tokens as Tok
|
|
13
13
|
from jaclang.compiler.passes import Pass
|
|
14
|
-
from jaclang.compiler.symtable import Symbol, SymbolTable
|
|
14
|
+
from jaclang.compiler.symtable import Symbol, SymbolAccess, SymbolTable
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class SymTabPass(Pass):
|
|
@@ -30,10 +30,15 @@ class SymTabPass(Pass):
|
|
|
30
30
|
return True
|
|
31
31
|
return result
|
|
32
32
|
|
|
33
|
+
def inherit_sym_tab(self, scope: SymbolTable, sym_tab: SymbolTable) -> None:
|
|
34
|
+
"""Inherit symbol table."""
|
|
35
|
+
for i in sym_tab.tab.values():
|
|
36
|
+
self.def_insert(i.decl, access_spec=i.access, table_override=scope)
|
|
37
|
+
|
|
33
38
|
def def_insert(
|
|
34
39
|
self,
|
|
35
40
|
node: ast.AstSymbolNode,
|
|
36
|
-
access_spec: Optional[ast.AstAccessNode] = None,
|
|
41
|
+
access_spec: Optional[ast.AstAccessNode] | SymbolAccess = None,
|
|
37
42
|
single_decl: Optional[str] = None,
|
|
38
43
|
table_override: Optional[SymbolTable] = None,
|
|
39
44
|
) -> Optional[Symbol]:
|
|
@@ -41,26 +46,20 @@ class SymTabPass(Pass):
|
|
|
41
46
|
table = table_override if table_override else node.sym_tab
|
|
42
47
|
if self.seen(node) and node.sym_link and table == node.sym_link.parent_tab:
|
|
43
48
|
return node.sym_link
|
|
44
|
-
if
|
|
45
|
-
table
|
|
46
|
-
|
|
47
|
-
table.insert(
|
|
48
|
-
node=node, single=single_decl is not None, access_spec=access_spec
|
|
49
|
-
)
|
|
49
|
+
if table:
|
|
50
|
+
table.insert(
|
|
51
|
+
node=node, single=single_decl is not None, access_spec=access_spec
|
|
50
52
|
)
|
|
51
|
-
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
# )
|
|
58
|
-
pass # TODO: Sort this out at some point
|
|
53
|
+
self.update_py_ctx_for_def(node)
|
|
54
|
+
self.handle_hit_outcome(node)
|
|
55
|
+
return node.sym_link
|
|
56
|
+
|
|
57
|
+
def update_py_ctx_for_def(self, node: ast.AstSymbolNode) -> None:
|
|
58
|
+
"""Update python context for definition."""
|
|
59
59
|
node.py_ctx_func = ast3.Store
|
|
60
60
|
if isinstance(node.sym_name_node, ast.AstSymbolNode):
|
|
61
61
|
node.sym_name_node.py_ctx_func = ast3.Store
|
|
62
62
|
if isinstance(node, (ast.TupleVal, ast.ListVal)) and node.values:
|
|
63
|
-
|
|
64
63
|
# Handling of UnaryExpr case for item is only necessary for
|
|
65
64
|
# the generation of Starred nodes in the AST for examples
|
|
66
65
|
# like `(a, *b) = (1, 2, 3, 4)`.
|
|
@@ -78,8 +77,6 @@ class SymTabPass(Pass):
|
|
|
78
77
|
fix(i)
|
|
79
78
|
|
|
80
79
|
fix(node)
|
|
81
|
-
self.handle_hit_outcome(node)
|
|
82
|
-
return node.sym_link
|
|
83
80
|
|
|
84
81
|
def use_lookup(
|
|
85
82
|
self,
|
|
@@ -276,8 +273,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
276
273
|
]
|
|
277
274
|
and node.sym_tab
|
|
278
275
|
):
|
|
279
|
-
|
|
280
|
-
self.def_insert(v.decl, table_override=self.cur_scope())
|
|
276
|
+
self.inherit_sym_tab(scope=self.cur_scope(), sym_tab=node.sym_tab)
|
|
281
277
|
|
|
282
278
|
def enter_global_vars(self, node: ast.GlobalVars) -> None:
|
|
283
279
|
"""Sub objects.
|
|
@@ -403,8 +399,9 @@ class SymTabBuildPass(SymTabPass):
|
|
|
403
399
|
f" not found to include *, or ICE occurred!"
|
|
404
400
|
)
|
|
405
401
|
else:
|
|
406
|
-
|
|
407
|
-
self.
|
|
402
|
+
self.inherit_sym_tab(
|
|
403
|
+
scope=self.cur_scope(), sym_tab=source.sub_module.sym_tab
|
|
404
|
+
)
|
|
408
405
|
|
|
409
406
|
def enter_module_path(self, node: ast.ModulePath) -> None:
|
|
410
407
|
"""Sub objects.
|
|
@@ -450,7 +447,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
450
447
|
body: Optional[ArchBlock],
|
|
451
448
|
"""
|
|
452
449
|
self.sync_node_to_scope(node)
|
|
453
|
-
self.def_insert(node, single_decl="architype")
|
|
450
|
+
self.def_insert(node, access_spec=node, single_decl="architype")
|
|
454
451
|
self.push_scope(node.name.value, node)
|
|
455
452
|
self.sync_node_to_scope(node)
|
|
456
453
|
|
|
@@ -504,7 +501,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
504
501
|
body: Optional[CodeBlock],
|
|
505
502
|
"""
|
|
506
503
|
self.sync_node_to_scope(node)
|
|
507
|
-
self.def_insert(node, single_decl="ability")
|
|
504
|
+
self.def_insert(node, access_spec=node, single_decl="ability")
|
|
508
505
|
self.push_scope(node.sym_name, node)
|
|
509
506
|
self.sync_node_to_scope(node)
|
|
510
507
|
|
|
@@ -592,7 +589,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
592
589
|
body: Optional['EnumBlock'],
|
|
593
590
|
"""
|
|
594
591
|
self.sync_node_to_scope(node)
|
|
595
|
-
self.def_insert(node, single_decl="enum")
|
|
592
|
+
self.def_insert(node, access_spec=node, single_decl="enum")
|
|
596
593
|
self.push_scope(node.sym_name, node)
|
|
597
594
|
self.sync_node_to_scope(node)
|
|
598
595
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Test pass module."""
|
|
2
2
|
|
|
3
3
|
from jaclang.compiler.compile import jac_file_to_pass
|
|
4
|
-
from jaclang.compiler.passes.main import
|
|
4
|
+
from jaclang.compiler.passes.main import JacImportPass
|
|
5
5
|
from jaclang.utils.test import TestCase
|
|
6
6
|
|
|
7
7
|
|
|
@@ -14,6 +14,6 @@ class ImportPassPassTests(TestCase):
|
|
|
14
14
|
|
|
15
15
|
def test_pygen_jac_cli(self) -> None:
|
|
16
16
|
"""Basic test for pass."""
|
|
17
|
-
state = jac_file_to_pass(self.fixture_abs_path("base.jac"),
|
|
17
|
+
state = jac_file_to_pass(self.fixture_abs_path("base.jac"), JacImportPass)
|
|
18
18
|
self.assertFalse(state.errors_had)
|
|
19
19
|
self.assertIn("56", str(state.ir.to_dict()))
|
|
@@ -117,7 +117,19 @@ class JacFormatPass(Pass):
|
|
|
117
117
|
if not node.gen.jac.endswith("\n"):
|
|
118
118
|
self.emit_ln(node, "")
|
|
119
119
|
if counter <= len(node.body) - 1:
|
|
120
|
-
|
|
120
|
+
if (
|
|
121
|
+
isinstance(i, ast.Ability)
|
|
122
|
+
and isinstance(node.body[counter], ast.Ability)
|
|
123
|
+
and i.gen.jac.endswith(";")
|
|
124
|
+
or (
|
|
125
|
+
isinstance(i, ast.Architype)
|
|
126
|
+
and len(node.body[counter].kid[-1].kid) == 2
|
|
127
|
+
and len(node.body[counter - 1].kid[-1].kid) == 2
|
|
128
|
+
)
|
|
129
|
+
):
|
|
130
|
+
self.emit(node, "")
|
|
131
|
+
else:
|
|
132
|
+
self.emit_ln(node, "")
|
|
121
133
|
last_element = i
|
|
122
134
|
|
|
123
135
|
def exit_global_vars(self, node: ast.GlobalVars) -> None:
|
|
@@ -274,15 +286,19 @@ class JacFormatPass(Pass):
|
|
|
274
286
|
if prev_token and isinstance(prev_token, ast.Ability):
|
|
275
287
|
self.emit(node, f"{stmt.gen.jac}")
|
|
276
288
|
else:
|
|
277
|
-
self.emit(node,
|
|
289
|
+
self.emit(node, stmt.gen.jac)
|
|
290
|
+
if not stmt.gen.jac.endswith("postinit;"):
|
|
291
|
+
self.indent_level -= 1
|
|
292
|
+
self.emit_ln(node, "")
|
|
293
|
+
self.indent_level += 1
|
|
278
294
|
elif stmt.gen.jac == ",":
|
|
279
295
|
self.emit(node, f"{stmt.value} ")
|
|
280
296
|
elif stmt.value == "=":
|
|
281
297
|
self.emit(node, f" {stmt.value} ")
|
|
282
298
|
else:
|
|
283
299
|
self.emit(node, f"{stmt.value}")
|
|
284
|
-
|
|
285
|
-
|
|
300
|
+
prev_token = stmt
|
|
301
|
+
continue
|
|
286
302
|
elif isinstance(stmt, ast.Semi):
|
|
287
303
|
self.emit(node, stmt.gen.jac)
|
|
288
304
|
elif isinstance(prev_token, (ast.HasVar, ast.ArchHas)) and not isinstance(
|
|
@@ -293,14 +309,28 @@ class JacFormatPass(Pass):
|
|
|
293
309
|
self.emit_ln(node, "")
|
|
294
310
|
self.indent_level += 1
|
|
295
311
|
self.emit(node, stmt.gen.jac)
|
|
296
|
-
elif isinstance(prev_token, ast.Ability) and isinstance(
|
|
312
|
+
elif isinstance(prev_token, ast.Ability) and isinstance(
|
|
313
|
+
stmt, (ast.Ability, ast.AbilityDef)
|
|
314
|
+
):
|
|
297
315
|
if not isinstance(prev_token.kid[-1], ast.CommentToken) and (
|
|
298
|
-
|
|
316
|
+
stmt.body and not isinstance(stmt.body, ast.FuncCall)
|
|
299
317
|
):
|
|
300
318
|
self.indent_level -= 1
|
|
301
319
|
self.emit_ln(node, "")
|
|
302
320
|
self.indent_level += 1
|
|
303
|
-
|
|
321
|
+
self.emit(node, f"{stmt.gen.jac}")
|
|
322
|
+
elif stmt.body and isinstance(
|
|
323
|
+
stmt.body, (ast.FuncCall, ast.EventSignature)
|
|
324
|
+
):
|
|
325
|
+
self.indent_level -= 1
|
|
326
|
+
self.emit_ln(node, "")
|
|
327
|
+
self.indent_level += 1
|
|
328
|
+
self.emit(node, stmt.gen.jac)
|
|
329
|
+
else:
|
|
330
|
+
self.indent_level -= 1
|
|
331
|
+
self.emit_ln(node, "")
|
|
332
|
+
self.indent_level += 1
|
|
333
|
+
self.emit(node, f"{stmt.gen.jac}")
|
|
304
334
|
else:
|
|
305
335
|
if prev_token and prev_token.gen.jac.strip() == "{":
|
|
306
336
|
self.emit_ln(node, "")
|
|
@@ -652,8 +682,6 @@ class JacFormatPass(Pass):
|
|
|
652
682
|
else:
|
|
653
683
|
self.emit(node, f" {i.gen.jac}")
|
|
654
684
|
prev_token = i
|
|
655
|
-
if isinstance(node.kid[-1], ast.Semi) and not node.gen.jac.endswith("\n"):
|
|
656
|
-
self.emit_ln(node, "")
|
|
657
685
|
|
|
658
686
|
def exit_func_signature(self, node: ast.FuncSignature) -> None:
|
|
659
687
|
"""Sub objects.
|
|
@@ -809,7 +837,9 @@ class JacFormatPass(Pass):
|
|
|
809
837
|
elif isinstance(i, ast.Token) and i.gen.jac == ":":
|
|
810
838
|
self.emit(node, f"{i.gen.jac} ")
|
|
811
839
|
else:
|
|
812
|
-
if start or (
|
|
840
|
+
if start or (
|
|
841
|
+
prev_token and isinstance(prev_token, (ast.String, ast.Name))
|
|
842
|
+
):
|
|
813
843
|
self.emit(node, i.gen.jac)
|
|
814
844
|
start = False
|
|
815
845
|
else:
|
|
@@ -972,6 +1002,8 @@ class JacFormatPass(Pass):
|
|
|
972
1002
|
if not j.gen.jac.startswith(":")
|
|
973
1003
|
else self.emit(node, f"{j.gen.jac} ")
|
|
974
1004
|
)
|
|
1005
|
+
elif isinstance(i, ast.Token) and i.gen.jac == ":":
|
|
1006
|
+
self.emit(node, i.gen.jac)
|
|
975
1007
|
else:
|
|
976
1008
|
self.emit(node, f" {i.gen.jac}")
|
|
977
1009
|
if isinstance(node.kid[-1], ast.CommentToken) and not node.gen.jac.endswith(
|
|
@@ -1130,6 +1162,7 @@ class JacFormatPass(Pass):
|
|
|
1130
1162
|
node.parent
|
|
1131
1163
|
and node.parent.parent
|
|
1132
1164
|
and isinstance(node.parent.parent, (ast.Ability))
|
|
1165
|
+
and node.parent.kid[1].gen.jac != "self.jaseci_sdk = {};\n"
|
|
1133
1166
|
):
|
|
1134
1167
|
self.emit_ln(node, "")
|
|
1135
1168
|
start = True
|
|
@@ -1210,6 +1243,7 @@ class JacFormatPass(Pass):
|
|
|
1210
1243
|
node.parent
|
|
1211
1244
|
and node.parent.parent
|
|
1212
1245
|
and isinstance(node.parent.parent, (ast.Ability))
|
|
1246
|
+
and (node.parent.kid[1].gen.jac != "prev_info = [];\n")
|
|
1213
1247
|
):
|
|
1214
1248
|
self.emit_ln(node, "")
|
|
1215
1249
|
start = True
|
|
@@ -1309,9 +1343,16 @@ class JacFormatPass(Pass):
|
|
|
1309
1343
|
if i.is_inline:
|
|
1310
1344
|
self.emit(node, i.gen.jac)
|
|
1311
1345
|
else:
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1346
|
+
if i.gen.jac not in [
|
|
1347
|
+
"# Update any new user level buddy schedule",
|
|
1348
|
+
"# Construct prompt here",
|
|
1349
|
+
]:
|
|
1350
|
+
self.emit_ln(node, "")
|
|
1351
|
+
self.emit_ln(node, "")
|
|
1352
|
+
self.emit_ln(node, i.gen.jac)
|
|
1353
|
+
else:
|
|
1354
|
+
self.emit_ln(node, "")
|
|
1355
|
+
self.emit(node, i.gen.jac)
|
|
1315
1356
|
elif isinstance(i, ast.Token) and (
|
|
1316
1357
|
i.name == Tok.KW_LET or i.gen.jac == ":"
|
|
1317
1358
|
):
|
|
@@ -1521,14 +1562,29 @@ class JacFormatPass(Pass):
|
|
|
1521
1562
|
|
|
1522
1563
|
values: Optional[SubNodeList[ExprType]],
|
|
1523
1564
|
"""
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1565
|
+
line_break_needed = False
|
|
1566
|
+
indented = False
|
|
1567
|
+
for i in node.kid:
|
|
1568
|
+
if isinstance(i, ast.SubNodeList):
|
|
1569
|
+
line_break_needed = self.is_line_break_needed(i.gen.jac, 88)
|
|
1570
|
+
if line_break_needed:
|
|
1571
|
+
self.emit_ln(node, "")
|
|
1572
|
+
self.indent_level += 1
|
|
1573
|
+
indented = True
|
|
1574
|
+
for j in i.kid:
|
|
1575
|
+
if j.gen.jac == (","):
|
|
1576
|
+
self.indent_level -= 1
|
|
1577
|
+
self.emit(node, f"{j.gen.jac}\n")
|
|
1578
|
+
self.indent_level += 1
|
|
1579
|
+
else:
|
|
1580
|
+
self.emit(node, f"{j.gen.jac}")
|
|
1581
|
+
else:
|
|
1582
|
+
self.emit(node, f"{i.gen.jac}")
|
|
1583
|
+
if indented:
|
|
1584
|
+
self.indent_level -= 1
|
|
1585
|
+
self.emit(node, "\n")
|
|
1586
|
+
else:
|
|
1587
|
+
self.emit(node, i.gen.jac)
|
|
1532
1588
|
|
|
1533
1589
|
def exit_set_val(self, node: ast.ListVal) -> None:
|
|
1534
1590
|
"""Sub objects.
|
|
@@ -1745,6 +1801,7 @@ class JacFormatPass(Pass):
|
|
|
1745
1801
|
ast.ElseStmt,
|
|
1746
1802
|
ast.SpecialVarRef,
|
|
1747
1803
|
ast.ListCompr,
|
|
1804
|
+
ast.Name,
|
|
1748
1805
|
),
|
|
1749
1806
|
):
|
|
1750
1807
|
self.emit(node, f" {i.gen.jac}")
|
|
@@ -1907,6 +1964,11 @@ class JacFormatPass(Pass):
|
|
|
1907
1964
|
node.parent
|
|
1908
1965
|
and node.parent.parent
|
|
1909
1966
|
and isinstance(node.parent.parent, (ast.Ability))
|
|
1967
|
+
and (
|
|
1968
|
+
isinstance(node.parent.kid[1], ast.Assignment)
|
|
1969
|
+
and node.parent.kid[1].kid[-1].gen.jac
|
|
1970
|
+
!= "# Update any new user level buddy schedule"
|
|
1971
|
+
)
|
|
1910
1972
|
):
|
|
1911
1973
|
self.indent_level -= 1
|
|
1912
1974
|
self.emit_ln(node, "")
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import ast as ast3
|
|
4
4
|
import os
|
|
5
5
|
import shutil
|
|
6
|
+
from contextlib import suppress
|
|
6
7
|
from difflib import unified_diff
|
|
7
8
|
|
|
8
9
|
import jaclang.compiler.absyntree as ast
|
|
@@ -56,12 +57,14 @@ class JacFormatPassTests(TestCaseMicroSuite, AstSyncTestMixin):
|
|
|
56
57
|
"""Set up test."""
|
|
57
58
|
root_dir = self.fixture_abs_path("")
|
|
58
59
|
directories_to_clean = [
|
|
59
|
-
os.path.join(root_dir, "myca_formatted_code", "__jac_gen__")
|
|
60
|
+
os.path.join(root_dir, "myca_formatted_code", "__jac_gen__"),
|
|
61
|
+
os.path.join(root_dir, "genai", "__jac_gen__"),
|
|
60
62
|
]
|
|
61
63
|
|
|
62
64
|
for directory in directories_to_clean:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
with suppress(Exception):
|
|
66
|
+
if os.path.exists(directory):
|
|
67
|
+
shutil.rmtree(directory)
|
|
65
68
|
return super().setUp()
|
|
66
69
|
|
|
67
70
|
def test_jac_file_compr(self) -> None:
|
|
@@ -79,15 +82,19 @@ class JacFormatPassTests(TestCaseMicroSuite, AstSyncTestMixin):
|
|
|
79
82
|
fixtures_dir = os.path.join(self.fixture_abs_path(""), "myca_formatted_code")
|
|
80
83
|
fixture_files = os.listdir(fixtures_dir)
|
|
81
84
|
for file_name in fixture_files:
|
|
85
|
+
if file_name == "__jac_gen__":
|
|
86
|
+
continue
|
|
82
87
|
with self.subTest(file=file_name):
|
|
83
88
|
file_path = os.path.join(fixtures_dir, file_name)
|
|
84
89
|
self.compare_files(file_path)
|
|
85
90
|
|
|
86
|
-
def
|
|
91
|
+
def test_compare_genai_fixtures(self) -> None:
|
|
87
92
|
"""Tests if files in the genai fixtures directory do not change after being formatted."""
|
|
88
93
|
fixtures_dir = os.path.join(self.fixture_abs_path(""), "genai")
|
|
89
94
|
fixture_files = os.listdir(fixtures_dir)
|
|
90
95
|
for file_name in fixture_files:
|
|
96
|
+
if file_name == "__jac_gen__":
|
|
97
|
+
continue
|
|
91
98
|
with self.subTest(file=file_name):
|
|
92
99
|
file_path = os.path.join(fixtures_dir, file_name)
|
|
93
100
|
self.compare_files(file_path)
|
|
@@ -54,10 +54,12 @@ class Transform(ABC, Generic[T]):
|
|
|
54
54
|
"""Pass Error."""
|
|
55
55
|
alrt = Alert(msg, self.cur_node.loc if not node_override else node_override.loc)
|
|
56
56
|
self.errors_had.append(alrt)
|
|
57
|
+
# print("Error:", str(alrt))
|
|
57
58
|
self.logger.error(str(alrt))
|
|
58
59
|
|
|
59
60
|
def log_warning(self, msg: str, node_override: Optional[AstNode] = None) -> None:
|
|
60
61
|
"""Pass Error."""
|
|
61
62
|
alrt = Alert(msg, self.cur_node.loc if not node_override else node_override.loc)
|
|
62
63
|
self.warnings_had.append(alrt)
|
|
64
|
+
# print("Warning:", str(alrt))
|
|
63
65
|
self.logger.warning(str(alrt))
|
jaclang/compiler/symtable.py
CHANGED
|
@@ -46,9 +46,12 @@ class SymbolType(Enum):
|
|
|
46
46
|
class SymbolInfo:
|
|
47
47
|
"""Symbol Info."""
|
|
48
48
|
|
|
49
|
-
def __init__(
|
|
49
|
+
def __init__(
|
|
50
|
+
self, typ: str = "NoType", acc_tag: Optional[SymbolAccess] = None
|
|
51
|
+
) -> None: # noqa: ANN401
|
|
50
52
|
"""Initialize."""
|
|
51
53
|
self.typ = typ
|
|
54
|
+
self.acc_tag: Optional[SymbolAccess] = acc_tag
|
|
52
55
|
self.typ_sym_table: Optional[SymbolTable] = None
|
|
53
56
|
|
|
54
57
|
|
|
@@ -146,7 +149,7 @@ class SymbolTable:
|
|
|
146
149
|
def insert(
|
|
147
150
|
self,
|
|
148
151
|
node: ast.AstSymbolNode,
|
|
149
|
-
access_spec: Optional[ast.AstAccessNode] = None,
|
|
152
|
+
access_spec: Optional[ast.AstAccessNode] | SymbolAccess = None,
|
|
150
153
|
single: bool = False,
|
|
151
154
|
) -> Optional[ast.AstNode]:
|
|
152
155
|
"""Set a variable in the symbol table.
|
|
@@ -162,7 +165,11 @@ class SymbolTable:
|
|
|
162
165
|
if node.sym_name not in self.tab:
|
|
163
166
|
self.tab[node.sym_name] = Symbol(
|
|
164
167
|
defn=node,
|
|
165
|
-
access=
|
|
168
|
+
access=(
|
|
169
|
+
access_spec
|
|
170
|
+
if isinstance(access_spec, SymbolAccess)
|
|
171
|
+
else access_spec.access_type if access_spec else SymbolAccess.PUBLIC
|
|
172
|
+
),
|
|
166
173
|
parent_tab=self,
|
|
167
174
|
)
|
|
168
175
|
else:
|
|
@@ -38,3 +38,12 @@ class TestLoader(TestCase):
|
|
|
38
38
|
"{SomeObj(a=10): 'check'} [MyObj(apple=5, banana=7), MyObj(apple=5, banana=7)]",
|
|
39
39
|
stdout_value,
|
|
40
40
|
)
|
|
41
|
+
|
|
42
|
+
def test_package_import(self) -> None:
|
|
43
|
+
"""Test package import."""
|
|
44
|
+
captured_output = io.StringIO()
|
|
45
|
+
sys.stdout = captured_output
|
|
46
|
+
cli.run(self.fixture_abs_path("../../../tests/fixtures/package_import.jac"))
|
|
47
|
+
sys.stdout = sys.__stdout__
|
|
48
|
+
stdout_value = captured_output.getvalue()
|
|
49
|
+
self.assertEqual("package is imported successfully!\n", stdout_value)
|
jaclang/compiler/workspace.py
CHANGED
|
@@ -7,8 +7,7 @@ from typing import Optional, Sequence
|
|
|
7
7
|
|
|
8
8
|
import jaclang.compiler.absyntree as ast
|
|
9
9
|
from jaclang.compiler.compile import jac_str_to_pass
|
|
10
|
-
from jaclang.compiler.passes.main import DefUsePass
|
|
11
|
-
from jaclang.compiler.passes.main.schedules import py_code_gen_typed
|
|
10
|
+
from jaclang.compiler.passes.main import DefUsePass, schedules
|
|
12
11
|
from jaclang.compiler.passes.transform import Alert
|
|
13
12
|
from jaclang.compiler.symtable import Symbol, SymbolTable
|
|
14
13
|
|
|
@@ -46,11 +45,14 @@ class ModuleInfo:
|
|
|
46
45
|
class Workspace:
|
|
47
46
|
"""Class for managing workspace."""
|
|
48
47
|
|
|
49
|
-
def __init__(
|
|
48
|
+
def __init__(
|
|
49
|
+
self, path: str, lazy_parse: bool = False, type_check: bool = False
|
|
50
|
+
) -> None:
|
|
50
51
|
"""Initialize workspace."""
|
|
51
52
|
self.path = path
|
|
52
53
|
self.modules: dict[str, ModuleInfo] = {}
|
|
53
54
|
self.lazy_parse = lazy_parse
|
|
55
|
+
self.type_check = type_check
|
|
54
56
|
self.rebuild_workspace()
|
|
55
57
|
|
|
56
58
|
def rebuild_workspace(self) -> None:
|
|
@@ -78,7 +80,12 @@ class Workspace:
|
|
|
78
80
|
build = jac_str_to_pass(
|
|
79
81
|
jac_str=source,
|
|
80
82
|
file_path=file,
|
|
81
|
-
|
|
83
|
+
schedule=(
|
|
84
|
+
schedules.py_code_gen_typed
|
|
85
|
+
if self.type_check
|
|
86
|
+
else schedules.py_code_gen
|
|
87
|
+
),
|
|
88
|
+
target=DefUsePass if not self.type_check else None,
|
|
82
89
|
)
|
|
83
90
|
if not isinstance(build.ir, ast.Module):
|
|
84
91
|
src = ast.JacSource(source, mod_path=file)
|
|
@@ -118,7 +125,12 @@ class Workspace:
|
|
|
118
125
|
build = jac_str_to_pass(
|
|
119
126
|
jac_str=source,
|
|
120
127
|
file_path=file_path,
|
|
121
|
-
schedule=
|
|
128
|
+
schedule=(
|
|
129
|
+
schedules.py_code_gen_typed
|
|
130
|
+
if self.type_check
|
|
131
|
+
else schedules.py_code_gen
|
|
132
|
+
),
|
|
133
|
+
target=DefUsePass if not self.type_check else None,
|
|
122
134
|
)
|
|
123
135
|
if not isinstance(build.ir, ast.Module):
|
|
124
136
|
src = ast.JacSource(source, mod_path=file_path)
|
jaclang/core/aott.py
CHANGED
|
@@ -8,78 +8,40 @@ import re
|
|
|
8
8
|
from enum import Enum
|
|
9
9
|
from typing import Any
|
|
10
10
|
|
|
11
|
+
from jaclang.core.llms.base import BaseLLM
|
|
11
12
|
from jaclang.core.registry import SemInfo, SemRegistry, SemScope
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
PROMPT_TEMPLATE = """
|
|
15
|
-
[System Prompt]
|
|
16
|
-
This is an operation you must perform and return the output values. Neither, the methodology, extra sentences nor the code are not needed.
|
|
17
|
-
Input/Type formatting: Explanation of the Input (variable_name) (type) = value
|
|
18
|
-
|
|
19
|
-
[Information]
|
|
20
|
-
{information}
|
|
21
|
-
|
|
22
|
-
[Inputs Information]
|
|
23
|
-
{inputs_information}
|
|
24
|
-
|
|
25
|
-
[Output Information]
|
|
26
|
-
{output_information}
|
|
27
|
-
|
|
28
|
-
[Type Explanations]
|
|
29
|
-
{type_explanations}
|
|
30
|
-
|
|
31
|
-
[Action]
|
|
32
|
-
{action}
|
|
33
|
-
|
|
34
|
-
{reason_suffix}
|
|
35
|
-
""" # noqa E501
|
|
36
|
-
|
|
37
|
-
WITH_REASON_SUFFIX = """
|
|
38
|
-
Reason and return the output result(s) only, adhering to the provided Type in the following format
|
|
39
|
-
|
|
40
|
-
[Reasoning] <Reason>
|
|
41
|
-
[Output] <Result>
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
WITHOUT_REASON_SUFFIX = """Generate and return the output result(s) only, adhering to the provided Type in the following format
|
|
45
|
-
|
|
46
|
-
[Output] <result>
|
|
47
|
-
""" # noqa E501
|
|
48
|
-
|
|
49
|
-
|
|
50
15
|
def aott_raise(
|
|
16
|
+
model: BaseLLM,
|
|
51
17
|
information: str,
|
|
52
18
|
inputs_information: str,
|
|
53
19
|
output_information: str,
|
|
54
20
|
type_explanations: str,
|
|
55
21
|
action: str,
|
|
56
|
-
|
|
22
|
+
context: str,
|
|
23
|
+
method: str,
|
|
24
|
+
tools: list["Tool"],
|
|
25
|
+
model_params: dict,
|
|
57
26
|
) -> str:
|
|
58
27
|
"""AOTT Raise uses the information (Meanings types values) provided to generate a prompt(meaning in)."""
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
output_match = re.search(r"\[Output\](.*)", s)
|
|
73
|
-
|
|
74
|
-
if reasoning_match and output_match:
|
|
75
|
-
reasoning = reasoning_match.group(1)
|
|
76
|
-
output = output_match.group(1)
|
|
77
|
-
return (reasoning.strip(), output.strip())
|
|
78
|
-
elif output_match:
|
|
79
|
-
output = output_match.group(1)
|
|
80
|
-
return (None, output.strip())
|
|
28
|
+
if method != "ReAct":
|
|
29
|
+
system_prompt = model.MTLLM_SYSTEM_PROMPT
|
|
30
|
+
mtllm_prompt = model.MTLLM_PROMPT.format(
|
|
31
|
+
information=information,
|
|
32
|
+
inputs_information=inputs_information,
|
|
33
|
+
output_information=output_information,
|
|
34
|
+
type_explanations=type_explanations,
|
|
35
|
+
action=action,
|
|
36
|
+
context=context,
|
|
37
|
+
)
|
|
38
|
+
method_prompt = model.MTLLM_METHOD_PROMPTS[method]
|
|
39
|
+
meaning_in = f"{system_prompt}\n{mtllm_prompt}\n{method_prompt}"
|
|
40
|
+
return model(meaning_in, **model_params)
|
|
81
41
|
else:
|
|
82
|
-
|
|
42
|
+
assert tools, "Tools must be provided for the ReAct method."
|
|
43
|
+
# TODO: Implement ReAct method
|
|
44
|
+
return ""
|
|
83
45
|
|
|
84
46
|
|
|
85
47
|
def get_info_types(
|
|
@@ -179,19 +141,19 @@ def get_type_explanation(
|
|
|
179
141
|
if sem_info.type == "Enum" and isinstance(type_info, list):
|
|
180
142
|
for enum_item in type_info:
|
|
181
143
|
type_info_str.append(
|
|
182
|
-
f"{enum_item.semstr} (
|
|
144
|
+
f"{enum_item.semstr} ({enum_item.name}) (EnumItem)"
|
|
183
145
|
)
|
|
184
146
|
elif sem_info.type in ["obj", "class", "node", "edge"] and isinstance(
|
|
185
147
|
type_info, list
|
|
186
148
|
):
|
|
187
149
|
for arch_item in type_info:
|
|
188
150
|
type_info_str.append(
|
|
189
|
-
f"{arch_item.semstr} ({arch_item.
|
|
151
|
+
f"{arch_item.semstr} ({arch_item.name}) ({arch_item.type})"
|
|
190
152
|
)
|
|
191
153
|
if arch_item.type and extract_non_primary_type(arch_item.type):
|
|
192
154
|
type_info_types.extend(extract_non_primary_type(arch_item.type))
|
|
193
155
|
return (
|
|
194
|
-
f"{sem_info.semstr} ({sem_info.
|
|
156
|
+
f"{sem_info.semstr} ({sem_info.name}) ({sem_info.type}) = {', '.join(type_info_str)}",
|
|
195
157
|
set(type_info_types),
|
|
196
158
|
)
|
|
197
159
|
return None, None
|
|
@@ -232,3 +194,12 @@ def get_type_annotation(data: Any) -> str: # noqa: ANN401
|
|
|
232
194
|
return "dict[str, Any]"
|
|
233
195
|
else:
|
|
234
196
|
return str(type(data).__name__)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class Tool:
|
|
200
|
+
"""Tool class for the AOTT operations."""
|
|
201
|
+
|
|
202
|
+
def __init__(self) -> None:
|
|
203
|
+
"""Initialize the Tool class."""
|
|
204
|
+
# TODO: Implement the Tool class
|
|
205
|
+
pass
|