jaclang 0.7.13__py3-none-any.whl → 0.7.16__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.py +15 -10
- jaclang/cli/cmdreg.py +9 -12
- jaclang/compiler/__init__.py +19 -53
- jaclang/compiler/absyntree.py +95 -17
- jaclang/compiler/jac.lark +4 -3
- jaclang/compiler/parser.py +35 -23
- jaclang/compiler/passes/ir_pass.py +4 -13
- jaclang/compiler/passes/main/access_modifier_pass.py +1 -1
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +4 -5
- jaclang/compiler/passes/main/import_pass.py +19 -23
- jaclang/compiler/passes/main/pyast_gen_pass.py +308 -567
- jaclang/compiler/passes/main/pyast_load_pass.py +33 -6
- jaclang/compiler/passes/main/registry_pass.py +37 -3
- jaclang/compiler/passes/main/sym_tab_build_pass.py +1 -1
- jaclang/compiler/passes/main/tests/__init__.py +1 -1
- jaclang/compiler/passes/main/tests/test_import_pass.py +5 -1
- jaclang/compiler/passes/main/type_check_pass.py +7 -0
- jaclang/compiler/passes/tool/fuse_comments_pass.py +14 -2
- jaclang/compiler/passes/tool/jac_formatter_pass.py +144 -94
- jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +0 -1
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/architype_test.jac +13 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/comment_alignment.jac +11 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/comments.jac +13 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/decorator_stack.jac +37 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/esc_keywords.jac +5 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/long_names.jac +19 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +6 -0
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +11 -0
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +33 -39
- jaclang/compiler/passes/transform.py +4 -0
- jaclang/compiler/semtable.py +31 -7
- jaclang/compiler/tests/test_importer.py +12 -5
- jaclang/langserve/engine.py +82 -143
- jaclang/langserve/sem_manager.py +379 -0
- jaclang/langserve/server.py +8 -10
- jaclang/langserve/tests/fixtures/base_module_structure.jac +27 -6
- jaclang/langserve/tests/fixtures/circle.jac +3 -3
- jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
- jaclang/langserve/tests/fixtures/circle_pure.test.jac +3 -3
- jaclang/langserve/tests/fixtures/import_include_statements.jac +1 -1
- jaclang/langserve/tests/test_sem_tokens.py +277 -0
- jaclang/langserve/tests/test_server.py +96 -16
- jaclang/langserve/utils.py +163 -96
- jaclang/plugin/builtin.py +1 -1
- jaclang/plugin/default.py +214 -24
- jaclang/plugin/feature.py +59 -11
- jaclang/plugin/spec.py +58 -6
- jaclang/{core → runtimelib}/architype.py +1 -1
- jaclang/{core → runtimelib}/context.py +8 -1
- jaclang/runtimelib/importer.py +361 -0
- jaclang/runtimelib/machine.py +94 -0
- jaclang/{core → runtimelib}/utils.py +13 -5
- jaclang/settings.py +4 -1
- jaclang/tests/fixtures/abc.jac +3 -3
- jaclang/tests/fixtures/blankwithentry.jac +3 -0
- jaclang/tests/fixtures/byllmissue.jac +1 -5
- jaclang/tests/fixtures/chandra_bugs2.jac +11 -10
- jaclang/tests/fixtures/cls_method.jac +41 -0
- jaclang/tests/fixtures/dblhello.jac +6 -0
- jaclang/tests/fixtures/deep/one_lev.jac +3 -3
- jaclang/tests/fixtures/deep/one_lev_dup.jac +2 -3
- jaclang/tests/fixtures/deep_import_mods.jac +13 -0
- jaclang/tests/fixtures/err.impl.jac +3 -0
- jaclang/tests/fixtures/err.jac +4 -2
- jaclang/tests/fixtures/err.test.jac +3 -0
- jaclang/tests/fixtures/err_runtime.jac +15 -0
- jaclang/tests/fixtures/game1.jac +1 -1
- jaclang/tests/fixtures/hello.jac +4 -0
- jaclang/tests/fixtures/impl_grab.impl.jac +2 -1
- jaclang/tests/fixtures/impl_grab.jac +4 -1
- jaclang/tests/fixtures/jp_importer_auto.jac +14 -0
- jaclang/tests/fixtures/maxfail_run_test.jac +4 -4
- jaclang/tests/fixtures/needs_import.jac +2 -2
- jaclang/tests/fixtures/pyfunc_2.py +3 -0
- jaclang/tests/fixtures/registry.jac +9 -0
- jaclang/tests/fixtures/run_test.jac +4 -4
- jaclang/tests/fixtures/semstr.jac +1 -4
- jaclang/tests/fixtures/simple_archs.jac +1 -1
- jaclang/tests/test_cli.py +65 -2
- jaclang/tests/test_language.py +83 -7
- jaclang/tests/test_man_code.py +17 -0
- jaclang/tests/test_reference.py +6 -0
- jaclang/utils/helpers.py +45 -21
- jaclang/utils/test.py +9 -0
- jaclang/utils/treeprinter.py +0 -4
- {jaclang-0.7.13.dist-info → jaclang-0.7.16.dist-info}/METADATA +3 -2
- {jaclang-0.7.13.dist-info → jaclang-0.7.16.dist-info}/RECORD +93 -77
- jaclang/core/importer.py +0 -344
- jaclang/tests/fixtures/aott_raise.jac +0 -25
- jaclang/tests/fixtures/package_import.jac +0 -6
- /jaclang/{core → runtimelib}/__init__.py +0 -0
- /jaclang/{core → runtimelib}/constructs.py +0 -0
- /jaclang/{core → runtimelib}/memory.py +0 -0
- /jaclang/{core → runtimelib}/test.py +0 -0
- {jaclang-0.7.13.dist-info → jaclang-0.7.16.dist-info}/WHEEL +0 -0
- {jaclang-0.7.13.dist-info → jaclang-0.7.16.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
obj inner_red {
|
|
2
|
+
has color22: string = 'red',
|
|
3
|
+
# self
|
|
4
|
+
doublepoint11: int = 2,
|
|
5
|
+
doublepoint22: float = 2.0,
|
|
6
|
+
# self
|
|
7
|
+
doublepoint33: int = 2,
|
|
8
|
+
# Comments explaining each attribute
|
|
9
|
+
# color22: represents the color, set to 'red'
|
|
10
|
+
point22: int = 20;
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
with entry:__main__ {
|
|
2
|
+
app = App();
|
|
3
|
+
app.run();
|
|
4
|
+
# ray.init_window(800, 450, "Hello");
|
|
5
|
+
# while not ray.window_should_close() {
|
|
6
|
+
# ray.begin_drawing();
|
|
7
|
+
# ray.clear_background(ray.WHITE);
|
|
8
|
+
# ray.draw_text("Hello world", 190, 200, 20, ray.VIOLET);
|
|
9
|
+
# ray.end_drawing();
|
|
10
|
+
# }
|
|
11
|
+
|
|
12
|
+
# ray.close_window();
|
|
13
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
can star(func: Any) {
|
|
2
|
+
can inner(x: Any) {
|
|
3
|
+
print(("*" * 30));
|
|
4
|
+
func(x);
|
|
5
|
+
print(("*" * 30));
|
|
6
|
+
}
|
|
7
|
+
return inner;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
can percent(func: Any) {
|
|
11
|
+
can inner(y: Any) {
|
|
12
|
+
print(("%" * 30));
|
|
13
|
+
func(y);
|
|
14
|
+
print(("%" * 30));
|
|
15
|
+
}
|
|
16
|
+
return inner;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
can percent2(func: Any) {
|
|
20
|
+
can inner(y: Any) {
|
|
21
|
+
print(("-" * 30));
|
|
22
|
+
func(y);
|
|
23
|
+
print(("+" * 30));
|
|
24
|
+
}
|
|
25
|
+
return inner;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@star
|
|
29
|
+
@percent
|
|
30
|
+
@percent2
|
|
31
|
+
can printer(msg: Any) {
|
|
32
|
+
print(msg);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
with entry {
|
|
36
|
+
printer("Hello");
|
|
37
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
with entry {
|
|
2
|
+
long_variable_name_1 = another_long_variable_name_2
|
|
3
|
+
= yet_another_long_variable_name_3
|
|
4
|
+
= still_another_long_variable_name_4
|
|
5
|
+
= yet_still_another_long_variable_name_5
|
|
6
|
+
= one_more_long_variable_name_6
|
|
7
|
+
= and_another_long_variable_name_7
|
|
8
|
+
= final_long_variable_name_8
|
|
9
|
+
=1.5;
|
|
10
|
+
result = long_variable_name_1
|
|
11
|
+
+ another_long_variable_name_2
|
|
12
|
+
* yet_another_long_variable_name_3
|
|
13
|
+
- still_another_long_variable_name_4
|
|
14
|
+
/ yet_still_another_long_variable_name_5
|
|
15
|
+
+ one_more_long_variable_name_6
|
|
16
|
+
* and_another_long_variable_name_7
|
|
17
|
+
- final_long_variable_name_8;
|
|
18
|
+
print("The result of the ugly calculation is:", result);
|
|
19
|
+
}
|
|
@@ -102,6 +102,17 @@ class JacFormatPassTests(TestCaseMicroSuite, AstSyncTestMixin):
|
|
|
102
102
|
file_path = os.path.join(fixtures_dir, file_name)
|
|
103
103
|
self.compare_files(file_path)
|
|
104
104
|
|
|
105
|
+
def test_general_format_fixtures(self) -> None:
|
|
106
|
+
"""Tests if files in the general fixtures directory do not change after being formatted."""
|
|
107
|
+
fixtures_dir = os.path.join(self.fixture_abs_path(""), "general_format_checks")
|
|
108
|
+
fixture_files = os.listdir(fixtures_dir)
|
|
109
|
+
for file_name in fixture_files:
|
|
110
|
+
if file_name == "__jac_gen__":
|
|
111
|
+
continue
|
|
112
|
+
with self.subTest(file=file_name):
|
|
113
|
+
file_path = os.path.join(fixtures_dir, file_name)
|
|
114
|
+
self.compare_files(file_path)
|
|
115
|
+
|
|
105
116
|
def micro_suite_test(self, filename: str) -> None:
|
|
106
117
|
"""Parse micro jac file."""
|
|
107
118
|
code_gen_pure = jac_file_to_pass(
|
|
@@ -33,47 +33,41 @@ class JacUnparseTests(TestCaseMicroSuite, AstSyncTestMixin):
|
|
|
33
33
|
|
|
34
34
|
def micro_suite_test(self, filename: str) -> None:
|
|
35
35
|
"""Parse micro jac file."""
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
code_gen_pure = jac_file_to_pass(
|
|
37
|
+
self.fixture_abs_path(filename),
|
|
38
|
+
target=PyastGenPass,
|
|
39
|
+
schedule=without_format,
|
|
40
|
+
)
|
|
41
|
+
before = ast3.dump(code_gen_pure.ir.gen.py_ast[0], indent=2)
|
|
42
|
+
x = code_gen_pure.ir.unparse()
|
|
43
|
+
# print(x)
|
|
44
|
+
# print(f"Testing {code_gen_pure.ir.name}")
|
|
45
|
+
# print(code_gen_pure.ir.pp())
|
|
46
|
+
code_gen_jac = jac_str_to_pass(
|
|
47
|
+
jac_str=x,
|
|
48
|
+
file_path=filename,
|
|
49
|
+
target=PyastGenPass,
|
|
50
|
+
schedule=without_format,
|
|
51
|
+
)
|
|
52
|
+
after = ast3.dump(code_gen_jac.ir.gen.py_ast[0], indent=2)
|
|
53
|
+
if "circle_clean_tests.jac" in filename:
|
|
54
|
+
self.assertEqual(
|
|
55
|
+
len(
|
|
56
|
+
[
|
|
57
|
+
i
|
|
58
|
+
for i in unified_diff(
|
|
59
|
+
before.splitlines(), after.splitlines(), n=0
|
|
60
|
+
)
|
|
61
|
+
if "test" not in i
|
|
62
|
+
]
|
|
63
|
+
),
|
|
64
|
+
5,
|
|
41
65
|
)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
# print(code_gen_pure.ir.pp())
|
|
47
|
-
code_gen_jac = jac_str_to_pass(
|
|
48
|
-
jac_str=x,
|
|
49
|
-
file_path=filename,
|
|
50
|
-
target=PyastGenPass,
|
|
51
|
-
schedule=without_format,
|
|
66
|
+
else:
|
|
67
|
+
self.assertEqual(
|
|
68
|
+
len("\n".join(unified_diff(before.splitlines(), after.splitlines()))),
|
|
69
|
+
0,
|
|
52
70
|
)
|
|
53
|
-
after = ast3.dump(code_gen_jac.ir.gen.py_ast[0], indent=2)
|
|
54
|
-
if "circle_clean_tests.jac" in filename:
|
|
55
|
-
self.assertEqual(
|
|
56
|
-
len(
|
|
57
|
-
[
|
|
58
|
-
i
|
|
59
|
-
for i in unified_diff(
|
|
60
|
-
before.splitlines(), after.splitlines(), n=0
|
|
61
|
-
)
|
|
62
|
-
if "test" not in i
|
|
63
|
-
]
|
|
64
|
-
),
|
|
65
|
-
5,
|
|
66
|
-
)
|
|
67
|
-
else:
|
|
68
|
-
self.assertEqual(
|
|
69
|
-
len(
|
|
70
|
-
"\n".join(unified_diff(before.splitlines(), after.splitlines()))
|
|
71
|
-
),
|
|
72
|
-
0,
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
except Exception as e:
|
|
76
|
-
raise e
|
|
77
71
|
|
|
78
72
|
|
|
79
73
|
JacUnparseTests.self_attach_micro_tests()
|
jaclang/compiler/semtable.py
CHANGED
|
@@ -6,14 +6,24 @@ semantic information.
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
from typing import Optional
|
|
9
|
+
from typing import Optional, TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
import jaclang.compiler.absyntree as ast
|
|
10
13
|
|
|
11
14
|
|
|
12
15
|
class SemInfo:
|
|
13
16
|
"""Semantic information class."""
|
|
14
17
|
|
|
15
|
-
def __init__(
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
node: ast.AstNode,
|
|
21
|
+
name: str,
|
|
22
|
+
type: Optional[str] = None,
|
|
23
|
+
semstr: str = "",
|
|
24
|
+
) -> None:
|
|
16
25
|
"""Initialize the class."""
|
|
26
|
+
self.node = node
|
|
17
27
|
self.name = name
|
|
18
28
|
self.type = type
|
|
19
29
|
self.semstr = semstr
|
|
@@ -22,6 +32,17 @@ class SemInfo:
|
|
|
22
32
|
"""Return the string representation of the class."""
|
|
23
33
|
return f"{self.semstr} ({self.type}) ({self.name})"
|
|
24
34
|
|
|
35
|
+
def get_children(
|
|
36
|
+
self, sem_registry: SemRegistry, filter: Optional[type[ast.AstNode]] = None
|
|
37
|
+
) -> list[SemInfo]:
|
|
38
|
+
"""Get the children of the SemInfo."""
|
|
39
|
+
scope, _ = sem_registry.lookup(name=self.name)
|
|
40
|
+
self_scope = str(scope) + f".{self.name}({self.type})"
|
|
41
|
+
_, children = sem_registry.lookup(scope=SemScope.get_scope_from_str(self_scope))
|
|
42
|
+
if filter and children and isinstance(children, list):
|
|
43
|
+
return [i for i in children if isinstance(i.node, filter)]
|
|
44
|
+
return children if children and isinstance(children, list) else []
|
|
45
|
+
|
|
25
46
|
|
|
26
47
|
class SemScope:
|
|
27
48
|
"""Scope class."""
|
|
@@ -38,7 +59,8 @@ class SemScope:
|
|
|
38
59
|
"""Return the string representation of the class."""
|
|
39
60
|
if self.parent:
|
|
40
61
|
return f"{self.parent}.{self.scope}({self.type})"
|
|
41
|
-
|
|
62
|
+
else:
|
|
63
|
+
return f"{self.scope}({self.type})"
|
|
42
64
|
|
|
43
65
|
def __repr__(self) -> str:
|
|
44
66
|
"""Return the string representation of the class."""
|
|
@@ -57,7 +79,7 @@ class SemScope:
|
|
|
57
79
|
|
|
58
80
|
@property
|
|
59
81
|
def as_type_str(self) -> Optional[str]:
|
|
60
|
-
"""Return the type string representation of the
|
|
82
|
+
"""Return the type string representation of the SemScope."""
|
|
61
83
|
if self.type not in ["class", "node", "obj"]:
|
|
62
84
|
return None
|
|
63
85
|
type_str = self.scope
|
|
@@ -127,9 +149,11 @@ class SemRegistry:
|
|
|
127
149
|
break
|
|
128
150
|
return i
|
|
129
151
|
|
|
130
|
-
def pp(self) ->
|
|
152
|
+
def pp(self) -> str:
|
|
131
153
|
"""Pretty print the registry."""
|
|
154
|
+
ret_str = ""
|
|
132
155
|
for k, v in self.registry.items():
|
|
133
|
-
|
|
156
|
+
ret_str += f"{k}\n"
|
|
134
157
|
for i in v:
|
|
135
|
-
|
|
158
|
+
ret_str += f" {i.name} {i.type} {i.semstr}\n"
|
|
159
|
+
return ret_str
|
|
@@ -5,6 +5,7 @@ import sys
|
|
|
5
5
|
|
|
6
6
|
from jaclang import jac_import
|
|
7
7
|
from jaclang.cli import cli
|
|
8
|
+
from jaclang.plugin.feature import JacFeature as Jac
|
|
8
9
|
from jaclang.utils.test import TestCase
|
|
9
10
|
|
|
10
11
|
|
|
@@ -17,13 +18,15 @@ class TestLoader(TestCase):
|
|
|
17
18
|
|
|
18
19
|
def test_import_basic_python(self) -> None:
|
|
19
20
|
"""Test basic self loading."""
|
|
21
|
+
Jac.context().init_memory(base_path=self.fixture_abs_path(__file__))
|
|
20
22
|
(h,) = jac_import("fixtures.hello_world", base_path=__file__)
|
|
21
23
|
self.assertEqual(h.hello(), "Hello World!") # type: ignore
|
|
22
24
|
|
|
23
25
|
def test_modules_correct(self) -> None:
|
|
24
26
|
"""Test basic self loading."""
|
|
27
|
+
Jac.context().init_memory(base_path=self.fixture_abs_path(__file__))
|
|
25
28
|
jac_import("fixtures.hello_world", base_path=__file__)
|
|
26
|
-
self.assertIn("module 'hello_world'", str(sys.modules))
|
|
29
|
+
self.assertIn("module 'fixtures.hello_world'", str(sys.modules))
|
|
27
30
|
self.assertIn("/tests/fixtures/hello_world.jac", str(sys.modules))
|
|
28
31
|
|
|
29
32
|
def test_jac_py_import(self) -> None:
|
|
@@ -39,11 +42,15 @@ class TestLoader(TestCase):
|
|
|
39
42
|
stdout_value,
|
|
40
43
|
)
|
|
41
44
|
|
|
42
|
-
def
|
|
43
|
-
"""
|
|
45
|
+
def test_jac_py_import_auto(self) -> None:
|
|
46
|
+
"""Basic test for pass."""
|
|
44
47
|
captured_output = io.StringIO()
|
|
45
48
|
sys.stdout = captured_output
|
|
46
|
-
cli.run(self.fixture_abs_path("../../../tests/fixtures/
|
|
49
|
+
cli.run(self.fixture_abs_path("../../../tests/fixtures/jp_importer_auto.jac"))
|
|
47
50
|
sys.stdout = sys.__stdout__
|
|
48
51
|
stdout_value = captured_output.getvalue()
|
|
49
|
-
self.
|
|
52
|
+
self.assertIn("Hello World!", stdout_value)
|
|
53
|
+
self.assertIn(
|
|
54
|
+
"{SomeObj(a=10): 'check'} [MyObj(apple=5, banana=7), MyObj(apple=5, banana=7)]",
|
|
55
|
+
stdout_value,
|
|
56
|
+
)
|