jaclang 0.7.22__py3-none-any.whl → 0.7.25__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 (65) hide show
  1. jaclang/__init__.py +5 -10
  2. jaclang/cli/cli.py +50 -30
  3. jaclang/compiler/__init__.py +2 -2
  4. jaclang/compiler/absyntree.py +87 -48
  5. jaclang/compiler/codeloc.py +7 -2
  6. jaclang/compiler/compile.py +10 -3
  7. jaclang/compiler/parser.py +26 -23
  8. jaclang/compiler/passes/ir_pass.py +2 -2
  9. jaclang/compiler/passes/main/def_impl_match_pass.py +46 -0
  10. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +146 -123
  11. jaclang/compiler/passes/main/import_pass.py +6 -2
  12. jaclang/compiler/passes/main/pyast_load_pass.py +36 -35
  13. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +7 -7
  14. jaclang/compiler/passes/main/registry_pass.py +3 -12
  15. jaclang/compiler/passes/main/tests/fixtures/defn_decl_mismatch.jac +19 -0
  16. jaclang/compiler/passes/main/tests/fixtures/fstrings.jac +2 -0
  17. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +59 -0
  18. jaclang/compiler/passes/main/tests/test_registry_pass.py +2 -10
  19. jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
  20. jaclang/compiler/passes/main/type_check_pass.py +8 -6
  21. jaclang/compiler/passes/transform.py +27 -3
  22. jaclang/compiler/passes/utils/mypy_ast_build.py +246 -26
  23. jaclang/compiler/symtable.py +6 -0
  24. jaclang/compiler/tests/test_importer.py +2 -2
  25. jaclang/langserve/engine.py +14 -12
  26. jaclang/langserve/server.py +7 -2
  27. jaclang/langserve/tests/test_server.py +1 -1
  28. jaclang/langserve/utils.py +17 -3
  29. jaclang/plugin/builtin.py +3 -3
  30. jaclang/plugin/default.py +612 -236
  31. jaclang/plugin/feature.py +274 -99
  32. jaclang/plugin/plugin.md +471 -0
  33. jaclang/plugin/spec.py +231 -86
  34. jaclang/plugin/tests/fixtures/other_root_access.jac +9 -9
  35. jaclang/plugin/tests/test_features.py +2 -2
  36. jaclang/runtimelib/architype.py +1 -370
  37. jaclang/runtimelib/constructs.py +2 -0
  38. jaclang/runtimelib/context.py +2 -4
  39. jaclang/runtimelib/importer.py +7 -2
  40. jaclang/runtimelib/machine.py +78 -6
  41. jaclang/runtimelib/memory.py +2 -4
  42. jaclang/settings.py +3 -0
  43. jaclang/tests/fixtures/arch_create_util.jac +7 -0
  44. jaclang/tests/fixtures/arch_rel_import_creation.jac +30 -0
  45. jaclang/tests/fixtures/builtin_dotgen.jac +6 -6
  46. jaclang/tests/fixtures/create_dynamic_architype.jac +35 -0
  47. jaclang/tests/fixtures/edge_node_walk.jac +1 -1
  48. jaclang/tests/fixtures/edges_walk.jac +1 -1
  49. jaclang/tests/fixtures/enum_inside_archtype.jac +16 -11
  50. jaclang/tests/fixtures/expr_type.jac +54 -0
  51. jaclang/tests/fixtures/gendot_bubble_sort.jac +1 -1
  52. jaclang/tests/fixtures/glob_multivar_statement.jac +15 -0
  53. jaclang/tests/fixtures/registry.jac +20 -8
  54. jaclang/tests/fixtures/visit_order.jac +20 -0
  55. jaclang/tests/foo/__init__.jac +0 -0
  56. jaclang/tests/main.jac +2 -0
  57. jaclang/tests/test_cli.py +68 -4
  58. jaclang/tests/test_language.py +113 -27
  59. jaclang/utils/helpers.py +92 -14
  60. jaclang/utils/lang_tools.py +6 -2
  61. jaclang/utils/treeprinter.py +4 -2
  62. {jaclang-0.7.22.dist-info → jaclang-0.7.25.dist-info}/METADATA +2 -1
  63. {jaclang-0.7.22.dist-info → jaclang-0.7.25.dist-info}/RECORD +65 -55
  64. {jaclang-0.7.22.dist-info → jaclang-0.7.25.dist-info}/WHEEL +1 -1
  65. {jaclang-0.7.22.dist-info → jaclang-0.7.25.dist-info}/entry_points.txt +0 -0
@@ -27,11 +27,11 @@ with entry{
27
27
  d3=dotgen(b[2],edge_limit=5,depth=5);l3=d3|>len; #generate dot for all connected with b[1] node
28
28
  d4=dotgen(b[1],bfs=True,edge_type= ["Edge1"],node_limit=100,edge_limit=900,depth=300);l4=d4|>len; #generate dot from nodes with depth 3 connected with b[1] node
29
29
  d5=dotgen(b[1],node_limit=10,edge_limit=90);l5:=d5|>len; #generate dot from nodes with depth 3 connected with b[1] node
30
- print(d1.count('a(val')==12,d1.count('#FFFFE0')==3,'Root' in d1,d1.count('GenericEdge')==30);
31
- print(d2.count('a(val')==19,d2.count('#F5E5FF')==2 ,'Edge1' not in d2,d2.count('GenericEdge')==42);
32
- print(d3.count('a(val')==6,d3.count("GenericEdge")==5,d3.count('#F5E5FF')==1);
33
- print(d4.count("a(val")==25,d4.count("GenericEdge")==66,d4.count('#FFF0F')==3);
34
- print(d5.count("Edge1(val=6)")==2, d5.count("GenericEdge()")==24);
30
+ print(d1.count('a(val')==12,d1.count('#FFFFE0')==3,'Root' in d1,d1.count('label=""')==30);
31
+ print(d2.count('a(val')==19,d2.count('#F5E5FF')==2 ,'Edge1' not in d2,d2.count('label=""')==42);
32
+ print(d3.count('a(val')==6,d3.count('label=""')==5,d3.count('#F5E5FF')==1);
33
+ print(d4.count("a(val")==25,d4.count('label=""')==66,d4.count('#FFF0F')==3);
34
+ print(d5.count("Edge1(val=6)")==2, d5.count('label=""')==24);
35
35
  # print(l3<l2);
36
36
  # print(d1);
37
37
  # print(d2);
@@ -39,4 +39,4 @@ with entry{
39
39
  # print(d4);
40
40
  # print(dotgen(node=b[2],bfs=True,depth=3.96,edge_limit=12,node_limit=12.96));
41
41
 
42
- }
42
+ }
@@ -0,0 +1,35 @@
1
+ import:py from jaclang.runtimelib.machine { JacMachine }
2
+ # Dynamically create a node architype
3
+ glob source_code = """
4
+ node dynamic_node {
5
+ has value:int;
6
+ can print_value with entry {
7
+ print("Dynamic Node Value:", f'{self.value}');
8
+ }
9
+ }
10
+ """;
11
+
12
+ # Create a new walker architype dynamically
13
+ glob walker_code = """
14
+ walker dynamic_walker {
15
+ can visit_nodes with entry {
16
+ visit [-->](`?dynamic_node);
17
+ }
18
+ }
19
+ """;
20
+
21
+ with entry {
22
+ node_arch = JacMachine.get().create_architype_from_source(source_code);
23
+ walker_arch = JacMachine.get().create_architype_from_source(walker_code);
24
+
25
+ node_obj = JacMachine.get().spawn_node(
26
+ 'dynamic_node',
27
+ {'value': 99},
28
+ node_arch.__name__
29
+ );
30
+ walker_obj = JacMachine.get().spawn_walker(
31
+ 'dynamic_walker',
32
+ module_name=walker_arch.__name__
33
+ );
34
+ node_obj spawn walker_obj;
35
+ }
@@ -37,7 +37,7 @@ edge Edge_c {
37
37
 
38
38
  with entry {
39
39
  print(root spawn creator());
40
- print(root.__jac__.gen_dot());
40
+ print(Jac.node_dot(root));
41
41
  print([root-:Edge_a:->]);
42
42
  print([root-:Edge_c:->]);
43
43
  print([root-:Edge_a:->-:Edge_b:->]);
@@ -30,7 +30,7 @@ edge Edge_c{
30
30
 
31
31
  with entry{
32
32
  print(root spawn creator());
33
- print(root.__jac__.gen_dot());
33
+ print(Jac.node_dot(root));
34
34
  print([root -:Edge_a:->]);
35
35
  print([root -:Edge_c:->]);
36
36
  print([root -:Edge_a:-> -:Edge_b:->]);
@@ -1,20 +1,25 @@
1
- obj outer{
2
- has o1:int=9;
1
+ obj outer {
2
+ has o1: int = 9;
3
3
 
4
- obj inner{
5
- has i1:int=8;
4
+ obj inner {
5
+ has i1: int = 8;
6
6
  }
7
- can foo(){
7
+ can foo() {
8
8
  return 'foo';
9
9
  }
10
- enum color{
10
+ enum color {
11
11
  red,
12
12
  green,
13
- blue
13
+ blue,
14
+ with entry {
15
+ print('Initializing role system..');
16
+ },
17
+ can foo -> str {
18
+ return 'Accessing privileged Data';
14
19
  }
15
-
20
+ }
16
21
  }
17
22
 
18
- with entry{
19
- print(outer.color.green.value);
20
- }
23
+ with entry {
24
+ print(outer.color.green.value, outer.color.foo());
25
+ }
@@ -0,0 +1,54 @@
1
+ with entry {
2
+ a = 4;
3
+ b = 7;
4
+ c = a + b; # OpExpr.
5
+ d = a + b + c;
6
+
7
+ h = float(a); # CallExpr.
8
+
9
+ (1 < 2); # ComparisonExpr.
10
+ ('a' + 'b').upper(); # CallExpr.
11
+ [1,2][0]; # IndexExpr.
12
+ not False; # UnaryExpr.
13
+ "a" if True else "b"; # ConditionalExpr.
14
+ [i for i in range(10)]; # ListComprehension.
15
+ }
16
+
17
+ # Remaining expressions to test:
18
+ # AssertTypeExpr,
19
+ # AssignmentExpr,
20
+ # AwaitExpr,
21
+ # BytesExpr,
22
+ # CastExpr,
23
+ # ComplexExpr,
24
+ # DictionaryComprehension,
25
+ # DictExpr,
26
+ # EllipsisExpr,
27
+ # EnumCallExpr,
28
+ # Expression,
29
+ # FloatExpr,
30
+ # GeneratorExpr,
31
+ # IntExpr,
32
+ # LambdaExpr,
33
+ # ListExpr,
34
+ # MemberExpr,
35
+ # NamedTupleExpr,
36
+ # NameExpr,
37
+ # NewTypeExpr,
38
+ # ParamSpecExpr,
39
+ # PromoteExpr,
40
+ # RefExpr,
41
+ # RevealExpr,
42
+ # SetComprehension,
43
+ # SetExpr,
44
+ # SliceExpr,
45
+ # StarExpr,
46
+ # StrExpr,
47
+ # SuperExpr,
48
+ # TupleExpr,
49
+ # TypeAliasExpr,
50
+ # TypedDictExpr,
51
+ # TypeVarExpr,
52
+ # TypeVarTupleExpr,
53
+ # YieldExpr,
54
+ # YieldFromExpr,
@@ -73,5 +73,5 @@ with entry {
73
73
  root spawn walker1();
74
74
  root spawn walker2();
75
75
  root spawn walker3();
76
- print(root.__jac__.gen_dot());
76
+ print(Jac.node_dot(root));
77
77
  }
@@ -0,0 +1,15 @@
1
+ glob a: str, b: str;
2
+ glob c: str;
3
+
4
+ can do() {
5
+ :g: a, b, c ;
6
+
7
+ (a, b, c) = ("Welcome", "to", "Jaseci!");
8
+ }
9
+
10
+ with entry {
11
+ (a, b, c) = ("Hello", "World", "!");
12
+ print(a, b, c);
13
+ do();
14
+ print(a, b, c);
15
+ }
@@ -13,16 +13,16 @@ Person {
13
13
 
14
14
  enum 'Personality of the Person'
15
15
  Personality {
16
- INTROVERT: 'Person who is shy and reticent' = 9,
17
- EXTROVERT: 'Person who is outgoing and socially confident'
16
+ INTROVERT: 'Person who is shy and reticent' = 9,
17
+ EXTROVERT: 'Person who is outgoing and socially confident'
18
18
  }
19
19
 
20
- glob personality_examples: 'Personality Information of Famous People': dict[str, Personality|None] = {
20
+ glob personality_examples: 'Personality Information of Famous People': dict[str, Personality | None] = {
21
21
  'Albert Einstein': Personality.INTROVERT,
22
22
  'Barack Obama': Personality.EXTROVERT
23
23
  };
24
24
 
25
- glob person_value : list[tuple[dict[str, Personality], int]] =(-90);
25
+ glob person_value: list[tuple[dict[str, Personality], int]] = (-90);
26
26
 
27
27
  can 'GenAI ability'
28
28
  genai_ability(x: 'Something': str) -> 'Something Else': str by llm();
@@ -34,13 +34,25 @@ normal_ability(x: 'Something': str) -> 'Something Else': str {
34
34
  }
35
35
 
36
36
  can foo() {
37
- person_value=22;
38
- can bar() {
39
- person_value=33;
40
- }
37
+ person_value = 22;
38
+ can bar() {
39
+ person_value = 33;
40
+ }
41
41
  }
42
42
  with entry {
43
43
  einstein_age: int = 75;
44
44
  einstein_age += 1;
45
45
  einstein = Person('Albert Einstein', einstein_age);
46
46
  }
47
+
48
+ import from jaclang.runtimelib.machine { JacMachine }
49
+
50
+ with entry {
51
+ registry = JacMachine.get().jac_program.sem_ir;
52
+
53
+ print(len(registry.registry));
54
+ print(len(list(registry.registry.items())[0][1]));
55
+ print(list(registry.registry.items())[3][0].scope);
56
+ (_, sem_info) = registry.lookup(name="normal_ability");
57
+ print(len(sem_info.get_children(registry)));
58
+ }
@@ -0,0 +1,20 @@
1
+ node MyNode{
2
+ has Name:str;
3
+ }
4
+
5
+ edge a{}
6
+
7
+ edge b{}
8
+
9
+ with entry{
10
+ Start = MyNode("Start");
11
+ End = MyNode("End");
12
+ mid = MyNode("Middle");
13
+ root <+:a:+ Start;
14
+ root +:a:+> End;
15
+ root +:b:+> mid;
16
+ root +:a:+> mid;
17
+
18
+ print([root-->]);
19
+
20
+ }
File without changes
jaclang/tests/main.jac ADDED
@@ -0,0 +1,2 @@
1
+ import foo;
2
+
jaclang/tests/test_cli.py CHANGED
@@ -1,5 +1,6 @@
1
1
  """Test Jac cli module."""
2
2
 
3
+ import contextlib
3
4
  import inspect
4
5
  import io
5
6
  import os
@@ -55,10 +56,8 @@ class JacCliTests(TestCase):
55
56
  sys.stdout = captured_output
56
57
  sys.stderr = captured_output
57
58
 
58
- try:
59
+ with contextlib.suppress(Exception):
59
60
  cli.run(self.fixture_abs_path("err_runtime.jac"))
60
- except Exception as e:
61
- print(f"Error: {e}")
62
61
 
63
62
  sys.stdout = sys.__stdout__
64
63
  sys.stderr = sys.__stderr__
@@ -71,7 +70,6 @@ class JacCliTests(TestCase):
71
70
  " at foo() ",
72
71
  " at <module> ",
73
72
  )
74
-
75
73
  logger_capture = "\n".join([rec.message for rec in self.caplog.records])
76
74
  for exp in expected_stdout_values:
77
75
  self.assertIn(exp, logger_capture)
@@ -217,6 +215,42 @@ class JacCliTests(TestCase):
217
215
  r"13\:12 \- 13\:18.*Name - append - .*SymbolPath: builtins_test.builtins.list.append",
218
216
  )
219
217
 
218
+ def test_expr_types(self) -> None:
219
+ """Testing for print AstTool."""
220
+ captured_output = io.StringIO()
221
+ sys.stdout = captured_output
222
+
223
+ cli.tool("ir", ["ast", f"{self.fixture_abs_path('expr_type.jac')}"])
224
+
225
+ sys.stdout = sys.__stdout__
226
+ stdout_value = captured_output.getvalue()
227
+
228
+ self.assertRegex(
229
+ stdout_value, r"4\:9 \- 4\:14.*BinaryExpr \- Type\: builtins.int"
230
+ )
231
+ self.assertRegex(
232
+ stdout_value, r"7\:9 \- 7\:17.*FuncCall \- Type\: builtins.float"
233
+ )
234
+ self.assertRegex(
235
+ stdout_value, r"9\:6 \- 9\:11.*CompareExpr \- Type\: builtins.bool"
236
+ )
237
+ self.assertRegex(
238
+ stdout_value, r"10\:6 - 10\:15.*BinaryExpr \- Type\: builtins.str"
239
+ )
240
+ self.assertRegex(
241
+ stdout_value, r"11\:5 \- 11\:13.*AtomTrailer \- Type\: builtins.int"
242
+ )
243
+ self.assertRegex(
244
+ stdout_value, r"12\:5 \- 12\:14.*UnaryExpr \- Type\: builtins.bool"
245
+ )
246
+ self.assertRegex(
247
+ stdout_value, r"13\:5 \- 13\:25.*IfElseExpr \- Type\: Literal\['a']\?"
248
+ )
249
+ self.assertRegex(
250
+ stdout_value,
251
+ r"14\:5 \- 14\:27.*ListCompr - \[ListCompr] \- Type\: builtins.list\[builtins.int]",
252
+ )
253
+
220
254
  def test_ast_dotgen(self) -> None:
221
255
  """Testing for print AstTool."""
222
256
  captured_output = io.StringIO()
@@ -247,6 +281,8 @@ class JacCliTests(TestCase):
247
281
  self.assertEqual(stdout_value.count("type_info.ServerWrapper"), 7)
248
282
  self.assertEqual(stdout_value.count("builtins.int"), 3)
249
283
  self.assertEqual(stdout_value.count("builtins.str"), 10)
284
+ self.assertIn("Literal['test_server']", stdout_value)
285
+ self.assertIn("Literal['1']", stdout_value)
250
286
 
251
287
  def test_build_and_run(self) -> None:
252
288
  """Testing for print AstTool."""
@@ -368,3 +404,31 @@ class JacCliTests(TestCase):
368
404
  sys.stdout = sys.__stdout__
369
405
  stdout_value = captured_output.getvalue()
370
406
  self.assertIn("can my_print(x: object) -> None", stdout_value)
407
+
408
+ def test_caching_issue(self) -> None:
409
+ """Test for Caching Issue."""
410
+ test_file = self.fixture_abs_path("test_caching_issue.jac")
411
+ test_cases = [(10, True), (11, False)]
412
+ for x, is_passed in test_cases:
413
+ with open(test_file, "w") as f:
414
+ f.write(
415
+ f"""
416
+ test mytest{{
417
+ check 10 == {x};
418
+ }}
419
+ """
420
+ )
421
+ process = subprocess.Popen(
422
+ ["jac", "test", test_file],
423
+ stdout=subprocess.PIPE,
424
+ stderr=subprocess.PIPE,
425
+ text=True,
426
+ )
427
+ stdout, stderr = process.communicate()
428
+ if is_passed:
429
+ self.assertIn("Passed successfully.", stdout)
430
+ self.assertIn(".", stderr)
431
+ else:
432
+ self.assertNotIn("Passed successfully.", stdout)
433
+ self.assertIn("F", stderr)
434
+ os.remove(test_file)
@@ -2,7 +2,6 @@
2
2
 
3
3
  import io
4
4
  import os
5
- import pickle
6
5
  import sys
7
6
  import sysconfig
8
7
 
@@ -24,7 +23,7 @@ class JacLanguageTests(TestCase):
24
23
  """Set up test."""
25
24
  SUPER_ROOT_ANCHOR.edges.clear()
26
25
  JacMachine(self.fixture_abs_path("./")).attach_program(
27
- JacProgram(mod_bundle=None, bytecode=None)
26
+ JacProgram(mod_bundle=None, bytecode=None, sem_ir=None)
28
27
  )
29
28
  return super().setUp()
30
29
 
@@ -80,6 +79,18 @@ class JacLanguageTests(TestCase):
80
79
  "\nValue: 5\nValue: 6\nValue: 7\nFinal Value: 8\nDone walking.\n",
81
80
  )
82
81
 
82
+ def test_simple_walk_by_edge(self) -> None:
83
+ """Parse micro jac file."""
84
+ captured_output = io.StringIO()
85
+ sys.stdout = captured_output
86
+ jac_import("micro.simple_walk_by_edge", base_path=self.examples_abs_path(""))
87
+ sys.stdout = sys.__stdout__
88
+ stdout_value = captured_output.getvalue()
89
+ self.assertEqual(
90
+ stdout_value,
91
+ "Visited 1\nVisited 2\n",
92
+ )
93
+
83
94
  def test_guess_game(self) -> None:
84
95
  """Parse micro jac file."""
85
96
  captured_output = io.StringIO()
@@ -197,8 +208,10 @@ class JacLanguageTests(TestCase):
197
208
  """Test semstring."""
198
209
  captured_output = io.StringIO()
199
210
  sys.stdout = captured_output
211
+ sys.stderr = captured_output
200
212
  jac_import("semstr", base_path=self.fixture_abs_path("./"))
201
213
  sys.stdout = sys.__stdout__
214
+ sys.stderr = sys.__stderr__
202
215
  stdout_value = captured_output.getvalue()
203
216
  self.assertNotIn("Error", stdout_value)
204
217
 
@@ -225,6 +238,7 @@ class JacLanguageTests(TestCase):
225
238
  self.assertEqual(stdout_value.split("\n")[0], "11 13 12 12 11 12 12")
226
239
  self.assertEqual(stdout_value.split("\n")[1], '12 12 """hello""" 18 18')
227
240
  self.assertEqual(stdout_value.split("\n")[2], "11 12 11 12 11 18 23")
241
+ self.assertEqual(stdout_value.split("\n")[3], 'hello klkl"""')
228
242
 
229
243
  def test_deep_imports(self) -> None:
230
244
  """Parse micro jac file."""
@@ -453,24 +467,22 @@ class JacLanguageTests(TestCase):
453
467
  """Test Jac registry feature."""
454
468
  captured_output = io.StringIO()
455
469
  sys.stdout = captured_output
470
+ sys.stderr = captured_output
456
471
  jac_import("registry", base_path=self.fixture_abs_path("./"))
457
472
  sys.stdout = sys.__stdout__
473
+ sys.stderr = sys.__stderr__
458
474
  stdout_value = captured_output.getvalue()
459
475
  self.assertNotIn("Error", stdout_value)
460
476
 
461
- with open(
462
- os.path.join(
463
- self.fixture_abs_path("./"), "__jac_gen__", "registry.registry.pkl"
464
- ),
465
- "rb",
466
- ) as f:
467
- registry = pickle.load(f)
477
+ output_lines = stdout_value.strip().split("\n")
478
+ outputs = [
479
+ int(output_lines[i]) if i != 2 else output_lines[i] for i in range(4)
480
+ ]
468
481
 
469
- self.assertEqual(len(registry.registry), 9)
470
- self.assertEqual(len(list(registry.registry.items())[0][1]), 2)
471
- self.assertEqual(list(registry.registry.items())[3][0].scope, "Person")
472
- _, sem_info = registry.lookup(name="normal_ability")
473
- self.assertEqual(len(sem_info.get_children(registry)), 2)
482
+ self.assertEqual(outputs[0], 9)
483
+ self.assertEqual(outputs[1], 2)
484
+ self.assertEqual(outputs[2], "Person")
485
+ self.assertEqual(outputs[3], 2)
474
486
 
475
487
  def test_enum_inside_arch(self) -> None:
476
488
  """Test Enum as member stmt."""
@@ -479,7 +491,7 @@ class JacLanguageTests(TestCase):
479
491
  jac_import("enum_inside_archtype", base_path=self.fixture_abs_path("./"))
480
492
  sys.stdout = sys.__stdout__
481
493
  stdout_value = captured_output.getvalue()
482
- self.assertEqual("2\n", stdout_value)
494
+ self.assertIn("2 Accessing privileged Data", stdout_value)
483
495
 
484
496
  def test_needs_import_1(self) -> None:
485
497
  """Test py ast to Jac ast conversion output."""
@@ -491,10 +503,13 @@ class JacLanguageTests(TestCase):
491
503
  import jaclang.compiler.absyntree as ast
492
504
 
493
505
  with open(file_name, "r") as f:
494
- parsed_ast = py_ast.parse(f.read())
506
+ file_source = f.read()
507
+ parsed_ast = py_ast.parse(file_source)
495
508
  try:
496
509
  py_ast_build_pass = PyastBuildPass(
497
- input_ir=ast.PythonModuleAst(parsed_ast, mod_path=file_name),
510
+ input_ir=ast.PythonModuleAst(
511
+ parsed_ast, orig_src=ast.JacSource(file_source, file_name)
512
+ ),
498
513
  )
499
514
  except Exception as e:
500
515
  return f"Error While Jac to Py AST conversion: {e}"
@@ -516,9 +531,11 @@ class JacLanguageTests(TestCase):
516
531
 
517
532
  py_out_path = os.path.join(self.fixture_abs_path("./"), "pyfunc_1.py")
518
533
  with open(py_out_path) as f:
534
+ file_source = f.read()
519
535
  output = PyastBuildPass(
520
536
  input_ir=ast.PythonModuleAst(
521
- py_ast.parse(f.read()), mod_path=py_out_path
537
+ py_ast.parse(file_source),
538
+ orig_src=ast.JacSource(file_source, py_out_path),
522
539
  ),
523
540
  ).ir.unparse()
524
541
  # print(output)
@@ -547,10 +564,14 @@ class JacLanguageTests(TestCase):
547
564
  import jaclang.compiler.absyntree as ast
548
565
 
549
566
  with open(file_name, "r") as f:
550
- parsed_ast = py_ast.parse(f.read())
567
+ file_source = f.read()
568
+ parsed_ast = py_ast.parse(file_source)
551
569
  try:
552
570
  py_ast_build_pass = PyastBuildPass(
553
- input_ir=ast.PythonModuleAst(parsed_ast, mod_path=file_name),
571
+ input_ir=ast.PythonModuleAst(
572
+ parsed_ast,
573
+ orig_src=ast.JacSource(file_source, file_name),
574
+ ),
554
575
  )
555
576
  except Exception as e:
556
577
  return f"Error While Jac to Py AST conversion: {e}"
@@ -575,9 +596,11 @@ class JacLanguageTests(TestCase):
575
596
 
576
597
  py_out_path = os.path.join(self.fixture_abs_path("./"), "pyfunc_2.py")
577
598
  with open(py_out_path) as f:
599
+ file_source = f.read()
578
600
  output = PyastBuildPass(
579
601
  input_ir=ast.PythonModuleAst(
580
- py_ast.parse(f.read()), mod_path=py_out_path
602
+ py_ast.parse(file_source),
603
+ orig_src=ast.JacSource(file_source, py_out_path),
581
604
  ),
582
605
  ).ir.unparse()
583
606
  self.assertIn("class X {\n with entry {\n\n a_b = 67;", output)
@@ -595,10 +618,14 @@ class JacLanguageTests(TestCase):
595
618
  import jaclang.compiler.absyntree as ast
596
619
 
597
620
  with open(file_name, "r") as f:
598
- parsed_ast = py_ast.parse(f.read())
621
+ file_source = f.read()
622
+ parsed_ast = py_ast.parse(file_source)
599
623
  try:
600
624
  py_ast_build_pass = PyastBuildPass(
601
- input_ir=ast.PythonModuleAst(parsed_ast, mod_path=file_name),
625
+ input_ir=ast.PythonModuleAst(
626
+ parsed_ast,
627
+ orig_src=ast.JacSource(file_source, file_name),
628
+ ),
602
629
  )
603
630
  except Exception as e:
604
631
  return f"Error While Jac to Py AST conversion: {e}"
@@ -622,9 +649,11 @@ class JacLanguageTests(TestCase):
622
649
 
623
650
  py_out_path = os.path.join(self.fixture_abs_path("./"), "pyfunc_3.py")
624
651
  with open(py_out_path) as f:
652
+ file_source = f.read()
625
653
  output = PyastBuildPass(
626
654
  input_ir=ast.PythonModuleAst(
627
- py_ast.parse(f.read()), mod_path=py_out_path
655
+ py_ast.parse(file_source),
656
+ orig_src=ast.JacSource(file_source, py_out_path),
628
657
  ),
629
658
  ).ir.unparse()
630
659
  self.assertIn("if 0 <= x<= 5 {", output)
@@ -749,9 +778,11 @@ class JacLanguageTests(TestCase):
749
778
  module_path + ".py",
750
779
  )
751
780
  with open(file_path) as f:
781
+ file_source = f.read()
752
782
  jac_ast = PyastBuildPass(
753
783
  input_ir=ast.PythonModuleAst(
754
- py_ast.parse(f.read()), mod_path=file_path
784
+ py_ast.parse(file_source),
785
+ orig_src=ast.JacSource(file_source, file_path),
755
786
  )
756
787
  )
757
788
  settings.print_py_raised_ast = True
@@ -774,11 +805,13 @@ class JacLanguageTests(TestCase):
774
805
  """Test for access tags working."""
775
806
  captured_output = io.StringIO()
776
807
  sys.stdout = captured_output
808
+ sys.stderr = captured_output
777
809
  cli.check(
778
810
  self.fixture_abs_path("../../tests/fixtures/access_modifier.jac"),
779
811
  print_errs=True,
780
812
  )
781
813
  sys.stdout = sys.__stdout__
814
+ sys.stderr = sys.__stderr__
782
815
  stdout_value = captured_output.getvalue()
783
816
  self.assertEqual(stdout_value.count("Invalid access"), 18)
784
817
 
@@ -796,10 +829,12 @@ class JacLanguageTests(TestCase):
796
829
  parsed_ast = py_ast.parse(f.read())
797
830
  try:
798
831
  py_ast_build_pass = PyastBuildPass(
799
- input_ir=ast.PythonModuleAst(parsed_ast, mod_path=file_name),
832
+ input_ir=ast.PythonModuleAst(
833
+ parsed_ast, orig_src=ast.JacSource(f.read(), file_name)
834
+ )
800
835
  )
801
836
  except Exception as e:
802
- return f"Error While Jac to Py AST conversion: {e}"
837
+ raise Exception(f"Error While Jac to Py AST conversion: {e}")
803
838
 
804
839
  settings.print_py_raised_ast = True
805
840
  ir = jac_pass_to_pass(py_ast_build_pass, schedule=py_code_gen_typed).ir
@@ -1070,6 +1105,38 @@ class JacLanguageTests(TestCase):
1070
1105
  f"Expected '{val}' to appear 2 times, but found {len(occurrences)}.",
1071
1106
  )
1072
1107
 
1108
+ def test_dynamic_architype_creation(self) -> None:
1109
+ """Test that the walker and node can be created dynamically."""
1110
+ captured_output = io.StringIO()
1111
+ sys.stdout = captured_output
1112
+ cli.run(self.fixture_abs_path("create_dynamic_architype.jac"))
1113
+
1114
+ output = captured_output.getvalue().strip()
1115
+ # Expected outputs for spawned entities
1116
+ expected_spawned_walker = "Dynamic Node Value: 99"
1117
+
1118
+ # Check for the spawned messages
1119
+ self.assertTrue(
1120
+ expected_spawned_walker in output,
1121
+ f"Expected '{expected_spawned_walker}' in output.",
1122
+ )
1123
+
1124
+ def test_dynamic_architype_creation_rel_import(self) -> None:
1125
+ """Test that the walker and node can be created dynamically, with relative import."""
1126
+ captured_output = io.StringIO()
1127
+ sys.stdout = captured_output
1128
+ cli.run(self.fixture_abs_path("arch_rel_import_creation.jac"))
1129
+
1130
+ output = captured_output.getvalue().strip().splitlines()
1131
+ # Expected outputs for spawned entities
1132
+ expected_values = ["DynamicWalker Started", "UtilityNode Data: 42"]
1133
+ for val in expected_values:
1134
+ # Check for the spawned messages
1135
+ self.assertTrue(
1136
+ val in output,
1137
+ f"Expected '{val}' in output.",
1138
+ )
1139
+
1073
1140
  def test_object_ref_interface(self) -> None:
1074
1141
  """Test class method output."""
1075
1142
  captured_output = io.StringIO()
@@ -1103,3 +1170,22 @@ class JacLanguageTests(TestCase):
1103
1170
  self.assertIn(
1104
1171
  "Exiting at the end of walker: test_node(value=", stdout_value[11]
1105
1172
  )
1173
+
1174
+ def test_visit_order(self) -> None:
1175
+ """Test entry and exit behavior of walker."""
1176
+ captured_output = io.StringIO()
1177
+ sys.stdout = captured_output
1178
+ jac_import("visit_order", base_path=self.fixture_abs_path("./"))
1179
+ sys.stdout = sys.__stdout__
1180
+ stdout_value = captured_output.getvalue()
1181
+ self.assertEqual("[MyNode(Name='End'), MyNode(Name='Middle')]\n", stdout_value)
1182
+
1183
+ def test_global_multivar(self) -> None:
1184
+ """Test supporting multiple global variable in a statement."""
1185
+ captured_output = io.StringIO()
1186
+ sys.stdout = captured_output
1187
+ jac_import("glob_multivar_statement", base_path=self.fixture_abs_path("./"))
1188
+ sys.stdout = sys.__stdout__
1189
+ stdout_value = captured_output.getvalue().split("\n")
1190
+ self.assertIn("Hello World !", stdout_value[0])
1191
+ self.assertIn("Welcome to Jaseci!", stdout_value[1])