jaclang 0.0.5__py3-none-any.whl → 0.0.8__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 +2 -1
- jaclang/cli/__jac_gen__/__init__.py +0 -0
- jaclang/cli/__jac_gen__/cli.py +175 -0
- jaclang/cli/__jac_gen__/cmds.py +132 -0
- jaclang/cli/cli.jac +2 -2
- jaclang/cli/cmds.jac +8 -2
- jaclang/cli/impl/__jac_gen__/__init__.py +0 -0
- jaclang/cli/impl/__jac_gen__/cli_impl.py +16 -0
- jaclang/cli/impl/__jac_gen__/cmds_impl.py +26 -0
- jaclang/cli/impl/cli_impl.jac +25 -8
- jaclang/cli/impl/cmds_impl.jac +35 -6
- jaclang/core/__jac_gen__/__init__.py +0 -0
- jaclang/core/__jac_gen__/primitives.py +567 -0
- jaclang/core/impl/__jac_gen__/__init__.py +0 -0
- jaclang/core/impl/__jac_gen__/arch_impl.py +24 -0
- jaclang/core/impl/__jac_gen__/element_impl.py +26 -0
- jaclang/core/impl/__jac_gen__/exec_ctx_impl.py +12 -0
- jaclang/core/impl/__jac_gen__/memory_impl.py +14 -0
- jaclang/core/impl/element_impl.jac +3 -3
- jaclang/core/impl/exec_ctx_impl.jac +3 -6
- jaclang/core/primitives.jac +4 -3
- jaclang/jac/absyntree.py +555 -180
- jaclang/jac/constant.py +6 -0
- jaclang/jac/importer.py +34 -56
- jaclang/jac/langserve.py +26 -0
- jaclang/jac/lexer.py +35 -3
- jaclang/jac/parser.py +146 -115
- jaclang/jac/passes/blue/__init__.py +8 -3
- jaclang/jac/passes/blue/ast_build_pass.py +454 -305
- jaclang/jac/passes/blue/blue_pygen_pass.py +112 -74
- jaclang/jac/passes/blue/decl_def_match_pass.py +49 -277
- jaclang/jac/passes/blue/import_pass.py +1 -1
- jaclang/jac/passes/blue/pyout_pass.py +74 -0
- jaclang/jac/passes/blue/semantic_check_pass.py +37 -0
- jaclang/jac/passes/blue/sym_tab_build_pass.py +1045 -0
- jaclang/jac/passes/blue/tests/test_ast_build_pass.py +2 -2
- jaclang/jac/passes/blue/tests/test_blue_pygen_pass.py +9 -28
- jaclang/jac/passes/blue/tests/test_decl_def_match_pass.py +13 -22
- jaclang/jac/passes/blue/tests/test_sym_tab_build_pass.py +22 -0
- jaclang/jac/passes/ir_pass.py +8 -6
- jaclang/jac/passes/purple/__jac_gen__/__init__.py +0 -0
- jaclang/jac/passes/purple/__jac_gen__/analyze_pass.py +37 -0
- jaclang/jac/passes/purple/__jac_gen__/purple_pygen_pass.py +305 -0
- jaclang/jac/passes/purple/impl/__jac_gen__/__init__.py +0 -0
- jaclang/jac/passes/purple/impl/__jac_gen__/purple_pygen_pass_impl.py +23 -0
- jaclang/jac/passes/purple/impl/purple_pygen_pass_impl.jac +2 -5
- jaclang/jac/symtable.py +154 -0
- jaclang/jac/tests/fixtures/__jac_gen__/__init__.py +0 -0
- jaclang/jac/tests/fixtures/__jac_gen__/hello_world.py +16 -0
- jaclang/jac/tests/fixtures/fam.jac +7 -8
- jaclang/jac/tests/fixtures/mod_doc_test.jac +1 -0
- jaclang/jac/tests/test_parser.py +8 -0
- jaclang/jac/transform.py +41 -14
- jaclang/jac/transpiler.py +18 -9
- jaclang/utils/fstring_parser.py +2 -2
- jaclang/utils/helpers.py +41 -0
- jaclang/utils/lang_tools.py +12 -2
- jaclang/utils/test.py +41 -0
- jaclang/vendor/__init__.py +1 -0
- jaclang/vendor/pygls/__init__.py +25 -0
- jaclang/vendor/pygls/capabilities.py +502 -0
- jaclang/vendor/pygls/client.py +176 -0
- jaclang/vendor/pygls/constants.py +26 -0
- jaclang/vendor/pygls/exceptions.py +220 -0
- jaclang/vendor/pygls/feature_manager.py +241 -0
- jaclang/vendor/pygls/lsp/__init__.py +139 -0
- jaclang/vendor/pygls/lsp/client.py +2224 -0
- jaclang/vendor/pygls/lsprotocol/__init__.py +2 -0
- jaclang/vendor/pygls/lsprotocol/_hooks.py +1233 -0
- jaclang/vendor/pygls/lsprotocol/converters.py +17 -0
- jaclang/vendor/pygls/lsprotocol/types.py +12820 -0
- jaclang/vendor/pygls/lsprotocol/validators.py +47 -0
- jaclang/vendor/pygls/progress.py +79 -0
- jaclang/vendor/pygls/protocol.py +1184 -0
- jaclang/vendor/pygls/server.py +620 -0
- jaclang/vendor/pygls/uris.py +184 -0
- jaclang/vendor/pygls/workspace/__init__.py +81 -0
- jaclang/vendor/pygls/workspace/position.py +204 -0
- jaclang/vendor/pygls/workspace/text_document.py +234 -0
- jaclang/vendor/pygls/workspace/workspace.py +311 -0
- {jaclang-0.0.5.dist-info → jaclang-0.0.8.dist-info}/METADATA +1 -1
- jaclang-0.0.8.dist-info/RECORD +118 -0
- jaclang/core/jaclang.jac +0 -62
- jaclang/jac/passes/blue/tests/test_type_analyze_pass.py +0 -53
- jaclang/jac/passes/blue/type_analyze_pass.py +0 -728
- jaclang/jac/sym_table.py +0 -127
- jaclang-0.0.5.dist-info/RECORD +0 -73
- /jaclang/{utils → vendor}/sly/__init__.py +0 -0
- /jaclang/{utils → vendor}/sly/docparse.py +0 -0
- /jaclang/{utils → vendor}/sly/lex.py +0 -0
- /jaclang/{utils → vendor}/sly/yacc.py +0 -0
- {jaclang-0.0.5.dist-info → jaclang-0.0.8.dist-info}/WHEEL +0 -0
- {jaclang-0.0.5.dist-info → jaclang-0.0.8.dist-info}/entry_points.txt +0 -0
- {jaclang-0.0.5.dist-info → jaclang-0.0.8.dist-info}/top_level.txt +0 -0
|
@@ -51,8 +51,8 @@ class AstBuildPassTests(TestCaseMicroSuite):
|
|
|
51
51
|
def micro_suite_test(self, filename: str) -> None:
|
|
52
52
|
"""Parse micro jac file."""
|
|
53
53
|
lex = JacLexer(mod_path=f"{filename}", input_ir=self.file_to_str(filename)).ir
|
|
54
|
-
prse = JacParser(mod_path=f"{filename}", input_ir=lex)
|
|
55
|
-
build_pass = AstBuildPass(mod_path="", input_ir=prse).ir
|
|
54
|
+
prse = JacParser(mod_path=f"{filename}", input_ir=lex)
|
|
55
|
+
build_pass = AstBuildPass(mod_path="", prior=prse, input_ir=prse.ir).ir
|
|
56
56
|
self.assertIsNotNone(build_pass)
|
|
57
57
|
if build_pass:
|
|
58
58
|
self.assertGreater(len(str(build_pass.to_dict())), 200)
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
"""Test ast build pass module."""
|
|
2
|
-
import inspect
|
|
3
|
-
|
|
4
2
|
from jaclang.jac.passes.blue import BluePygenPass
|
|
5
|
-
from jaclang.jac.transpiler import jac_file_to_pass
|
|
6
|
-
from jaclang.utils.
|
|
7
|
-
from jaclang.utils.test import TestCaseMicroSuite
|
|
3
|
+
from jaclang.jac.transpiler import jac_file_to_pass
|
|
4
|
+
from jaclang.utils.test import AstSyncTestMixin, TestCaseMicroSuite
|
|
8
5
|
|
|
9
6
|
|
|
10
|
-
class BluePygenPassTests(TestCaseMicroSuite):
|
|
7
|
+
class BluePygenPassTests(TestCaseMicroSuite, AstSyncTestMixin):
|
|
11
8
|
"""Test pass module."""
|
|
12
9
|
|
|
10
|
+
TargetPass = BluePygenPass
|
|
11
|
+
|
|
13
12
|
def setUp(self) -> None:
|
|
14
13
|
"""Set up test."""
|
|
15
14
|
return super().setUp()
|
|
@@ -88,30 +87,12 @@ class BluePygenPassTests(TestCaseMicroSuite):
|
|
|
88
87
|
self.assertIn("GREEN = __jac_auto__()", code_gen.ir.meta["py_code"])
|
|
89
88
|
self.assertIn("RED = 1", code_gen.ir.meta["py_code"])
|
|
90
89
|
|
|
91
|
-
def test_pass_ast_complete(self) -> None:
|
|
92
|
-
"""Test for enter/exit name diffs with parser."""
|
|
93
|
-
ast_func_names = [
|
|
94
|
-
x for x in ast_snakes() if x not in ["ast_node", "o_o_p_access_node"]
|
|
95
|
-
]
|
|
96
|
-
pygen_func_names = []
|
|
97
|
-
for name, value in inspect.getmembers(BluePygenPass):
|
|
98
|
-
if (
|
|
99
|
-
(name.startswith("enter_") or name.startswith("exit_"))
|
|
100
|
-
and inspect.isfunction(value)
|
|
101
|
-
and not getattr(BluePygenPass.__base__, value.__name__, False)
|
|
102
|
-
and value.__qualname__.split(".")[0]
|
|
103
|
-
== BluePygenPass.__name__.replace("enter_", "").replace("exit_", "")
|
|
104
|
-
):
|
|
105
|
-
pygen_func_names.append(name.replace("enter_", "").replace("exit_", ""))
|
|
106
|
-
for name in pygen_func_names:
|
|
107
|
-
self.assertIn(name, ast_func_names)
|
|
108
|
-
for name in ast_func_names:
|
|
109
|
-
self.assertIn(name, pygen_func_names)
|
|
110
|
-
|
|
111
90
|
def micro_suite_test(self, filename: str) -> None:
|
|
112
91
|
"""Parse micro jac file."""
|
|
113
|
-
code_gen =
|
|
114
|
-
|
|
92
|
+
code_gen = jac_file_to_pass(
|
|
93
|
+
self.fixture_abs_path(filename), target=BluePygenPass
|
|
94
|
+
)
|
|
95
|
+
self.assertGreater(len(code_gen.ir.meta["py_code"]), 10)
|
|
115
96
|
|
|
116
97
|
|
|
117
98
|
BluePygenPassTests.self_attach_micro_tests()
|
|
@@ -11,25 +11,16 @@ class DeclDefMatchPassTests(TestCase):
|
|
|
11
11
|
"""Set up test."""
|
|
12
12
|
return super().setUp()
|
|
13
13
|
|
|
14
|
-
def test_import_values_avail(self) -> None:
|
|
15
|
-
"""Basic test for pass."""
|
|
16
|
-
state = jac_file_to_pass(
|
|
17
|
-
self.fixture_abs_path("base.jac"), "", DeclDefMatchPass
|
|
18
|
-
)
|
|
19
|
-
self.assertFalse(state.errors_had)
|
|
20
|
-
self.assertIn("mine", state.sym_tab.tab)
|
|
21
|
-
self.assertIsNotNone(state.sym_tab.tab["mine"].node.body)
|
|
22
|
-
|
|
23
14
|
def test_ability_connected_to_decl(self) -> None:
|
|
24
15
|
"""Basic test for pass."""
|
|
25
16
|
state = jac_file_to_pass(
|
|
26
17
|
self.fixture_abs_path("base.jac"), "", DeclDefMatchPass
|
|
27
18
|
)
|
|
28
19
|
self.assertFalse(state.errors_had)
|
|
29
|
-
self.assertIn("Test.say_hi", state.sym_tab.tab)
|
|
30
|
-
self.assertIsNotNone(state.sym_tab.tab["Test.say_hi"].
|
|
31
|
-
self.assertIn("Test.init", state.sym_tab.tab)
|
|
32
|
-
self.assertIsNotNone(state.sym_tab.tab["Test.init"].
|
|
20
|
+
self.assertIn("(o)Test.(a)say_hi", state.ir.sym_tab.tab)
|
|
21
|
+
self.assertIsNotNone(state.ir.sym_tab.tab["(o)Test.(a)say_hi"].decl.body)
|
|
22
|
+
self.assertIn("(o)Test.(a)init", state.ir.sym_tab.tab)
|
|
23
|
+
self.assertIsNotNone(state.ir.sym_tab.tab["(o)Test.(a)init"].decl.body)
|
|
33
24
|
|
|
34
25
|
def test_ability_connected_to_decl_post(self) -> None:
|
|
35
26
|
"""Basic test for pass."""
|
|
@@ -37,18 +28,18 @@ class DeclDefMatchPassTests(TestCase):
|
|
|
37
28
|
self.fixture_abs_path("base2.jac"), "", DeclDefMatchPass
|
|
38
29
|
)
|
|
39
30
|
self.assertFalse(state.errors_had)
|
|
40
|
-
self.assertIn("Test.say_hi", state.sym_tab.tab)
|
|
41
|
-
self.assertIsNotNone(state.sym_tab.tab["Test.say_hi"].
|
|
42
|
-
self.assertIn("Test.init", state.sym_tab.tab)
|
|
43
|
-
self.assertIsNotNone(state.sym_tab.tab["Test.init"].
|
|
31
|
+
self.assertIn("(o)Test.(a)say_hi", state.ir.sym_tab.tab)
|
|
32
|
+
self.assertIsNotNone(state.ir.sym_tab.tab["(o)Test.(a)say_hi"].decl.body)
|
|
33
|
+
self.assertIn("(o)Test.(a)init", state.ir.sym_tab.tab)
|
|
34
|
+
self.assertIsNotNone(state.ir.sym_tab.tab["(o)Test.(a)init"].decl.body)
|
|
44
35
|
|
|
45
36
|
def test_collision_error_correct(self) -> None:
|
|
46
37
|
"""Basic test for multi defs."""
|
|
47
38
|
state = jac_file_to_pass(
|
|
48
39
|
self.fixture_abs_path("decls.jac"), "", DeclDefMatchPass
|
|
49
40
|
)
|
|
50
|
-
self.assertTrue(state.
|
|
51
|
-
self.assertIn("/impl/defs2.jac", state.
|
|
52
|
-
self.assertIn("/impl/defs1.jac", state.
|
|
53
|
-
self.assertIn("/impl/defs2.jac", state.
|
|
54
|
-
self.assertIn("/impl/defs1.jac", state.
|
|
41
|
+
self.assertTrue(state.warnings_had)
|
|
42
|
+
self.assertIn("/impl/defs2.jac", str(state.warnings_had[0]))
|
|
43
|
+
self.assertIn("/impl/defs1.jac", str(state.warnings_had[0]))
|
|
44
|
+
self.assertIn("/impl/defs2.jac", str(state.warnings_had[1]))
|
|
45
|
+
self.assertIn("/impl/defs1.jac", str(state.warnings_had[1]))
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Test pass module."""
|
|
2
|
+
from jaclang.jac.passes.blue import SymTabBuildPass
|
|
3
|
+
from jaclang.jac.transpiler import jac_file_to_pass
|
|
4
|
+
from jaclang.utils.test import AstSyncTestMixin, TestCase
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SymTabBuildPassTests(TestCase, AstSyncTestMixin):
|
|
8
|
+
"""Test pass module."""
|
|
9
|
+
|
|
10
|
+
TargetPass = SymTabBuildPass
|
|
11
|
+
|
|
12
|
+
def setUp(self) -> None:
|
|
13
|
+
"""Set up test."""
|
|
14
|
+
return super().setUp()
|
|
15
|
+
|
|
16
|
+
def test_name_collision(self) -> None:
|
|
17
|
+
"""Basic test for pass."""
|
|
18
|
+
state = jac_file_to_pass(
|
|
19
|
+
self.fixture_abs_path("multi_def_err.jac"), "", SymTabBuildPass
|
|
20
|
+
)
|
|
21
|
+
self.assertGreater(len(state.warnings_had), 0)
|
|
22
|
+
self.assertIn("MyObject", str(state.warnings_had[0]))
|
jaclang/jac/passes/ir_pass.py
CHANGED
|
@@ -13,15 +13,16 @@ class Pass(Transform):
|
|
|
13
13
|
|
|
14
14
|
def __init__(
|
|
15
15
|
self,
|
|
16
|
+
prior: Transform,
|
|
16
17
|
mod_path: str,
|
|
17
18
|
input_ir: ast.AstNode,
|
|
18
19
|
base_path: str = "",
|
|
19
|
-
prior: Optional[Transform] = None,
|
|
20
20
|
) -> None:
|
|
21
21
|
"""Initialize parser."""
|
|
22
22
|
self.term_signal = False
|
|
23
23
|
self.prune_signal = False
|
|
24
24
|
self.cur_node = input_ir # tracks current node during traversal
|
|
25
|
+
self.ir = input_ir
|
|
25
26
|
Transform.__init__(self, mod_path, input_ir, base_path, prior)
|
|
26
27
|
|
|
27
28
|
def before_pass(self) -> None:
|
|
@@ -125,18 +126,19 @@ class Pass(Transform):
|
|
|
125
126
|
self.cur_line = node.line
|
|
126
127
|
if node.mod_link:
|
|
127
128
|
self.rel_mod_path = node.mod_link.rel_mod_path
|
|
129
|
+
self.mod_path = node.mod_link.mod_path
|
|
128
130
|
|
|
129
|
-
def error(self, msg: str) -> None:
|
|
131
|
+
def error(self, msg: str, node_override: Optional[ast.AstNode] = None) -> None:
|
|
130
132
|
"""Pass Error."""
|
|
131
|
-
self.update_code_loc()
|
|
133
|
+
self.update_code_loc(node_override)
|
|
132
134
|
self.log_error(f"{msg}")
|
|
133
135
|
|
|
134
|
-
def warning(self, msg: str) -> None:
|
|
136
|
+
def warning(self, msg: str, node_override: Optional[ast.AstNode] = None) -> None:
|
|
135
137
|
"""Pass Error."""
|
|
136
|
-
self.update_code_loc()
|
|
138
|
+
self.update_code_loc(node_override)
|
|
137
139
|
self.log_warning(f"{msg}")
|
|
138
140
|
|
|
139
|
-
def ice(self, msg: str) -> None:
|
|
141
|
+
def ice(self, msg: str = "Something went horribly wrong!") -> None:
|
|
140
142
|
"""Pass Error."""
|
|
141
143
|
if isinstance(self.cur_node, ast.AstNode):
|
|
142
144
|
self.cur_line = self.cur_node.line
|
|
File without changes
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Type Analyze Pass.""" # 0 1
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
import traceback as __jac_traceback__ # -1 0
|
|
4
|
+
from jaclang import handle_jac_error as __jac_error__ # -1 0
|
|
5
|
+
import jaclang.jac.absyntree as ast # 0 2
|
|
6
|
+
|
|
7
|
+
from jaclang.jac.passes import Pass # 0 4
|
|
8
|
+
|
|
9
|
+
from jaclang.jac.constant import Tokens as Tok # 0 5
|
|
10
|
+
|
|
11
|
+
class AnalyzePass(Pass): # 0 8
|
|
12
|
+
def __init__(self, # 0 0
|
|
13
|
+
*args, **kwargs): # 0 0
|
|
14
|
+
super().__init__(*args, **kwargs) # 0 0
|
|
15
|
+
def enter_arch_block(self,nd: ast.ArchBlock): # 0 9
|
|
16
|
+
try: # 0 9
|
|
17
|
+
if (isinstance(nd.parent, ast.Architype) and nd.parent.arch_type.name == Tok.KW_WALKER): # 0 14
|
|
18
|
+
for i in self.get_all_sub_nodes(nd, ast.VisitStmt, brute_force = False): # 0 18
|
|
19
|
+
i.from_walker = True # 0 19 # 0 18
|
|
20
|
+
for i in self.get_all_sub_nodes(nd, ast.IgnoreStmt, brute_force = False): # 0 21
|
|
21
|
+
i.from_walker = True # 0 22 # 0 21
|
|
22
|
+
for i in self.get_all_sub_nodes(nd, ast.DisengageStmt, brute_force = False): # 0 24
|
|
23
|
+
i.from_walker = True # 0 25 # 0 24
|
|
24
|
+
for i in self.get_all_sub_nodes(nd, ast.EdgeOpRef, brute_force = False): # 0 27
|
|
25
|
+
i.from_walker = True # 0 28 # 0 27
|
|
26
|
+
|
|
27
|
+
except Exception as e: # 0 9
|
|
28
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 9
|
|
29
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 9
|
|
30
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 9
|
|
31
|
+
raise e # 0 9
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
r""" JAC DEBUG INFO
|
|
36
|
+
/home/ninja/jaclang/jaclang/jac/passes/purple/analyze_pass.jac
|
|
37
|
+
JAC DEBUG INFO """
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
"""First Jac pass bootstrapped in Jac""" # 0 1
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from jaclang import jac_blue_import as __jac_import__ # -1 0
|
|
4
|
+
import traceback as __jac_traceback__ # -1 0
|
|
5
|
+
from jaclang import handle_jac_error as __jac_error__ # -1 0
|
|
6
|
+
import jaclang.jac.absyntree as ast # 0 2
|
|
7
|
+
|
|
8
|
+
from jaclang.jac.passes.blue import BluePygenPass # 0 3
|
|
9
|
+
|
|
10
|
+
from jaclang.core import Object, Node, Edge, Walker # 0 4
|
|
11
|
+
|
|
12
|
+
__jac_import__(target='impl.purple_pygen_pass_impl', base_path=__file__) # 0 7
|
|
13
|
+
from impl.purple_pygen_pass_impl import * # 0 7
|
|
14
|
+
|
|
15
|
+
class PurplePygenPass(BluePygenPass): # 0 13
|
|
16
|
+
"""
|
|
17
|
+
This pass leverages data spacial lib to provide code
|
|
18
|
+
gen for full Jac language. It is bootstrapped in Jac blue.
|
|
19
|
+
""" # 0 13
|
|
20
|
+
def __init__(self, # 0 0
|
|
21
|
+
*args, **kwargs): # 0 0
|
|
22
|
+
super().__init__(*args, **kwargs) # 0 0
|
|
23
|
+
def add_element_import(self,arch: str): # 0 19
|
|
24
|
+
try: # 0 19
|
|
25
|
+
self.emit_ln_unique(self.preamble, f"from jaclang.core import {arch} as _jac_{arch}_") # 1 6
|
|
26
|
+
self.emit_ln_unique(self.preamble, f"from jaclang.core import make_architype as _jac_make_architype_") # 1 6
|
|
27
|
+
except Exception as e: # 0 19
|
|
28
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 19
|
|
29
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 19
|
|
30
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 19
|
|
31
|
+
raise e # 0 19
|
|
32
|
+
|
|
33
|
+
def add_exec_context(self,): # 0 20
|
|
34
|
+
try: # 0 20
|
|
35
|
+
self.emit_ln_unique(self.preamble, f"from jaclang.core import exec_ctx as {C.EXEC_CONTEXT}") # 1 13
|
|
36
|
+
except Exception as e: # 0 20
|
|
37
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 20
|
|
38
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 20
|
|
39
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 20
|
|
40
|
+
raise e # 0 20
|
|
41
|
+
|
|
42
|
+
def add_edge_directions(self,): # 0 21
|
|
43
|
+
try: # 0 21
|
|
44
|
+
self.emit_ln_unique(self.preamble, f"from jaclang.jac.constant import EdgeDir as {C.EDGE_DIR}") # 1 18
|
|
45
|
+
except Exception as e: # 0 21
|
|
46
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 21
|
|
47
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 21
|
|
48
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 21
|
|
49
|
+
raise e # 0 21
|
|
50
|
+
|
|
51
|
+
def needs_jac_import(self,): # 0 22
|
|
52
|
+
try: # 0 22
|
|
53
|
+
self.emit_ln_unique(self.preamble, "from jaclang import jac_purple_import as __jac_import__") # 1 23
|
|
54
|
+
except Exception as e: # 0 22
|
|
55
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 22
|
|
56
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 22
|
|
57
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 22
|
|
58
|
+
raise e # 0 22
|
|
59
|
+
|
|
60
|
+
def exit_architype(self,nd: ast.Architype): # 0 24
|
|
61
|
+
try: # 0 24
|
|
62
|
+
self.add_exec_context() # 1 40
|
|
63
|
+
if nd.decorators: # 1 41
|
|
64
|
+
self.emit_ln(nd, nd.decorators.meta["py_code"]) # 1 42
|
|
65
|
+
|
|
66
|
+
arch_type = nd.arch_type.name # 1 40
|
|
67
|
+
arch_insert = "" # 1 40
|
|
68
|
+
if arch_type == Tok.KW_OBJECT: # 1 46
|
|
69
|
+
self.add_element_import("Object") # 1 47
|
|
70
|
+
arch_insert = C.OBJECT_CLASS # 1 47
|
|
71
|
+
self.emit_ln(nd, f"@_jac_make_architype_({arch_insert})") # 1 47
|
|
72
|
+
|
|
73
|
+
elif arch_type == Tok.KW_NODE: # 1 51
|
|
74
|
+
self.add_element_import("Node") # 1 52
|
|
75
|
+
arch_insert = C.NODE_CLASS # 1 52
|
|
76
|
+
self.emit_ln(nd, f"@_jac_make_architype_({arch_insert})") # 1 52
|
|
77
|
+
|
|
78
|
+
elif arch_type == Tok.KW_EDGE: # 1 51
|
|
79
|
+
self.add_element_import("Edge") # 1 57
|
|
80
|
+
arch_insert = C.EDGE_CLASS # 1 57
|
|
81
|
+
self.emit_ln(nd, f"@_jac_make_architype_({arch_insert})") # 1 57
|
|
82
|
+
|
|
83
|
+
elif arch_type == Tok.KW_WALKER: # 1 51
|
|
84
|
+
self.add_element_import("Walker") # 1 62
|
|
85
|
+
arch_insert = C.WALKER_CLASS # 1 62
|
|
86
|
+
self.emit_ln(nd, f"@_jac_make_architype_({arch_insert})") # 1 62
|
|
87
|
+
|
|
88
|
+
if len(nd.base_classes.base_classes): # 1 66
|
|
89
|
+
self.emit_ln(nd, f"class {nd.name.meta['py_code']}"f"({nd.base_classes.meta['py_code']}):") # 1 67
|
|
90
|
+
|
|
91
|
+
else: # 1 70
|
|
92
|
+
self.emit_ln(nd, f"class {nd.name.meta['py_code']}:") # 1 71
|
|
93
|
+
|
|
94
|
+
self.indent_level += 1 # 1 40
|
|
95
|
+
if nd.doc: # 1 74
|
|
96
|
+
self.emit_ln(nd, nd.doc.meta["py_code"]) # 1 75
|
|
97
|
+
|
|
98
|
+
if nd.body: # 1 76
|
|
99
|
+
self.emit_ln(nd, nd.body.meta["py_code"]) # 1 77
|
|
100
|
+
|
|
101
|
+
else: # 1 78
|
|
102
|
+
self.decl_def_missing(nd.name.meta["py_code"]) # 1 79
|
|
103
|
+
|
|
104
|
+
self.indent_level -= 1 # 1 40
|
|
105
|
+
except Exception as e: # 0 24
|
|
106
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 24
|
|
107
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 24
|
|
108
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 24
|
|
109
|
+
raise e # 0 24
|
|
110
|
+
|
|
111
|
+
def exit_ability(self,nd: ast.Ability): # 0 25
|
|
112
|
+
try: # 0 25
|
|
113
|
+
ability_name = nd.py_resolve_name() # 1 98
|
|
114
|
+
if nd.arch_attached and ability_name == "__init__": # 1 99
|
|
115
|
+
return # 1 100
|
|
116
|
+
|
|
117
|
+
if type(nd.signature) == ast.EventSignature and nd.arch_attached and nd.signature.event.name == Tok.KW_ENTRY: # 1 102
|
|
118
|
+
self.add_element_import("Object") # 1 104
|
|
119
|
+
type_list = _jac_tmp if (_jac_tmp := (((nd.signature.arch_tag_info.meta if nd.signature.arch_tag_info is not None else None)["py_code"] if (nd.signature.arch_tag_info.meta if nd.signature.arch_tag_info is not None else None) is not None else None))) is not None else "" # 1 104
|
|
120
|
+
self.emit_ln(nd, f"@{C.OBJECT_CLASS}._jac_on_entry([{type_list.replace('|', ', ')}])") # 1 104
|
|
121
|
+
|
|
122
|
+
elif type(nd.signature) == ast.EventSignature and nd.arch_attached and nd.signature.event.name == Tok.KW_EXIT: # 1 108
|
|
123
|
+
self.add_element_import("Object") # 1 110
|
|
124
|
+
type_list = _jac_tmp if (_jac_tmp := (((nd.signature.arch_tag_info.meta if nd.signature.arch_tag_info is not None else None)["py_code"] if (nd.signature.arch_tag_info.meta if nd.signature.arch_tag_info is not None else None) is not None else None))) is not None else "" # 1 110
|
|
125
|
+
self.emit_ln(nd, f"@{C.OBJECT_CLASS}._jac_on_exit([{type_list.replace('|', ', ')}])") # 1 110
|
|
126
|
+
|
|
127
|
+
super().exit_ability((nd)) # 1 98
|
|
128
|
+
except Exception as e: # 0 25
|
|
129
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 25
|
|
130
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 25
|
|
131
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 25
|
|
132
|
+
raise e # 0 25
|
|
133
|
+
|
|
134
|
+
def exit_event_signature(self,nd: ast.EventSignature): # 0 26
|
|
135
|
+
try: # 0 26
|
|
136
|
+
if nd.arch_tag_info: # 1 126
|
|
137
|
+
self.emit(nd, f"{C.HERE}: {nd.arch_tag_info.meta['py_code']}") # 1 127
|
|
138
|
+
|
|
139
|
+
else: # 1 129
|
|
140
|
+
self.emit(nd, f"{C.HERE}") # 1 130
|
|
141
|
+
|
|
142
|
+
if nd.return_type: # 1 132
|
|
143
|
+
self.emit(nd, f" -> {nd.return_type.meta['py_code']}") # 1 133
|
|
144
|
+
|
|
145
|
+
except Exception as e: # 0 26
|
|
146
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 26
|
|
147
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 26
|
|
148
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 26
|
|
149
|
+
raise e # 0 26
|
|
150
|
+
|
|
151
|
+
def exit_ctrl_stmt(self,nd: ast.CtrlStmt): # 0 27
|
|
152
|
+
try: # 0 27
|
|
153
|
+
if nd.ctrl.name == Tok.KW_SKIP: # 1 144
|
|
154
|
+
self.emit_ln(nd, "return") # 1 145
|
|
155
|
+
|
|
156
|
+
else: # 1 146
|
|
157
|
+
super().exit_ctrl_stmt(nd) # 1 147
|
|
158
|
+
|
|
159
|
+
except Exception as e: # 0 27
|
|
160
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 27
|
|
161
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 27
|
|
162
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 27
|
|
163
|
+
raise e # 0 27
|
|
164
|
+
|
|
165
|
+
def exit_report_stmt(self,nd: ast.ReportStmt): # 0 28
|
|
166
|
+
try: # 0 28
|
|
167
|
+
pass # 0 28
|
|
168
|
+
except Exception as e: # 0 28
|
|
169
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 28
|
|
170
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 28
|
|
171
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 28
|
|
172
|
+
raise e # 0 28
|
|
173
|
+
|
|
174
|
+
def exit_ignore_stmt(self,nd: ast.IgnoreStmt): # 0 29
|
|
175
|
+
try: # 0 29
|
|
176
|
+
loc = 'self' if nd.from_walker else C.HERE # 1 159
|
|
177
|
+
self.emit_ln(nd, f"{loc}.{C.WALKER_IGNORE}({nd.target.meta['py_code']})") # 1 159
|
|
178
|
+
except Exception as e: # 0 29
|
|
179
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 29
|
|
180
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 29
|
|
181
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 29
|
|
182
|
+
raise e # 0 29
|
|
183
|
+
|
|
184
|
+
def exit_visit_stmt(self,nd: ast.VisitStmt): # 0 30
|
|
185
|
+
try: # 0 30
|
|
186
|
+
vis_type = _jac_tmp if (_jac_tmp := ((nd.vis_type.value if nd.vis_type is not None else None))) is not None else "" # 1 174
|
|
187
|
+
loc = 'self' if nd.from_walker else C.HERE # 1 174
|
|
188
|
+
self.emit_ln(nd, f"if not {loc}.{C.WALKER_VISIT}({nd.target.meta['py_code']}): ") # 1 174
|
|
189
|
+
self.indent_level += 1 # 1 174
|
|
190
|
+
if nd.else_body: # 1 179
|
|
191
|
+
self.emit(nd, nd.else_body.body.meta["py_code"]) # 1 180
|
|
192
|
+
|
|
193
|
+
else: # 1 181
|
|
194
|
+
self.emit_ln(nd, 'pass') # 1 182
|
|
195
|
+
|
|
196
|
+
self.indent_level -= 1 # 1 174
|
|
197
|
+
except Exception as e: # 0 30
|
|
198
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 30
|
|
199
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 30
|
|
200
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 30
|
|
201
|
+
raise e # 0 30
|
|
202
|
+
|
|
203
|
+
def exit_revisit_stmt(self,nd: ast.RevisitStmt): # 0 31
|
|
204
|
+
try: # 0 31
|
|
205
|
+
pass # 0 31
|
|
206
|
+
except Exception as e: # 0 31
|
|
207
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 31
|
|
208
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 31
|
|
209
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 31
|
|
210
|
+
raise e # 0 31
|
|
211
|
+
|
|
212
|
+
def exit_await_stmt(self,nd: ast.AwaitStmt): # 0 32
|
|
213
|
+
try: # 0 32
|
|
214
|
+
pass # 0 32
|
|
215
|
+
except Exception as e: # 0 32
|
|
216
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 32
|
|
217
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 32
|
|
218
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 32
|
|
219
|
+
raise e # 0 32
|
|
220
|
+
|
|
221
|
+
def exit_disengage_stmt(self,nd: ast.DisengageStmt): # 0 33
|
|
222
|
+
try: # 0 33
|
|
223
|
+
loc = 'self' if nd.from_walker else C.HERE # 1 193
|
|
224
|
+
self.emit_ln(nd, f"return {loc}.{C.DISENGAGE}()") # 1 193
|
|
225
|
+
except Exception as e: # 0 33
|
|
226
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 33
|
|
227
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 33
|
|
228
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 33
|
|
229
|
+
raise e # 0 33
|
|
230
|
+
|
|
231
|
+
def exit_binary_expr(self,nd: ast.BinaryExpr): # 0 34
|
|
232
|
+
try: # 0 34
|
|
233
|
+
if (type(nd.op)) == ast.ConnectOp: # 1 206
|
|
234
|
+
self.emit(nd, f"{nd.left.meta['py_code']}.{C.CONNECT_NODE}({nd.right.meta['py_code']}, {nd.op.meta['py_code']})") # 1 207
|
|
235
|
+
|
|
236
|
+
elif (type(nd.op)) == ast.DisconnectOp: # 1 209
|
|
237
|
+
self.ds_feature_warn() # 1 210
|
|
238
|
+
|
|
239
|
+
elif nd.op.name == Tok.PIPE_FWD and isinstance(nd.right, ast.TupleVal): # 1 209
|
|
240
|
+
self.ds_feature_warn() # 1 212
|
|
241
|
+
|
|
242
|
+
else: # 1 214
|
|
243
|
+
super().exit_binary_expr(nd) # 1 215
|
|
244
|
+
|
|
245
|
+
except Exception as e: # 0 34
|
|
246
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 34
|
|
247
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 34
|
|
248
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 34
|
|
249
|
+
raise e # 0 34
|
|
250
|
+
|
|
251
|
+
def exit_edge_op_ref(self,nd: ast.EdgeOpRef): # 0 35
|
|
252
|
+
try: # 0 35
|
|
253
|
+
loc = C.HERE if nd.from_walker else 'self' # 1 229
|
|
254
|
+
edge_dir = f"{C.EDGE_DIR}.IN" if nd.edge_dir == EdgeDir.IN else f"{C.EDGE_DIR}.OUT" if nd.edge_dir == EdgeDir.OUT else f"{C.EDGE_DIR}.ANY" # 1 229
|
|
255
|
+
if nd.filter_type and nd.filter_cond: # 1 233
|
|
256
|
+
self.emit(nd, f"[{C.JAC_TMP} for {C.JAC_TMP} in {loc}.{C.EDGES_TO_NODE}({edge_dir})"f" if isinstance({C.JAC_TMP}, {nd.filter_type.meta['py_code']})"f" and {nd.filter_cond.meta['py_code'].replace(C.PATCH, C.JAC_TMP)}]") # 1 234
|
|
257
|
+
|
|
258
|
+
elif nd.filter_type: # 1 239
|
|
259
|
+
self.emit(nd, f"[{C.JAC_TMP} for {C.JAC_TMP} in {loc}.{C.EDGES_TO_NODE}({edge_dir})"f" if isinstance({C.JAC_TMP}, {nd.filter_type.meta['py_code']})]") # 1 240
|
|
260
|
+
|
|
261
|
+
else: # 1 244
|
|
262
|
+
self.emit(nd, f"{loc}.{C.EDGES_TO_NODE}({edge_dir})") # 1 245
|
|
263
|
+
|
|
264
|
+
except Exception as e: # 0 35
|
|
265
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 35
|
|
266
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 35
|
|
267
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 35
|
|
268
|
+
raise e # 0 35
|
|
269
|
+
|
|
270
|
+
def exit_connect_op(self,nd: ast.ConnectOp): # 0 36
|
|
271
|
+
try: # 0 36
|
|
272
|
+
self.add_element_import("Edge") # 1 259
|
|
273
|
+
self.add_edge_directions() # 1 259
|
|
274
|
+
if nd.conn_type: # 1 262
|
|
275
|
+
self.emit(nd, f"{nd.conn_type.meta['py_code']}.{C.WITH_DIR}({C.EDGE_DIR}.{nd.edge_dir.name}") # 1 263
|
|
276
|
+
|
|
277
|
+
else: # 1 264
|
|
278
|
+
self.emit(nd, f"{C.EDGE_CLASS}().{C.WITH_DIR}({C.EDGE_DIR}.{nd.edge_dir.name}") # 1 265
|
|
279
|
+
|
|
280
|
+
if nd.conn_assign: # 1 267
|
|
281
|
+
self.emit(nd, f", {nd.conn_assign.meta['py_code']})") # 1 268
|
|
282
|
+
|
|
283
|
+
else: # 1 269
|
|
284
|
+
self.emit(nd, ")") # 1 270
|
|
285
|
+
|
|
286
|
+
except Exception as e: # 0 36
|
|
287
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 36
|
|
288
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 36
|
|
289
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 36
|
|
290
|
+
raise e # 0 36
|
|
291
|
+
|
|
292
|
+
def exit_disconnect_op(self,nd: ast.DisconnectOp): # 0 37
|
|
293
|
+
try: # 0 37
|
|
294
|
+
pass # 1 281
|
|
295
|
+
except Exception as e: # 0 37
|
|
296
|
+
tb = __jac_traceback__.extract_tb(e.__traceback__) # 0 37
|
|
297
|
+
__jac_tmp__ = __jac_error__(_jac_pycodestring_, e, tb) # 0 37
|
|
298
|
+
e.args = (f'{e.args[0]}\n' + __jac_tmp__,) + e.args[1:] if 'Jac error originates from...' not in str(e) else e.args # 0 37
|
|
299
|
+
raise e # 0 37
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
r""" JAC DEBUG INFO
|
|
303
|
+
/home/ninja/jaclang/jaclang/jac/passes/purple/purple_pygen_pass.jac
|
|
304
|
+
/home/ninja/jaclang/jaclang/jac/passes/purple/impl/purple_pygen_pass_impl.jac
|
|
305
|
+
JAC DEBUG INFO """
|
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""First Jac pass bootstrapped in Jac""" # 1 1
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from jaclang.jac.constant import Constants as C, EdgeDir, Tokens as Tok # 1 2
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
r""" JAC DEBUG INFO
|
|
21
|
+
/home/ninja/jaclang/jaclang/jac/passes/purple/purple_pygen_pass.jac
|
|
22
|
+
/home/ninja/jaclang/jaclang/jac/passes/purple/impl/purple_pygen_pass_impl.jac
|
|
23
|
+
JAC DEBUG INFO """
|
|
@@ -123,14 +123,11 @@ return_type: Optional["TypeSpec"],
|
|
|
123
123
|
"""
|
|
124
124
|
:object:PurplePygenPass:ability:exit_event_signature
|
|
125
125
|
(nd: ast.EventSignature) {
|
|
126
|
-
if (nd.parent|>type) == ast.Ability and nd.parent.arch_attached {
|
|
127
|
-
(nd, ", ") |> <self>.emit;
|
|
128
|
-
}
|
|
129
126
|
if nd.arch_tag_info {
|
|
130
|
-
(nd, f"{C.HERE}: {nd.arch_tag_info.meta['py_code']}
|
|
127
|
+
(nd, f"{C.HERE}: {nd.arch_tag_info.meta['py_code']}")
|
|
131
128
|
|> <self>.emit;
|
|
132
129
|
} else {
|
|
133
|
-
(nd, f"{C.HERE}
|
|
130
|
+
(nd, f"{C.HERE}") |> <self>.emit;
|
|
134
131
|
}
|
|
135
132
|
if nd.return_type {
|
|
136
133
|
(nd, f" -> {nd.return_type.meta['py_code']}") |> <self>.emit;
|