jaclang 0.7.17__py3-none-any.whl → 0.7.21__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 (53) hide show
  1. jaclang/cli/cli.py +5 -7
  2. jaclang/compiler/absyntree.py +1 -1
  3. jaclang/compiler/jac.lark +14 -14
  4. jaclang/compiler/parser.py +71 -59
  5. jaclang/compiler/passes/ir_pass.py +2 -0
  6. jaclang/compiler/passes/main/__init__.py +1 -1
  7. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +50 -13
  8. jaclang/compiler/passes/main/import_pass.py +29 -1
  9. jaclang/compiler/passes/main/py_collect_dep_pass.py +8 -0
  10. jaclang/compiler/passes/main/pyast_gen_pass.py +25 -0
  11. jaclang/compiler/passes/main/registry_pass.py +4 -0
  12. jaclang/compiler/passes/main/sym_tab_build_pass.py +0 -18
  13. jaclang/compiler/passes/main/tests/fixtures/mod_type_assign.jac +7 -0
  14. jaclang/compiler/passes/main/tests/fixtures/pygame_mock/__init__.pyi +3 -0
  15. jaclang/compiler/passes/main/tests/test_import_pass.py +10 -10
  16. jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
  17. jaclang/compiler/passes/main/tests/test_typeinfo_pass.py +23 -1
  18. jaclang/compiler/passes/main/type_check_pass.py +4 -4
  19. jaclang/compiler/passes/tool/jac_formatter_pass.py +63 -31
  20. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/line_spacing.jac +57 -0
  21. jaclang/compiler/semtable.py +4 -4
  22. jaclang/compiler/symtable.py +5 -0
  23. jaclang/langserve/engine.py +92 -22
  24. jaclang/langserve/tests/fixtures/import_include_statements.jac +3 -3
  25. jaclang/langserve/tests/test_server.py +11 -7
  26. jaclang/langserve/utils.py +11 -213
  27. jaclang/plugin/builtin.py +8 -4
  28. jaclang/plugin/default.py +17 -3
  29. jaclang/plugin/feature.py +10 -0
  30. jaclang/plugin/spec.py +12 -0
  31. jaclang/plugin/tests/test_jaseci.py +23 -4
  32. jaclang/runtimelib/architype.py +20 -2
  33. jaclang/runtimelib/importer.py +4 -0
  34. jaclang/runtimelib/machine.py +92 -4
  35. jaclang/runtimelib/memory.py +7 -7
  36. jaclang/settings.py +4 -0
  37. jaclang/tests/fixtures/bar.jac +1 -1
  38. jaclang/tests/fixtures/builtin_dotgen.jac +1 -0
  39. jaclang/tests/fixtures/builtins_test.jac +16 -0
  40. jaclang/tests/fixtures/dynamic_architype.jac +34 -0
  41. jaclang/tests/fixtures/entry_exit.jac +36 -0
  42. jaclang/tests/fixtures/foo.jac +0 -1
  43. jaclang/tests/fixtures/match_multi_ex.jac +12 -0
  44. jaclang/tests/fixtures/objref.jac +12 -0
  45. jaclang/tests/fixtures/trailing_comma.jac +88 -0
  46. jaclang/tests/fixtures/walker_update.jac +19 -0
  47. jaclang/tests/test_cli.py +29 -2
  48. jaclang/tests/test_language.py +144 -4
  49. jaclang/utils/treeprinter.py +1 -1
  50. {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/METADATA +6 -2
  51. {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/RECORD +53 -43
  52. {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/WHEEL +0 -0
  53. {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/entry_points.txt +0 -0
@@ -31,6 +31,7 @@ with entry{
31
31
  print(d2.count('a(val')==19,d2.count('#F5E5FF')==2 ,'Edge1' not in d2,d2.count('GenericEdge')==42);
32
32
  print(d3.count('a(val')==6,d3.count("GenericEdge")==5,d3.count('#F5E5FF')==1);
33
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);
34
35
  # print(l3<l2);
35
36
  # print(d1);
36
37
  # print(d2);
@@ -0,0 +1,16 @@
1
+ with entry {
2
+ a: list[str] = [];
3
+ a.append("str1");
4
+ a.append("str2");
5
+ a.pop();
6
+ a.pop();
7
+
8
+ str(6).count("6");
9
+ int("5");
10
+
11
+ b: dict[str, list[int]] = {"a": [2, 3, 4]};
12
+ b.keys();
13
+ b["a"].append(9);
14
+
15
+ dir(a);
16
+ }
@@ -0,0 +1,34 @@
1
+ import:py from jaclang.runtimelib.machine {JacMachine}
2
+ import:jac from bar {Item}
3
+
4
+ node test_node {
5
+ has value:int;
6
+ }
7
+
8
+ walker test_walker {
9
+ can visit_nodes with `root entry {
10
+ visit [-->];
11
+ }
12
+
13
+ can print_value with test_node | Item entry {
14
+ print("Value:", f'{here.value}');
15
+ }
16
+ }
17
+
18
+ walker child_walker :test_walker: {}
19
+
20
+ with entry {
21
+ for value in range(1, 4) {
22
+ root ++> test_node(value=value);
23
+ root ++> Item(value=value);
24
+ }
25
+ node_obj = JacMachine.get().spawn_node(node_name='test_node', attributes={'value': 0}, module_name='__main__');
26
+ walker_obj = JacMachine.get().spawn_walker(walker_name='child_walker', module_name='__main__');
27
+ external_node = JacMachine.get().spawn_node(node_name='Item', attributes={'value': 0}, module_name='bar');
28
+ root ++> external_node;
29
+ root ++> node_obj;
30
+ print("Spawned Node:", node_obj);
31
+ print("Spawned Walker:", walker_obj);
32
+ print("Spawned External node:", external_node);
33
+ root spawn walker_obj;
34
+ }
@@ -0,0 +1,36 @@
1
+ node test_node {
2
+ has value: int;
3
+ }
4
+
5
+ walker test_walker {
6
+ has visited_nodes: list = [];
7
+ has entry_count: int = 0;
8
+ has exit_count: int = 0;
9
+
10
+ can traverse with `root entry {
11
+ visit [-->](`?test_node);
12
+ }
13
+
14
+ can log_entry with entry {
15
+ print("Entering at the beginning of walker: ",here);
16
+ self.entry_count += 1;
17
+ }
18
+
19
+ can log_visit with test_node exit {
20
+ print("Visiting node : ", here);
21
+ self.visited_nodes.append(here);
22
+ }
23
+
24
+ can log_exit with exit {
25
+ print("Exiting at the end of walker: ",here);
26
+ self.exit_count += 1;
27
+ }
28
+ }
29
+
30
+ with entry {
31
+ for i in range(10) {
32
+ root ++> (next:=test_node(value=i));
33
+ }
34
+ wlk_obj = root spawn test_walker();
35
+ print(wlk_obj);
36
+ }
@@ -1,4 +1,3 @@
1
- import:py from jaclang.plugin.feature, JacFeature as Jac;
2
1
  import:py from jaclang.runtimelib.machine, JacMachine;
3
2
  import:jac from bar, bar_walk;
4
3
  # Test runner to initialize the walker
@@ -0,0 +1,12 @@
1
+ with entry{
2
+ Num =10;
3
+ match Num{
4
+ case 2:
5
+ print("Two");
6
+ case 10:
7
+ print("Ten");
8
+ print("ten");
9
+ case _:
10
+ print("nothing");
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ node MyNode {
2
+ has value: int = 0;
3
+ }
4
+
5
+ with entry {
6
+ root ++> (x:=MyNode());
7
+ obj_id = jid(x);
8
+ myobj = &obj_id;
9
+ print(obj_id);
10
+ print(myobj);
11
+ print("valid:", myobj == x);
12
+ }
@@ -0,0 +1,88 @@
1
+ """
2
+ This test file is to ensure the valid syntax of jac lang.
3
+ Add new jac syntax here to test if it compile without any issue.
4
+ """
5
+
6
+
7
+ # Import statement without trailing comma.
8
+ import:py from time { sleep, timezone, tzname }
9
+ # Import statement with trailing comma.
10
+ import:py from os { path, getenv, getpid, }
11
+
12
+ enum WithoutTrailComma {
13
+ FOO = "FOO",
14
+ BAR = "BAR"
15
+ }
16
+
17
+ enum WithTrailComma {
18
+ FOO = "FOO",
19
+ BAR = "BAR",
20
+ }
21
+
22
+ can without_trail_comma(a: int, b: int) {}
23
+
24
+ can with_trail_comma(a: int, b: int, c: int, ) {}
25
+
26
+ with entry {
27
+
28
+ dict_without_trail_comma = {"key": "value"};
29
+ dict_with_trail_comma = {"key": "val",};
30
+
31
+ list_without_trail_comma = ["foo", "bar"];
32
+ list_with_trail_comma = ["foo", "bar",];
33
+
34
+ set_without_trail_comma = {"foo", "bar"};
35
+ set_with_trail_comma = {"foo", "bar"};
36
+ obj foo11 {
37
+ has val: int,
38
+ val2: int = 9,
39
+ val3: int = 8,
40
+ val4: int = 8,
41
+ val5: int = 8;
42
+ }
43
+ empty_tuple = ();
44
+ single_tuple = ('single', );
45
+
46
+ tuple_without_trail_comma = ("foo", "bar");
47
+ tuple_with_trail_comma = ("foo", "bar", );
48
+
49
+ mixed_tuple = (1, 'two', 3.0, False);
50
+ mixed_tuple_with_trail_comma = (1, 'two', 3.0, False, );
51
+
52
+ nested_tuple = (1, (2, 3), 'four');
53
+ nested_tuple_with_trail_comma = (1, (2, 3), 'four', );
54
+
55
+ deeply_nested_tuple = (1, (2, (3, (4, 5))));
56
+ deeply_nested_tuple_with_trail_comma = (1, (2, (3, (4, 5))), );
57
+
58
+ tuple1 = ("foo", );
59
+ tuple1_2 = ("foo", "bar", "baz");
60
+ tuple_2_2 = ("foo", "bar", "baz", );
61
+
62
+ foo_instance1 = foo11(val=90);
63
+ foo_instance1_2 = foo11(val=90, );
64
+
65
+ foo_instance3 = foo11(2, 34, val3=90);
66
+ foo_instance3_2 = foo11(2, 34, val3=90, );
67
+
68
+ foo_instance4 = foo11(2, 34, val3=90, val4=90);
69
+ foo_instance4_2 = foo11(2, 34, val3=90, val4=90, );
70
+
71
+ func_tuple = (foo_instance1, foo_instance3_2, len(tuple1_2));
72
+ func_tuple_with_trail_comma = (foo_instance1, foo_instance3_2, len(tuple1_2), );
73
+
74
+ unpack_tuple = (1, 2, 3);
75
+ (a, b, c, ) = unpack_tuple;
76
+ values = (a, b, c);
77
+
78
+ (1, 2);
79
+ (1, 2, );
80
+ (1, 2, 3, 4);
81
+ (1, 2, 3, 4, );
82
+
83
+ val_f = (foo_instance3_2.val, foo_instance3_2.val2, foo_instance3_2.val3);
84
+ expression_tuple = (1 + 2, len("abc"), foo_instance1.val * 2);
85
+ tuple_with_list = (1, [2, 3], 4);
86
+ print("Code compiled and ran successfully!");
87
+
88
+ }
@@ -0,0 +1,19 @@
1
+ import:jac from bar { bar_walk }
2
+ import:py from jaclang.runtimelib.machine { JacMachine }
3
+ import:py os;
4
+
5
+ can update_bar_walker {
6
+ "Updating bar.jac with new behavior." |> print;
7
+ (bar_walk_new, ) = JacMachine.get().update_walker(
8
+ "bar",
9
+ items={'bar_walk': None}
10
+ );
11
+ "Running bar_walk after update..." |> print;
12
+ root spawn bar_walk_new();
13
+ print(f"bar_walk: {bar_walk_new.__dict__}");
14
+ }
15
+
16
+
17
+ with entry {
18
+ update_bar_walker();
19
+ }
jaclang/tests/test_cli.py CHANGED
@@ -190,6 +190,33 @@ class JacCliTests(TestCase):
190
190
  r"8\:37 \- 8:44.*ModuleItem - display - abs_path\:.*fixtures/pygame_mock/display.py",
191
191
  )
192
192
 
193
+ def test_builtins_loading(self) -> None:
194
+ """Testing for print AstTool."""
195
+ from jaclang.settings import settings
196
+
197
+ settings.ast_symbol_info_detailed = True
198
+ captured_output = io.StringIO()
199
+ sys.stdout = captured_output
200
+
201
+ cli.tool("ir", ["ast", f"{self.fixture_abs_path('builtins_test.jac')}"])
202
+
203
+ sys.stdout = sys.__stdout__
204
+ stdout_value = captured_output.getvalue()
205
+ settings.ast_symbol_info_detailed = False
206
+
207
+ self.assertRegex(
208
+ stdout_value,
209
+ r"2\:8 \- 2\:12.*BuiltinType - list - .*SymbolPath: builtins_test.builtins.list",
210
+ )
211
+ self.assertRegex(
212
+ stdout_value,
213
+ r"15\:5 \- 15\:8.*Name - dir - .*SymbolPath: builtins_test.builtins.dir",
214
+ )
215
+ self.assertRegex(
216
+ stdout_value,
217
+ r"13\:12 \- 13\:18.*Name - append - .*SymbolPath: builtins_test.builtins.list.append",
218
+ )
219
+
193
220
  def test_ast_dotgen(self) -> None:
194
221
  """Testing for print AstTool."""
195
222
  captured_output = io.StringIO()
@@ -218,8 +245,8 @@ class JacCliTests(TestCase):
218
245
  sys.stdout = sys.__stdout__
219
246
  stdout_value = captured_output.getvalue()
220
247
  self.assertEqual(stdout_value.count("type_info.ServerWrapper"), 7)
221
- self.assertEqual(stdout_value.count("builtins.int"), 2)
222
- self.assertEqual(stdout_value.count("builtins.str"), 7)
248
+ self.assertEqual(stdout_value.count("builtins.int"), 3)
249
+ self.assertEqual(stdout_value.count("builtins.str"), 10)
223
250
 
224
251
  def test_build_and_run(self) -> None:
225
252
  """Testing for print AstTool."""
@@ -39,7 +39,7 @@ class JacLanguageTests(TestCase):
39
39
  sys.stdout = captured_output
40
40
 
41
41
  # Execute the function
42
- cli.run(self.fixture_abs_path("sub_abil_sep.jac")) # type: ignore
42
+ cli.run(self.fixture_abs_path("sub_abil_sep.jac"))
43
43
 
44
44
  sys.stdout = sys.__stdout__
45
45
  stdout_value = captured_output.getvalue()
@@ -376,7 +376,7 @@ class JacLanguageTests(TestCase):
376
376
  jac_import("builtin_dotgen", base_path=self.fixture_abs_path("./"))
377
377
  sys.stdout = sys.__stdout__
378
378
  stdout_value = captured_output.getvalue()
379
- self.assertEqual(stdout_value.count("True"), 14)
379
+ self.assertEqual(stdout_value.count("True"), 16)
380
380
 
381
381
  def test_with_contexts(self) -> None:
382
382
  """Test walking through edges."""
@@ -522,7 +522,7 @@ class JacLanguageTests(TestCase):
522
522
  self.assertIn("can greet2(**kwargs: Any) {", output)
523
523
  self.assertIn("squares_dict = {x: (x ** 2) for x in numbers};", output)
524
524
  self.assertIn(
525
- '\n\n@ my_decorator \n can say_hello() {\n """Say hello""" ; ', output
525
+ '\n\n@ my_decorator \n can say_hello() {\n\n """Say hello""" ;', output
526
526
  )
527
527
 
528
528
  def test_needs_import_2(self) -> None:
@@ -568,7 +568,7 @@ class JacLanguageTests(TestCase):
568
568
  py_ast.parse(f.read()), mod_path=py_out_path
569
569
  ),
570
570
  ).ir.unparse()
571
- self.assertIn("class X {\n with entry {\n a_b = 67;", output)
571
+ self.assertIn("class X {\n with entry {\n\n a_b = 67;", output)
572
572
  self.assertIn("br = b'Hello\\\\\\\\nWorld'", output)
573
573
  self.assertIn("class Circle {\n can init(radius: float", output)
574
574
  self.assertIn("<>node = 90; \n print(<>node) ;\n}\n", output)
@@ -677,6 +677,15 @@ class JacLanguageTests(TestCase):
677
677
  self.assertIn("1", stdout_value[0])
678
678
  self.assertIn("[2, 3, 4]", stdout_value[1])
679
679
 
680
+ def test_trailing_comma(self) -> None:
681
+ """Test trailing comma."""
682
+ captured_output = io.StringIO()
683
+ sys.stdout = captured_output
684
+ jac_import("trailing_comma", base_path=self.fixture_abs_path("./"))
685
+ sys.stdout = sys.__stdout__
686
+ stdout_value = captured_output.getvalue()
687
+ self.assertIn("Code compiled and ran successfully!", stdout_value)
688
+
680
689
  def test_try_finally(self) -> None:
681
690
  """Test try finally."""
682
691
  captured_output = io.StringIO()
@@ -951,3 +960,134 @@ class JacLanguageTests(TestCase):
951
960
  self.assertIn("Edges in bar:\n - Edge: Link", stdout_value)
952
961
  self.assertIn("Item value: 0", stdout_value)
953
962
  self.assertIn("Created 5 items.", stdout_value)
963
+
964
+ def test_walker_dynamic_update(self) -> None:
965
+ """Test dynamic update of a walker during runtime."""
966
+ session = self.fixture_abs_path("bar_walk.session")
967
+ bar_file_path = self.fixture_abs_path("bar.jac")
968
+ update_file_path = self.fixture_abs_path("walker_update.jac")
969
+ captured_output = io.StringIO()
970
+ sys.stdout = captured_output
971
+ cli.enter(
972
+ filename=bar_file_path,
973
+ session=session,
974
+ entrypoint="bar_walk",
975
+ args=[],
976
+ )
977
+ sys.stdout = sys.__stdout__
978
+ stdout_value = captured_output.getvalue()
979
+ expected_output = "Created 5 items."
980
+ self.assertIn(expected_output, stdout_value.split("\n"))
981
+ # Define the new behavior to be added
982
+ new_behavior = """
983
+ # New behavior added during runtime
984
+ can end with `root exit {
985
+ "bar_walk has been updated with new behavior!" |> print;
986
+ disengage;
987
+ }
988
+ }
989
+ """
990
+
991
+ # Backup the original file content
992
+ with open(bar_file_path, "r") as bar_file:
993
+ original_content = bar_file.read()
994
+
995
+ # Update the bar.jac file with new behavior
996
+ with open(bar_file_path, "r+") as bar_file:
997
+ content = bar_file.read()
998
+ last_brace_index = content.rfind("}")
999
+ if last_brace_index != -1:
1000
+ updated_content = content[:last_brace_index] + new_behavior
1001
+ bar_file.seek(0)
1002
+ bar_file.write(updated_content)
1003
+ bar_file.truncate()
1004
+
1005
+ captured_output = io.StringIO()
1006
+ sys.stdout = captured_output
1007
+
1008
+ try:
1009
+ cli.run(
1010
+ filename=update_file_path,
1011
+ )
1012
+ sys.stdout = sys.__stdout__
1013
+ stdout_value = captured_output.getvalue()
1014
+ expected_output = "bar_walk has been updated with new behavior!"
1015
+ self.assertIn(expected_output, stdout_value.split("\n"))
1016
+ finally:
1017
+ # Restore the original content of bar.jac
1018
+ with open(bar_file_path, "w") as bar_file:
1019
+ bar_file.write(original_content)
1020
+
1021
+ def test_dynamic_spawn_architype(self) -> None:
1022
+ """Test that the walker and node can be spawned and behaves as expected."""
1023
+ captured_output = io.StringIO()
1024
+ sys.stdout = captured_output
1025
+ cli.run(self.fixture_abs_path("dynamic_architype.jac"))
1026
+
1027
+ output = captured_output.getvalue().strip()
1028
+ output_lines = output.split("\n")
1029
+
1030
+ # Expected outputs for spawned entities
1031
+ expected_spawned_node = "Spawned Node:"
1032
+ expected_spawned_walker = "Spawned Walker:"
1033
+ expected_spawned_external_node = "Spawned External node:"
1034
+
1035
+ # Check for the spawned messages
1036
+ self.assertTrue(
1037
+ any(expected_spawned_node in line for line in output_lines),
1038
+ f"Expected '{expected_spawned_node}' in output.",
1039
+ )
1040
+ self.assertTrue(
1041
+ any(expected_spawned_walker in line for line in output_lines),
1042
+ f"Expected '{expected_spawned_walker}' in output.",
1043
+ )
1044
+ self.assertTrue(
1045
+ any(expected_spawned_external_node in line for line in output_lines),
1046
+ f"Expected '{expected_spawned_external_node}' in output.",
1047
+ )
1048
+
1049
+ # Expected values from the walker traversal
1050
+ expected_values = ["Value: 0", "Value: 1", "Value: 2", "Value: 3"]
1051
+
1052
+ # Each expected value should appear twice (once for test_node, once for Item)
1053
+ for val in expected_values:
1054
+ occurrences = [line for line in output_lines if line.strip() == val]
1055
+ self.assertEqual(
1056
+ len(occurrences),
1057
+ 2,
1058
+ f"Expected '{val}' to appear 2 times, but found {len(occurrences)}.",
1059
+ )
1060
+
1061
+ def test_object_ref_interface(self) -> None:
1062
+ """Test class method output."""
1063
+ captured_output = io.StringIO()
1064
+ sys.stdout = captured_output
1065
+ cli.run(self.fixture_abs_path("objref.jac"))
1066
+ sys.stdout = sys.__stdout__
1067
+ stdout_value = captured_output.getvalue().split("\n")
1068
+ self.assertEqual(len(stdout_value[0]), 32)
1069
+ self.assertEqual("MyNode(value=0)", stdout_value[1])
1070
+ self.assertEqual("valid: True", stdout_value[2])
1071
+
1072
+ def test_match_multi_ex(self) -> None:
1073
+ """Test match case with multiple expressions."""
1074
+ captured_output = io.StringIO()
1075
+ sys.stdout = captured_output
1076
+ jac_import("match_multi_ex", base_path=self.fixture_abs_path("./"))
1077
+ sys.stdout = sys.__stdout__
1078
+ stdout_value = captured_output.getvalue().split("\n")
1079
+ self.assertEqual("Ten", stdout_value[0])
1080
+ self.assertEqual("ten", stdout_value[1])
1081
+
1082
+ def test_entry_exit(self) -> None:
1083
+ """Test entry and exit behavior of walker."""
1084
+ captured_output = io.StringIO()
1085
+ sys.stdout = captured_output
1086
+ jac_import("entry_exit", base_path=self.fixture_abs_path("./"))
1087
+ sys.stdout = sys.__stdout__
1088
+ stdout_value = captured_output.getvalue().split("\n")
1089
+ self.assertIn("Entering at the beginning of walker: Root()", stdout_value[0])
1090
+ self.assertIn("entry_count=1, exit_count=1", str(stdout_value[12]))
1091
+ self.assertIn(
1092
+ "Exiting at the end of walker: test_node(value=", stdout_value[11]
1093
+ )
@@ -113,7 +113,7 @@ def print_ast_tree(
113
113
  if node.sym
114
114
  else "<No Symbol is associated with this node>"
115
115
  )
116
- out += f" SymbolPath: {symbol}"
116
+ out += f", SymbolPath: {symbol}"
117
117
  return out
118
118
  elif isinstance(node, Token):
119
119
  return f"{node.__class__.__name__} - {node.value}, {access}"
@@ -1,18 +1,22 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jaclang
3
- Version: 0.7.17
3
+ Version: 0.7.21
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
  Home-page: https://jaseci.org
6
6
  License: MIT
7
7
  Keywords: jac,jaclang,jaseci,python,programming-language,machine-learning,artificial-intelligence
8
8
  Author: Jason Mars
9
9
  Author-email: jason@jaseci.org
10
+ Maintainer: Jason Mars
11
+ Maintainer-email: jason@jaseci.org
10
12
  Requires-Python: >=3.11.0,<4.0.0
11
13
  Classifier: License :: OSI Approved :: MIT License
12
14
  Classifier: Programming Language :: Python :: 3
13
15
  Classifier: Programming Language :: Python :: 3.11
14
16
  Classifier: Programming Language :: Python :: 3.12
17
+ Provides-Extra: all
15
18
  Provides-Extra: llm
19
+ Provides-Extra: streamlit
16
20
  Project-URL: Documentation, https://jac-lang.org
17
21
  Project-URL: Repository, https://github.com/Jaseci-Labs/jaclang
18
22
  Description-Content-Type: text/markdown
@@ -40,7 +44,7 @@ This is the main source code repository for the [Jac] programming language. It c
40
44
  [Documentation]: https://www.jac-lang.org//learn/guide/
41
45
  [Contributing]: .github/CONTRIBUTING.md
42
46
 
43
- ## What and Why Jac?
47
+ ## What and Why is Jac?
44
48
 
45
49
  - **Native Superset of Python** - Jac is a native superset of python, meaning the entire python ecosystem is directly interoperable with Jac without any trickery (no interop interface needed). Like Typescript is to Javascript, or C++ is to C, Jac is to Python. (every Jac program can be ejected to pure python, and every python program can be transpiled to a Jac program)
46
50