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.
- jaclang/cli/cli.md +4 -3
- jaclang/cli/cli.py +63 -29
- jaclang/cli/cmdreg.py +1 -140
- jaclang/compiler/passes/main/__init__.py +2 -0
- jaclang/compiler/passes/main/cfg_build_pass.py +21 -1
- jaclang/compiler/passes/main/inheritance_pass.py +8 -1
- jaclang/compiler/passes/main/pyast_gen_pass.py +70 -11
- jaclang/compiler/passes/main/pyast_load_pass.py +14 -20
- jaclang/compiler/passes/main/sym_tab_build_pass.py +4 -0
- jaclang/compiler/passes/main/tests/fixtures/cfg_has_var.jac +12 -0
- jaclang/compiler/passes/main/tests/fixtures/cfg_if_no_else.jac +11 -0
- jaclang/compiler/passes/main/tests/fixtures/cfg_return.jac +9 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_binary_op.jac +21 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_call_expr_class.jac +12 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_cyclic_symbol.jac +4 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_expr_call.jac +9 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_import_missing_module.jac +13 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_imported.jac +2 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_importer.jac +6 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_magic_call.jac +17 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_mod_path.jac +8 -0
- jaclang/compiler/passes/main/tests/fixtures/data_spatial_types.jac +1 -1
- jaclang/compiler/passes/main/tests/fixtures/import_symbol_type_infer.jac +11 -0
- jaclang/compiler/passes/main/tests/fixtures/infer_type_assignment.jac +5 -0
- jaclang/compiler/passes/main/tests/fixtures/member_access_type_inferred.jac +13 -0
- jaclang/compiler/passes/main/tests/fixtures/member_access_type_resolve.jac +11 -0
- jaclang/compiler/passes/main/tests/fixtures/type_annotation_assignment.jac +8 -0
- jaclang/compiler/passes/main/tests/test_cfg_build_pass.py +62 -24
- jaclang/compiler/passes/main/tests/test_checker_pass.py +161 -0
- jaclang/compiler/passes/main/type_checker_pass.py +147 -0
- jaclang/compiler/passes/tool/tests/fixtures/simple_walk_fmt.jac +1 -4
- jaclang/compiler/program.py +17 -3
- jaclang/compiler/type_system/__init__.py +1 -0
- jaclang/compiler/type_system/operations.py +104 -0
- jaclang/compiler/type_system/type_evaluator.py +560 -0
- jaclang/compiler/type_system/type_utils.py +41 -0
- jaclang/compiler/type_system/types.py +240 -0
- jaclang/compiler/unitree.py +15 -9
- jaclang/langserve/dev_engine.jac +645 -0
- jaclang/langserve/dev_server.jac +201 -0
- jaclang/langserve/engine.jac +135 -91
- jaclang/langserve/server.jac +21 -14
- jaclang/langserve/tests/server_test/test_lang_serve.py +2 -5
- jaclang/langserve/tests/test_dev_server.py +80 -0
- jaclang/langserve/tests/test_server.py +9 -2
- jaclang/langserve/utils.jac +44 -48
- jaclang/runtimelib/builtin.py +28 -39
- jaclang/runtimelib/importer.py +1 -1
- jaclang/runtimelib/machine.py +48 -64
- jaclang/runtimelib/memory.py +23 -5
- jaclang/runtimelib/tests/fixtures/savable_object.jac +10 -2
- jaclang/runtimelib/utils.py +13 -6
- jaclang/tests/fixtures/edge_node_walk.jac +1 -1
- jaclang/tests/fixtures/edges_walk.jac +1 -1
- jaclang/tests/fixtures/gendot_bubble_sort.jac +1 -1
- jaclang/tests/fixtures/jac_run_py_bugs.py +18 -0
- jaclang/tests/fixtures/jac_run_py_import.py +13 -0
- jaclang/tests/fixtures/lambda_arg_annotation.jac +15 -0
- jaclang/tests/fixtures/lambda_self.jac +18 -0
- jaclang/tests/fixtures/py_run.jac +8 -0
- jaclang/tests/fixtures/py_run.py +23 -0
- jaclang/tests/fixtures/pyfunc.py +2 -0
- jaclang/tests/test_cli.py +103 -14
- jaclang/tests/test_language.py +10 -4
- jaclang/utils/lang_tools.py +3 -0
- jaclang/utils/module_resolver.py +1 -1
- {jaclang-0.8.5.dist-info → jaclang-0.8.7.dist-info}/METADATA +4 -2
- {jaclang-0.8.5.dist-info → jaclang-0.8.7.dist-info}/RECORD +70 -37
- {jaclang-0.8.5.dist-info → jaclang-0.8.7.dist-info}/WHEEL +1 -1
- {jaclang-0.8.5.dist-info → jaclang-0.8.7.dist-info}/entry_points.txt +0 -0
jaclang/runtimelib/utils.py
CHANGED
|
@@ -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
|
|
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:
|
|
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
|
-
|
|
77
|
+
edge_.id,
|
|
78
|
+
edge_.source.archetype,
|
|
74
79
|
target.archetype,
|
|
75
|
-
edge_.
|
|
80
|
+
edge_.archetype,
|
|
76
81
|
)
|
|
77
82
|
)
|
|
78
|
-
collect_node_connections(
|
|
83
|
+
collect_node_connections(
|
|
84
|
+
target.archetype, visited_nodes, connections, edge_ids
|
|
85
|
+
)
|
|
79
86
|
|
|
80
87
|
|
|
81
88
|
def traverse_graph(
|
|
@@ -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,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,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"))
|
jaclang/tests/fixtures/pyfunc.py
CHANGED
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(
|
|
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)
|
jaclang/tests/test_language.py
CHANGED
|
@@ -122,13 +122,19 @@ class JacLanguageTests(TestCase):
|
|
|
122
122
|
data = json.loads(stdout_value)
|
|
123
123
|
|
|
124
124
|
nodes = data["nodes"]
|
|
125
|
-
|
|
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
|
-
|
|
131
|
-
|
|
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
|
|
jaclang/utils/lang_tools.py
CHANGED
|
@@ -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":
|
jaclang/utils/module_resolver.py
CHANGED
|
@@ -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
|
|
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.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: jaclang
|
|
3
|
-
Version: 0.8.
|
|
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)
|