jaclang 0.8.1__py3-none-any.whl → 0.8.3__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 +6 -0
- jaclang/cli/cli.py +21 -50
- jaclang/compiler/codeinfo.py +0 -1
- jaclang/compiler/constant.py +2 -0
- jaclang/compiler/jac.lark +17 -10
- jaclang/compiler/larkparse/jac_parser.py +2 -2
- jaclang/compiler/parser.py +34 -10
- jaclang/compiler/passes/main/__init__.py +2 -14
- jaclang/compiler/passes/main/annex_pass.py +2 -8
- jaclang/compiler/passes/main/cfg_build_pass.py +38 -12
- jaclang/compiler/passes/main/import_pass.py +3 -11
- jaclang/compiler/passes/main/pyast_gen_pass.py +246 -592
- jaclang/compiler/passes/main/sem_def_match_pass.py +67 -0
- jaclang/compiler/passes/main/sym_tab_build_pass.py +8 -0
- jaclang/compiler/passes/main/sym_tab_link_pass.py +2 -5
- jaclang/compiler/passes/main/tests/fixtures/sem_def_match.impl.jac +12 -0
- jaclang/compiler/passes/main/tests/fixtures/sem_def_match.jac +31 -0
- jaclang/compiler/passes/main/tests/test_cfg_build_pass.py +2 -8
- jaclang/compiler/passes/main/tests/test_decl_impl_match_pass.py +7 -8
- jaclang/compiler/passes/main/tests/test_import_pass.py +5 -18
- jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +2 -6
- jaclang/compiler/passes/main/tests/test_sem_def_match_pass.py +38 -0
- jaclang/compiler/passes/main/tests/test_sub_node_pass.py +1 -3
- jaclang/compiler/passes/main/tests/test_sym_tab_link_pass.py +20 -17
- jaclang/compiler/passes/tool/doc_ir_gen_pass.py +259 -106
- jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -0
- jaclang/compiler/passes/tool/tests/fixtures/archetype_frmt.jac +14 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +5 -4
- jaclang/compiler/passes/tool/tests/fixtures/has_frmt.jac +13 -0
- jaclang/compiler/passes/tool/tests/fixtures/import_fmt.jac +6 -0
- jaclang/compiler/passes/tool/tests/fixtures/simple_walk_fmt.jac +3 -3
- jaclang/compiler/passes/tool/tests/fixtures/tagbreak.jac +9 -0
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +25 -3
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +2 -2
- jaclang/compiler/program.py +23 -60
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/__init__.py +2 -8
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/__init__.py +1 -5
- jaclang/compiler/tests/test_importer.py +10 -13
- jaclang/compiler/unitree.py +88 -16
- jaclang/langserve/__init__.jac +1 -1
- jaclang/langserve/engine.jac +113 -108
- jaclang/langserve/server.jac +17 -2
- jaclang/langserve/tests/server_test/test_lang_serve.py +138 -46
- jaclang/langserve/tests/server_test/utils.py +35 -9
- jaclang/langserve/tests/test_sem_tokens.py +1 -1
- jaclang/langserve/tests/test_server.py +3 -7
- jaclang/runtimelib/archetype.py +127 -5
- jaclang/runtimelib/importer.py +51 -94
- jaclang/runtimelib/machine.py +391 -268
- jaclang/runtimelib/meta_importer.py +86 -0
- jaclang/runtimelib/tests/fixtures/graph_purger.jac +24 -26
- jaclang/runtimelib/tests/fixtures/other_root_access.jac +25 -16
- jaclang/runtimelib/tests/test_jaseci.py +3 -1
- jaclang/tests/fixtures/arch_rel_import_creation.jac +23 -23
- jaclang/tests/fixtures/async_ability.jac +43 -10
- jaclang/tests/fixtures/async_function.jac +18 -0
- jaclang/tests/fixtures/async_walker.jac +17 -12
- jaclang/tests/fixtures/create_dynamic_archetype.jac +25 -28
- jaclang/tests/fixtures/deep/deeper/deep_outer_import.jac +7 -4
- jaclang/tests/fixtures/deep/deeper/snd_lev.jac +2 -2
- jaclang/tests/fixtures/deep/deeper/snd_lev_dup.jac +6 -0
- jaclang/tests/fixtures/deep/one_lev.jac +2 -2
- jaclang/tests/fixtures/deep/one_lev_dup.jac +4 -3
- jaclang/tests/fixtures/dynamic_archetype.jac +19 -12
- jaclang/tests/fixtures/foo.jac +14 -22
- jaclang/tests/fixtures/jac_from_py.py +1 -1
- jaclang/tests/fixtures/jp_importer.jac +6 -6
- jaclang/tests/fixtures/jp_importer_auto.jac +5 -3
- jaclang/tests/fixtures/unicode_strings.jac +24 -0
- jaclang/tests/fixtures/walker_update.jac +5 -7
- jaclang/tests/test_language.py +138 -140
- jaclang/tests/test_reference.py +9 -4
- jaclang/tests/test_typecheck.py +13 -26
- jaclang/utils/lang_tools.py +7 -5
- jaclang/utils/module_resolver.py +23 -0
- {jaclang-0.8.1.dist-info → jaclang-0.8.3.dist-info}/METADATA +1 -1
- {jaclang-0.8.1.dist-info → jaclang-0.8.3.dist-info}/RECORD +79 -72
- jaclang/compiler/passes/main/tests/fixtures/main_err.jac +0 -6
- jaclang/compiler/passes/main/tests/fixtures/second_err.jac +0 -4
- jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +0 -644
- jaclang/compiler/passes/tool/tests/test_doc_ir_gen_pass.py +0 -29
- jaclang/tests/fixtures/deep/deeper/__init__.jac +0 -1
- {jaclang-0.8.1.dist-info → jaclang-0.8.3.dist-info}/WHEEL +0 -0
- {jaclang-0.8.1.dist-info → jaclang-0.8.3.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""Semantic Definition Matching Pass for the Jac compiler.
|
|
2
|
+
|
|
3
|
+
This pass connects semantic string definitions (SemDefs) in the AST to their corresponding
|
|
4
|
+
declarations. It:
|
|
5
|
+
|
|
6
|
+
1. Establishes links between semantic string definitions in the main module and their declarations
|
|
7
|
+
2. Handles dotted name resolution for nested symbols
|
|
8
|
+
3. Issues warnings for unmatched semantic definitions
|
|
9
|
+
|
|
10
|
+
This pass is essential for Jac's semantic annotation system, allowing developers to define
|
|
11
|
+
semantics in one file and link them to their corresponding declarations in another.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import jaclang.compiler.unitree as uni
|
|
15
|
+
from jaclang.compiler.passes.transform import Transform
|
|
16
|
+
from jaclang.compiler.unitree import Symbol, UniScopeNode
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class SemDefMatchPass(Transform[uni.Module, uni.Module]):
|
|
20
|
+
"""Jac Semantic definition match pass."""
|
|
21
|
+
|
|
22
|
+
def transform(self, ir_in: uni.Module) -> uni.Module:
|
|
23
|
+
"""Connect Decls and Defs."""
|
|
24
|
+
self.cur_node = ir_in
|
|
25
|
+
|
|
26
|
+
self.connect_sems(ir_in.sym_tab, ir_in.sym_tab)
|
|
27
|
+
for impl_module in ir_in.impl_mod:
|
|
28
|
+
self.connect_sems(impl_module.sym_tab, ir_in.sym_tab)
|
|
29
|
+
|
|
30
|
+
return ir_in
|
|
31
|
+
|
|
32
|
+
def find_symbol_from_dotted_name(
|
|
33
|
+
self, dotted_name: str, target_sym_tab: UniScopeNode
|
|
34
|
+
) -> Symbol | None:
|
|
35
|
+
"""Find a symbol in the target symbol table by its dotted name.
|
|
36
|
+
|
|
37
|
+
Example:
|
|
38
|
+
"Foo.bar.baz" will do the following lookups:
|
|
39
|
+
target_sym_tab.lookup("Foo").lookup("bar").lookup("baz")
|
|
40
|
+
"""
|
|
41
|
+
parts = dotted_name.lstrip("sem.").split(".")
|
|
42
|
+
current_sym_tab = target_sym_tab
|
|
43
|
+
sym: uni.Symbol | None = None
|
|
44
|
+
for part in parts:
|
|
45
|
+
if current_sym_tab is None:
|
|
46
|
+
return None
|
|
47
|
+
sym = current_sym_tab.lookup(part, deep=False)
|
|
48
|
+
if sym is None:
|
|
49
|
+
return None
|
|
50
|
+
current_sym_tab = sym.fetch_sym_tab
|
|
51
|
+
return sym
|
|
52
|
+
|
|
53
|
+
def connect_sems(
|
|
54
|
+
self, source_sym_tab: UniScopeNode, target_sym_tab: UniScopeNode
|
|
55
|
+
) -> None:
|
|
56
|
+
"""Connect sem strings from source symbol table to declarations in target symbol table.
|
|
57
|
+
|
|
58
|
+
When source_sym_tab and target_sym_tab are the same, this connects within the same module.
|
|
59
|
+
When different, it connects implementations from impl_mod to declarations in the main module.
|
|
60
|
+
"""
|
|
61
|
+
for sym in source_sym_tab.names_in_scope.values():
|
|
62
|
+
if not isinstance(sym.decl.name_of, uni.SemDef):
|
|
63
|
+
continue
|
|
64
|
+
semdef = sym.decl.name_of
|
|
65
|
+
target_sym = self.find_symbol_from_dotted_name(sym.sym_name, target_sym_tab)
|
|
66
|
+
if target_sym is not None:
|
|
67
|
+
target_sym.decl.name_of.semstr = semdef.value.lit_value
|
|
@@ -115,6 +115,14 @@ class SymTabBuildPass(UniPass):
|
|
|
115
115
|
def exit_impl_def(self, node: uni.ImplDef) -> None:
|
|
116
116
|
self.pop_scope()
|
|
117
117
|
|
|
118
|
+
def enter_sem_def(self, node: uni.SemDef) -> None:
|
|
119
|
+
self.push_scope_and_link(node)
|
|
120
|
+
assert node.parent_scope is not None
|
|
121
|
+
node.parent_scope.def_insert(node, single_decl="sem")
|
|
122
|
+
|
|
123
|
+
def exit_sem_def(self, node: uni.SemDef) -> None:
|
|
124
|
+
self.pop_scope()
|
|
125
|
+
|
|
118
126
|
def enter_enum(self, node: uni.Enum) -> None:
|
|
119
127
|
self.push_scope_and_link(node)
|
|
120
128
|
assert node.parent_scope is not None
|
|
@@ -32,11 +32,8 @@ class SymTabLinkPass(Transform[uni.Module, uni.Module]):
|
|
|
32
32
|
def transform(self, ir_in: uni.Module) -> uni.Module:
|
|
33
33
|
"""Link the symbol tables for all modules in the program."""
|
|
34
34
|
# Process all modules in the program hub
|
|
35
|
-
for
|
|
36
|
-
|
|
37
|
-
for node in module_paths:
|
|
38
|
-
self.process_module_path(mod, node)
|
|
39
|
-
|
|
35
|
+
for node in ir_in.get_all_sub_nodes(uni.ModulePath):
|
|
36
|
+
self.process_module_path(ir_in, node)
|
|
40
37
|
return ir_in
|
|
41
38
|
|
|
42
39
|
def process_module_path(self, mod: uni.Module, node: uni.ModulePath) -> None:
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
sem Person = "A class representing a person.";
|
|
3
|
+
sem Person.name = "The name of the person.";
|
|
4
|
+
sem Person.yob = "The year of birth of the person.";
|
|
5
|
+
|
|
6
|
+
sem Person.calc_age = "Calculate the age of the person.";
|
|
7
|
+
sem Person.calc_age.year = "The year to calculate the age against.";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
sem OuterClass = "A class containing an inner class.";
|
|
11
|
+
sem OuterClass.InnerClass = "An inner class within OuterClass.";
|
|
12
|
+
sem OuterClass.InnerClass.inner_value = "A value specific to the inner class.";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
enum E {
|
|
3
|
+
A = 0,
|
|
4
|
+
B = 1,
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
sem E = "An enum representing some values.";
|
|
8
|
+
sem E.A = "The first value of the enum E.";
|
|
9
|
+
sem E.B = "The second value of the enum E.";
|
|
10
|
+
|
|
11
|
+
obj Person {
|
|
12
|
+
has name: str;
|
|
13
|
+
has yob: int;
|
|
14
|
+
|
|
15
|
+
def calc_age(year: int) -> int {
|
|
16
|
+
return year - self.yob;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
obj OuterClass {
|
|
22
|
+
obj InnerClass {
|
|
23
|
+
has inner_value: str;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
with entry {
|
|
30
|
+
print(E.A);
|
|
31
|
+
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
"""Test pass module."""
|
|
2
2
|
|
|
3
|
-
from jaclang.compiler.passes.main import CompilerMode as CMode
|
|
4
3
|
from jaclang.compiler.program import JacProgram
|
|
5
4
|
from jaclang.utils.test import TestCase
|
|
6
5
|
import unittest
|
|
7
6
|
|
|
8
7
|
|
|
9
|
-
@unittest.skip("Skipping CFG build pass tests")
|
|
10
8
|
class TestCFGBuildPass(TestCase):
|
|
11
9
|
"""Test FuseTypeInfoPass module."""
|
|
12
10
|
|
|
@@ -23,9 +21,7 @@ class TestCFGBuildPass(TestCase):
|
|
|
23
21
|
with open(file_name, "r") as f:
|
|
24
22
|
file_source = f.read()
|
|
25
23
|
|
|
26
|
-
ir = (prog := JacProgram()).
|
|
27
|
-
source_str=file_source, file_path=file_name, mode=CMode.COMPILE
|
|
28
|
-
)
|
|
24
|
+
ir = (prog := JacProgram()).compile(use_str=file_source, file_path=file_name)
|
|
29
25
|
|
|
30
26
|
cfg_pass = CoalesceBBPass(
|
|
31
27
|
ir_in=ir,
|
|
@@ -71,9 +67,7 @@ class TestCFGBuildPass(TestCase):
|
|
|
71
67
|
with open(file_name, "r") as f:
|
|
72
68
|
file_source = f.read()
|
|
73
69
|
|
|
74
|
-
ir = (prog := JacProgram()).
|
|
75
|
-
source_str=file_source, file_path=file_name, mode=CMode.COMPILE
|
|
76
|
-
)
|
|
70
|
+
ir = (prog := JacProgram()).compile(use_str=file_source, file_path=file_name)
|
|
77
71
|
|
|
78
72
|
cfg_pass = CoalesceBBPass(
|
|
79
73
|
ir_in=ir,
|
|
@@ -4,7 +4,7 @@ import io
|
|
|
4
4
|
import sys
|
|
5
5
|
|
|
6
6
|
import jaclang.compiler.unitree as uni
|
|
7
|
-
from jaclang import
|
|
7
|
+
from jaclang import JacMachine as Jac
|
|
8
8
|
from jaclang.cli import cli
|
|
9
9
|
from jaclang.compiler.program import JacProgram
|
|
10
10
|
from jaclang.utils.test import TestCase
|
|
@@ -15,9 +15,8 @@ class DeclImplMatchPassTests(TestCase):
|
|
|
15
15
|
|
|
16
16
|
def setUp(self) -> None:
|
|
17
17
|
"""Set up test."""
|
|
18
|
-
|
|
18
|
+
Jac.set_base_path(self.fixture_abs_path("./"))
|
|
19
19
|
Jac.attach_program(
|
|
20
|
-
self.mach,
|
|
21
20
|
JacProgram(),
|
|
22
21
|
)
|
|
23
22
|
return super().setUp()
|
|
@@ -110,7 +109,7 @@ class DeclImplMatchPassTests(TestCase):
|
|
|
110
109
|
"""Test walking through edges and nodes."""
|
|
111
110
|
captured_output = io.StringIO()
|
|
112
111
|
sys.stdout = captured_output
|
|
113
|
-
Jac.jac_import(
|
|
112
|
+
Jac.jac_import("mtest", base_path=self.fixture_abs_path("./"))
|
|
114
113
|
sys.stdout = sys.__stdout__
|
|
115
114
|
stdout_value = captured_output.getvalue()
|
|
116
115
|
self.assertIn("2.0\n", stdout_value)
|
|
@@ -119,7 +118,7 @@ class DeclImplMatchPassTests(TestCase):
|
|
|
119
118
|
"""Test walking through edges."""
|
|
120
119
|
captured_output = io.StringIO()
|
|
121
120
|
sys.stdout = captured_output
|
|
122
|
-
Jac.jac_import(
|
|
121
|
+
Jac.jac_import("impl_grab", base_path=self.fixture_abs_path("./"))
|
|
123
122
|
sys.stdout = sys.__stdout__
|
|
124
123
|
stdout_value = captured_output.getvalue()
|
|
125
124
|
self.assertIn("1.414", stdout_value)
|
|
@@ -128,7 +127,7 @@ class DeclImplMatchPassTests(TestCase):
|
|
|
128
127
|
"""Test complex nested impls."""
|
|
129
128
|
captured_output = io.StringIO()
|
|
130
129
|
sys.stdout = captured_output
|
|
131
|
-
Jac.jac_import(
|
|
130
|
+
Jac.jac_import("nested_impls", base_path=self.fixture_abs_path("./"))
|
|
132
131
|
sys.stdout = sys.__stdout__
|
|
133
132
|
stdout_value = captured_output.getvalue().split("\n")
|
|
134
133
|
self.assertIn("Hello,from bar in kk", stdout_value[0])
|
|
@@ -142,7 +141,7 @@ class DeclImplMatchPassTests(TestCase):
|
|
|
142
141
|
"""Parse micro jac file."""
|
|
143
142
|
captured_output = io.StringIO()
|
|
144
143
|
sys.stdout = captured_output
|
|
145
|
-
Jac.jac_import(
|
|
144
|
+
Jac.jac_import("atest", base_path=self.fixture_abs_path("./"))
|
|
146
145
|
sys.stdout = sys.__stdout__
|
|
147
146
|
stdout_value = captured_output.getvalue()
|
|
148
147
|
self.assertEqual(stdout_value, "42\n")
|
|
@@ -151,7 +150,7 @@ class DeclImplMatchPassTests(TestCase):
|
|
|
151
150
|
"""Parse micro jac file."""
|
|
152
151
|
captured_output = io.StringIO()
|
|
153
152
|
sys.stdout = captured_output
|
|
154
|
-
Jac.jac_import(
|
|
153
|
+
Jac.jac_import("enumerations", base_path=self.fixture_abs_path("./"))
|
|
155
154
|
sys.stdout = sys.__stdout__
|
|
156
155
|
stdout_value = captured_output.getvalue()
|
|
157
156
|
self.assertEqual(stdout_value, "1\n")
|
|
@@ -7,7 +7,6 @@ import unittest
|
|
|
7
7
|
|
|
8
8
|
import jaclang.compiler.unitree as uni
|
|
9
9
|
from jaclang.cli import cli
|
|
10
|
-
from jaclang.compiler.passes.main import CompilerMode as CMode
|
|
11
10
|
from jaclang.compiler.program import JacProgram
|
|
12
11
|
from jaclang.utils.test import TestCase
|
|
13
12
|
|
|
@@ -21,7 +20,7 @@ class ImportPassPassTests(TestCase):
|
|
|
21
20
|
|
|
22
21
|
def test_pygen_jac_cli(self) -> None:
|
|
23
22
|
"""Basic test for pass."""
|
|
24
|
-
(out := JacProgram()).
|
|
23
|
+
(out := JacProgram()).build(self.fixture_abs_path("base.jac"))
|
|
25
24
|
self.assertFalse(out.errors_had)
|
|
26
25
|
mod = out.mod.hub[self.fixture_abs_path("impl/imps.jac")]
|
|
27
26
|
self.assertIn("56", str(mod.to_dict()))
|
|
@@ -38,7 +37,7 @@ class ImportPassPassTests(TestCase):
|
|
|
38
37
|
|
|
39
38
|
def test_import_include_auto_impl(self) -> None:
|
|
40
39
|
"""Basic test for pass."""
|
|
41
|
-
(prog := JacProgram()).
|
|
40
|
+
(prog := JacProgram()).build(self.fixture_abs_path("incautoimpl.jac"))
|
|
42
41
|
num_modules = len(list(prog.mod.hub.values())[1].impl_mod) + 1
|
|
43
42
|
mod_names = [i.name for i in list(prog.mod.hub.values())[1].impl_mod]
|
|
44
43
|
self.assertEqual(num_modules, 5)
|
|
@@ -50,7 +49,7 @@ class ImportPassPassTests(TestCase):
|
|
|
50
49
|
|
|
51
50
|
def test_annexalbe_by_discovery(self) -> None:
|
|
52
51
|
"""Basic test for pass."""
|
|
53
|
-
(prog := JacProgram()).
|
|
52
|
+
(prog := JacProgram()).build(self.fixture_abs_path("incautoimpl.jac"))
|
|
54
53
|
count = 0
|
|
55
54
|
all_mods = prog.mod.hub.values()
|
|
56
55
|
self.assertEqual(len(all_mods), 6)
|
|
@@ -66,10 +65,7 @@ class ImportPassPassTests(TestCase):
|
|
|
66
65
|
@unittest.skip("TODO: Fix when we have the type checker")
|
|
67
66
|
def test_py_raise_map(self) -> None:
|
|
68
67
|
"""Basic test for pass."""
|
|
69
|
-
(build := JacProgram()).
|
|
70
|
-
self.fixture_abs_path("py_imp_test.jac"),
|
|
71
|
-
mode=CMode.TYPECHECK,
|
|
72
|
-
)
|
|
68
|
+
(build := JacProgram()).build(self.fixture_abs_path("py_imp_test.jac"))
|
|
73
69
|
p = {
|
|
74
70
|
"math": r"jaclang/vendor/mypy/typeshed/stdlib/math.pyi$",
|
|
75
71
|
"pygame_mock": r"pygame_mock/__init__.pyi$",
|
|
@@ -91,9 +87,7 @@ class ImportPassPassTests(TestCase):
|
|
|
91
87
|
@unittest.skip("TODO: Fix when we have the type checker")
|
|
92
88
|
def test_py_raised_mods(self) -> None:
|
|
93
89
|
"""Basic test for pass."""
|
|
94
|
-
(prog := JacProgram()).
|
|
95
|
-
self.fixture_abs_path("py_imp_test.jac"), mode=CMode.TYPECHECK
|
|
96
|
-
)
|
|
90
|
+
(prog := JacProgram()).build(self.fixture_abs_path("py_imp_test.jac"))
|
|
97
91
|
for i in list(
|
|
98
92
|
filter(
|
|
99
93
|
lambda x: x.is_raised_from_py,
|
|
@@ -125,13 +119,6 @@ class ImportPassPassTests(TestCase):
|
|
|
125
119
|
self.assertIn("bar", stdout_value)
|
|
126
120
|
self.assertIn("baz", stdout_value)
|
|
127
121
|
|
|
128
|
-
def test_raise_syntax_error(self) -> None:
|
|
129
|
-
"""Test raise error on the parser , dont go to the next pass."""
|
|
130
|
-
(state := JacProgram()).compile(self.fixture_abs_path("main_err.jac"))
|
|
131
|
-
self.assertTrue(state.errors_had)
|
|
132
|
-
self.assertEqual(len(state.errors_had), 1)
|
|
133
|
-
self.assertIn("Syntax Error", state.errors_had[0].msg)
|
|
134
|
-
|
|
135
122
|
def test_circular_import(self) -> None:
|
|
136
123
|
"""Test circular import."""
|
|
137
124
|
(state := JacProgram()).compile(self.fixture_abs_path("circular_import.jac"))
|
|
@@ -6,9 +6,8 @@ import sys
|
|
|
6
6
|
import types
|
|
7
7
|
|
|
8
8
|
import jaclang.compiler.unitree as uni
|
|
9
|
-
from jaclang.compiler.passes.main import
|
|
9
|
+
from jaclang.compiler.passes.main import PyastGenPass
|
|
10
10
|
from jaclang.compiler.program import JacProgram
|
|
11
|
-
from jaclang.runtimelib.machine import JacMachine
|
|
12
11
|
from jaclang.utils.test import AstSyncTestMixin, TestCaseMicroSuite
|
|
13
12
|
|
|
14
13
|
|
|
@@ -53,7 +52,6 @@ class PyastGenPassTests(TestCaseMicroSuite, AstSyncTestMixin):
|
|
|
53
52
|
sys.stdout = captured_output
|
|
54
53
|
module = types.ModuleType("__main__")
|
|
55
54
|
module.__dict__["__file__"] = code_gen.loc.mod_path
|
|
56
|
-
module.__dict__["__jac_mach__"] = JacMachine()
|
|
57
55
|
exec(prog, module.__dict__)
|
|
58
56
|
sys.stdout = sys.__stdout__
|
|
59
57
|
stdout_value = captured_output.getvalue()
|
|
@@ -123,9 +121,7 @@ class ValidateTreeParentTest(TestCaseMicroSuite):
|
|
|
123
121
|
|
|
124
122
|
def micro_suite_test(self, filename: str) -> None:
|
|
125
123
|
"""Parse micro jac file."""
|
|
126
|
-
code_gen = JacProgram().compile(
|
|
127
|
-
self.fixture_abs_path(filename), mode=CMode.PARSE
|
|
128
|
-
)
|
|
124
|
+
code_gen = JacProgram().compile(self.fixture_abs_path(filename))
|
|
129
125
|
self.assertTrue(self.parent_scrub(code_gen))
|
|
130
126
|
code_gen = JacProgram().compile(self.fixture_abs_path(filename))
|
|
131
127
|
self.assertTrue(self.parent_scrub(code_gen))
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Test pass module."""
|
|
2
|
+
|
|
3
|
+
import jaclang.compiler.unitree as uni
|
|
4
|
+
from jaclang.compiler.program import JacProgram
|
|
5
|
+
from jaclang.utils.test import TestCase
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SemDefMatchPassTests(TestCase):
|
|
9
|
+
"""Test pass module."""
|
|
10
|
+
|
|
11
|
+
def test_sem_def_match(self) -> None:
|
|
12
|
+
"""Basic test for pass."""
|
|
13
|
+
(out := JacProgram()).compile(self.fixture_abs_path("sem_def_match.jac"))
|
|
14
|
+
self.assertFalse(out.errors_had)
|
|
15
|
+
mod = out.mod.hub[self.fixture_abs_path("sem_def_match.jac")]
|
|
16
|
+
|
|
17
|
+
self.assertEqual(mod.lookup("E").decl.name_of.semstr, "An enum representing some values.") # type: ignore
|
|
18
|
+
self.assertEqual(mod.lookup("E").fetch_sym_tab.lookup("A").decl.name_of.semstr, "The first value of the enum E.") # type: ignore
|
|
19
|
+
self.assertEqual(mod.lookup("E").fetch_sym_tab.lookup("B").decl.name_of.semstr, "The second value of the enum E.") # type: ignore
|
|
20
|
+
|
|
21
|
+
self.assertEqual(mod.lookup("Person").decl.name_of.semstr, "A class representing a person.") # type: ignore
|
|
22
|
+
|
|
23
|
+
person_scope = mod.lookup("Person").fetch_sym_tab # type: ignore
|
|
24
|
+
self.assertEqual(person_scope.lookup("name").decl.name_of.semstr, "The name of the person.") # type: ignore
|
|
25
|
+
self.assertEqual(person_scope.lookup("yob").decl.name_of.semstr, "The year of birth of the person.") # type: ignore
|
|
26
|
+
|
|
27
|
+
sym_calc_age = person_scope.lookup("calc_age") # type: ignore
|
|
28
|
+
self.assertEqual(sym_calc_age.decl.name_of.semstr, "Calculate the age of the person.") # type: ignore
|
|
29
|
+
|
|
30
|
+
calc_age_scope = sym_calc_age.fetch_sym_tab # type: ignore
|
|
31
|
+
self.assertEqual(calc_age_scope.lookup("year").decl.name_of.semstr, "The year to calculate the age against.") # type: ignore
|
|
32
|
+
|
|
33
|
+
self.assertEqual(mod.lookup("OuterClass").decl.name_of.semstr, "A class containing an inner class.") # type: ignore
|
|
34
|
+
outer_scope = mod.lookup("OuterClass").fetch_sym_tab # type: ignore
|
|
35
|
+
self.assertEqual(outer_scope.lookup("InnerClass").decl.name_of.semstr, "An inner class within OuterClass.") # type: ignore
|
|
36
|
+
inner_scope = outer_scope.lookup("InnerClass").fetch_sym_tab # type: ignore
|
|
37
|
+
self.assertEqual(inner_scope.lookup("inner_value").decl.name_of.semstr, "A value specific to the inner class.") # type: ignore
|
|
38
|
+
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""Test sub node pass module."""
|
|
2
2
|
|
|
3
3
|
from jaclang.compiler.passes import UniPass
|
|
4
|
-
from jaclang.compiler.passes.main import CompilerMode as CMode
|
|
5
4
|
from jaclang.compiler.program import JacProgram
|
|
6
5
|
from jaclang.utils.test import TestCase
|
|
7
6
|
|
|
@@ -16,8 +15,7 @@ class SubNodePassTests(TestCase):
|
|
|
16
15
|
def test_sub_node_pass(self) -> None:
|
|
17
16
|
"""Basic test for pass."""
|
|
18
17
|
code_gen = (out := JacProgram()).compile(
|
|
19
|
-
file_path=self.examples_abs_path("manual_code/circle.jac")
|
|
20
|
-
mode=CMode.PARSE,
|
|
18
|
+
file_path=self.examples_abs_path("manual_code/circle.jac")
|
|
21
19
|
)
|
|
22
20
|
for i in code_gen.kid[1].kid:
|
|
23
21
|
for k, v in i._sub_node_tab.items():
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
|
|
5
|
-
from jaclang.compiler.passes.main import CompilerMode as CMode
|
|
6
5
|
from jaclang.compiler.program import JacProgram
|
|
7
6
|
from jaclang.utils.test import TestCase
|
|
8
7
|
|
|
@@ -23,7 +22,7 @@ class SymTabLinkPassTests(TestCase):
|
|
|
23
22
|
"symtab_link_tests",
|
|
24
23
|
"no_dupls.jac",
|
|
25
24
|
)
|
|
26
|
-
mod = JacProgram().
|
|
25
|
+
mod = JacProgram().build(file_path)
|
|
27
26
|
self.assertEqual(
|
|
28
27
|
len(mod.sym_tab.names_in_scope.values()),
|
|
29
28
|
3,
|
|
@@ -33,20 +32,24 @@ class SymTabLinkPassTests(TestCase):
|
|
|
33
32
|
i,
|
|
34
33
|
str(mod.sym_tab.names_in_scope.values()),
|
|
35
34
|
)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
)
|
|
35
|
+
# TODO: def use is called on single file so this breaks
|
|
36
|
+
# Def Use pass will go away with full type checking
|
|
37
|
+
# self.assertEqual(
|
|
38
|
+
# len(mod.sym_tab.names_in_scope["a"].uses), 4
|
|
39
|
+
# )
|
|
40
|
+
# self.assertEqual(
|
|
41
|
+
# len(
|
|
42
|
+
# list(
|
|
43
|
+
# mod.sym_tab.kid_scope[0]
|
|
44
|
+
# .kid_scope[0]
|
|
45
|
+
# .kid_scope[0]
|
|
46
|
+
# .kid_scope[0]
|
|
47
|
+
# .inherited_scope[0]
|
|
48
|
+
# .base_symbol_table.names_in_scope.values()
|
|
49
|
+
# )[0].uses,
|
|
50
|
+
# ),
|
|
51
|
+
# 3,
|
|
52
|
+
# )
|
|
50
53
|
|
|
51
54
|
def test_package(self) -> None:
|
|
52
55
|
"""Test package."""
|
|
@@ -57,6 +60,6 @@ class SymTabLinkPassTests(TestCase):
|
|
|
57
60
|
"main.jac",
|
|
58
61
|
)
|
|
59
62
|
prog = JacProgram()
|
|
60
|
-
prog.compile(file_path
|
|
63
|
+
prog.compile(file_path)
|
|
61
64
|
self.assertEqual(prog.errors_had, [])
|
|
62
65
|
self.assertEqual(prog.warnings_had, [])
|