jaclang 0.5.17__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/__init__.py +2 -6
- jaclang/cli/cli.py +4 -2
- jaclang/compiler/__init__.py +12 -5
- jaclang/compiler/absyntree.py +23 -23
- jaclang/compiler/generated/jac_parser.py +2 -2
- jaclang/compiler/jac.lark +9 -9
- jaclang/compiler/parser.py +76 -21
- jaclang/compiler/passes/ir_pass.py +10 -8
- jaclang/compiler/passes/main/__init__.py +3 -2
- jaclang/compiler/passes/main/access_modifier_pass.py +173 -0
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +3 -2
- jaclang/compiler/passes/main/import_pass.py +33 -21
- jaclang/compiler/passes/main/pyast_gen_pass.py +99 -44
- jaclang/compiler/passes/main/pyast_load_pass.py +141 -77
- 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 +47 -37
- jaclang/compiler/passes/main/tests/test_import_pass.py +2 -2
- jaclang/compiler/passes/tool/jac_formatter_pass.py +85 -23
- 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 +19 -11
- 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 +47 -16
- jaclang/plugin/feature.py +9 -6
- jaclang/plugin/spec.py +8 -1
- jaclang/settings.py +95 -0
- jaclang/utils/helpers.py +6 -2
- jaclang/utils/treeprinter.py +9 -6
- jaclang/vendor/mypy/checker.py +2 -3
- jaclang-0.6.0.dist-info/METADATA +17 -0
- {jaclang-0.5.17.dist-info → jaclang-0.6.0.dist-info}/RECORD +49 -39
- jaclang/core/llms.py +0 -29
- jaclang-0.5.17.dist-info/METADATA +0 -7
- {jaclang-0.5.17.dist-info → jaclang-0.6.0.dist-info}/WHEEL +0 -0
- {jaclang-0.5.17.dist-info → jaclang-0.6.0.dist-info}/entry_points.txt +0 -0
- {jaclang-0.5.17.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,38 +46,37 @@ 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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
# Handling of UnaryExpr case for item is only necessary for
|
|
64
|
+
# the generation of Starred nodes in the AST for examples
|
|
65
|
+
# like `(a, *b) = (1, 2, 3, 4)`.
|
|
66
|
+
def fix(item: ast.TupleVal | ast.ListVal | ast.UnaryExpr) -> None:
|
|
67
|
+
if isinstance(item, ast.UnaryExpr):
|
|
68
|
+
if isinstance(item.operand, ast.AstSymbolNode):
|
|
69
|
+
item.operand.py_ctx_func = ast3.Store
|
|
70
|
+
elif isinstance(item, (ast.TupleVal, ast.ListVal)):
|
|
71
|
+
for i in item.values.items if item.values else []:
|
|
72
|
+
if isinstance(i, ast.AstSymbolNode):
|
|
73
|
+
i.py_ctx_func = ast3.Store
|
|
74
|
+
elif isinstance(i, ast.AtomTrailer):
|
|
75
|
+
self.chain_def_insert(self.unwind_atom_trailer(i))
|
|
76
|
+
if isinstance(i, (ast.TupleVal, ast.ListVal, ast.UnaryExpr)):
|
|
77
|
+
fix(i)
|
|
72
78
|
|
|
73
79
|
fix(node)
|
|
74
|
-
self.handle_hit_outcome(node)
|
|
75
|
-
return node.sym_link
|
|
76
80
|
|
|
77
81
|
def use_lookup(
|
|
78
82
|
self,
|
|
@@ -269,8 +273,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
269
273
|
]
|
|
270
274
|
and node.sym_tab
|
|
271
275
|
):
|
|
272
|
-
|
|
273
|
-
self.def_insert(v.decl, table_override=self.cur_scope())
|
|
276
|
+
self.inherit_sym_tab(scope=self.cur_scope(), sym_tab=node.sym_tab)
|
|
274
277
|
|
|
275
278
|
def enter_global_vars(self, node: ast.GlobalVars) -> None:
|
|
276
279
|
"""Sub objects.
|
|
@@ -381,17 +384,24 @@ class SymTabBuildPass(SymTabPass):
|
|
|
381
384
|
is_absorb: bool,
|
|
382
385
|
sub_module: Optional[Module],
|
|
383
386
|
"""
|
|
384
|
-
if node.
|
|
387
|
+
if not node.is_absorb:
|
|
385
388
|
for i in node.items.items:
|
|
386
389
|
self.def_insert(i, single_decl="import item")
|
|
387
390
|
elif node.is_absorb and node.hint.tag.value == "jac":
|
|
388
|
-
|
|
391
|
+
source = node.items.items[0]
|
|
392
|
+
if (
|
|
393
|
+
not isinstance(source, ast.ModulePath)
|
|
394
|
+
or not source.sub_module
|
|
395
|
+
or not source.sub_module.sym_tab
|
|
396
|
+
):
|
|
389
397
|
self.error(
|
|
390
|
-
f"Module {node.
|
|
398
|
+
f"Module {node.from_loc.path_str if node.from_loc else 'from location'}"
|
|
399
|
+
f" not found to include *, or ICE occurred!"
|
|
391
400
|
)
|
|
392
401
|
else:
|
|
393
|
-
|
|
394
|
-
self.
|
|
402
|
+
self.inherit_sym_tab(
|
|
403
|
+
scope=self.cur_scope(), sym_tab=source.sub_module.sym_tab
|
|
404
|
+
)
|
|
395
405
|
|
|
396
406
|
def enter_module_path(self, node: ast.ModulePath) -> None:
|
|
397
407
|
"""Sub objects.
|
|
@@ -437,7 +447,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
437
447
|
body: Optional[ArchBlock],
|
|
438
448
|
"""
|
|
439
449
|
self.sync_node_to_scope(node)
|
|
440
|
-
self.def_insert(node, single_decl="architype")
|
|
450
|
+
self.def_insert(node, access_spec=node, single_decl="architype")
|
|
441
451
|
self.push_scope(node.name.value, node)
|
|
442
452
|
self.sync_node_to_scope(node)
|
|
443
453
|
|
|
@@ -491,7 +501,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
491
501
|
body: Optional[CodeBlock],
|
|
492
502
|
"""
|
|
493
503
|
self.sync_node_to_scope(node)
|
|
494
|
-
self.def_insert(node, single_decl="ability")
|
|
504
|
+
self.def_insert(node, access_spec=node, single_decl="ability")
|
|
495
505
|
self.push_scope(node.sym_name, node)
|
|
496
506
|
self.sync_node_to_scope(node)
|
|
497
507
|
|
|
@@ -579,7 +589,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
579
589
|
body: Optional['EnumBlock'],
|
|
580
590
|
"""
|
|
581
591
|
self.sync_node_to_scope(node)
|
|
582
|
-
self.def_insert(node, single_decl="enum")
|
|
592
|
+
self.def_insert(node, access_spec=node, single_decl="enum")
|
|
583
593
|
self.push_scope(node.sym_name, node)
|
|
584
594
|
self.sync_node_to_scope(node)
|
|
585
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
|
):
|
|
@@ -1443,10 +1484,10 @@ class JacFormatPass(Pass):
|
|
|
1443
1484
|
body: Expr,
|
|
1444
1485
|
"""
|
|
1445
1486
|
out = ""
|
|
1446
|
-
if node.signature.params:
|
|
1487
|
+
if node.signature and node.signature.params:
|
|
1447
1488
|
self.comma_sep_node_list(node.signature.params)
|
|
1448
1489
|
out += node.signature.params.gen.jac
|
|
1449
|
-
if node.signature.return_type:
|
|
1490
|
+
if node.signature and node.signature.return_type:
|
|
1450
1491
|
out += f" -> {node.signature.return_type.gen.jac}"
|
|
1451
1492
|
self.emit(node, f"with {out} can {node.body.gen.jac}")
|
|
1452
1493
|
|
|
@@ -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)
|
|
@@ -171,9 +183,7 @@ class Workspace:
|
|
|
171
183
|
[
|
|
172
184
|
i
|
|
173
185
|
for i in mod_ir.get_all_sub_nodes(ast.ModulePath)
|
|
174
|
-
if i.
|
|
175
|
-
and isinstance(i.parent, ast.Import)
|
|
176
|
-
and i.parent.hint.tag.value == "jac"
|
|
186
|
+
if i.parent_of_type(ast.Import).hint.tag.value == "jac"
|
|
177
187
|
]
|
|
178
188
|
if mod_ir
|
|
179
189
|
else []
|
|
@@ -184,9 +194,7 @@ class Workspace:
|
|
|
184
194
|
i
|
|
185
195
|
for i in mod_ir.get_all_sub_nodes(ast.ModulePath)
|
|
186
196
|
if i.loc.mod_path == file_path
|
|
187
|
-
and i.
|
|
188
|
-
and isinstance(i.parent, ast.Import)
|
|
189
|
-
and i.parent.hint.tag.value == "jac"
|
|
197
|
+
and i.parent_of_type(ast.Import).hint.tag.value == "jac"
|
|
190
198
|
]
|
|
191
199
|
if mod_ir
|
|
192
200
|
else []
|