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.

Files changed (51) hide show
  1. jaclang/__init__.py +2 -6
  2. jaclang/cli/cli.py +4 -2
  3. jaclang/compiler/__init__.py +12 -5
  4. jaclang/compiler/absyntree.py +23 -23
  5. jaclang/compiler/generated/jac_parser.py +2 -2
  6. jaclang/compiler/jac.lark +9 -9
  7. jaclang/compiler/parser.py +76 -21
  8. jaclang/compiler/passes/ir_pass.py +10 -8
  9. jaclang/compiler/passes/main/__init__.py +3 -2
  10. jaclang/compiler/passes/main/access_modifier_pass.py +173 -0
  11. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +3 -2
  12. jaclang/compiler/passes/main/import_pass.py +33 -21
  13. jaclang/compiler/passes/main/pyast_gen_pass.py +99 -44
  14. jaclang/compiler/passes/main/pyast_load_pass.py +141 -77
  15. jaclang/compiler/passes/main/pyout_pass.py +14 -13
  16. jaclang/compiler/passes/main/registry_pass.py +8 -3
  17. jaclang/compiler/passes/main/schedules.py +5 -3
  18. jaclang/compiler/passes/main/sym_tab_build_pass.py +47 -37
  19. jaclang/compiler/passes/main/tests/test_import_pass.py +2 -2
  20. jaclang/compiler/passes/tool/jac_formatter_pass.py +85 -23
  21. jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +11 -4
  22. jaclang/compiler/passes/transform.py +2 -0
  23. jaclang/compiler/symtable.py +10 -3
  24. jaclang/compiler/tests/test_importer.py +9 -0
  25. jaclang/compiler/workspace.py +19 -11
  26. jaclang/core/aott.py +34 -63
  27. jaclang/core/importer.py +73 -65
  28. jaclang/core/llms/__init__.py +20 -0
  29. jaclang/core/llms/anthropic.py +61 -0
  30. jaclang/core/llms/base.py +206 -0
  31. jaclang/core/llms/groq.py +67 -0
  32. jaclang/core/llms/huggingface.py +73 -0
  33. jaclang/core/llms/ollama.py +78 -0
  34. jaclang/core/llms/openai.py +61 -0
  35. jaclang/core/llms/togetherai.py +60 -0
  36. jaclang/core/llms/utils.py +9 -0
  37. jaclang/core/utils.py +16 -1
  38. jaclang/plugin/default.py +47 -16
  39. jaclang/plugin/feature.py +9 -6
  40. jaclang/plugin/spec.py +8 -1
  41. jaclang/settings.py +95 -0
  42. jaclang/utils/helpers.py +6 -2
  43. jaclang/utils/treeprinter.py +9 -6
  44. jaclang/vendor/mypy/checker.py +2 -3
  45. jaclang-0.6.0.dist-info/METADATA +17 -0
  46. {jaclang-0.5.17.dist-info → jaclang-0.6.0.dist-info}/RECORD +49 -39
  47. jaclang/core/llms.py +0 -29
  48. jaclang-0.5.17.dist-info/METADATA +0 -7
  49. {jaclang-0.5.17.dist-info → jaclang-0.6.0.dist-info}/WHEEL +0 -0
  50. {jaclang-0.5.17.dist-info → jaclang-0.6.0.dist-info}/entry_points.txt +0 -0
  51. {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
- and (
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
- and single_decl
52
- ):
53
- # self.already_declared_err(
54
- # name=node.sym_name,
55
- # typ=single_decl if single_decl else "ICE",
56
- # original=collide,
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
- def fix(item: ast.TupleVal | ast.ListVal) -> None:
65
- for i in item.values.items if item.values else []:
66
- if isinstance(i, ast.AstSymbolNode):
67
- i.py_ctx_func = ast3.Store
68
- elif isinstance(i, ast.AtomTrailer):
69
- self.chain_def_insert(self.unwind_atom_trailer(i))
70
- if isinstance(i, (ast.TupleVal, ast.ListVal)):
71
- fix(i)
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
- for v in node.sym_tab.tab.values():
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.items:
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
- if not node.paths[0].sub_module or not node.paths[0].sub_module.sym_tab:
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.paths[0].path_str} not found to include *, or ICE occurred!"
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
- for v in node.paths[0].sub_module.sym_tab.tab.values():
394
- self.def_insert(v.decl, table_override=self.cur_scope())
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 ImportPass
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"), ImportPass)
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
- self.emit_ln(node, "")
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, f"{stmt.gen.jac}\n")
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
- prev_token = stmt
285
- continue
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(stmt, ast.Ability):
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
- prev_token.body and stmt.body
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
- self.emit(node, stmt.gen.jac)
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 (prev_token and isinstance(prev_token, ast.String)):
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
- self.emit_ln(node, "")
1313
- self.emit_ln(node, "")
1314
- self.emit_ln(node, i.gen.jac)
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
- if node.values is not None:
1525
- self.comma_sep_node_list(node.values)
1526
- self.emit(
1527
- node,
1528
- f"[{node.values.gen.jac}]",
1529
- )
1530
- else:
1531
- self.emit(node, "[]")
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
- if os.path.exists(directory):
64
- shutil.rmtree(directory)
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 test_compare_genia_fixtures(self) -> None:
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))
@@ -46,9 +46,12 @@ class SymbolType(Enum):
46
46
  class SymbolInfo:
47
47
  """Symbol Info."""
48
48
 
49
- def __init__(self, typ: str = "NoType") -> None: # noqa: ANN401
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=access_spec.access_type if access_spec else SymbolAccess.PUBLIC,
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)
@@ -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__(self, path: str, lazy_parse: bool = False) -> None:
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
- target=DefUsePass,
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=py_code_gen_typed,
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.parent
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.parent
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 []