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.
- jaclang/__init__.py +5 -10
- jaclang/cli/cli.py +50 -30
- jaclang/compiler/__init__.py +2 -2
- jaclang/compiler/absyntree.py +87 -48
- jaclang/compiler/codeloc.py +7 -2
- jaclang/compiler/compile.py +10 -3
- jaclang/compiler/parser.py +26 -23
- jaclang/compiler/passes/ir_pass.py +2 -2
- jaclang/compiler/passes/main/def_impl_match_pass.py +46 -0
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +146 -123
- jaclang/compiler/passes/main/import_pass.py +6 -2
- jaclang/compiler/passes/main/pyast_load_pass.py +36 -35
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +7 -7
- jaclang/compiler/passes/main/registry_pass.py +3 -12
- jaclang/compiler/passes/main/tests/fixtures/defn_decl_mismatch.jac +19 -0
- jaclang/compiler/passes/main/tests/fixtures/fstrings.jac +2 -0
- jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +59 -0
- jaclang/compiler/passes/main/tests/test_registry_pass.py +2 -10
- jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
- jaclang/compiler/passes/main/type_check_pass.py +8 -6
- jaclang/compiler/passes/transform.py +27 -3
- jaclang/compiler/passes/utils/mypy_ast_build.py +246 -26
- jaclang/compiler/symtable.py +6 -0
- jaclang/compiler/tests/test_importer.py +2 -2
- jaclang/langserve/engine.py +14 -12
- jaclang/langserve/server.py +7 -2
- jaclang/langserve/tests/test_server.py +1 -1
- jaclang/langserve/utils.py +17 -3
- jaclang/plugin/builtin.py +3 -3
- jaclang/plugin/default.py +612 -236
- jaclang/plugin/feature.py +274 -99
- jaclang/plugin/plugin.md +471 -0
- jaclang/plugin/spec.py +231 -86
- jaclang/plugin/tests/fixtures/other_root_access.jac +9 -9
- jaclang/plugin/tests/test_features.py +2 -2
- jaclang/runtimelib/architype.py +1 -370
- jaclang/runtimelib/constructs.py +2 -0
- jaclang/runtimelib/context.py +2 -4
- jaclang/runtimelib/importer.py +7 -2
- jaclang/runtimelib/machine.py +78 -6
- jaclang/runtimelib/memory.py +2 -4
- jaclang/settings.py +3 -0
- jaclang/tests/fixtures/arch_create_util.jac +7 -0
- jaclang/tests/fixtures/arch_rel_import_creation.jac +30 -0
- jaclang/tests/fixtures/builtin_dotgen.jac +6 -6
- jaclang/tests/fixtures/create_dynamic_architype.jac +35 -0
- jaclang/tests/fixtures/edge_node_walk.jac +1 -1
- jaclang/tests/fixtures/edges_walk.jac +1 -1
- jaclang/tests/fixtures/enum_inside_archtype.jac +16 -11
- jaclang/tests/fixtures/expr_type.jac +54 -0
- jaclang/tests/fixtures/gendot_bubble_sort.jac +1 -1
- jaclang/tests/fixtures/glob_multivar_statement.jac +15 -0
- jaclang/tests/fixtures/registry.jac +20 -8
- jaclang/tests/fixtures/visit_order.jac +20 -0
- jaclang/tests/foo/__init__.jac +0 -0
- jaclang/tests/main.jac +2 -0
- jaclang/tests/test_cli.py +68 -4
- jaclang/tests/test_language.py +113 -27
- jaclang/utils/helpers.py +92 -14
- jaclang/utils/lang_tools.py +6 -2
- jaclang/utils/treeprinter.py +4 -2
- {jaclang-0.7.22.dist-info → jaclang-0.7.25.dist-info}/METADATA +2 -1
- {jaclang-0.7.22.dist-info → jaclang-0.7.25.dist-info}/RECORD +65 -55
- {jaclang-0.7.22.dist-info → jaclang-0.7.25.dist-info}/WHEEL +1 -1
- {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('
|
|
31
|
-
print(d2.count('a(val')==19,d2.count('#F5E5FF')==2 ,'Edge1' not in d2,d2.count('
|
|
32
|
-
print(d3.count('a(val')==6,d3.count("
|
|
33
|
-
print(d4.count("a(val")==25,d4.count("
|
|
34
|
-
print(d5.count("Edge1(val=6)")==2, d5.count("
|
|
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
|
+
}
|
|
@@ -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
|
|
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,
|
|
@@ -13,16 +13,16 @@ Person {
|
|
|
13
13
|
|
|
14
14
|
enum 'Personality of the Person'
|
|
15
15
|
Personality {
|
|
16
|
-
|
|
17
|
-
|
|
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
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
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
|
-
|
|
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)
|
jaclang/tests/test_language.py
CHANGED
|
@@ -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
|
-
|
|
462
|
-
|
|
463
|
-
|
|
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(
|
|
470
|
-
self.assertEqual(
|
|
471
|
-
self.assertEqual(
|
|
472
|
-
|
|
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.
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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])
|