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
jaclang/runtimelib/machine.py
CHANGED
|
@@ -329,23 +329,27 @@ class JacWalker:
|
|
|
329
329
|
| NodeArchetype
|
|
330
330
|
| EdgeArchetype
|
|
331
331
|
),
|
|
332
|
+
insert_loc: int = -1,
|
|
332
333
|
) -> bool: # noqa: ANN401
|
|
333
334
|
"""Jac's visit stmt feature."""
|
|
334
335
|
if isinstance(walker, WalkerArchetype):
|
|
335
336
|
"""Walker visits node."""
|
|
336
337
|
wanch = walker.__jac__
|
|
337
338
|
before_len = len(wanch.next)
|
|
339
|
+
next = []
|
|
338
340
|
for anchor in (
|
|
339
341
|
(i.__jac__ for i in expr) if isinstance(expr, list) else [expr.__jac__]
|
|
340
342
|
):
|
|
341
343
|
if anchor not in wanch.ignores:
|
|
342
|
-
if isinstance(anchor, NodeAnchor):
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
344
|
+
if isinstance(anchor, (NodeAnchor, EdgeAnchor)):
|
|
345
|
+
next.append(anchor)
|
|
346
|
+
else:
|
|
347
|
+
raise ValueError("Anchor should be NodeAnchor or EdgeAnchor.")
|
|
348
|
+
if insert_loc < -len(wanch.next): # for out of index selection
|
|
349
|
+
insert_loc = 0
|
|
350
|
+
elif insert_loc < 0:
|
|
351
|
+
insert_loc += len(wanch.next) + 1
|
|
352
|
+
wanch.next = wanch.next[:insert_loc] + next + wanch.next[insert_loc:]
|
|
349
353
|
return len(wanch.next) > before_len
|
|
350
354
|
else:
|
|
351
355
|
raise TypeError("Invalid walker object")
|
|
@@ -381,83 +385,91 @@ class JacWalker:
|
|
|
381
385
|
raise TypeError("Invalid walker object")
|
|
382
386
|
|
|
383
387
|
@staticmethod
|
|
384
|
-
def spawn_call(
|
|
388
|
+
def spawn_call(
|
|
389
|
+
walker: WalkerAnchor,
|
|
390
|
+
node: NodeAnchor | EdgeAnchor,
|
|
391
|
+
) -> WalkerArchetype:
|
|
385
392
|
"""Jac's spawn operator feature."""
|
|
386
393
|
warch = walker.archetype
|
|
387
394
|
walker.path = []
|
|
388
|
-
|
|
389
|
-
current_node = node.archetype
|
|
395
|
+
current_loc = node.archetype
|
|
390
396
|
|
|
391
|
-
# walker entry
|
|
397
|
+
# walker ability on any entry
|
|
392
398
|
for i in warch._jac_entry_funcs_:
|
|
393
399
|
if not i.trigger:
|
|
394
|
-
i.func(warch,
|
|
400
|
+
i.func(warch, current_loc)
|
|
395
401
|
if walker.disengaged:
|
|
396
402
|
return warch
|
|
397
403
|
|
|
398
404
|
while len(walker.next):
|
|
399
|
-
if
|
|
400
|
-
# walker
|
|
405
|
+
if current_loc := walker.next.pop(0).archetype:
|
|
406
|
+
# walker ability with loc entry
|
|
401
407
|
for i in warch._jac_entry_funcs_:
|
|
402
408
|
if (
|
|
403
409
|
i.trigger
|
|
404
|
-
and
|
|
405
|
-
|
|
410
|
+
and (
|
|
411
|
+
all_issubclass(i.trigger, NodeArchetype)
|
|
412
|
+
or all_issubclass(i.trigger, EdgeArchetype)
|
|
413
|
+
)
|
|
414
|
+
and isinstance(current_loc, i.trigger)
|
|
406
415
|
):
|
|
407
|
-
i.func(warch,
|
|
416
|
+
i.func(warch, current_loc)
|
|
408
417
|
if walker.disengaged:
|
|
409
418
|
return warch
|
|
410
419
|
|
|
411
|
-
#
|
|
412
|
-
for i in
|
|
420
|
+
# loc ability with any entry
|
|
421
|
+
for i in current_loc._jac_entry_funcs_:
|
|
413
422
|
if not i.trigger:
|
|
414
|
-
i.func(
|
|
423
|
+
i.func(current_loc, warch)
|
|
415
424
|
if walker.disengaged:
|
|
416
425
|
return warch
|
|
417
426
|
|
|
418
|
-
#
|
|
419
|
-
for i in
|
|
427
|
+
# loc ability with walker entry
|
|
428
|
+
for i in current_loc._jac_entry_funcs_:
|
|
420
429
|
if (
|
|
421
430
|
i.trigger
|
|
422
431
|
and all_issubclass(i.trigger, WalkerArchetype)
|
|
423
432
|
and isinstance(warch, i.trigger)
|
|
424
433
|
):
|
|
425
|
-
i.func(
|
|
434
|
+
i.func(current_loc, warch)
|
|
426
435
|
if walker.disengaged:
|
|
427
436
|
return warch
|
|
428
437
|
|
|
429
|
-
#
|
|
430
|
-
for i in
|
|
438
|
+
# loc ability with walker exit
|
|
439
|
+
for i in current_loc._jac_exit_funcs_:
|
|
431
440
|
if (
|
|
432
441
|
i.trigger
|
|
433
442
|
and all_issubclass(i.trigger, WalkerArchetype)
|
|
434
443
|
and isinstance(warch, i.trigger)
|
|
435
444
|
):
|
|
436
|
-
i.func(
|
|
445
|
+
i.func(current_loc, warch)
|
|
437
446
|
if walker.disengaged:
|
|
438
447
|
return warch
|
|
439
448
|
|
|
440
|
-
#
|
|
441
|
-
for i in
|
|
449
|
+
# loc ability with any exit
|
|
450
|
+
for i in current_loc._jac_exit_funcs_:
|
|
442
451
|
if not i.trigger:
|
|
443
|
-
i.func(
|
|
452
|
+
i.func(current_loc, warch)
|
|
444
453
|
if walker.disengaged:
|
|
445
454
|
return warch
|
|
446
455
|
|
|
447
|
-
# walker
|
|
456
|
+
# walker ability with loc exit
|
|
448
457
|
for i in warch._jac_exit_funcs_:
|
|
449
458
|
if (
|
|
450
459
|
i.trigger
|
|
451
|
-
and
|
|
452
|
-
|
|
460
|
+
and (
|
|
461
|
+
all_issubclass(i.trigger, NodeArchetype)
|
|
462
|
+
or all_issubclass(i.trigger, EdgeArchetype)
|
|
463
|
+
)
|
|
464
|
+
and isinstance(current_loc, i.trigger)
|
|
453
465
|
):
|
|
454
|
-
i.func(warch,
|
|
466
|
+
i.func(warch, current_loc)
|
|
455
467
|
if walker.disengaged:
|
|
456
468
|
return warch
|
|
457
|
-
# walker exit
|
|
469
|
+
# walker ability with any exit
|
|
458
470
|
for i in warch._jac_exit_funcs_:
|
|
459
471
|
if not i.trigger:
|
|
460
|
-
i.func(warch,
|
|
472
|
+
i.func(warch, current_loc)
|
|
461
473
|
if walker.disengaged:
|
|
462
474
|
return warch
|
|
463
475
|
|
|
@@ -467,12 +479,14 @@ class JacWalker:
|
|
|
467
479
|
@staticmethod
|
|
468
480
|
def spawn(op1: Archetype, op2: Archetype) -> WalkerArchetype | asyncio.Future:
|
|
469
481
|
"""Jac's spawn operator feature."""
|
|
482
|
+
edge: EdgeAnchor | None = None
|
|
470
483
|
if isinstance(op1, WalkerArchetype):
|
|
471
484
|
warch = op1
|
|
472
485
|
walker = op1.__jac__
|
|
473
486
|
if isinstance(op2, NodeArchetype):
|
|
474
487
|
node = op2.__jac__
|
|
475
488
|
elif isinstance(op2, EdgeArchetype):
|
|
489
|
+
edge = op2.__jac__
|
|
476
490
|
node = op2.__jac__.target
|
|
477
491
|
else:
|
|
478
492
|
raise TypeError("Invalid target object")
|
|
@@ -482,21 +496,29 @@ class JacWalker:
|
|
|
482
496
|
if isinstance(op1, NodeArchetype):
|
|
483
497
|
node = op1.__jac__
|
|
484
498
|
elif isinstance(op1, EdgeArchetype):
|
|
499
|
+
edge = op1.__jac__
|
|
485
500
|
node = op1.__jac__.target
|
|
486
501
|
else:
|
|
487
502
|
raise TypeError("Invalid target object")
|
|
488
503
|
else:
|
|
489
504
|
raise TypeError("Invalid walker object")
|
|
490
505
|
|
|
506
|
+
if edge is not None:
|
|
507
|
+
loc: EdgeAnchor | NodeAnchor = edge
|
|
508
|
+
walker.next = [edge, node]
|
|
509
|
+
else:
|
|
510
|
+
loc = node
|
|
511
|
+
walker.next = [node]
|
|
512
|
+
|
|
491
513
|
if warch.__jac_async__:
|
|
492
514
|
machine = JacMachineInterface.py_get_jac_machine()
|
|
493
515
|
_event_loop = machine._event_loop
|
|
494
|
-
func = partial(JacMachineInterface.spawn_call, *(walker,
|
|
516
|
+
func = partial(JacMachineInterface.spawn_call, *(walker, loc))
|
|
495
517
|
return asyncio.ensure_future(
|
|
496
518
|
_event_loop.run_in_executor(None, func), loop=_event_loop
|
|
497
519
|
)
|
|
498
520
|
else:
|
|
499
|
-
return JacMachineInterface.spawn_call(walker=walker, node=
|
|
521
|
+
return JacMachineInterface.spawn_call(walker=walker, node=loc)
|
|
500
522
|
|
|
501
523
|
@staticmethod
|
|
502
524
|
def disengage(walker: WalkerArchetype) -> bool:
|
|
@@ -525,7 +547,7 @@ class JacBuiltin:
|
|
|
525
547
|
"""Jac Builtins."""
|
|
526
548
|
|
|
527
549
|
@staticmethod
|
|
528
|
-
def
|
|
550
|
+
def printgraph(
|
|
529
551
|
node: NodeArchetype,
|
|
530
552
|
depth: int,
|
|
531
553
|
traverse: bool,
|
|
@@ -533,9 +555,10 @@ class JacBuiltin:
|
|
|
533
555
|
bfs: bool,
|
|
534
556
|
edge_limit: int,
|
|
535
557
|
node_limit: int,
|
|
536
|
-
|
|
558
|
+
file: Optional[str],
|
|
559
|
+
format: str,
|
|
537
560
|
) -> str:
|
|
538
|
-
"""Generate
|
|
561
|
+
"""Generate graph for visualizing nodes and edges."""
|
|
539
562
|
edge_type = edge_type if edge_type else []
|
|
540
563
|
visited_nodes: list[NodeArchetype] = []
|
|
541
564
|
node_depths: dict[NodeArchetype, int] = {node: 0}
|
|
@@ -589,24 +612,32 @@ class JacBuiltin:
|
|
|
589
612
|
'digraph {\nnode [style="filled", shape="ellipse", '
|
|
590
613
|
'fillcolor="invis", fontcolor="black"];\n'
|
|
591
614
|
)
|
|
615
|
+
mermaid_content = "flowchart LR\n"
|
|
592
616
|
for source, target, edge in connections:
|
|
593
617
|
edge_label = html.escape(str(edge.__jac__.archetype))
|
|
594
618
|
dot_content += (
|
|
595
619
|
f"{visited_nodes.index(source)} -> {visited_nodes.index(target)} "
|
|
596
620
|
f' [label="{edge_label if "GenericEdge" not in edge_label else ""}"];\n'
|
|
597
621
|
)
|
|
622
|
+
mermaid_content += (
|
|
623
|
+
f"{visited_nodes.index(source)} -->"
|
|
624
|
+
f"|{edge_label if 'GenericEdge' not in edge_label else ''}| {visited_nodes.index(target)}\n"
|
|
625
|
+
)
|
|
598
626
|
for node_ in visited_nodes:
|
|
599
627
|
color = (
|
|
600
628
|
colors[node_depths[node_]] if node_depths[node_] < 25 else colors[24]
|
|
601
629
|
)
|
|
630
|
+
label = html.escape(str(node_.__jac__.archetype))
|
|
602
631
|
dot_content += (
|
|
603
|
-
f'{visited_nodes.index(node_)} [label="{
|
|
632
|
+
f'{visited_nodes.index(node_)} [label="{label}"'
|
|
604
633
|
f'fillcolor="{color}"];\n'
|
|
605
634
|
)
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
635
|
+
mermaid_content += f'{visited_nodes.index(node_)}["{label}"]\n'
|
|
636
|
+
output = dot_content + "}" if format == "dot" else mermaid_content
|
|
637
|
+
if file:
|
|
638
|
+
with open(file, "w") as f:
|
|
639
|
+
f.write(output)
|
|
640
|
+
return output
|
|
610
641
|
|
|
611
642
|
|
|
612
643
|
class JacCmd:
|
|
@@ -803,7 +834,7 @@ class JacBasics:
|
|
|
803
834
|
items,
|
|
804
835
|
)
|
|
805
836
|
|
|
806
|
-
if not mach.
|
|
837
|
+
if not mach.program:
|
|
807
838
|
JacMachineInterface.attach_program(mach, JacProgram())
|
|
808
839
|
|
|
809
840
|
if lng == "py":
|
|
@@ -924,7 +955,10 @@ class JacBasics:
|
|
|
924
955
|
dir: EdgeDir = EdgeDir.OUT,
|
|
925
956
|
filter: Callable[[EdgeArchetype], bool] | None = None,
|
|
926
957
|
edges_only: bool = False,
|
|
927
|
-
|
|
958
|
+
from_visit: bool = False,
|
|
959
|
+
) -> (
|
|
960
|
+
list[NodeArchetype] | list[EdgeArchetype] | list[NodeArchetype | EdgeArchetype]
|
|
961
|
+
):
|
|
928
962
|
"""Jac's apply_dir stmt feature."""
|
|
929
963
|
if isinstance(sources, NodeArchetype):
|
|
930
964
|
sources = [sources]
|
|
@@ -934,14 +968,23 @@ class JacBasics:
|
|
|
934
968
|
else targets if targets else None
|
|
935
969
|
)
|
|
936
970
|
if edges_only:
|
|
937
|
-
connected_edges: list[EdgeArchetype] = []
|
|
971
|
+
connected_edges: list[EdgeArchetype | NodeArchetype] = []
|
|
938
972
|
for node in sources:
|
|
939
973
|
edges = JacMachineInterface.get_edges(
|
|
940
974
|
node.__jac__, dir, filter, target_obj=targ_obj_set
|
|
941
975
|
)
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
976
|
+
for edge in edges:
|
|
977
|
+
assert isinstance(edge, EdgeArchetype)
|
|
978
|
+
if edge in connected_edges:
|
|
979
|
+
continue
|
|
980
|
+
if from_visit:
|
|
981
|
+
connected_edges.append(edge)
|
|
982
|
+
if dir == EdgeDir.IN:
|
|
983
|
+
connected_edges.append(edge.__jac__.source.archetype)
|
|
984
|
+
else:
|
|
985
|
+
connected_edges.append(edge.__jac__.target.archetype)
|
|
986
|
+
else:
|
|
987
|
+
connected_edges.append(edge)
|
|
945
988
|
return connected_edges
|
|
946
989
|
else:
|
|
947
990
|
connected_nodes: list[NodeArchetype] = []
|
|
@@ -1310,7 +1353,7 @@ class JacUtils:
|
|
|
1310
1353
|
@staticmethod
|
|
1311
1354
|
def attach_program(mach: JacMachine, jac_program: JacProgram) -> None:
|
|
1312
1355
|
"""Attach a JacProgram to the machine."""
|
|
1313
|
-
mach.
|
|
1356
|
+
mach.program = jac_program
|
|
1314
1357
|
|
|
1315
1358
|
@staticmethod
|
|
1316
1359
|
def load_module(
|
|
@@ -1545,7 +1588,6 @@ class JacMachine(JacMachineInterface):
|
|
|
1545
1588
|
base_path: str = "",
|
|
1546
1589
|
session: Optional[str] = None,
|
|
1547
1590
|
root: Optional[str] = None,
|
|
1548
|
-
interp_mode: bool = False,
|
|
1549
1591
|
) -> None:
|
|
1550
1592
|
"""Initialize JacMachine."""
|
|
1551
1593
|
self.loaded_modules: dict[str, types.ModuleType] = {}
|
|
@@ -1558,8 +1600,7 @@ class JacMachine(JacMachineInterface):
|
|
|
1558
1600
|
if not os.path.isdir(base_path)
|
|
1559
1601
|
else os.path.abspath(base_path)
|
|
1560
1602
|
)
|
|
1561
|
-
self.
|
|
1562
|
-
self.interp_mode = interp_mode
|
|
1603
|
+
self.program: JacProgram = JacProgram()
|
|
1563
1604
|
self.pool = ThreadPoolExecutor()
|
|
1564
1605
|
self._event_loop = asyncio.new_event_loop()
|
|
1565
1606
|
self.mem: Memory = ShelfStorage(session)
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
node A {}
|
|
2
2
|
node B {}
|
|
3
3
|
|
|
4
|
+
|
|
4
5
|
walker build {
|
|
5
6
|
can run with `root entry {
|
|
6
7
|
a = A();
|
|
7
|
-
a ++> B();
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
a ++> B();
|
|
9
|
+
# connecting two non persistent nodes
|
|
10
|
+
here ++> a;
|
|
10
11
|
}
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
|
|
13
15
|
walker view {
|
|
14
16
|
can run with `root entry {
|
|
15
|
-
print(
|
|
17
|
+
print(printgraph(here));
|
|
16
18
|
}
|
|
17
|
-
}
|
|
19
|
+
}
|
jaclang/runtimelib/utils.py
CHANGED
|
@@ -133,7 +133,7 @@ def extract_params(
|
|
|
133
133
|
include_info = []
|
|
134
134
|
exclude_info = []
|
|
135
135
|
if body.params:
|
|
136
|
-
for param in body.params
|
|
136
|
+
for param in body.params:
|
|
137
137
|
if isinstance(param, uni.KWPair) and isinstance(param.key, uni.Name):
|
|
138
138
|
key = param.key.value
|
|
139
139
|
value = param.value
|
|
@@ -153,7 +153,7 @@ def extract_params(
|
|
|
153
153
|
)
|
|
154
154
|
include_info.append((var_name, value.gen.py_ast[0]))
|
|
155
155
|
elif isinstance(value, uni.TupleVal) and value.values:
|
|
156
|
-
for i in value.values
|
|
156
|
+
for i in value.values:
|
|
157
157
|
var_name = (
|
|
158
158
|
i.right.value
|
|
159
159
|
if isinstance(i, uni.AtomTrailer)
|
|
@@ -175,7 +175,7 @@ def extract_params(
|
|
|
175
175
|
)
|
|
176
176
|
exclude_info.append((var_name, value.gen.py_ast[0]))
|
|
177
177
|
elif isinstance(value, uni.TupleVal) and value.values:
|
|
178
|
-
for i in value.values
|
|
178
|
+
for i in value.values:
|
|
179
179
|
var_name = (
|
|
180
180
|
i.right.value
|
|
181
181
|
if isinstance(i, uni.AtomTrailer)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
node MyNode{
|
|
2
|
+
has val:int;
|
|
3
|
+
|
|
4
|
+
can do with MyWalker entry {
|
|
5
|
+
print( visitor,"from node", self);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
edge MyEdge {
|
|
10
|
+
has path:int;
|
|
11
|
+
|
|
12
|
+
can do with MyWalker entry {
|
|
13
|
+
print(visitor,"from edge",self);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
walker MyWalker {
|
|
18
|
+
can does with MyNode entry {
|
|
19
|
+
visit [edge <--];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
with entry {
|
|
24
|
+
n0 = MyNode(0);
|
|
25
|
+
n1 = MyNode(10);
|
|
26
|
+
root +>:MyEdge(0):+> n0 <+:MyEdge(1):<+ n1;
|
|
27
|
+
n1 <+:MyEdge(2):<+ MyNode(20);
|
|
28
|
+
n1 <+:MyEdge(3):<+ MyNode(30);
|
|
29
|
+
n1 <+:MyEdge(4):<+ MyNode(40);
|
|
30
|
+
MyWalker() spawn n0;
|
|
31
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
node a {
|
|
2
|
+
has val: int;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
edge Edge1 {
|
|
7
|
+
has val: int = 5;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
with entry {
|
|
12
|
+
end = root;
|
|
13
|
+
for i in range(0, 4) {
|
|
14
|
+
end ++> (end := [ a(val=i) for i in range(0, 3) ]);
|
|
15
|
+
}
|
|
16
|
+
x = [ a(val=i) for i in range(0, 3) ];
|
|
17
|
+
end = x[1];
|
|
18
|
+
for i in range(0, 8) {
|
|
19
|
+
locals()[chr(ord('b') + i)] = (values := [ a(val=j * i + 5.2 * i + 6) for j in range(0, 3) ]);
|
|
20
|
+
end ++> (end := values);
|
|
21
|
+
}
|
|
22
|
+
p = b[1];
|
|
23
|
+
for k in range(0, 10) {
|
|
24
|
+
p +>: Edge1 : val=6 :+> (p := a(val=k));
|
|
25
|
+
}
|
|
26
|
+
# b++>c;
|
|
27
|
+
# c++>b;
|
|
28
|
+
d1 = printgraph();
|
|
29
|
+
l1 = d1 |> len;
|
|
30
|
+
#generate dot for all connected with root
|
|
31
|
+
# d2=printgraph(b[1],Traverse=True,depth=20,bfs=False,node_limit=12);l2=d2|>len; #generate dot for all connected with root
|
|
32
|
+
d2 = printgraph(
|
|
33
|
+
b[1],
|
|
34
|
+
edge_type=["Edge1"],
|
|
35
|
+
depth=20,
|
|
36
|
+
traverse=True,
|
|
37
|
+
bfs=False,
|
|
38
|
+
node_limit=19
|
|
39
|
+
);
|
|
40
|
+
l2 = d2 |> len;
|
|
41
|
+
#generate dot for all connected with root
|
|
42
|
+
d3 = printgraph(b[2], edge_limit=5, depth=5);
|
|
43
|
+
l3 = d3 |> len;
|
|
44
|
+
#generate dot for all connected with b[1] node
|
|
45
|
+
d4 = printgraph(
|
|
46
|
+
b[1],
|
|
47
|
+
bfs=True,
|
|
48
|
+
edge_type=["Edge1"],
|
|
49
|
+
node_limit=100,
|
|
50
|
+
edge_limit=900,
|
|
51
|
+
depth=300
|
|
52
|
+
);
|
|
53
|
+
l4 = d4 |> len;
|
|
54
|
+
#generate dot from nodes with depth 3 connected with b[1] node
|
|
55
|
+
d5 = printgraph(b[1], node_limit=10, edge_limit=90);
|
|
56
|
+
l5 := d5 |> len;
|
|
57
|
+
#generate dot from nodes with depth 3 connected with b[1] node
|
|
58
|
+
print(
|
|
59
|
+
d1.count('a(val') == 12,
|
|
60
|
+
d1.count('#FFFFE0') == 3,
|
|
61
|
+
'Root' in d1,
|
|
62
|
+
d1.count('label=""') == 30
|
|
63
|
+
);
|
|
64
|
+
print(
|
|
65
|
+
d2.count('a(val') == 19,
|
|
66
|
+
d2.count('#F5E5FF') == 2,
|
|
67
|
+
'Edge1' not in d2,
|
|
68
|
+
d2.count('label=""') == 42
|
|
69
|
+
);
|
|
70
|
+
print(d3.count('a(val') == 6, d3.count('label=""') == 5, d3.count('#F5E5FF') == 1);
|
|
71
|
+
print(d4.count("a(val") == 25, d4.count('label=""') == 66, d4.count('#FFF0F') == 3);
|
|
72
|
+
print(d5.count("Edge1(val=6)") == 2, d5.count('label=""') == 24);
|
|
73
|
+
# print(l3<l2);
|
|
74
|
+
|
|
75
|
+
# print(d1);
|
|
76
|
+
|
|
77
|
+
# print(d2);
|
|
78
|
+
|
|
79
|
+
# print(d3);
|
|
80
|
+
|
|
81
|
+
# print(d4);
|
|
82
|
+
|
|
83
|
+
# print(printgraph(node=b[2],bfs=True,depth=3.96,edge_limit=12,node_limit=12.96));
|
|
84
|
+
|
|
85
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import json;
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
node N {
|
|
5
|
+
has val: int;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
edge E {
|
|
10
|
+
has val: int = 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
with entry {
|
|
15
|
+
end = root;
|
|
16
|
+
for i in range(0, 2) {
|
|
17
|
+
end +>: E : val=i :+> (end := [ N(val=i) for i in range(0, 2) ]);
|
|
18
|
+
}
|
|
19
|
+
data = printgraph(node=root, format="json");
|
|
20
|
+
print(data);
|
|
21
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
node N {
|
|
2
|
+
has val: int;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
edge E {
|
|
6
|
+
has val: int = 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
with entry {
|
|
10
|
+
end = root;
|
|
11
|
+
for i in range(0, 2) {
|
|
12
|
+
end +>: E : val=i :+> (end := [ N(val=i) for i in range(0, 2) ]);
|
|
13
|
+
}
|
|
14
|
+
data = printgraph(node=root, format="mermaid");
|
|
15
|
+
print(data);
|
|
16
|
+
}
|
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
import re;
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
glob a : int = 5;
|
|
5
|
+
|
|
4
6
|
|
|
5
7
|
with entry {
|
|
6
|
-
arguments = {x: None
|
|
7
|
-
|
|
8
|
-
"Apple {apple} pineapple {pineapple}"
|
|
9
|
-
)};
|
|
10
|
-
a: int = 5;
|
|
8
|
+
arguments = { x : None for x in re.findall(r'\{([A-Za-z0-9_]+)\}', "Apple {apple} pineapple {pineapple}") };
|
|
9
|
+
a : int = 5;
|
|
11
10
|
if False {
|
|
12
|
-
with open(f"Apple{apple}.txt") as f {
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
with open(f"Apple{apple}.txt") as f {
|
|
12
|
+
# Fix syntax highlighting
|
|
13
|
+
print(
|
|
14
|
+
f.read()
|
|
15
|
+
);
|
|
15
16
|
}
|
|
16
17
|
}
|
|
17
18
|
print(arguments);
|
|
18
|
-
print(
|
|
19
|
-
|
|
19
|
+
print(
|
|
20
|
+
"""This is a long
|
|
21
|
+
line of code."""
|
|
22
|
+
);
|
|
20
23
|
}
|
|
21
24
|
|
|
25
|
+
|
|
22
26
|
with entry {
|
|
23
|
-
a = {"a": "apple", "b": "ball", "c": "cat"};
|
|
24
|
-
y = {**a, "d": "dog", "e": "elephant"};
|
|
27
|
+
a = {"a" : "apple" , "b" : "ball" , "c" : "cat" };
|
|
28
|
+
y = {** a , "d" : "dog" , "e" : "elephant" };
|
|
25
29
|
print(y);
|
|
26
30
|
}
|
|
31
|
+
|
|
32
|
+
|
|
27
33
|
# Use before def error would be nice
|
|
34
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
node MyNode {
|
|
2
|
+
has val:int;
|
|
3
|
+
|
|
4
|
+
can ability1 with MyWalker entry {
|
|
5
|
+
print("MyWalker from node",visitor);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
can ability2 with MyWalker exit {
|
|
9
|
+
print("MyWalker from node",visitor);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
edge MyEdge {
|
|
14
|
+
has path:int;
|
|
15
|
+
|
|
16
|
+
can ability3 with MyWalker entry {
|
|
17
|
+
print("MyWalker from edge",visitor);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
can ability4 with MyWalker exit {
|
|
21
|
+
print("MyWalker from edge",visitor);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
walker MyWalker {
|
|
26
|
+
can ability5 with MyEdge entry {
|
|
27
|
+
print("MyEdge from walker",here);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
can ability6 with MyEdge exit {
|
|
31
|
+
print("MyEdge from walker",here);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
can ability7 with MyNode entry {
|
|
35
|
+
print("MyNode from walker",here);
|
|
36
|
+
visit [edge -->];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
can ability8 with MyNode exit {
|
|
40
|
+
print("MyNode from walker",here);
|
|
41
|
+
visit [edge -->];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
with entry {
|
|
46
|
+
e1 = MyEdge(1);
|
|
47
|
+
root +>:e1:+> MyNode(10) +>:MyEdge(2):+> MyNode(20);
|
|
48
|
+
MyWalker() spawn e1;
|
|
49
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
node MyNode{
|
|
2
|
+
has val:int;
|
|
3
|
+
|
|
4
|
+
can ability1 with MyWalker entry {
|
|
5
|
+
print("Visitor name is ",here.name);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
walker MyWalker{
|
|
10
|
+
has name:str;
|
|
11
|
+
|
|
12
|
+
can ability2 with MyNode entry {
|
|
13
|
+
print("Here value is ",here.val);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
with entry {
|
|
18
|
+
Node1 = MyNode(10);
|
|
19
|
+
Walker1 = MyWalker("Walker 1");
|
|
20
|
+
Walker1 spawn Node1;
|
|
21
|
+
}
|