jaclang 0.7.14__py3-none-any.whl → 0.7.17__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 +147 -77
- jaclang/cli/cmdreg.py +9 -12
- jaclang/compiler/__init__.py +19 -53
- jaclang/compiler/absyntree.py +94 -16
- jaclang/compiler/constant.py +8 -8
- jaclang/compiler/jac.lark +4 -3
- jaclang/compiler/parser.py +41 -25
- jaclang/compiler/passes/ir_pass.py +4 -13
- jaclang/compiler/passes/main/__init__.py +1 -1
- jaclang/compiler/passes/main/access_modifier_pass.py +96 -147
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +155 -54
- jaclang/compiler/passes/main/import_pass.py +99 -75
- jaclang/compiler/passes/main/py_collect_dep_pass.py +70 -0
- jaclang/compiler/passes/main/pyast_gen_pass.py +328 -565
- jaclang/compiler/passes/main/pyast_load_pass.py +33 -6
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +7 -0
- jaclang/compiler/passes/main/registry_pass.py +37 -3
- jaclang/compiler/passes/main/schedules.py +9 -2
- jaclang/compiler/passes/main/sym_tab_build_pass.py +10 -6
- jaclang/compiler/passes/main/tests/__init__.py +1 -1
- jaclang/compiler/passes/main/tests/fixtures/autoimpl.empty.impl.jac +0 -0
- jaclang/compiler/passes/main/tests/fixtures/autoimpl.jac +1 -1
- jaclang/compiler/passes/main/tests/fixtures/py_imp_test.jac +29 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/__init__.py +3 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/color.py +3 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/constants.py +5 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/display.py +2 -0
- jaclang/compiler/passes/main/tests/test_import_pass.py +72 -13
- jaclang/compiler/passes/main/type_check_pass.py +22 -5
- jaclang/compiler/passes/tool/jac_formatter_pass.py +135 -89
- jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +37 -41
- jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +37 -42
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/access_mod_check.jac +27 -0
- 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/passes/utils/mypy_ast_build.py +45 -0
- jaclang/compiler/semtable.py +31 -7
- jaclang/compiler/symtable.py +16 -11
- jaclang/compiler/tests/test_importer.py +25 -10
- jaclang/langserve/engine.py +104 -118
- jaclang/langserve/sem_manager.py +379 -0
- jaclang/langserve/server.py +24 -11
- 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/fixtures/rename.jac +30 -0
- jaclang/langserve/tests/test_sem_tokens.py +277 -0
- jaclang/langserve/tests/test_server.py +287 -17
- jaclang/langserve/utils.py +184 -98
- jaclang/plugin/builtin.py +1 -1
- jaclang/plugin/default.py +288 -92
- jaclang/plugin/feature.py +65 -27
- jaclang/plugin/spec.py +62 -23
- jaclang/plugin/tests/fixtures/other_root_access.jac +82 -0
- jaclang/plugin/tests/test_jaseci.py +414 -42
- jaclang/runtimelib/architype.py +650 -0
- jaclang/{core → runtimelib}/constructs.py +5 -8
- jaclang/{core → runtimelib}/context.py +86 -59
- jaclang/runtimelib/importer.py +361 -0
- jaclang/runtimelib/machine.py +158 -0
- jaclang/runtimelib/memory.py +158 -0
- jaclang/{core → runtimelib}/utils.py +30 -15
- jaclang/settings.py +5 -4
- jaclang/tests/fixtures/abc.jac +3 -3
- jaclang/tests/fixtures/access_checker.jac +12 -17
- jaclang/tests/fixtures/access_modifier.jac +88 -33
- jaclang/tests/fixtures/baddy.jac +3 -0
- jaclang/tests/fixtures/baddy.test.jac +3 -0
- jaclang/tests/fixtures/bar.jac +34 -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/edge_node_walk.jac +1 -1
- jaclang/tests/fixtures/edge_ops.jac +1 -1
- jaclang/tests/fixtures/edges_walk.jac +1 -1
- jaclang/tests/fixtures/err.impl.jac +3 -0
- jaclang/tests/fixtures/err.jac +4 -2
- jaclang/tests/fixtures/err_runtime.jac +15 -0
- jaclang/tests/fixtures/foo.jac +43 -0
- jaclang/tests/fixtures/gendot_bubble_sort.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/import.jac +9 -0
- jaclang/tests/fixtures/index_slice.jac +30 -0
- 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_1.py +1 -1
- jaclang/tests/fixtures/pyfunc_2.py +5 -2
- jaclang/tests/fixtures/pygame_mock/__init__.py +3 -0
- jaclang/tests/fixtures/pygame_mock/color.py +3 -0
- jaclang/tests/fixtures/pygame_mock/constants.py +5 -0
- jaclang/tests/fixtures/pygame_mock/display.py +2 -0
- jaclang/tests/fixtures/pygame_mock/inner/__init__.py +0 -0
- jaclang/tests/fixtures/pygame_mock/inner/iner_mod.py +2 -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 +109 -3
- jaclang/tests/test_language.py +170 -68
- jaclang/tests/test_reference.py +2 -3
- jaclang/utils/helpers.py +45 -21
- jaclang/utils/test.py +9 -0
- jaclang/utils/treeprinter.py +30 -7
- {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/METADATA +3 -2
- {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/RECORD +126 -90
- jaclang/core/architype.py +0 -502
- jaclang/core/importer.py +0 -344
- jaclang/core/memory.py +0 -99
- 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}/test.py +0 -0
- {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/WHEEL +0 -0
- {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/entry_points.txt +0 -0
|
@@ -10,6 +10,7 @@ import jaclang.compiler.absyntree as ast
|
|
|
10
10
|
from jaclang.compiler.absyntree import AstNode
|
|
11
11
|
from jaclang.compiler.constant import Tokens as Tok
|
|
12
12
|
from jaclang.compiler.passes import Pass
|
|
13
|
+
from jaclang.settings import settings
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
class JacFormatPass(Pass):
|
|
@@ -20,7 +21,7 @@ class JacFormatPass(Pass):
|
|
|
20
21
|
self.comments: list[ast.CommentToken] = []
|
|
21
22
|
self.indent_size = 4
|
|
22
23
|
self.indent_level = 0
|
|
23
|
-
self.MAX_LINE_LENGTH =
|
|
24
|
+
self.MAX_LINE_LENGTH = int(float(settings.max_line_length) / 2)
|
|
24
25
|
|
|
25
26
|
def enter_node(self, node: ast.AstNode) -> None:
|
|
26
27
|
"""Enter node."""
|
|
@@ -49,7 +50,8 @@ class JacFormatPass(Pass):
|
|
|
49
50
|
|
|
50
51
|
def emit(self, node: ast.AstNode, s: str, strip_mode: bool = True) -> None:
|
|
51
52
|
"""Emit code to node."""
|
|
52
|
-
|
|
53
|
+
indented_str = re.sub(r"\n(?!\n)", f"\n{self.indent_str()}", s)
|
|
54
|
+
node.gen.jac += self.indent_str() + indented_str
|
|
53
55
|
if "\n" in node.gen.jac:
|
|
54
56
|
if strip_mode:
|
|
55
57
|
node.gen.jac = node.gen.jac.rstrip(" ")
|
|
@@ -129,9 +131,15 @@ class JacFormatPass(Pass):
|
|
|
129
131
|
else:
|
|
130
132
|
if isinstance(last_element, ast.Import):
|
|
131
133
|
self.emit_ln(node, "")
|
|
132
|
-
|
|
133
|
-
|
|
134
|
+
if last_element and (
|
|
135
|
+
isinstance(i, ast.Architype)
|
|
136
|
+
and isinstance(last_element, ast.Architype)
|
|
137
|
+
and i.loc.first_line - last_element.loc.last_line == 2
|
|
138
|
+
and not node.gen.jac.endswith("\n\n")
|
|
139
|
+
):
|
|
134
140
|
self.emit_ln(node, "")
|
|
141
|
+
self.emit_ln(node, i.gen.jac)
|
|
142
|
+
|
|
135
143
|
if counter <= len(node.body) - 1:
|
|
136
144
|
if (
|
|
137
145
|
isinstance(i, ast.Ability)
|
|
@@ -142,6 +150,7 @@ class JacFormatPass(Pass):
|
|
|
142
150
|
and len(node.body[counter].kid[-1].kid) == 2
|
|
143
151
|
and len(node.body[counter - 1].kid[-1].kid) == 2
|
|
144
152
|
)
|
|
153
|
+
and node.gen.jac.endswith("\n")
|
|
145
154
|
):
|
|
146
155
|
self.emit(node, "")
|
|
147
156
|
else:
|
|
@@ -212,7 +221,7 @@ class JacFormatPass(Pass):
|
|
|
212
221
|
items: list[T],
|
|
213
222
|
"""
|
|
214
223
|
prev_token = None
|
|
215
|
-
for
|
|
224
|
+
for stmt in node.kid:
|
|
216
225
|
if isinstance(node.parent, (ast.EnumDef, ast.Enum)) and stmt.gen.jac == ",":
|
|
217
226
|
self.indent_level -= 1
|
|
218
227
|
self.emit_ln(node, f"{stmt.gen.jac}")
|
|
@@ -238,42 +247,18 @@ class JacFormatPass(Pass):
|
|
|
238
247
|
if stmt.name == Tok.LBRACE:
|
|
239
248
|
self.emit(node, f" {stmt.value}")
|
|
240
249
|
elif stmt.name == Tok.RBRACE:
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
if (stmt.parent and stmt.parent.gen.jac.strip() == "{") or (
|
|
244
|
-
stmt.parent
|
|
245
|
-
and stmt.parent.parent
|
|
246
|
-
and isinstance(
|
|
247
|
-
stmt.parent.parent,
|
|
248
|
-
(ast.ElseIf, ast.IfStmt, ast.IterForStmt, ast.TryStmt),
|
|
249
|
-
)
|
|
250
|
-
):
|
|
250
|
+
self.indent_level = max(0, self.indent_level - 1)
|
|
251
|
+
if stmt.parent and stmt.parent.gen.jac.strip() == "{":
|
|
251
252
|
self.emit(node, f"{stmt.value}")
|
|
252
253
|
else:
|
|
253
|
-
|
|
254
|
-
node.kid[i + 1]
|
|
255
|
-
if i < (len(node.kid) - 1)
|
|
256
|
-
else ast.EmptyToken()
|
|
257
|
-
)
|
|
258
|
-
if (
|
|
259
|
-
isinstance(next_kid, ast.CommentToken)
|
|
260
|
-
and next_kid.is_inline
|
|
261
|
-
):
|
|
262
|
-
self.emit(node, f" {stmt.value}")
|
|
263
|
-
elif not (node.gen.jac).endswith("\n"):
|
|
254
|
+
if not node.gen.jac.endswith("\n"):
|
|
264
255
|
self.emit_ln(node, "")
|
|
265
|
-
|
|
266
|
-
else:
|
|
267
|
-
self.emit(node, f"{stmt.value}")
|
|
256
|
+
self.emit(node, f"{stmt.value}")
|
|
268
257
|
elif isinstance(stmt, ast.CommentToken):
|
|
269
258
|
if stmt.is_inline:
|
|
270
259
|
if isinstance(prev_token, ast.Semi) or (
|
|
271
260
|
isinstance(prev_token, ast.Token)
|
|
272
|
-
and prev_token.name
|
|
273
|
-
in [
|
|
274
|
-
Tok.LBRACE,
|
|
275
|
-
Tok.RBRACE,
|
|
276
|
-
]
|
|
261
|
+
and prev_token.name in [Tok.LBRACE, Tok.RBRACE]
|
|
277
262
|
):
|
|
278
263
|
self.indent_level -= 1
|
|
279
264
|
self.emit(node, f" {stmt.gen.jac}")
|
|
@@ -297,48 +282,33 @@ class JacFormatPass(Pass):
|
|
|
297
282
|
self.emit(node, stmt.gen.jac)
|
|
298
283
|
if not stmt.gen.jac.endswith("postinit;"):
|
|
299
284
|
self.indent_level -= 1
|
|
285
|
+
self.emit_ln(stmt, "")
|
|
300
286
|
self.emit_ln(node, "")
|
|
301
287
|
self.indent_level += 1
|
|
302
288
|
elif stmt.gen.jac == ",":
|
|
303
289
|
self.emit(node, f"{stmt.value} ")
|
|
304
290
|
elif stmt.value == "=":
|
|
305
291
|
self.emit(node, f" {stmt.value} ")
|
|
292
|
+
elif prev_token and prev_token.gen.jac.strip() == "@":
|
|
293
|
+
self.emit_ln(node, stmt.value)
|
|
306
294
|
else:
|
|
307
|
-
self.emit(node, f"{stmt.
|
|
295
|
+
self.emit(node, f"{stmt.gen.jac}")
|
|
308
296
|
prev_token = stmt
|
|
309
297
|
continue
|
|
310
298
|
elif isinstance(stmt, ast.Semi):
|
|
311
299
|
self.emit(node, stmt.gen.jac)
|
|
312
|
-
elif
|
|
313
|
-
|
|
300
|
+
elif (
|
|
301
|
+
isinstance(prev_token, (ast.HasVar, ast.ArchHas))
|
|
302
|
+
and not isinstance(stmt, (ast.HasVar, ast.ArchHas))
|
|
303
|
+
) or (
|
|
304
|
+
isinstance(prev_token, ast.Ability)
|
|
305
|
+
and isinstance(stmt, (ast.Ability, ast.AbilityDef))
|
|
314
306
|
):
|
|
315
307
|
if not isinstance(prev_token.kid[-1], ast.CommentToken):
|
|
316
308
|
self.indent_level -= 1
|
|
317
309
|
self.emit_ln(node, "")
|
|
318
310
|
self.indent_level += 1
|
|
319
311
|
self.emit(node, stmt.gen.jac)
|
|
320
|
-
elif isinstance(prev_token, ast.Ability) and isinstance(
|
|
321
|
-
stmt, (ast.Ability, ast.AbilityDef)
|
|
322
|
-
):
|
|
323
|
-
if not isinstance(prev_token.kid[-1], ast.CommentToken) and (
|
|
324
|
-
stmt.body and not isinstance(stmt.body, ast.FuncCall)
|
|
325
|
-
):
|
|
326
|
-
self.indent_level -= 1
|
|
327
|
-
self.emit_ln(node, "")
|
|
328
|
-
self.indent_level += 1
|
|
329
|
-
self.emit(node, f"{stmt.gen.jac}")
|
|
330
|
-
elif stmt.body and isinstance(
|
|
331
|
-
stmt.body, (ast.FuncCall, ast.EventSignature)
|
|
332
|
-
):
|
|
333
|
-
self.indent_level -= 1
|
|
334
|
-
self.emit_ln(node, "")
|
|
335
|
-
self.indent_level += 1
|
|
336
|
-
self.emit(node, stmt.gen.jac)
|
|
337
|
-
else:
|
|
338
|
-
self.indent_level -= 1
|
|
339
|
-
self.emit_ln(node, "")
|
|
340
|
-
self.indent_level += 1
|
|
341
|
-
self.emit(node, f"{stmt.gen.jac}")
|
|
342
312
|
else:
|
|
343
313
|
if prev_token and prev_token.gen.jac.strip() == "{":
|
|
344
314
|
self.emit_ln(node, "")
|
|
@@ -352,6 +322,7 @@ class JacFormatPass(Pass):
|
|
|
352
322
|
tag: T,
|
|
353
323
|
"""
|
|
354
324
|
start = True
|
|
325
|
+
prev_token = None
|
|
355
326
|
for i in node.kid:
|
|
356
327
|
if isinstance(i, ast.CommentToken):
|
|
357
328
|
if i.is_inline:
|
|
@@ -366,8 +337,13 @@ class JacFormatPass(Pass):
|
|
|
366
337
|
elif i.gen.jac == ",":
|
|
367
338
|
self.emit(node, f"{i.gen.jac} ")
|
|
368
339
|
else:
|
|
369
|
-
if
|
|
370
|
-
|
|
340
|
+
if isinstance(i, ast.Token) and not isinstance(i, ast.BuiltinType):
|
|
341
|
+
try:
|
|
342
|
+
prev_token = self.token_before(i)
|
|
343
|
+
except Exception:
|
|
344
|
+
prev_token = None
|
|
345
|
+
if start or (prev_token and prev_token.gen.jac.strip() == ":"):
|
|
346
|
+
self.emit(node, i.gen.jac.strip())
|
|
371
347
|
start = False
|
|
372
348
|
else:
|
|
373
349
|
self.emit(node, f" {i.gen.jac}")
|
|
@@ -469,7 +445,7 @@ class JacFormatPass(Pass):
|
|
|
469
445
|
path: list[Token],
|
|
470
446
|
alias: Optional[Name],
|
|
471
447
|
"""
|
|
472
|
-
self.emit(node, node.
|
|
448
|
+
self.emit(node, node.dot_path_str)
|
|
473
449
|
if node.alias:
|
|
474
450
|
self.emit(node, " as " + node.alias.gen.jac)
|
|
475
451
|
|
|
@@ -681,6 +657,8 @@ class JacFormatPass(Pass):
|
|
|
681
657
|
self.emit(node, i.gen.jac)
|
|
682
658
|
elif isinstance(i, ast.SubNodeList) and i.gen.jac.startswith("@"):
|
|
683
659
|
self.emit_ln(node, i.gen.jac)
|
|
660
|
+
elif isinstance(i, ast.SubTag):
|
|
661
|
+
self.emit(node, i.gen.jac)
|
|
684
662
|
else:
|
|
685
663
|
if start:
|
|
686
664
|
self.emit(node, i.gen.jac)
|
|
@@ -763,7 +741,7 @@ class JacFormatPass(Pass):
|
|
|
763
741
|
self.indent_level += indent_val
|
|
764
742
|
indented = True
|
|
765
743
|
else:
|
|
766
|
-
self.emit(node,
|
|
744
|
+
self.emit(node, j.gen.jac.lstrip())
|
|
767
745
|
if indented:
|
|
768
746
|
self.indent_level -= indent_val
|
|
769
747
|
else:
|
|
@@ -929,6 +907,8 @@ class JacFormatPass(Pass):
|
|
|
929
907
|
"""Check if the length of the current generated code exceeds the max line length."""
|
|
930
908
|
if max_line_length == 0:
|
|
931
909
|
max_line_length = self.MAX_LINE_LENGTH
|
|
910
|
+
# print(content)
|
|
911
|
+
# print(len(content))
|
|
932
912
|
return len(content) > max_line_length
|
|
933
913
|
|
|
934
914
|
def exit_binary_expr(self, node: ast.BinaryExpr) -> None:
|
|
@@ -978,6 +958,7 @@ class JacFormatPass(Pass):
|
|
|
978
958
|
self.error(
|
|
979
959
|
f"Binary operator {node.op.value} not supported in bootstrap Jac"
|
|
980
960
|
)
|
|
961
|
+
# print(node.gen)
|
|
981
962
|
if isinstance(
|
|
982
963
|
node.kid[-1], (ast.Semi, ast.CommentToken)
|
|
983
964
|
) and not node.gen.jac.endswith("\n"):
|
|
@@ -1110,6 +1091,9 @@ class JacFormatPass(Pass):
|
|
|
1110
1091
|
if isinstance(i, ast.CommentToken):
|
|
1111
1092
|
if i.is_inline:
|
|
1112
1093
|
self.emit(node, f" {i.gen.jac}")
|
|
1094
|
+
elif (tok := self.token_before(i)) and (i.line_no - tok.line_no == 1):
|
|
1095
|
+
self.emit_ln(node, "")
|
|
1096
|
+
self.emit(node, i.gen.jac)
|
|
1113
1097
|
else:
|
|
1114
1098
|
self.emit_ln(node, "")
|
|
1115
1099
|
self.emit_ln(node, "")
|
|
@@ -1340,38 +1324,96 @@ class JacFormatPass(Pass):
|
|
|
1340
1324
|
if isinstance(node.kid[-1], (ast.Semi, ast.CommentToken)):
|
|
1341
1325
|
self.emit_ln(node, "")
|
|
1342
1326
|
|
|
1327
|
+
def handle_long_assignment(self, node: ast.Assignment, kid: ast.AstNode) -> None:
|
|
1328
|
+
"""Handle long assignment lines."""
|
|
1329
|
+
parts = re.split(r"(=)", kid.gen.jac)
|
|
1330
|
+
first_part = parts.pop(0).strip()
|
|
1331
|
+
self.emit_ln(
|
|
1332
|
+
node, f"{first_part} {parts.pop(0).strip()} {parts.pop(0).strip()}"
|
|
1333
|
+
)
|
|
1334
|
+
for j in range(0, len(parts) - 1, 2):
|
|
1335
|
+
op = parts[j]
|
|
1336
|
+
var = parts[j + 1].strip() if j + 1 < len(parts) else ""
|
|
1337
|
+
if var:
|
|
1338
|
+
self.indent_level += 1
|
|
1339
|
+
self.emit(node, f"{op} {var}")
|
|
1340
|
+
self.indent_level -= 1
|
|
1341
|
+
self.emit_ln(node, "")
|
|
1342
|
+
else:
|
|
1343
|
+
self.indent_level += 1
|
|
1344
|
+
self.emit(node, op)
|
|
1345
|
+
self.indent_level -= 1
|
|
1346
|
+
|
|
1347
|
+
def handle_long_expression(self, node: ast.AstNode, kid: ast.AstNode) -> None:
|
|
1348
|
+
"""Handle long expressions with multiple operators."""
|
|
1349
|
+
parts = re.split(r"(\+|\-|\*|\/)", kid.gen.jac)
|
|
1350
|
+
self.emit_ln(node, f"{parts.pop(0).strip()}")
|
|
1351
|
+
for j in range(0, len(parts) - 1, 2):
|
|
1352
|
+
op = parts[j]
|
|
1353
|
+
var = parts[j + 1].strip() if j + 1 < len(parts) else ""
|
|
1354
|
+
if j < len(parts) - 2:
|
|
1355
|
+
self.indent_level += 1
|
|
1356
|
+
self.emit(node, f"{op} {var}")
|
|
1357
|
+
self.indent_level -= 1
|
|
1358
|
+
self.emit_ln(node, "")
|
|
1359
|
+
else:
|
|
1360
|
+
self.indent_level += 1
|
|
1361
|
+
self.emit(node, f"{op} {var}")
|
|
1362
|
+
self.indent_level -= 1
|
|
1363
|
+
|
|
1343
1364
|
def exit_assignment(self, node: ast.Assignment) -> None:
|
|
1344
1365
|
"""Sub objects.
|
|
1345
1366
|
|
|
1346
|
-
target: SubNodeList[
|
|
1347
|
-
value: Optional[
|
|
1348
|
-
type_tag: Optional[SubTag[
|
|
1367
|
+
target: SubNodeList[Expr],
|
|
1368
|
+
value: Optional[Expr | YieldExpr],
|
|
1369
|
+
type_tag: Optional[SubTag[Expr]],
|
|
1349
1370
|
mutable: bool = True,
|
|
1350
|
-
aug_op: Optional[Token] = None
|
|
1371
|
+
aug_op: Optional[Token] = None,
|
|
1372
|
+
semstr: Optional[String] = None,
|
|
1373
|
+
is_enum_stmt: bool = False,
|
|
1351
1374
|
"""
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1375
|
+
prev_token = None
|
|
1376
|
+
for kid in node.kid:
|
|
1377
|
+
if isinstance(kid, ast.CommentToken):
|
|
1378
|
+
if kid.is_inline:
|
|
1379
|
+
self.emit(node, kid.gen.jac)
|
|
1356
1380
|
else:
|
|
1357
|
-
if
|
|
1381
|
+
if kid.gen.jac not in [
|
|
1358
1382
|
"# Update any new user level buddy schedule",
|
|
1359
1383
|
"# Construct prompt here",
|
|
1360
1384
|
]:
|
|
1361
1385
|
self.emit_ln(node, "")
|
|
1362
1386
|
self.emit_ln(node, "")
|
|
1363
|
-
self.emit_ln(node,
|
|
1387
|
+
self.emit_ln(node, kid.gen.jac)
|
|
1364
1388
|
else:
|
|
1365
1389
|
self.emit_ln(node, "")
|
|
1366
|
-
self.emit(node,
|
|
1367
|
-
elif isinstance(
|
|
1368
|
-
|
|
1390
|
+
self.emit(node, kid.gen.jac)
|
|
1391
|
+
elif isinstance(kid, ast.Token) and (
|
|
1392
|
+
kid.name == Tok.KW_LET or kid.gen.jac == ":"
|
|
1369
1393
|
):
|
|
1370
|
-
self.emit(node, f"{
|
|
1371
|
-
elif isinstance(
|
|
1372
|
-
self.emit(node, f" {
|
|
1394
|
+
self.emit(node, f"{kid.gen.jac} ")
|
|
1395
|
+
elif isinstance(kid, ast.Token) and "=" in kid.gen.jac:
|
|
1396
|
+
self.emit(node, f" {kid.gen.jac} ")
|
|
1397
|
+
elif (
|
|
1398
|
+
"=" in kid.gen.jac
|
|
1399
|
+
and self.is_line_break_needed(
|
|
1400
|
+
kid.gen.jac, max_line_length=self.MAX_LINE_LENGTH * 2
|
|
1401
|
+
)
|
|
1402
|
+
and "\n" not in kid.gen.jac
|
|
1403
|
+
):
|
|
1404
|
+
self.handle_long_assignment(node, kid)
|
|
1405
|
+
elif (
|
|
1406
|
+
prev_token
|
|
1407
|
+
and "=" in prev_token.gen.jac
|
|
1408
|
+
and self.is_line_break_needed(
|
|
1409
|
+
kid.gen.jac, max_line_length=self.MAX_LINE_LENGTH * 2
|
|
1410
|
+
)
|
|
1411
|
+
and "\n" not in kid.gen.jac
|
|
1412
|
+
):
|
|
1413
|
+
self.handle_long_expression(node, kid)
|
|
1373
1414
|
else:
|
|
1374
|
-
self.emit(node,
|
|
1415
|
+
self.emit(node, kid.gen.jac)
|
|
1416
|
+
prev_token = kid
|
|
1375
1417
|
if isinstance(
|
|
1376
1418
|
node.kid[-1], (ast.Semi, ast.CommentToken)
|
|
1377
1419
|
) and not node.gen.jac.endswith("\n"):
|
|
@@ -2386,7 +2428,7 @@ class JacFormatPass(Pass):
|
|
|
2386
2428
|
"""
|
|
2387
2429
|
self.emit(node, f"<>{node.value}" if node.is_kwesc else node.value)
|
|
2388
2430
|
|
|
2389
|
-
def
|
|
2431
|
+
def exit_float(self, node: ast.Float) -> None:
|
|
2390
2432
|
"""Sub objects.
|
|
2391
2433
|
|
|
2392
2434
|
name: str,
|
|
@@ -2399,7 +2441,7 @@ class JacFormatPass(Pass):
|
|
|
2399
2441
|
"""
|
|
2400
2442
|
self.emit(node, node.value)
|
|
2401
2443
|
|
|
2402
|
-
def
|
|
2444
|
+
def exit_int(self, node: ast.Int) -> None:
|
|
2403
2445
|
"""Sub objects.
|
|
2404
2446
|
|
|
2405
2447
|
name: str,
|
|
@@ -2412,7 +2454,7 @@ class JacFormatPass(Pass):
|
|
|
2412
2454
|
"""
|
|
2413
2455
|
self.emit(node, node.value)
|
|
2414
2456
|
|
|
2415
|
-
def
|
|
2457
|
+
def exit_string(self, node: ast.String) -> None:
|
|
2416
2458
|
"""Sub objects.
|
|
2417
2459
|
|
|
2418
2460
|
name: str,
|
|
@@ -2424,7 +2466,11 @@ class JacFormatPass(Pass):
|
|
|
2424
2466
|
pos_end: int,
|
|
2425
2467
|
"""
|
|
2426
2468
|
# if string is in docstring format and spans multiple lines turn into the multiple single quoted strings
|
|
2427
|
-
if "\n" in node.value and
|
|
2469
|
+
if "\n" in node.value and (
|
|
2470
|
+
node.parent
|
|
2471
|
+
and isinstance(node.parent, ast.Expr)
|
|
2472
|
+
and not isinstance(node.parent, ast.MultiString)
|
|
2473
|
+
):
|
|
2428
2474
|
string_type = node.value[0:3]
|
|
2429
2475
|
pure_string = node.value[3:-3]
|
|
2430
2476
|
lines = pure_string.split("\n")
|
|
@@ -2442,14 +2488,14 @@ class JacFormatPass(Pass):
|
|
|
2442
2488
|
string_type = node.value[0:3]
|
|
2443
2489
|
pure_string = node.value[3:-3]
|
|
2444
2490
|
lines = pure_string.split("\n")
|
|
2445
|
-
self.
|
|
2446
|
-
for line in lines[:-1]:
|
|
2447
|
-
self.emit_ln(node, line)
|
|
2448
|
-
self.
|
|
2491
|
+
self.emit_ln(node, f"{string_type}{lines[0].lstrip()}")
|
|
2492
|
+
for line in lines[1:-1]:
|
|
2493
|
+
self.emit_ln(node, line.lstrip())
|
|
2494
|
+
self.emit(node, f"{lines[-1].lstrip()}{string_type}")
|
|
2449
2495
|
else:
|
|
2450
2496
|
self.emit(node, node.value)
|
|
2451
2497
|
|
|
2452
|
-
def
|
|
2498
|
+
def exit_bool(self, node: ast.Bool) -> None:
|
|
2453
2499
|
"""Sub objects.
|
|
2454
2500
|
|
|
2455
2501
|
name: str,
|
|
@@ -32,7 +32,7 @@ obj ExecutionContext {
|
|
|
32
32
|
"Global Execution Context, should be monkey patched by the user."
|
|
33
33
|
glob exec_ctx = ExecutionContext();
|
|
34
34
|
|
|
35
|
-
obj
|
|
35
|
+
obj Anchor :ArchitypeProtocol: {
|
|
36
36
|
has ob: object,
|
|
37
37
|
jid: UUID = :> uuid4,
|
|
38
38
|
timestamp: datetime = :> datetime.now,
|
|
@@ -41,8 +41,12 @@ obj ElementAnchor {
|
|
|
41
41
|
rw_access: set = :> set,
|
|
42
42
|
ro_access: set = :> set,
|
|
43
43
|
owner_id: UUID = exec_ctx.master,
|
|
44
|
-
mem: Memory = exec_ctx.memory
|
|
44
|
+
mem: Memory = exec_ctx.memory,
|
|
45
|
+
ds_entry_funcs: list[DSFunc],
|
|
46
|
+
ds_exit_funcs: list[DSFunc];
|
|
45
47
|
|
|
48
|
+
static can on_entry(cls: type, triggers: list[type]);
|
|
49
|
+
static can on_exit(cls: type, triggers: list[type]);
|
|
46
50
|
can make_public_ro;
|
|
47
51
|
can make_public_rw;
|
|
48
52
|
can make_private;
|
|
@@ -55,15 +59,7 @@ obj ElementAnchor {
|
|
|
55
59
|
can revoke_access(caller_id: UUID);
|
|
56
60
|
}
|
|
57
61
|
|
|
58
|
-
obj
|
|
59
|
-
has ds_entry_funcs: list[DSFunc],
|
|
60
|
-
ds_exit_funcs: list[DSFunc];
|
|
61
|
-
|
|
62
|
-
static can on_entry(cls: type, triggers: list[type]);
|
|
63
|
-
static can on_exit(cls: type, triggers: list[type]);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
obj NodeAnchor :ObjectAnchor: {
|
|
62
|
+
obj NodeAnchor :Anchor: {
|
|
67
63
|
has edges: dict[EdgeDir, list[Edge]] = {EdgeDir.IN: [], EdgeDir.OUT: []};
|
|
68
64
|
|
|
69
65
|
can connect_node(nd: Node, edg: Edge) -> Node;
|
|
@@ -71,7 +67,7 @@ obj NodeAnchor :ObjectAnchor: {
|
|
|
71
67
|
can __call__(walk: Walker);
|
|
72
68
|
}
|
|
73
69
|
|
|
74
|
-
obj EdgeAnchor :
|
|
70
|
+
obj EdgeAnchor :Anchor: {
|
|
75
71
|
has source: Node = None,
|
|
76
72
|
target: Node = None,
|
|
77
73
|
dir: EdgeDir = None;
|
|
@@ -81,7 +77,7 @@ obj EdgeAnchor :ObjectAnchor: {
|
|
|
81
77
|
can __call__(walk: Walker);
|
|
82
78
|
}
|
|
83
79
|
|
|
84
|
-
obj WalkerAnchor :
|
|
80
|
+
obj WalkerAnchor :Anchor: {
|
|
85
81
|
has path: list[Node] = [],
|
|
86
82
|
next: list[Node] = [],
|
|
87
83
|
ignores: list[Node] = [],
|
|
@@ -94,27 +90,27 @@ obj WalkerAnchor :ObjectAnchor: {
|
|
|
94
90
|
}
|
|
95
91
|
|
|
96
92
|
obj Root :AbsRootHook: {
|
|
97
|
-
has
|
|
93
|
+
has __jac__: NodeAnchor | None = None;
|
|
98
94
|
|
|
99
95
|
can postinit {
|
|
100
|
-
self.
|
|
96
|
+
self.__jac__ = NodeAnchor(self, ds_entry_funcs=[], ds_exit_funcs=[]);
|
|
101
97
|
}
|
|
102
98
|
}
|
|
103
99
|
|
|
104
100
|
obj GenericEdge :ArchitypeProtocol: {
|
|
105
|
-
has
|
|
101
|
+
has __jac__: EdgeAnchor | None = None;
|
|
106
102
|
|
|
107
103
|
can postinit {
|
|
108
|
-
self.
|
|
104
|
+
self.__jac__ = EdgeAnchor(self, ds_entry_funcs=[], ds_exit_funcs=[]);
|
|
109
105
|
}
|
|
110
106
|
}
|
|
111
107
|
|
|
112
108
|
obj Master {
|
|
113
|
-
has
|
|
109
|
+
has __jac__: Anchor | None = None;
|
|
114
110
|
has root_node: Root = Root(Root);
|
|
115
111
|
|
|
116
112
|
can postinit {
|
|
117
|
-
self.
|
|
113
|
+
self.__jac__ = Anchor(self);
|
|
118
114
|
}
|
|
119
115
|
}
|
|
120
116
|
|
|
@@ -204,31 +200,31 @@ obj JacPlugin {
|
|
|
204
200
|
PRIVATE
|
|
205
201
|
}
|
|
206
202
|
|
|
207
|
-
:obj:
|
|
203
|
+
:obj:Anchor:can:make_public_ro {
|
|
208
204
|
self.__jinfo.access_mode = AccessMode.READ_ONLY;
|
|
209
205
|
}
|
|
210
206
|
|
|
211
|
-
:obj:
|
|
207
|
+
:obj:Anchor:can:make_public_rw {
|
|
212
208
|
self.__jinfo.access_mode = AccessMode.READ_WRITE;
|
|
213
209
|
}
|
|
214
210
|
|
|
215
|
-
:obj:
|
|
211
|
+
:obj:Anchor:can:make_private {
|
|
216
212
|
self.__jinfo.access_mode = AccessMode.PRIVATE;
|
|
217
213
|
}
|
|
218
214
|
|
|
219
|
-
:obj:
|
|
215
|
+
:obj:Anchor:can:is_public_ro -> bool {
|
|
220
216
|
return self.__jinfo.access_mode == AccessMode.READ_ONLY;
|
|
221
217
|
}
|
|
222
218
|
|
|
223
|
-
:obj:
|
|
219
|
+
:obj:Anchor:can:is_public_rw -> bool {
|
|
224
220
|
return self.__jinfo.access_mode == AccessMode.READ_WRITE;
|
|
225
221
|
}
|
|
226
222
|
|
|
227
|
-
:obj:
|
|
223
|
+
:obj:Anchor:can:is_private -> bool {
|
|
228
224
|
return self.__jinfo.access_mode == AccessMode.PRIVATE;
|
|
229
225
|
}
|
|
230
226
|
|
|
231
|
-
:obj:
|
|
227
|
+
:obj:Anchor:can:is_readable
|
|
232
228
|
(caller_id: UUID) -> bool {
|
|
233
229
|
return (caller_id == self.owner_id
|
|
234
230
|
or |> self.is_public_read
|
|
@@ -236,14 +232,14 @@ obj JacPlugin {
|
|
|
236
232
|
or caller_id in self.rw_access);
|
|
237
233
|
}
|
|
238
234
|
|
|
239
|
-
:obj:
|
|
235
|
+
:obj:Anchor:can:is_writable
|
|
240
236
|
(caller_id: UUID) -> bool {
|
|
241
237
|
return (caller_id == self.owner_id
|
|
242
238
|
or |> self.is_public_write
|
|
243
239
|
or caller_id in self.rw_access);
|
|
244
240
|
}
|
|
245
241
|
|
|
246
|
-
:obj:
|
|
242
|
+
:obj:Anchor:can:give_access
|
|
247
243
|
(caller_id: UUID, read_write: bool=False) {
|
|
248
244
|
if read_write {
|
|
249
245
|
caller_id |> self.rw_access.add;
|
|
@@ -252,13 +248,13 @@ obj JacPlugin {
|
|
|
252
248
|
}
|
|
253
249
|
}
|
|
254
250
|
|
|
255
|
-
:obj:
|
|
251
|
+
:obj:Anchor:can:revoke_access
|
|
256
252
|
(caller_id: UUID) {
|
|
257
253
|
caller_id |> self.ro_access.discard;
|
|
258
254
|
caller_id |> self.rw_access.discard;
|
|
259
255
|
}
|
|
260
256
|
|
|
261
|
-
:obj:
|
|
257
|
+
:obj:Anchor:can:on_entry
|
|
262
258
|
(cls: type, triggers: list) {
|
|
263
259
|
can decorator(func: callable) -> callable {
|
|
264
260
|
cls.ds_entry_funcs.append(
|
|
@@ -272,7 +268,7 @@ obj JacPlugin {
|
|
|
272
268
|
return decorator;
|
|
273
269
|
}
|
|
274
270
|
|
|
275
|
-
:obj:
|
|
271
|
+
:obj:Anchor:can:on_exit
|
|
276
272
|
(cls: type, triggers: list) {
|
|
277
273
|
can decorator(func: callable) -> callable {
|
|
278
274
|
cls.ds_exit_funcs.append(
|
|
@@ -361,7 +357,7 @@ obj JacPlugin {
|
|
|
361
357
|
|
|
362
358
|
:obj:NodeAnchor:can:__call__
|
|
363
359
|
(walk: object) {
|
|
364
|
-
if not isinstance(walk.
|
|
360
|
+
if not isinstance(walk.__jac__, WalkerAnchor) {
|
|
365
361
|
raise TypeError("Argument must be a Walker instance");
|
|
366
362
|
}
|
|
367
363
|
walk(self);
|
|
@@ -369,10 +365,10 @@ obj JacPlugin {
|
|
|
369
365
|
|
|
370
366
|
:obj:EdgeAnchor:can:__call__
|
|
371
367
|
(walk: EdgeInterface) {
|
|
372
|
-
if not isinstance(walk.
|
|
368
|
+
if not isinstance(walk.__jac__, WalkerAnchor) {
|
|
373
369
|
raise TypeError("Argument must be a Walker instance");
|
|
374
370
|
}
|
|
375
|
-
walk(self.
|
|
371
|
+
walk(self.__jac__.target);
|
|
376
372
|
}
|
|
377
373
|
|
|
378
374
|
:obj:WalkerAnchor:can:__call__
|
|
@@ -423,25 +419,25 @@ obj JacPlugin {
|
|
|
423
419
|
(arch: AT, arch_type: str, on_entry: list[DSFunc], on_exit: list[DSFunc]) -> bool {
|
|
424
420
|
match arch_type {
|
|
425
421
|
case 'obj':
|
|
426
|
-
arch.
|
|
422
|
+
arch.__jac__ = Anchor(
|
|
427
423
|
ob=arch,
|
|
428
424
|
ds_entry_funcs=on_entry,
|
|
429
425
|
ds_exit_funcs=on_exit
|
|
430
426
|
);
|
|
431
427
|
case 'node':
|
|
432
|
-
arch.
|
|
428
|
+
arch.__jac__ = NodeAnchor(
|
|
433
429
|
ob=arch,
|
|
434
430
|
ds_entry_funcs=on_entry,
|
|
435
431
|
ds_exit_funcs=on_exit
|
|
436
432
|
);
|
|
437
433
|
case 'edge':
|
|
438
|
-
arch.
|
|
434
|
+
arch.__jac__ = EdgeAnchor(
|
|
439
435
|
ob=arch,
|
|
440
436
|
ds_entry_funcs=on_entry,
|
|
441
437
|
ds_exit_funcs=on_exit
|
|
442
438
|
);
|
|
443
439
|
case 'walker':
|
|
444
|
-
arch.
|
|
440
|
+
arch.__jac__ = WalkerAnchor(
|
|
445
441
|
ob=arch,
|
|
446
442
|
ds_entry_funcs=on_entry,
|
|
447
443
|
ds_exit_funcs=on_exit
|
|
@@ -464,19 +460,19 @@ obj JacPlugin {
|
|
|
464
460
|
edg_type = edge_spec[1];
|
|
465
461
|
}
|
|
466
462
|
edg = edg_type(*(edge_spec[2])) if edge_spec[2] else edg_type();
|
|
467
|
-
edg.
|
|
463
|
+
edg.__jac__.apply_dir(edge_spec[0]);
|
|
468
464
|
return edg;
|
|
469
465
|
}
|
|
470
466
|
|
|
471
467
|
:obj:JacPlugin:can:connect
|
|
472
468
|
(left: T, right: T, edge_spec: tuple[int, Optional[type], Optional[tuple]]) -> Architype {
|
|
473
469
|
edg = JacPlugin.build_edge(edge_spec);
|
|
474
|
-
left.connect_node(right.
|
|
470
|
+
left.connect_node(right.__jac__, edg.__jac__);
|
|
475
471
|
}
|
|
476
472
|
|
|
477
473
|
:obj:JacPlugin:can:visit_node
|
|
478
474
|
(walker_obj: Any, expr: Any) -> bool {
|
|
479
|
-
return walker_obj.
|
|
475
|
+
return walker_obj.__jac__.visit_node(expr);
|
|
480
476
|
}
|
|
481
477
|
|
|
482
478
|
glob expected_area = 78.53981633974483;
|