jaclang 0.8.0__py3-none-any.whl → 0.8.1__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 +11 -9
- jaclang/compiler/jac.lark +2 -12
- jaclang/compiler/larkparse/jac_parser.py +1 -1
- jaclang/compiler/parser.py +360 -521
- jaclang/compiler/passes/main/cfg_build_pass.py +2 -2
- jaclang/compiler/passes/main/def_impl_match_pass.py +14 -13
- jaclang/compiler/passes/main/def_use_pass.py +4 -7
- jaclang/compiler/passes/main/import_pass.py +3 -3
- jaclang/compiler/passes/main/inheritance_pass.py +2 -2
- jaclang/compiler/passes/main/pyast_gen_pass.py +196 -218
- jaclang/compiler/passes/main/pyast_load_pass.py +115 -311
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +8 -7
- jaclang/compiler/passes/main/sym_tab_build_pass.py +3 -3
- jaclang/compiler/passes/main/sym_tab_link_pass.py +4 -4
- jaclang/compiler/passes/main/tests/fixtures/symtab_link_tests/action/actions.jac +1 -5
- jaclang/compiler/passes/main/tests/fixtures/symtab_link_tests/main.jac +1 -8
- jaclang/compiler/passes/main/tests/test_cfg_build_pass.py +4 -2
- jaclang/compiler/passes/tool/doc_ir_gen_pass.py +197 -120
- jaclang/compiler/program.py +2 -7
- jaclang/compiler/tests/fixtures/fam.jac +2 -2
- jaclang/compiler/tests/fixtures/pkg_import_lib/__init__.jac +1 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib/sub/__init__.jac +1 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib/sub/helper.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib/tools.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/__init__.py +11 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/__init__.py +7 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/helper.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/tools.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_main.jac +10 -0
- jaclang/compiler/tests/fixtures/pkg_import_main_py.jac +11 -0
- jaclang/compiler/tests/test_importer.py +20 -0
- jaclang/compiler/tests/test_parser.py +1 -0
- jaclang/compiler/unitree.py +456 -304
- jaclang/langserve/engine.jac +498 -0
- jaclang/langserve/sem_manager.jac +309 -0
- jaclang/langserve/server.jac +186 -0
- jaclang/langserve/tests/server_test/test_lang_serve.py +6 -7
- jaclang/langserve/tests/server_test/utils.py +4 -1
- jaclang/langserve/tests/session.jac +294 -0
- jaclang/langserve/tests/test_sem_tokens.py +2 -2
- jaclang/langserve/tests/test_server.py +12 -7
- jaclang/langserve/utils.jac +51 -30
- jaclang/runtimelib/archetype.py +1 -1
- jaclang/runtimelib/builtin.py +17 -14
- jaclang/runtimelib/importer.py +26 -8
- jaclang/runtimelib/machine.py +96 -55
- jaclang/runtimelib/tests/fixtures/traversing_save.jac +7 -5
- jaclang/runtimelib/utils.py +3 -3
- jaclang/tests/fixtures/backward_edge_visit.jac +31 -0
- jaclang/tests/fixtures/builtin_printgraph.jac +85 -0
- jaclang/tests/fixtures/builtin_printgraph_json.jac +21 -0
- jaclang/tests/fixtures/builtin_printgraph_mermaid.jac +16 -0
- jaclang/tests/fixtures/chandra_bugs2.jac +20 -13
- jaclang/tests/fixtures/concurrency.jac +1 -1
- jaclang/tests/fixtures/edge_ability.jac +49 -0
- jaclang/tests/fixtures/guess_game.jac +1 -1
- jaclang/tests/fixtures/here_usage_error.jac +21 -0
- jaclang/tests/fixtures/here_visitor_usage.jac +21 -0
- jaclang/tests/fixtures/node_del.jac +30 -36
- jaclang/tests/fixtures/visit_traversal.jac +47 -0
- jaclang/tests/test_cli.py +12 -7
- jaclang/tests/test_language.py +91 -16
- jaclang/utils/helpers.py +14 -6
- jaclang/utils/lang_tools.py +2 -3
- jaclang/utils/tests/test_lang_tools.py +2 -1
- jaclang/utils/treeprinter.py +3 -4
- {jaclang-0.8.0.dist-info → jaclang-0.8.1.dist-info}/METADATA +4 -3
- {jaclang-0.8.0.dist-info → jaclang-0.8.1.dist-info}/RECORD +71 -55
- {jaclang-0.8.0.dist-info → jaclang-0.8.1.dist-info}/WHEEL +1 -1
- jaclang/langserve/engine.py +0 -553
- jaclang/langserve/sem_manager.py +0 -383
- jaclang/langserve/server.py +0 -167
- jaclang/langserve/tests/session.py +0 -255
- jaclang/tests/fixtures/builtin_dotgen.jac +0 -42
- jaclang/tests/fixtures/builtin_dotgen_json.jac +0 -21
- /jaclang/langserve/{__init__.py → __init__.jac} +0 -0
- {jaclang-0.8.0.dist-info → jaclang-0.8.1.dist-info}/entry_points.txt +0 -0
|
@@ -14,6 +14,7 @@ relationships between the two AST representations throughout the compilation pro
|
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
import ast as ast3
|
|
17
|
+
from typing import Sequence
|
|
17
18
|
|
|
18
19
|
import jaclang.compiler.unitree as uni
|
|
19
20
|
from jaclang.compiler.passes import UniPass
|
|
@@ -50,7 +51,7 @@ class PyJacAstLinkPass(UniPass):
|
|
|
50
51
|
self.link_jac_py_nodes(jac_node=node.body, py_nodes=node.gen.py_ast)
|
|
51
52
|
|
|
52
53
|
def exit_impl_def(self, node: uni.ImplDef) -> None:
|
|
53
|
-
for i in node.target
|
|
54
|
+
for i in node.target:
|
|
54
55
|
if i.name_spec.name_of.sym:
|
|
55
56
|
self.link_jac_py_nodes(
|
|
56
57
|
jac_node=i, py_nodes=i.name_spec.name_of.sym.decl.gen.py_ast
|
|
@@ -62,12 +63,12 @@ class PyJacAstLinkPass(UniPass):
|
|
|
62
63
|
|
|
63
64
|
if isinstance(node.decl_link, uni.Ability) and node.decl_link.signature:
|
|
64
65
|
if isinstance(node.spec, uni.FuncSignature) and node.spec.params:
|
|
65
|
-
for src_prm in node.spec.params
|
|
66
|
+
for src_prm in node.spec.params:
|
|
66
67
|
if (
|
|
67
68
|
isinstance(node.decl_link.signature, uni.FuncSignature)
|
|
68
69
|
and node.decl_link.signature.params
|
|
69
70
|
):
|
|
70
|
-
for trg_prm in node.decl_link.signature.params
|
|
71
|
+
for trg_prm in node.decl_link.signature.params:
|
|
71
72
|
if src_prm.name.sym_name == trg_prm.name.sym_name:
|
|
72
73
|
self.link_jac_py_nodes(
|
|
73
74
|
jac_node=src_prm, py_nodes=trg_prm.gen.py_ast
|
|
@@ -88,9 +89,9 @@ class PyJacAstLinkPass(UniPass):
|
|
|
88
89
|
)
|
|
89
90
|
|
|
90
91
|
if isinstance(node.decl_link, uni.Ability) and isinstance(
|
|
91
|
-
node.target,
|
|
92
|
+
node.target, Sequence
|
|
92
93
|
):
|
|
93
|
-
for arch in node.target
|
|
94
|
+
for arch in node.target:
|
|
94
95
|
if arch.name_spec.name_of.sym:
|
|
95
96
|
arch.name_spec.name_of.sym.add_use(arch.name_spec)
|
|
96
97
|
|
|
@@ -107,11 +108,11 @@ class PyJacAstLinkPass(UniPass):
|
|
|
107
108
|
self.link_jac_py_nodes(jac_node=node.alias, py_nodes=node.gen.py_ast)
|
|
108
109
|
|
|
109
110
|
def exit_global_stmt(self, node: uni.GlobalStmt) -> None:
|
|
110
|
-
for x, y in enumerate(node.target
|
|
111
|
+
for x, y in enumerate(node.target):
|
|
111
112
|
self.link_jac_py_nodes(jac_node=y, py_nodes=[node.gen.py_ast[x]])
|
|
112
113
|
|
|
113
114
|
def exit_non_local_stmt(self, node: uni.NonLocalStmt) -> None:
|
|
114
|
-
for x, y in enumerate(node.target
|
|
115
|
+
for x, y in enumerate(node.target):
|
|
115
116
|
self.link_jac_py_nodes(jac_node=y, py_nodes=[node.gen.py_ast[x]])
|
|
116
117
|
|
|
117
118
|
def exit_k_w_pair(self, node: uni.KWPair) -> None:
|
|
@@ -54,7 +54,7 @@ class SymTabBuildPass(UniPass):
|
|
|
54
54
|
|
|
55
55
|
def exit_global_vars(self, node: uni.GlobalVars) -> None:
|
|
56
56
|
for i in self.get_all_sub_nodes(node, uni.Assignment):
|
|
57
|
-
for j in i.target
|
|
57
|
+
for j in i.target:
|
|
58
58
|
if isinstance(j, uni.AstSymbolNode):
|
|
59
59
|
j.sym_tab.def_insert(j, access_spec=node, single_decl="global var")
|
|
60
60
|
else:
|
|
@@ -75,12 +75,12 @@ class SymTabBuildPass(UniPass):
|
|
|
75
75
|
def exit_module_path(self, node: uni.ModulePath) -> None:
|
|
76
76
|
if node.alias:
|
|
77
77
|
node.alias.sym_tab.def_insert(node.alias, single_decl="import")
|
|
78
|
-
elif node.path and isinstance(node.path
|
|
78
|
+
elif node.path and isinstance(node.path[0], uni.Name):
|
|
79
79
|
if node.parent_of_type(uni.Import) and not (
|
|
80
80
|
node.parent_of_type(uni.Import).from_loc
|
|
81
81
|
and node.parent_of_type(uni.Import).is_jac
|
|
82
82
|
):
|
|
83
|
-
node.path
|
|
83
|
+
node.path[0].sym_tab.def_insert(node.path[0])
|
|
84
84
|
else:
|
|
85
85
|
pass # Need to support pythonic import symbols with dots in it
|
|
86
86
|
|
|
@@ -97,15 +97,15 @@ class SymTabLinkPass(Transform[uni.Module, uni.Module]):
|
|
|
97
97
|
|
|
98
98
|
def _is_all_import(self, imp_node: uni.Import, node: uni.ModulePath) -> bool:
|
|
99
99
|
"""Determine if this is an all import (import everything from module)."""
|
|
100
|
-
return (
|
|
101
|
-
imp_node.
|
|
102
|
-
)
|
|
100
|
+
return (imp_node.is_jac and node in imp_node.items) or (
|
|
101
|
+
imp_node.is_py and imp_node.from_loc is None and not imp_node.is_absorb
|
|
102
|
+
)
|
|
103
103
|
|
|
104
104
|
def _get_imported_symbols(self, node: uni.ModulePath) -> list[str]:
|
|
105
105
|
"""Get list of specific symbols being imported."""
|
|
106
106
|
symbols = []
|
|
107
107
|
if node.parent and isinstance(node.parent, uni.Import):
|
|
108
|
-
for mod_items in node.parent.items
|
|
108
|
+
for mod_items in node.parent.items:
|
|
109
109
|
if isinstance(mod_items, uni.ModuleItem):
|
|
110
110
|
symbols.append(mod_items.name.value)
|
|
111
111
|
return symbols
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
node LLM{
|
|
4
2
|
|
|
5
3
|
can infer with AgentNode entry{
|
|
@@ -9,15 +7,13 @@ node LLM{
|
|
|
9
7
|
def testing_infer {
|
|
10
8
|
return "LLM's response";
|
|
11
9
|
}
|
|
12
|
-
|
|
13
10
|
}
|
|
14
11
|
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
walker Agent{
|
|
17
14
|
has describ :str = "AgentNode";
|
|
18
15
|
|
|
19
16
|
can connect with LLM entry{
|
|
20
17
|
return "AgentNode's response";
|
|
21
|
-
|
|
22
18
|
}
|
|
23
19
|
}
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
from jaclang.compiler.passes.main import CompilerMode as CMode
|
|
4
4
|
from jaclang.compiler.program import JacProgram
|
|
5
5
|
from jaclang.utils.test import TestCase
|
|
6
|
+
import unittest
|
|
6
7
|
|
|
7
8
|
|
|
9
|
+
@unittest.skip("Skipping CFG build pass tests")
|
|
8
10
|
class TestCFGBuildPass(TestCase):
|
|
9
11
|
"""Test FuseTypeInfoPass module."""
|
|
10
12
|
|
|
@@ -30,7 +32,7 @@ class TestCFGBuildPass(TestCase):
|
|
|
30
32
|
prog=prog,
|
|
31
33
|
)
|
|
32
34
|
|
|
33
|
-
dot = cfg_pass.
|
|
35
|
+
dot = cfg_pass.printgraph_cfg()
|
|
34
36
|
|
|
35
37
|
expected_dot = (
|
|
36
38
|
"digraph G {\n"
|
|
@@ -78,7 +80,7 @@ class TestCFGBuildPass(TestCase):
|
|
|
78
80
|
prog=prog,
|
|
79
81
|
)
|
|
80
82
|
|
|
81
|
-
dot = cfg_pass.
|
|
83
|
+
dot = cfg_pass.printgraph_cfg()
|
|
82
84
|
|
|
83
85
|
expected_dot = (
|
|
84
86
|
"digraph G {\n"
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
This is a pass for generating DocIr for Jac code.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
from typing import List, Optional
|
|
6
|
+
from typing import List, Optional, Sequence
|
|
7
7
|
|
|
8
8
|
import jaclang.compiler.passes.tool.doc_ir as doc
|
|
9
9
|
import jaclang.compiler.unitree as uni
|
|
@@ -139,12 +139,7 @@ class DocIRGenPass(UniPass):
|
|
|
139
139
|
"""Exit import node."""
|
|
140
140
|
parts: list[doc.DocType] = []
|
|
141
141
|
for i in node.kid:
|
|
142
|
-
if isinstance(i, uni.
|
|
143
|
-
parts.append(
|
|
144
|
-
self.indent(self.concat([self.tight_line(), i.gen.doc_ir]))
|
|
145
|
-
)
|
|
146
|
-
parts.append(self.line())
|
|
147
|
-
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
142
|
+
if isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
148
143
|
parts.pop()
|
|
149
144
|
parts.append(i.gen.doc_ir)
|
|
150
145
|
else:
|
|
@@ -179,13 +174,38 @@ class DocIRGenPass(UniPass):
|
|
|
179
174
|
def exit_archetype(self, node: uni.Archetype) -> None:
|
|
180
175
|
"""Generate DocIR for archetypes."""
|
|
181
176
|
parts: list[doc.DocType] = []
|
|
177
|
+
body_parts: list[doc.DocType] = []
|
|
178
|
+
prev_item = None
|
|
179
|
+
in_body = False
|
|
182
180
|
for i in node.kid:
|
|
183
|
-
if i
|
|
181
|
+
if (node.doc and i is node.doc) or (
|
|
182
|
+
node.decorators and i in node.decorators
|
|
183
|
+
):
|
|
184
184
|
parts.append(i.gen.doc_ir)
|
|
185
185
|
parts.append(self.hard_line())
|
|
186
186
|
elif i == node.name:
|
|
187
187
|
parts.append(i.gen.doc_ir)
|
|
188
188
|
parts.append(self.space())
|
|
189
|
+
elif isinstance(i, uni.Token) and i.name == Tok.LBRACE:
|
|
190
|
+
parts.append(i.gen.doc_ir)
|
|
191
|
+
elif isinstance(node.body, Sequence) and i in node.body:
|
|
192
|
+
if not in_body:
|
|
193
|
+
body_parts.append(self.hard_line())
|
|
194
|
+
if (prev_item and type(prev_item) is not type(i)) or (
|
|
195
|
+
prev_item and not self.is_one_line(prev_item)
|
|
196
|
+
):
|
|
197
|
+
body_parts.append(self.hard_line())
|
|
198
|
+
body_parts.append(i.gen.doc_ir)
|
|
199
|
+
body_parts.append(self.hard_line())
|
|
200
|
+
prev_item = i
|
|
201
|
+
in_body = True
|
|
202
|
+
elif in_body:
|
|
203
|
+
in_body = False
|
|
204
|
+
body_parts.pop()
|
|
205
|
+
parts.append(self.indent(self.concat(body_parts)))
|
|
206
|
+
parts.append(self.hard_line())
|
|
207
|
+
parts.append(i.gen.doc_ir)
|
|
208
|
+
parts.append(self.space())
|
|
189
209
|
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
190
210
|
parts.pop()
|
|
191
211
|
parts.append(i.gen.doc_ir)
|
|
@@ -193,39 +213,72 @@ class DocIRGenPass(UniPass):
|
|
|
193
213
|
else:
|
|
194
214
|
parts.append(i.gen.doc_ir)
|
|
195
215
|
parts.append(self.space())
|
|
216
|
+
|
|
196
217
|
node.gen.doc_ir = self.finalize(parts)
|
|
197
218
|
|
|
198
219
|
def exit_ability(self, node: uni.Ability) -> None:
|
|
199
220
|
"""Generate DocIR for abilities."""
|
|
200
221
|
parts: list[doc.DocType] = []
|
|
222
|
+
body_parts: list[doc.DocType] = []
|
|
223
|
+
in_body = False
|
|
201
224
|
for i in node.kid:
|
|
202
|
-
if i
|
|
225
|
+
if i == node.doc or (node.decorators and i in node.decorators):
|
|
203
226
|
parts.append(i.gen.doc_ir)
|
|
204
227
|
parts.append(self.hard_line())
|
|
205
228
|
elif i == node.name_ref:
|
|
206
229
|
parts.append(i.gen.doc_ir)
|
|
207
230
|
if not isinstance(node.signature, uni.FuncSignature):
|
|
208
231
|
parts.append(self.space())
|
|
232
|
+
elif isinstance(node.body, Sequence) and i in node.body:
|
|
233
|
+
if not in_body:
|
|
234
|
+
parts.pop()
|
|
235
|
+
body_parts.append(self.hard_line())
|
|
236
|
+
body_parts.append(i.gen.doc_ir)
|
|
237
|
+
body_parts.append(self.hard_line())
|
|
238
|
+
in_body = True
|
|
239
|
+
elif in_body:
|
|
240
|
+
in_body = False
|
|
241
|
+
body_parts.pop()
|
|
242
|
+
parts.append(self.indent(self.concat(body_parts)))
|
|
243
|
+
parts.append(self.hard_line())
|
|
244
|
+
parts.append(i.gen.doc_ir)
|
|
245
|
+
parts.append(self.space())
|
|
209
246
|
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
210
247
|
parts.pop()
|
|
211
248
|
parts.append(i.gen.doc_ir)
|
|
249
|
+
parts.append(self.space())
|
|
212
250
|
else:
|
|
213
251
|
parts.append(i.gen.doc_ir)
|
|
214
|
-
|
|
215
|
-
parts.append(self.space())
|
|
252
|
+
parts.append(self.space())
|
|
216
253
|
node.gen.doc_ir = self.finalize(parts)
|
|
217
254
|
|
|
218
255
|
def exit_func_signature(self, node: uni.FuncSignature) -> None:
|
|
219
256
|
"""Generate DocIR for function signatures."""
|
|
220
257
|
parts: list[doc.DocType] = []
|
|
258
|
+
indent_parts: list[doc.DocType] = []
|
|
259
|
+
in_params = False
|
|
221
260
|
for i in node.kid:
|
|
222
|
-
if isinstance(i, uni.Token) and i.name == Tok.LPAREN:
|
|
261
|
+
if isinstance(i, uni.Token) and i.name == Tok.LPAREN and node.params:
|
|
262
|
+
in_params = True
|
|
223
263
|
parts.append(i.gen.doc_ir)
|
|
224
|
-
elif i == node.params:
|
|
264
|
+
elif isinstance(i, uni.Token) and i.name == Tok.RPAREN and node.params:
|
|
265
|
+
in_params = False
|
|
225
266
|
parts.append(
|
|
226
|
-
self.indent(self.concat([self.tight_line(),
|
|
267
|
+
self.indent(self.concat([self.tight_line(), *indent_parts]))
|
|
227
268
|
)
|
|
228
269
|
parts.append(self.tight_line())
|
|
270
|
+
parts.append(i.gen.doc_ir)
|
|
271
|
+
parts.append(self.space())
|
|
272
|
+
elif isinstance(i, uni.Token) and i.name == Tok.RPAREN:
|
|
273
|
+
parts.pop()
|
|
274
|
+
parts.append(i.gen.doc_ir)
|
|
275
|
+
parts.append(self.space())
|
|
276
|
+
elif in_params:
|
|
277
|
+
if isinstance(i, uni.Token) and i.name == Tok.COMMA:
|
|
278
|
+
indent_parts.append(i.gen.doc_ir)
|
|
279
|
+
indent_parts.append(self.space())
|
|
280
|
+
else:
|
|
281
|
+
indent_parts.append(i.gen.doc_ir)
|
|
229
282
|
else:
|
|
230
283
|
parts.append(i.gen.doc_ir)
|
|
231
284
|
parts.append(self.space())
|
|
@@ -254,7 +307,7 @@ class DocIRGenPass(UniPass):
|
|
|
254
307
|
"""Generate DocIR for assignments."""
|
|
255
308
|
parts: list[doc.DocType] = []
|
|
256
309
|
for i in node.kid:
|
|
257
|
-
if isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
310
|
+
if i == node.type_tag or (isinstance(i, uni.Token) and i.name == Tok.SEMI):
|
|
258
311
|
parts.pop()
|
|
259
312
|
parts.append(i.gen.doc_ir)
|
|
260
313
|
parts.append(self.space())
|
|
@@ -266,25 +319,88 @@ class DocIRGenPass(UniPass):
|
|
|
266
319
|
def exit_if_stmt(self, node: uni.IfStmt) -> None:
|
|
267
320
|
"""Generate DocIR for if statements."""
|
|
268
321
|
parts: list[doc.DocType] = []
|
|
322
|
+
body_parts: list[doc.DocType] = []
|
|
323
|
+
in_body = False
|
|
269
324
|
for i in node.kid:
|
|
270
|
-
|
|
271
|
-
|
|
325
|
+
if isinstance(node.body, Sequence) and i in node.body:
|
|
326
|
+
if not in_body:
|
|
327
|
+
parts.pop()
|
|
328
|
+
body_parts.append(self.hard_line())
|
|
329
|
+
body_parts.append(i.gen.doc_ir)
|
|
330
|
+
body_parts.append(self.hard_line())
|
|
331
|
+
in_body = True
|
|
332
|
+
elif in_body:
|
|
333
|
+
in_body = False
|
|
334
|
+
body_parts.pop()
|
|
335
|
+
parts.append(self.indent(self.concat(body_parts)))
|
|
336
|
+
parts.append(self.hard_line())
|
|
337
|
+
parts.append(i.gen.doc_ir)
|
|
338
|
+
parts.append(self.space())
|
|
339
|
+
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
340
|
+
parts.pop()
|
|
341
|
+
parts.append(i.gen.doc_ir)
|
|
342
|
+
parts.append(self.space())
|
|
343
|
+
else:
|
|
344
|
+
parts.append(i.gen.doc_ir)
|
|
345
|
+
parts.append(self.space())
|
|
272
346
|
node.gen.doc_ir = self.finalize(parts)
|
|
273
347
|
|
|
274
348
|
def exit_else_if(self, node: uni.ElseIf) -> None:
|
|
275
349
|
"""Generate DocIR for else if statements."""
|
|
276
350
|
parts: list[doc.DocType] = []
|
|
351
|
+
body_parts: list[doc.DocType] = []
|
|
352
|
+
in_body = False
|
|
277
353
|
for i in node.kid:
|
|
278
|
-
|
|
279
|
-
|
|
354
|
+
if isinstance(node.body, Sequence) and i in node.body:
|
|
355
|
+
if not in_body:
|
|
356
|
+
parts.pop()
|
|
357
|
+
body_parts.append(self.hard_line())
|
|
358
|
+
body_parts.append(i.gen.doc_ir)
|
|
359
|
+
body_parts.append(self.hard_line())
|
|
360
|
+
in_body = True
|
|
361
|
+
elif in_body:
|
|
362
|
+
in_body = False
|
|
363
|
+
body_parts.pop()
|
|
364
|
+
parts.append(self.indent(self.concat(body_parts)))
|
|
365
|
+
parts.append(self.hard_line())
|
|
366
|
+
parts.append(i.gen.doc_ir)
|
|
367
|
+
parts.append(self.space())
|
|
368
|
+
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
369
|
+
parts.pop()
|
|
370
|
+
parts.append(i.gen.doc_ir)
|
|
371
|
+
parts.append(self.space())
|
|
372
|
+
else:
|
|
373
|
+
parts.append(i.gen.doc_ir)
|
|
374
|
+
parts.append(self.space())
|
|
280
375
|
node.gen.doc_ir = self.finalize(parts)
|
|
281
376
|
|
|
282
377
|
def exit_else_stmt(self, node: uni.ElseStmt) -> None:
|
|
283
378
|
"""Generate DocIR for else statements."""
|
|
284
379
|
parts: list[doc.DocType] = []
|
|
380
|
+
body_parts: list[doc.DocType] = []
|
|
381
|
+
in_body = False
|
|
285
382
|
for i in node.kid:
|
|
286
|
-
|
|
287
|
-
|
|
383
|
+
if isinstance(node.body, Sequence) and i in node.body:
|
|
384
|
+
if not in_body:
|
|
385
|
+
parts.pop()
|
|
386
|
+
body_parts.append(self.hard_line())
|
|
387
|
+
body_parts.append(i.gen.doc_ir)
|
|
388
|
+
body_parts.append(self.hard_line())
|
|
389
|
+
in_body = True
|
|
390
|
+
elif in_body:
|
|
391
|
+
in_body = False
|
|
392
|
+
body_parts.pop()
|
|
393
|
+
parts.append(self.indent(self.concat(body_parts)))
|
|
394
|
+
parts.append(self.hard_line())
|
|
395
|
+
parts.append(i.gen.doc_ir)
|
|
396
|
+
parts.append(self.space())
|
|
397
|
+
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
398
|
+
parts.pop()
|
|
399
|
+
parts.append(i.gen.doc_ir)
|
|
400
|
+
parts.append(self.space())
|
|
401
|
+
else:
|
|
402
|
+
parts.append(i.gen.doc_ir)
|
|
403
|
+
parts.append(self.space())
|
|
288
404
|
node.gen.doc_ir = self.finalize(parts)
|
|
289
405
|
|
|
290
406
|
def exit_binary_expr(self, node: uni.BinaryExpr) -> None:
|
|
@@ -298,18 +414,8 @@ class DocIRGenPass(UniPass):
|
|
|
298
414
|
def exit_expr_stmt(self, node: uni.ExprStmt) -> None:
|
|
299
415
|
"""Generate DocIR for expression statements."""
|
|
300
416
|
parts: list[doc.DocType] = []
|
|
301
|
-
is_fstring = (
|
|
302
|
-
node.parent
|
|
303
|
-
and isinstance(node.parent, uni.SubNodeList)
|
|
304
|
-
and node.parent.parent
|
|
305
|
-
and isinstance(node.parent.parent, uni.FString)
|
|
306
|
-
)
|
|
307
417
|
for i in node.kid:
|
|
308
|
-
if is_fstring:
|
|
309
|
-
parts.append(self.text("{"))
|
|
310
418
|
parts.append(i.gen.doc_ir)
|
|
311
|
-
if is_fstring:
|
|
312
|
-
parts.append(self.text("}"))
|
|
313
419
|
node.gen.doc_ir = self.group(self.concat(parts))
|
|
314
420
|
|
|
315
421
|
def exit_concurrent_expr(self, node: uni.ConcurrentExpr) -> None:
|
|
@@ -335,8 +441,27 @@ class DocIRGenPass(UniPass):
|
|
|
335
441
|
def exit_func_call(self, node: uni.FuncCall) -> None:
|
|
336
442
|
"""Generate DocIR for function calls."""
|
|
337
443
|
parts: list[doc.DocType] = []
|
|
444
|
+
indent_parts: list[doc.DocType] = []
|
|
445
|
+
in_params = False
|
|
338
446
|
for i in node.kid:
|
|
339
|
-
|
|
447
|
+
if isinstance(i, uni.Token) and i.name == Tok.LPAREN and node.params:
|
|
448
|
+
in_params = True
|
|
449
|
+
parts.append(i.gen.doc_ir)
|
|
450
|
+
elif isinstance(i, uni.Token) and i.name == Tok.RPAREN and node.params:
|
|
451
|
+
in_params = False
|
|
452
|
+
parts.append(
|
|
453
|
+
self.indent(self.concat([self.tight_line(), *indent_parts]))
|
|
454
|
+
)
|
|
455
|
+
parts.append(self.tight_line())
|
|
456
|
+
parts.append(i.gen.doc_ir)
|
|
457
|
+
elif in_params:
|
|
458
|
+
if isinstance(i, uni.Token) and i.name == Tok.COMMA:
|
|
459
|
+
indent_parts.append(i.gen.doc_ir)
|
|
460
|
+
indent_parts.append(self.space())
|
|
461
|
+
else:
|
|
462
|
+
indent_parts.append(i.gen.doc_ir)
|
|
463
|
+
else:
|
|
464
|
+
parts.append(i.gen.doc_ir)
|
|
340
465
|
node.gen.doc_ir = self.group(self.concat(parts))
|
|
341
466
|
|
|
342
467
|
def exit_atom_trailer(self, node: uni.AtomTrailer) -> None:
|
|
@@ -395,12 +520,10 @@ class DocIRGenPass(UniPass):
|
|
|
395
520
|
if i == node.doc:
|
|
396
521
|
parts.append(i.gen.doc_ir)
|
|
397
522
|
parts.append(self.hard_line())
|
|
398
|
-
elif (
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
):
|
|
403
|
-
parts.append(self.align(i.gen.doc_ir))
|
|
523
|
+
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
524
|
+
parts.pop()
|
|
525
|
+
parts.append(i.gen.doc_ir)
|
|
526
|
+
parts.append(self.space())
|
|
404
527
|
else:
|
|
405
528
|
parts.append(i.gen.doc_ir)
|
|
406
529
|
parts.append(self.space())
|
|
@@ -472,12 +595,7 @@ class DocIRGenPass(UniPass):
|
|
|
472
595
|
"""Generate DocIR for set values."""
|
|
473
596
|
parts: list[doc.DocType] = []
|
|
474
597
|
for i in node.kid:
|
|
475
|
-
|
|
476
|
-
parts.append(i.gen.doc_ir)
|
|
477
|
-
elif isinstance(i, uni.SubNodeList):
|
|
478
|
-
parts.append(self.if_break(self.line(), self.space()))
|
|
479
|
-
parts.append(i.gen.doc_ir)
|
|
480
|
-
parts.append(self.if_break(self.line(), self.space()))
|
|
598
|
+
parts.append(i.gen.doc_ir)
|
|
481
599
|
|
|
482
600
|
node.gen.doc_ir = self.group(self.concat(parts))
|
|
483
601
|
|
|
@@ -722,21 +840,40 @@ class DocIRGenPass(UniPass):
|
|
|
722
840
|
def exit_module_code(self, node: uni.ModuleCode) -> None:
|
|
723
841
|
"""Generate DocIR for module code."""
|
|
724
842
|
parts: list[doc.DocType] = []
|
|
843
|
+
body_parts: list[doc.DocType] = []
|
|
844
|
+
in_body = False
|
|
725
845
|
for i in node.kid:
|
|
726
|
-
if i
|
|
846
|
+
if node.doc and i is node.doc:
|
|
727
847
|
parts.append(i.gen.doc_ir)
|
|
728
848
|
parts.append(self.hard_line())
|
|
729
|
-
elif
|
|
849
|
+
elif i == node.name:
|
|
850
|
+
parts.append(i.gen.doc_ir)
|
|
851
|
+
parts.append(self.space())
|
|
852
|
+
elif isinstance(node.body, Sequence) and i in node.body:
|
|
853
|
+
if not in_body:
|
|
854
|
+
parts.pop()
|
|
855
|
+
body_parts.append(self.hard_line())
|
|
856
|
+
body_parts.append(i.gen.doc_ir)
|
|
857
|
+
body_parts.append(self.hard_line())
|
|
858
|
+
in_body = True
|
|
859
|
+
elif in_body:
|
|
860
|
+
in_body = False
|
|
861
|
+
body_parts.pop()
|
|
862
|
+
parts.append(self.indent(self.concat(body_parts)))
|
|
863
|
+
parts.append(self.hard_line())
|
|
864
|
+
parts.append(i.gen.doc_ir)
|
|
865
|
+
parts.append(self.space())
|
|
866
|
+
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
867
|
+
parts.pop()
|
|
730
868
|
parts.append(i.gen.doc_ir)
|
|
731
869
|
parts.append(self.space())
|
|
732
870
|
else:
|
|
733
|
-
parts.append(
|
|
734
|
-
|
|
735
|
-
node.gen.doc_ir = self.
|
|
871
|
+
parts.append(i.gen.doc_ir)
|
|
872
|
+
parts.append(self.space())
|
|
873
|
+
node.gen.doc_ir = self.finalize(parts)
|
|
736
874
|
|
|
737
875
|
def exit_global_stmt(self, node: uni.GlobalStmt) -> None:
|
|
738
876
|
"""Generate DocIR for global statements."""
|
|
739
|
-
# node.kid is [GLOBAL_OP_token, name_list_SubNodeList, SEMI_token]
|
|
740
877
|
parts: list[doc.DocType] = []
|
|
741
878
|
for i in node.kid:
|
|
742
879
|
parts.append(i.gen.doc_ir)
|
|
@@ -1000,15 +1137,20 @@ class DocIRGenPass(UniPass):
|
|
|
1000
1137
|
"""Generate DocIR for match architecture patterns."""
|
|
1001
1138
|
parts: list[doc.DocType] = []
|
|
1002
1139
|
for i in node.kid:
|
|
1003
|
-
|
|
1004
|
-
|
|
1140
|
+
if isinstance(i, uni.Token) and i.name == Tok.COMMA:
|
|
1141
|
+
parts.append(i.gen.doc_ir)
|
|
1142
|
+
parts.append(self.space())
|
|
1143
|
+
else:
|
|
1144
|
+
parts.append(i.gen.doc_ir)
|
|
1005
1145
|
node.gen.doc_ir = self.finalize(parts)
|
|
1006
1146
|
|
|
1007
1147
|
def exit_enum(self, node: uni.Enum) -> None:
|
|
1008
1148
|
"""Generate DocIR for enum declarations."""
|
|
1009
1149
|
parts: list[doc.DocType] = []
|
|
1010
1150
|
for i in node.kid:
|
|
1011
|
-
if i
|
|
1151
|
+
if (node.doc and i is node.doc) or (
|
|
1152
|
+
node.decorators and i in node.decorators
|
|
1153
|
+
):
|
|
1012
1154
|
parts.append(i.gen.doc_ir)
|
|
1013
1155
|
parts.append(self.hard_line())
|
|
1014
1156
|
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
@@ -1028,74 +1170,11 @@ class DocIRGenPass(UniPass):
|
|
|
1028
1170
|
parts.append(self.space())
|
|
1029
1171
|
node.gen.doc_ir = self.finalize(parts)
|
|
1030
1172
|
|
|
1031
|
-
def exit_sub_node_list(self, node: uni.SubNodeList) -> None:
|
|
1032
|
-
"""Generate DocIR for a SubNodeList."""
|
|
1033
|
-
parts: list[doc.DocType] = []
|
|
1034
|
-
indent_parts: list[doc.DocType] = []
|
|
1035
|
-
prev_item: Optional[uni.UniNode] = None
|
|
1036
|
-
in_codeblock = node.delim and node.delim.name == Tok.WS
|
|
1037
|
-
in_archetype = (
|
|
1038
|
-
node.parent
|
|
1039
|
-
and isinstance(node.parent, (uni.Archetype, uni.Enum))
|
|
1040
|
-
and node == node.parent.body
|
|
1041
|
-
)
|
|
1042
|
-
is_assignment = node.delim and node.delim.name == Tok.EQ
|
|
1043
|
-
for i in node.kid:
|
|
1044
|
-
if i == node.left_enc:
|
|
1045
|
-
parts.append(i.gen.doc_ir)
|
|
1046
|
-
indent_parts.append(self.hard_line())
|
|
1047
|
-
elif i == node.right_enc:
|
|
1048
|
-
if in_codeblock:
|
|
1049
|
-
indent_parts.pop()
|
|
1050
|
-
parts.append(self.indent(self.concat(indent_parts)))
|
|
1051
|
-
if prev_item != node.left_enc:
|
|
1052
|
-
parts.append(self.line())
|
|
1053
|
-
parts.append(i.gen.doc_ir)
|
|
1054
|
-
elif (
|
|
1055
|
-
isinstance(i, uni.Token)
|
|
1056
|
-
and node.delim
|
|
1057
|
-
and i.name == node.delim.name
|
|
1058
|
-
and i.name not in [Tok.DOT, Tok.DECOR_OP]
|
|
1059
|
-
):
|
|
1060
|
-
indent_parts.append(i.gen.doc_ir)
|
|
1061
|
-
indent_parts.append(self.line())
|
|
1062
|
-
else:
|
|
1063
|
-
if (
|
|
1064
|
-
in_codeblock
|
|
1065
|
-
and prev_item
|
|
1066
|
-
and self.has_gap(prev_item, i)
|
|
1067
|
-
and isinstance(i, uni.CommentToken)
|
|
1068
|
-
and (
|
|
1069
|
-
not in_archetype
|
|
1070
|
-
or not prev_item
|
|
1071
|
-
or not (
|
|
1072
|
-
self.is_one_line(prev_item) and type(prev_item) is type(i)
|
|
1073
|
-
)
|
|
1074
|
-
)
|
|
1075
|
-
) or (
|
|
1076
|
-
in_archetype
|
|
1077
|
-
and prev_item not in [None, node.left_enc, node.right_enc]
|
|
1078
|
-
and (
|
|
1079
|
-
type(prev_item) is not type(i)
|
|
1080
|
-
or (prev_item and not self.is_one_line(prev_item))
|
|
1081
|
-
)
|
|
1082
|
-
):
|
|
1083
|
-
indent_parts.append(self.hard_line())
|
|
1084
|
-
indent_parts.append(i.gen.doc_ir)
|
|
1085
|
-
if in_codeblock:
|
|
1086
|
-
indent_parts.append(self.hard_line())
|
|
1087
|
-
elif is_assignment:
|
|
1088
|
-
indent_parts.append(self.space())
|
|
1089
|
-
prev_item = i
|
|
1090
|
-
if is_assignment:
|
|
1091
|
-
indent_parts.pop()
|
|
1092
|
-
node.gen.doc_ir = self.concat(parts) if parts else self.concat(indent_parts)
|
|
1093
|
-
|
|
1094
1173
|
def exit_impl_def(self, node: uni.ImplDef) -> None:
|
|
1095
1174
|
"""Generate DocIR for implementation definitions."""
|
|
1096
1175
|
parts: list[doc.DocType] = []
|
|
1097
1176
|
for i in node.kid:
|
|
1098
|
-
if i
|
|
1177
|
+
if i == node.doc or (node.decorators and i in node.decorators):
|
|
1099
1178
|
parts.append(i.gen.doc_ir)
|
|
1100
1179
|
parts.append(self.hard_line())
|
|
1101
1180
|
elif i == node.target:
|
|
@@ -1154,9 +1233,7 @@ class DocIRGenPass(UniPass):
|
|
|
1154
1233
|
is_escaped_curly = (
|
|
1155
1234
|
node.lit_value in ["{", "}"]
|
|
1156
1235
|
and node.parent
|
|
1157
|
-
and isinstance(node.parent, uni.
|
|
1158
|
-
and node.parent.parent
|
|
1159
|
-
and isinstance(node.parent.parent, uni.FString)
|
|
1236
|
+
and isinstance(node.parent, uni.FString)
|
|
1160
1237
|
)
|
|
1161
1238
|
|
|
1162
1239
|
if "\n" in node.value:
|
jaclang/compiler/program.py
CHANGED
|
@@ -61,17 +61,12 @@ class JacProgram:
|
|
|
61
61
|
self.errors_had: list[Alert] = []
|
|
62
62
|
self.warnings_had: list[Alert] = []
|
|
63
63
|
|
|
64
|
-
def get_bytecode(
|
|
65
|
-
self, full_target: str, full_compile: bool = True
|
|
66
|
-
) -> Optional[types.CodeType]:
|
|
64
|
+
def get_bytecode(self, full_target: str) -> Optional[types.CodeType]:
|
|
67
65
|
"""Get the bytecode for a specific module."""
|
|
68
66
|
if full_target in self.mod.hub:
|
|
69
67
|
codeobj = self.mod.hub[full_target].gen.py_bytecode
|
|
70
68
|
return marshal.loads(codeobj) if isinstance(codeobj, bytes) else None
|
|
71
|
-
result = self.compile(
|
|
72
|
-
file_path=full_target,
|
|
73
|
-
mode=CompilerMode.COMPILE if full_compile else CompilerMode.COMPILE_SINGLE,
|
|
74
|
-
)
|
|
69
|
+
result = self.compile(file_path=full_target, mode=CompilerMode.COMPILE_SINGLE)
|
|
75
70
|
return marshal.loads(result.gen.py_bytecode) if result.gen.py_bytecode else None
|
|
76
71
|
|
|
77
72
|
def compile(
|