jaclang 0.8.5__py3-none-any.whl → 0.8.7__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 (70) hide show
  1. jaclang/cli/cli.md +4 -3
  2. jaclang/cli/cli.py +63 -29
  3. jaclang/cli/cmdreg.py +1 -140
  4. jaclang/compiler/passes/main/__init__.py +2 -0
  5. jaclang/compiler/passes/main/cfg_build_pass.py +21 -1
  6. jaclang/compiler/passes/main/inheritance_pass.py +8 -1
  7. jaclang/compiler/passes/main/pyast_gen_pass.py +70 -11
  8. jaclang/compiler/passes/main/pyast_load_pass.py +14 -20
  9. jaclang/compiler/passes/main/sym_tab_build_pass.py +4 -0
  10. jaclang/compiler/passes/main/tests/fixtures/cfg_has_var.jac +12 -0
  11. jaclang/compiler/passes/main/tests/fixtures/cfg_if_no_else.jac +11 -0
  12. jaclang/compiler/passes/main/tests/fixtures/cfg_return.jac +9 -0
  13. jaclang/compiler/passes/main/tests/fixtures/checker_binary_op.jac +21 -0
  14. jaclang/compiler/passes/main/tests/fixtures/checker_call_expr_class.jac +12 -0
  15. jaclang/compiler/passes/main/tests/fixtures/checker_cyclic_symbol.jac +4 -0
  16. jaclang/compiler/passes/main/tests/fixtures/checker_expr_call.jac +9 -0
  17. jaclang/compiler/passes/main/tests/fixtures/checker_import_missing_module.jac +13 -0
  18. jaclang/compiler/passes/main/tests/fixtures/checker_imported.jac +2 -0
  19. jaclang/compiler/passes/main/tests/fixtures/checker_importer.jac +6 -0
  20. jaclang/compiler/passes/main/tests/fixtures/checker_magic_call.jac +17 -0
  21. jaclang/compiler/passes/main/tests/fixtures/checker_mod_path.jac +8 -0
  22. jaclang/compiler/passes/main/tests/fixtures/data_spatial_types.jac +1 -1
  23. jaclang/compiler/passes/main/tests/fixtures/import_symbol_type_infer.jac +11 -0
  24. jaclang/compiler/passes/main/tests/fixtures/infer_type_assignment.jac +5 -0
  25. jaclang/compiler/passes/main/tests/fixtures/member_access_type_inferred.jac +13 -0
  26. jaclang/compiler/passes/main/tests/fixtures/member_access_type_resolve.jac +11 -0
  27. jaclang/compiler/passes/main/tests/fixtures/type_annotation_assignment.jac +8 -0
  28. jaclang/compiler/passes/main/tests/test_cfg_build_pass.py +62 -24
  29. jaclang/compiler/passes/main/tests/test_checker_pass.py +161 -0
  30. jaclang/compiler/passes/main/type_checker_pass.py +147 -0
  31. jaclang/compiler/passes/tool/tests/fixtures/simple_walk_fmt.jac +1 -4
  32. jaclang/compiler/program.py +17 -3
  33. jaclang/compiler/type_system/__init__.py +1 -0
  34. jaclang/compiler/type_system/operations.py +104 -0
  35. jaclang/compiler/type_system/type_evaluator.py +560 -0
  36. jaclang/compiler/type_system/type_utils.py +41 -0
  37. jaclang/compiler/type_system/types.py +240 -0
  38. jaclang/compiler/unitree.py +15 -9
  39. jaclang/langserve/dev_engine.jac +645 -0
  40. jaclang/langserve/dev_server.jac +201 -0
  41. jaclang/langserve/engine.jac +135 -91
  42. jaclang/langserve/server.jac +21 -14
  43. jaclang/langserve/tests/server_test/test_lang_serve.py +2 -5
  44. jaclang/langserve/tests/test_dev_server.py +80 -0
  45. jaclang/langserve/tests/test_server.py +9 -2
  46. jaclang/langserve/utils.jac +44 -48
  47. jaclang/runtimelib/builtin.py +28 -39
  48. jaclang/runtimelib/importer.py +1 -1
  49. jaclang/runtimelib/machine.py +48 -64
  50. jaclang/runtimelib/memory.py +23 -5
  51. jaclang/runtimelib/tests/fixtures/savable_object.jac +10 -2
  52. jaclang/runtimelib/utils.py +13 -6
  53. jaclang/tests/fixtures/edge_node_walk.jac +1 -1
  54. jaclang/tests/fixtures/edges_walk.jac +1 -1
  55. jaclang/tests/fixtures/gendot_bubble_sort.jac +1 -1
  56. jaclang/tests/fixtures/jac_run_py_bugs.py +18 -0
  57. jaclang/tests/fixtures/jac_run_py_import.py +13 -0
  58. jaclang/tests/fixtures/lambda_arg_annotation.jac +15 -0
  59. jaclang/tests/fixtures/lambda_self.jac +18 -0
  60. jaclang/tests/fixtures/py_run.jac +8 -0
  61. jaclang/tests/fixtures/py_run.py +23 -0
  62. jaclang/tests/fixtures/pyfunc.py +2 -0
  63. jaclang/tests/test_cli.py +103 -14
  64. jaclang/tests/test_language.py +10 -4
  65. jaclang/utils/lang_tools.py +3 -0
  66. jaclang/utils/module_resolver.py +1 -1
  67. {jaclang-0.8.5.dist-info → jaclang-0.8.7.dist-info}/METADATA +4 -2
  68. {jaclang-0.8.5.dist-info → jaclang-0.8.7.dist-info}/RECORD +70 -37
  69. {jaclang-0.8.5.dist-info → jaclang-0.8.7.dist-info}/WHEEL +1 -1
  70. {jaclang-0.8.5.dist-info → jaclang-0.8.7.dist-info}/entry_points.txt +0 -0
@@ -11,7 +11,7 @@ from typing import Callable, Iterator, TYPE_CHECKING
11
11
  import jaclang.compiler.unitree as uni
12
12
 
13
13
  if TYPE_CHECKING:
14
- from jaclang.runtimelib.constructs import NodeAnchor, NodeArchetype
14
+ from jaclang.runtimelib.constructs import NodeArchetype
15
15
 
16
16
 
17
17
  def read_file_with_encoding(file_path: str) -> str:
@@ -57,25 +57,32 @@ def sys_path_context(path: str) -> Iterator[None]:
57
57
 
58
58
 
59
59
  def collect_node_connections(
60
- current_node: NodeAnchor,
60
+ current_node: NodeArchetype,
61
61
  visited_nodes: set,
62
62
  connections: set,
63
+ edge_ids: set,
63
64
  ) -> None:
64
65
  """Nodes and edges representing the graph are collected in visited_nodes and connections."""
65
66
  if current_node not in visited_nodes:
66
67
  visited_nodes.add(current_node)
67
- edges = current_node.edges
68
+ edges = current_node.__jac__.edges
68
69
  for edge_ in edges:
70
+ if edge_.id in edge_ids:
71
+ continue
72
+ edge_ids.add(edge_.id)
69
73
  target = edge_.target
70
74
  if target:
71
75
  connections.add(
72
76
  (
73
- current_node.archetype,
77
+ edge_.id,
78
+ edge_.source.archetype,
74
79
  target.archetype,
75
- edge_.__class__.__name__,
80
+ edge_.archetype,
76
81
  )
77
82
  )
78
- collect_node_connections(target, visited_nodes, connections)
83
+ collect_node_connections(
84
+ target.archetype, visited_nodes, connections, edge_ids
85
+ )
79
86
 
80
87
 
81
88
  def traverse_graph(
@@ -37,7 +37,7 @@ impl creator.create {
37
37
 
38
38
  with entry {
39
39
  print(root spawn creator());
40
- print(_.node_dot(root));
40
+ print(printgraph(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 @@ impl creator.create{
30
30
 
31
31
  with entry{
32
32
  print(root spawn creator());
33
- print(_.node_dot(root));
33
+ print(printgraph(root));
34
34
  print([root ->:Edge_a:->]);
35
35
  print([root ->:Edge_c:->]);
36
36
  print([root ->:Edge_a:-> ->:Edge_b:->]);
@@ -73,5 +73,5 @@ with entry {
73
73
  root spawn walker1();
74
74
  root spawn walker2();
75
75
  root spawn walker3();
76
- print(_.node_dot(root));
76
+ print(printgraph(root));
77
77
  }
@@ -0,0 +1,18 @@
1
+ from jaclang.tests.fixtures.jac_run_py_import import MyModule
2
+
3
+ class SimpleClass:
4
+ def __init__(self, name: str, age: int) -> None:
5
+ self.name = name
6
+ self.age = age
7
+
8
+ def greet(self):
9
+ return f"Hello, my name is {self.name} and I am {self.age} years old."
10
+
11
+
12
+ # Create an object of the class
13
+ person = SimpleClass("Alice", 30)
14
+
15
+ # Run the greet method
16
+ print(person.greet())
17
+
18
+ MyModule.init()
@@ -0,0 +1,13 @@
1
+ class MyModule:
2
+ @staticmethod
3
+ def init():
4
+ print("MyModule initialized!")
5
+
6
+ @staticmethod
7
+ def do_something():
8
+ print("Doing something...")
9
+
10
+
11
+
12
+
13
+
@@ -0,0 +1,15 @@
1
+
2
+
3
+ with entry {
4
+ x = lambda a: int, b: int : b + a;
5
+ print(x(5, 4));
6
+ y = lambda : 567;
7
+ print(y());
8
+ }
9
+
10
+
11
+ with entry{
12
+ f = lambda x:Any :"even" if x % 2 == 0 else "odd";
13
+ print(f(7));
14
+
15
+ }
@@ -0,0 +1,18 @@
1
+
2
+
3
+ walker Tourist {
4
+ can travel with City entry {
5
+
6
+ def foo(a:int){}
7
+ x = lambda a: int, b: int : b + a;
8
+ y = lambda : 567;
9
+ sorted_users = sorted(
10
+ users,
11
+ key=lambda x: dict: x["email"], reverse=True
12
+ );
13
+
14
+ }
15
+ def visit_city(c:City){
16
+ print("Visiting", c.name);
17
+ }
18
+ }
@@ -0,0 +1,8 @@
1
+ with entry {
2
+ print('Hello, Jaseci');
3
+ a = 10;
4
+ b = 15;
5
+ sum_ab = (a + b);
6
+ print('Sum:', sum_ab);
7
+ }
8
+
@@ -0,0 +1,23 @@
1
+ # Print Hello, World!
2
+ print("Hello, World!")
3
+
4
+ a = 5
5
+ b = 3
6
+ sum_ab = a + b
7
+ print("Sum:", sum_ab)
8
+
9
+ num = 7
10
+ if num % 2 == 0:
11
+ print(num, "is even")
12
+ else:
13
+ print(num, "is odd")
14
+
15
+ # Loop through a list
16
+ fruits = ["apple", "banana", "cherry"]
17
+ for fruit in fruits:
18
+ print(fruit)
19
+
20
+ def greet(name):
21
+ return f"Hello, {name}!"
22
+
23
+ print(greet("Alice"))
@@ -4,6 +4,8 @@
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
+ class MyClass:
8
+ pass
7
9
 
8
10
  def my_print(x: object) -> None:
9
11
  """Print function."""
jaclang/tests/test_cli.py CHANGED
@@ -65,7 +65,9 @@ class JacCliTests(TestCase):
65
65
  self.assertIn("Hello Peter Peter", stdout_value)
66
66
  self.assertIn("Peter squared is Peter Peter", stdout_value)
67
67
  self.assertIn("PETER! wrong poem", stdout_value)
68
- self.assertIn("Hello Peter , yoo mother is Mary. Myself, I am Peter.", stdout_value)
68
+ self.assertIn(
69
+ "Hello Peter , yoo mother is Mary. Myself, I am Peter.", stdout_value
70
+ )
69
71
  self.assertIn("Left aligned: Apple | Price: 1.23", stdout_value)
70
72
  self.assertIn("name = Peter 🤔", stdout_value)
71
73
 
@@ -205,19 +207,6 @@ class JacCliTests(TestCase):
205
207
  self.assertIn("Sub objects.", stdout_value)
206
208
  self.assertGreater(stdout_value.count("def exit_"), 10)
207
209
 
208
- def test_jac_cmd_line(self) -> None:
209
- """Basic test for pass."""
210
- process = subprocess.Popen(
211
- ["jac"],
212
- stdin=subprocess.PIPE,
213
- stdout=subprocess.PIPE,
214
- stderr=subprocess.PIPE,
215
- text=True,
216
- )
217
- stdout_value, _ = process.communicate(input="exit\n")
218
- self.assertEqual(process.returncode, 0, "Process did not exit successfully")
219
- self.assertIn("Welcome to the Jac CLI!", stdout_value)
220
-
221
210
  def test_ast_print(self) -> None:
222
211
  """Testing for print AstTool."""
223
212
  captured_output = io.StringIO()
@@ -271,6 +260,27 @@ class JacCliTests(TestCase):
271
260
  stdout_value,
272
261
  )
273
262
 
263
+ def test_cfg_printgraph(self) -> None:
264
+ """Testing for print CFG."""
265
+ captured_output = io.StringIO()
266
+ sys.stdout = captured_output
267
+
268
+ cli.tool("ir", ["cfg.", f"{self.fixture_abs_path('hello.jac')}"])
269
+
270
+ sys.stdout = sys.__stdout__
271
+ stdout_value = captured_output.getvalue()
272
+ correct_graph = (
273
+ "digraph G {\n"
274
+ ' 0 [label="BB0\\n\\nprint ( \\"im still here\\" ) ;", shape=box];\n'
275
+ ' 1 [label="BB1\\n\\"Hello World!\\" |> print ;", shape=box];\n'
276
+ "}\n\n"
277
+ )
278
+
279
+ self.assertEqual(
280
+ correct_graph,
281
+ stdout_value,
282
+ )
283
+
274
284
  def test_del_clean(self) -> None:
275
285
  """Testing for print AstTool."""
276
286
  captured_output = io.StringIO()
@@ -391,6 +401,36 @@ class JacCliTests(TestCase):
391
401
  sys.stdout = sys.__stdout__
392
402
  stdout_value = captured_output.getvalue()
393
403
  self.assertIn("def my_print(x: object) -> None", stdout_value)
404
+ self.assertIn("class MyClass {", stdout_value)
405
+ self.assertIn('"""Print function."""', stdout_value)
406
+
407
+ def test_lambda_arg_annotation(self) -> None:
408
+ """Test for lambda argument annotation."""
409
+ captured_output = io.StringIO()
410
+ sys.stdout = captured_output
411
+ cli.jac2py(
412
+ f"{self.fixture_abs_path('../../tests/fixtures/lambda_arg_annotation.jac')}"
413
+ )
414
+ sys.stdout = sys.__stdout__
415
+ stdout_value = captured_output.getvalue()
416
+ self.assertIn("x = lambda a, b: b + a", stdout_value)
417
+ self.assertIn("y = lambda: 567", stdout_value)
418
+ self.assertIn("f = lambda x: 'even' if x % 2 == 0 else 'odd'", stdout_value)
419
+
420
+ def test_lambda_self(self) -> None:
421
+ """Test for lambda argument annotation."""
422
+ captured_output = io.StringIO()
423
+ sys.stdout = captured_output
424
+ cli.jac2py(f"{self.fixture_abs_path('../../tests/fixtures/lambda_self.jac')}")
425
+ sys.stdout = sys.__stdout__
426
+ stdout_value = captured_output.getvalue()
427
+ self.assertIn("def travel(self, here: City) -> None:", stdout_value)
428
+ self.assertIn("def foo(a: int) -> None:", stdout_value)
429
+ self.assertIn("x = lambda a, b: b + a", stdout_value)
430
+ self.assertIn("def visit_city(self, c: City) -> None:", stdout_value)
431
+ self.assertIn(
432
+ "sorted(users, key=lambda x: x['email'], reverse=True)", stdout_value
433
+ )
394
434
 
395
435
  def test_caching_issue(self) -> None:
396
436
  """Test for Caching Issue."""
@@ -520,3 +560,52 @@ class JacCliTests(TestCase):
520
560
  description_pattern,
521
561
  f"Parameter description for '{param_name}' not found in help text for '{cmd_name}'",
522
562
  )
563
+
564
+ def test_run_jac_name_py(self) -> None:
565
+ """Test a specific test case."""
566
+ process = subprocess.Popen(
567
+ [
568
+ "jac",
569
+ "run",
570
+ self.fixture_abs_path("py_run.py"),
571
+ ],
572
+ stdin=subprocess.PIPE,
573
+ stdout=subprocess.PIPE,
574
+ stderr=subprocess.PIPE,
575
+ text=True,
576
+ )
577
+ stdout, stderr = process.communicate()
578
+ self.assertIn("Hello, World!", stdout)
579
+ self.assertIn("Sum: 8", stdout)
580
+
581
+ def test_jac_run_py_bugs(self) -> None:
582
+ """Test jac run python files."""
583
+ process = subprocess.Popen(
584
+ [
585
+ "jac",
586
+ "run",
587
+ self.fixture_abs_path("jac_run_py_bugs.py"),
588
+ ],
589
+ stdin=subprocess.PIPE,
590
+ stdout=subprocess.PIPE,
591
+ stderr=subprocess.PIPE,
592
+ text=True,
593
+ )
594
+ stdout, stderr = process.communicate()
595
+ self.assertIn("Hello, my name is Alice and I am 30 years old.", stdout)
596
+ self.assertIn("MyModule initialized!", stdout)
597
+
598
+ def test_cli_defaults_to_run_with_file(self) -> None:
599
+ """jac myfile.jac should behave like jac run myfile.jac."""
600
+ process = subprocess.Popen(
601
+ [
602
+ "jac",
603
+ self.fixture_abs_path("hello.jac"),
604
+ ],
605
+ stdin=subprocess.PIPE,
606
+ stdout=subprocess.PIPE,
607
+ stderr=subprocess.PIPE,
608
+ text=True,
609
+ )
610
+ stdout, stderr = process.communicate()
611
+ self.assertIn("Hello World!", stdout)
@@ -122,13 +122,19 @@ class JacLanguageTests(TestCase):
122
122
  data = json.loads(stdout_value)
123
123
 
124
124
  nodes = data["nodes"]
125
- self.assertEqual(len(nodes), 7)
125
+ edges = data["edges"]
126
+
127
+ self.assertEqual(len(nodes), 5)
128
+ self.assertEqual(len(edges), 6)
129
+
126
130
  for node in nodes:
127
131
  label = node["label"]
128
132
  self.assertIn(label, ["root", "N(val=0)", "N(val=1)"])
129
133
 
130
- edges = data["edges"]
131
- self.assertEqual(len(edges), 6)
134
+ for edge in edges:
135
+ label = edge["label"]
136
+ self.assertIn(label, ["E(val=1)", "E(val=1)", "E(val=1)", "E(val=0)", "E(val=0)", "E(val=0)"])
137
+
132
138
 
133
139
  def test_printgraph_mermaid(self) -> None:
134
140
  """Test the mermaid gen of builtin function."""
@@ -229,7 +235,7 @@ class JacLanguageTests(TestCase):
229
235
  sys.stdout = sys.__stdout__
230
236
  stdout_value = captured_output.getvalue()
231
237
  self.assertIn(
232
- '[label="inner_node(main=5, sub=2)"];',
238
+ '[label="inner_node(main=5, sub=2)"fillcolor="#FFDEAD"];',
233
239
  stdout_value,
234
240
  )
235
241
 
@@ -8,6 +8,7 @@ from typing import List, Optional, Type
8
8
 
9
9
  import jaclang.compiler.unitree as uni
10
10
  from jaclang.compiler.passes.main import PyastBuildPass
11
+ from jaclang.compiler.passes.main.cfg_build_pass import cfg_dot_from_file
11
12
  from jaclang.compiler.passes.tool.doc_ir_gen_pass import DocIRGenPass
12
13
  from jaclang.compiler.program import JacProgram
13
14
  from jaclang.compiler.unitree import UniScopeNode
@@ -242,6 +243,8 @@ class AstTool:
242
243
  return out
243
244
  case "ast.":
244
245
  return ir.printgraph()
246
+ case "cfg.":
247
+ return cfg_dot_from_file(file_name)
245
248
  case "unparse":
246
249
  return ir.unparse()
247
250
  case "pyast":
@@ -52,7 +52,7 @@ def resolve_module(target: str, base_path: str) -> Tuple[str, str]:
52
52
  level += 1
53
53
  actual_parts = parts[level:]
54
54
 
55
- for sp in site.getsitepackages():
55
+ for sp in get_jac_search_paths(base_path):
56
56
  res = _candidate_from(sp, actual_parts)
57
57
  if res:
58
58
  return res
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: jaclang
3
- Version: 0.8.5
3
+ Version: 0.8.7
4
4
  Summary: Jac is a unique and powerful programming language that runs on top of Python, offering an unprecedented level of intelligence and intuitive understanding.
5
5
  License: MIT
6
6
  Keywords: jac,jaclang,jaseci,python,programming-language,machine-learning,artificial-intelligence
@@ -14,7 +14,9 @@ Classifier: Programming Language :: Python :: 3
14
14
  Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
17
18
  Provides-Extra: all
19
+ Provides-Extra: cloud
18
20
  Provides-Extra: llm
19
21
  Provides-Extra: streamlit
20
22
  Requires-Dist: mypy (>=1.15.0,<2.0.0)