jaclang 0.2.5__py3-none-any.whl → 0.3.0__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 +3 -3
- jaclang/cli/__init__.py +0 -1
- jaclang/cli/__jac_gen__/cli.py +4 -4
- jaclang/cli/__jac_gen__/cmds.py +1 -1
- jaclang/cli/__jac_gen__/cmds_impl.py +1 -1
- jaclang/core/__init__.py +5 -11
- jaclang/core/__jac_gen__/corelib.py +289 -0
- jaclang/core/__jac_gen__/corelib_impl.py +220 -0
- jaclang/core/corelib.jac +21 -34
- jaclang/core/corelib_impl.jac +317 -0
- jaclang/jac/__init__.py +1 -0
- jaclang/jac/__jac_gen__/jac_parser.py +2 -2
- jaclang/jac/absyntree.py +28 -8
- jaclang/jac/constant.py +3 -7
- jaclang/jac/parser.py +13 -9
- jaclang/jac/passes/main/__init__.py +2 -0
- jaclang/jac/passes/main/def_use_pass.py +3 -2
- jaclang/jac/passes/main/pyast_gen_pass.py +99 -34
- jaclang/jac/passes/main/schedules.py +6 -0
- jaclang/jac/passes/main/sym_tab_build_pass.py +3 -5
- jaclang/jac/passes/main/tests/test_jac_format_pass.py +22 -4
- jaclang/jac/passes/main/tests/test_type_check_pass.py +42 -0
- jaclang/jac/passes/main/type_check_pass.py +103 -0
- jaclang/jac/passes/tool/fuse_comments_pass.py +57 -39
- jaclang/jac/passes/tool/jac_formatter_pass.py +419 -192
- jaclang/jac/passes/transform.py +0 -39
- jaclang/jac/passes/utils/__init__.py +1 -0
- jaclang/jac/passes/utils/mypy_ast_build.py +302 -0
- jaclang/jac/plugin/__init__.py +5 -2
- jaclang/jac/plugin/default.py +20 -4
- jaclang/jac/plugin/feature.py +15 -6
- jaclang/jac/plugin/spec.py +34 -6
- jaclang/jac/tests/test_workspace.py +45 -5
- jaclang/jac/transpiler.py +4 -9
- jaclang/utils/helpers.py +0 -33
- jaclang/utils/lang_tools.py +3 -0
- jaclang/utils/test.py +3 -1
- jaclang/vendor/lark/py.typed +0 -0
- jaclang/vendor/mypy/checker.py +19 -12
- jaclang/vendor/mypy/checkexpr.py +31 -10
- jaclang/vendor/mypy/constraints.py +56 -38
- jaclang/vendor/mypy/expandtype.py +1 -0
- jaclang/vendor/mypy/meet.py +10 -1
- jaclang/vendor/mypy/messages.py +16 -4
- jaclang/vendor/mypy/moduleinspect.py +10 -4
- jaclang/vendor/mypy/py.typed +1 -0
- jaclang/vendor/mypy/semanal.py +18 -17
- jaclang/vendor/mypy/semanal_enum.py +7 -4
- jaclang/vendor/mypy/semanal_namedtuple.py +11 -1
- jaclang/vendor/mypy/semanal_typeddict.py +25 -11
- jaclang/vendor/mypy/stubdoc.py +18 -4
- jaclang/vendor/mypy/stubgen.py +80 -1
- jaclang/vendor/mypy/stubgenc.py +47 -5
- jaclang/vendor/mypy/stubtest.py +53 -3
- jaclang/vendor/mypy/stubutil.py +9 -9
- jaclang/vendor/mypy/test/testipc.py +16 -7
- jaclang/vendor/mypy/test/teststubtest.py +20 -2
- jaclang/vendor/mypy/types.py +1 -1
- jaclang/vendor/mypyc/irbuild/prebuildvisitor.py +2 -1
- jaclang/vendor/mypyc/test/test_run.py +2 -4
- jaclang/vendor/pluggy/py.typed +0 -0
- {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/METADATA +1 -1
- {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/RECORD +67 -62
- {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/WHEEL +1 -1
- {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/entry_points.txt +3 -0
- jaclang/core/arch_impl.jac +0 -131
- jaclang/core/element_impl.jac +0 -109
- jaclang/core/exec_ctx_impl.jac +0 -14
- jaclang/core/memory_impl.jac +0 -57
- jaclang/jac/tests/fixtures/__jac_gen__/hello_world.py +0 -5
- /jaclang/{jac/tests/fixtures → core}/__jac_gen__/__init__.py +0 -0
- {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/top_level.txt +0 -0
jaclang/__init__.py
CHANGED
|
@@ -4,17 +4,17 @@ import sys
|
|
|
4
4
|
|
|
5
5
|
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "vendor"))
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
from jaclang.jac.importer import jac_import # noqa: E402
|
|
9
|
-
from jaclang.
|
|
8
|
+
from jaclang.jac.plugin.feature import JacFeature # noqa: E402
|
|
10
9
|
from jaclang.vendor import lark # noqa: E402
|
|
11
10
|
from jaclang.vendor import mypy # noqa: E402
|
|
12
11
|
from jaclang.vendor import pluggy # noqa: E402
|
|
13
12
|
|
|
14
13
|
__all__ = [
|
|
15
14
|
"jac_import",
|
|
16
|
-
"handle_jac_error",
|
|
17
15
|
"lark",
|
|
18
16
|
"mypy",
|
|
19
17
|
"pluggy",
|
|
20
18
|
]
|
|
19
|
+
|
|
20
|
+
JacFeature.pm.load_setuptools_entrypoints("jac")
|
jaclang/cli/__init__.py
CHANGED
jaclang/cli/__jac_gen__/cli.py
CHANGED
|
@@ -5,7 +5,7 @@ represents the first such complete Jac program.
|
|
|
5
5
|
"""
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
from jaclang import jac_import as __jac_import__
|
|
8
|
-
from jaclang.jac.plugin.feature import JacFeature as
|
|
8
|
+
from jaclang.jac.plugin.feature import JacFeature as _JacFeature
|
|
9
9
|
import inspect
|
|
10
10
|
import argparse
|
|
11
11
|
import cmd
|
|
@@ -13,7 +13,7 @@ __jac_import__(target='cli_impl', base_path=__file__)
|
|
|
13
13
|
from cli_impl import *
|
|
14
14
|
import cli_impl
|
|
15
15
|
|
|
16
|
-
@
|
|
16
|
+
@_JacFeature.make_architype('obj')
|
|
17
17
|
class Command:
|
|
18
18
|
func: callable
|
|
19
19
|
sig: inspect.Signature
|
|
@@ -25,7 +25,7 @@ class Command:
|
|
|
25
25
|
def call(self, *args: list, **kwargs: dict) -> None:
|
|
26
26
|
return self.func(*args, **kwargs)
|
|
27
27
|
|
|
28
|
-
@
|
|
28
|
+
@_JacFeature.make_architype('obj')
|
|
29
29
|
class CommandRegistry:
|
|
30
30
|
registry: dict[str, Command]
|
|
31
31
|
sub_parsers: argparse._SubParsersActionp
|
|
@@ -65,7 +65,7 @@ class CommandRegistry:
|
|
|
65
65
|
def items(self) -> dict[str, Command]:
|
|
66
66
|
return self.registry.items()
|
|
67
67
|
|
|
68
|
-
@
|
|
68
|
+
@_JacFeature.make_architype('obj')
|
|
69
69
|
class CommandShell(cmd.Cmd):
|
|
70
70
|
(intro): str = 'Welcome to the Jac CLI!'
|
|
71
71
|
(prompt): str = 'jac> '
|
jaclang/cli/__jac_gen__/cmds.py
CHANGED
|
@@ -5,7 +5,7 @@ represents the first such production Jac program.
|
|
|
5
5
|
"""
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
from jaclang import jac_import as __jac_import__
|
|
8
|
-
from jaclang.jac.plugin.feature import JacFeature as
|
|
8
|
+
from jaclang.jac.plugin.feature import JacFeature as _JacFeature
|
|
9
9
|
__jac_import__(target='cli', base_path=__file__)
|
|
10
10
|
from cli import cmd_registry as cmd_reg
|
|
11
11
|
__jac_import__(target='cmds_impl', base_path=__file__)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Implementations for the jac command line interface."""
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
from jaclang import jac_import as __jac_import__
|
|
4
|
-
from jaclang.jac.plugin.feature import JacFeature as
|
|
4
|
+
from jaclang.jac.plugin.feature import JacFeature as _JacFeature
|
|
5
5
|
import os
|
|
6
6
|
import shutil
|
|
7
7
|
import unittest
|
jaclang/core/__init__.py
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
"""Core primitives for Jaseci."""
|
|
2
|
-
|
|
2
|
+
from jaclang import jac_import
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
prim = jac_import("corelib")
|
|
5
|
+
if not prim:
|
|
6
|
+
raise ImportError("Could not import primitives, internal compile error")
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
# Node = prim.Node
|
|
10
|
-
# Edge = prim.Edge
|
|
11
|
-
# Walker = prim.Walker
|
|
12
|
-
# make_architype = prim.make_architype
|
|
13
|
-
|
|
14
|
-
# exec_ctx = prim.exec_ctx
|
|
8
|
+
JacPlugin = prim.JacPlugin
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"""Jac's Key Elemental Abstractions"""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from enum import Enum as __jac_Enum__, auto as __jac_auto__
|
|
4
|
+
from jaclang import jac_import as __jac_import__
|
|
5
|
+
from jaclang.jac.plugin.feature import JacFeature as _JacFeature
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from uuid import UUID, uuid4
|
|
8
|
+
from jaclang.jac.constant import EdgeDir
|
|
9
|
+
from jaclang.jac.plugin import Architype, AbsRootHook, hookimpl
|
|
10
|
+
__jac_import__(target='corelib_impl', base_path=__file__)
|
|
11
|
+
from corelib_impl import *
|
|
12
|
+
import corelib_impl
|
|
13
|
+
|
|
14
|
+
class AccessMode(__jac_Enum__):
|
|
15
|
+
READ_ONLY = __jac_auto__()
|
|
16
|
+
READ_WRITE = __jac_auto__()
|
|
17
|
+
PRIVATE = __jac_auto__()
|
|
18
|
+
|
|
19
|
+
@_JacFeature.make_architype('obj')
|
|
20
|
+
class Memory:
|
|
21
|
+
(index): dict[UUID, Element] = {}
|
|
22
|
+
(save_queue): list[Element] = []
|
|
23
|
+
|
|
24
|
+
def get_obj(self, caller_id: UUID, item_id: UUID, override: bool=False) -> Element:
|
|
25
|
+
ret = self.index.get(item_id)
|
|
26
|
+
if override or ret.__is_readable(ret is not None and caller_id):
|
|
27
|
+
return ret
|
|
28
|
+
|
|
29
|
+
def has_obj(self, item_id: UUID) -> bool:
|
|
30
|
+
return item_id in self.index
|
|
31
|
+
|
|
32
|
+
def save_obj(self, caller_id: UUID, item: Element) -> None:
|
|
33
|
+
if item.is_writable(caller_id):
|
|
34
|
+
self.index[item.id] = item
|
|
35
|
+
if item._persist:
|
|
36
|
+
self.save_obj_list.add(item)
|
|
37
|
+
self.mem[item.id] = item
|
|
38
|
+
if item._persist:
|
|
39
|
+
self.save_obj_list.add(item)
|
|
40
|
+
|
|
41
|
+
def del_obj(self, caller_id: UUID, item: Element) -> None:
|
|
42
|
+
if item.is_writable(caller_id):
|
|
43
|
+
self.index.pop(item.id)
|
|
44
|
+
if item._persist:
|
|
45
|
+
self.save_obj_list.remove(item)
|
|
46
|
+
|
|
47
|
+
def get_object_distribution(self) -> dict:
|
|
48
|
+
dist = {}
|
|
49
|
+
for i in self.index.keys():
|
|
50
|
+
t = type(self.index[i])
|
|
51
|
+
if t in dist:
|
|
52
|
+
dist[t] += 1
|
|
53
|
+
else:
|
|
54
|
+
dist[t] = 1
|
|
55
|
+
return dist
|
|
56
|
+
|
|
57
|
+
def get_mem_size(self) -> float:
|
|
58
|
+
return sys.getsizeof(self.index) / 1024.0
|
|
59
|
+
|
|
60
|
+
@_JacFeature.make_architype('obj')
|
|
61
|
+
class ExecutionContext:
|
|
62
|
+
(master): Master = uuid4()
|
|
63
|
+
(memory): Memory = Memory()
|
|
64
|
+
|
|
65
|
+
def reset(self) -> None:
|
|
66
|
+
self.__init__()
|
|
67
|
+
|
|
68
|
+
def get_root(self) -> Node:
|
|
69
|
+
if type(self.master) == UUID:
|
|
70
|
+
self.master = Master()
|
|
71
|
+
return self.master.root_node
|
|
72
|
+
'Global Execution Context, should be monkey patched by the user.'
|
|
73
|
+
exec_ctx = ExecutionContext()
|
|
74
|
+
|
|
75
|
+
@_JacFeature.make_architype('obj')
|
|
76
|
+
class ElementInterface:
|
|
77
|
+
(jid): UUID = uuid4()
|
|
78
|
+
(timestamp): datetime = datetime.now()
|
|
79
|
+
(persist): bool = False
|
|
80
|
+
(access_mode): AccessMode = AccessMode.PRIVATE
|
|
81
|
+
(rw_access): set = set()
|
|
82
|
+
(ro_access): set = set()
|
|
83
|
+
(owner_id): UUID = exec_ctx.master
|
|
84
|
+
(mem): Memory = exec_ctx.memory
|
|
85
|
+
|
|
86
|
+
def make_public_ro(self) -> None:
|
|
87
|
+
self.__jinfo.access_mode = AccessMode.READ_ONLY
|
|
88
|
+
|
|
89
|
+
def make_public_rw(self) -> None:
|
|
90
|
+
self.__jinfo.access_mode = AccessMode.READ_WRITE
|
|
91
|
+
|
|
92
|
+
def make_private(self) -> None:
|
|
93
|
+
self.__jinfo.access_mode = AccessMode.PRIVATE
|
|
94
|
+
|
|
95
|
+
def is_public_ro(self) -> bool:
|
|
96
|
+
return self.__jinfo.access_mode == AccessMode.READ_ONLY
|
|
97
|
+
|
|
98
|
+
def is_public_rw(self) -> bool:
|
|
99
|
+
return self.__jinfo.access_mode == AccessMode.READ_WRITE
|
|
100
|
+
|
|
101
|
+
def is_private(self) -> bool:
|
|
102
|
+
return self.__jinfo.access_mode == AccessMode.PRIVATE
|
|
103
|
+
|
|
104
|
+
def is_readable(self, caller_id: UUID) -> bool:
|
|
105
|
+
return caller_id == self.owner_id or (self.is_public_read() or (caller_id in self.ro_access or caller_id in self.rw_access))
|
|
106
|
+
|
|
107
|
+
def is_writable(self, caller_id: UUID) -> bool:
|
|
108
|
+
return caller_id == self.owner_id or (self.is_public_write() or caller_id in self.rw_access)
|
|
109
|
+
|
|
110
|
+
def give_access(self, caller_id: UUID, read_write: bool=False) -> None:
|
|
111
|
+
if read_write:
|
|
112
|
+
self.rw_access.add(caller_id)
|
|
113
|
+
else:
|
|
114
|
+
add.ro_access.self(caller_id)
|
|
115
|
+
|
|
116
|
+
def revoke_access(self, caller_id: UUID) -> None:
|
|
117
|
+
self.ro_access.discard(caller_id)
|
|
118
|
+
self.rw_access.discard(caller_id)
|
|
119
|
+
|
|
120
|
+
@_JacFeature.make_architype('obj')
|
|
121
|
+
class ObjectInterface(ElementInterface):
|
|
122
|
+
pass
|
|
123
|
+
|
|
124
|
+
@_JacFeature.make_architype('obj')
|
|
125
|
+
class DataSpatialInterface(ObjectInterface):
|
|
126
|
+
(ds_entry_funcs): list[dict] = []
|
|
127
|
+
(ds_exit_funcs): list[dict] = []
|
|
128
|
+
|
|
129
|
+
@staticmethod
|
|
130
|
+
def on_entry(cls: type, triggers: list[type]) -> None:
|
|
131
|
+
|
|
132
|
+
def decorator(func: callable) -> callable:
|
|
133
|
+
cls.ds_entry_funcs.append({'types': triggers, 'func': func})
|
|
134
|
+
|
|
135
|
+
def wrapper(*args: list, **kwargs: dict) -> callable:
|
|
136
|
+
return func(*args, **kwargs)
|
|
137
|
+
return wrapper
|
|
138
|
+
return decorator
|
|
139
|
+
|
|
140
|
+
@staticmethod
|
|
141
|
+
def on_exit(cls: type, triggers: list[type]) -> None:
|
|
142
|
+
|
|
143
|
+
def decorator(func: callable) -> callable:
|
|
144
|
+
cls.ds_exit_funcs.append({'types': triggers, 'func': func})
|
|
145
|
+
|
|
146
|
+
def wrapper(*args: list, **kwargs: dict) -> callable:
|
|
147
|
+
return func(*args, **kwargs)
|
|
148
|
+
return wrapper
|
|
149
|
+
return decorator
|
|
150
|
+
|
|
151
|
+
@_JacFeature.make_architype('obj')
|
|
152
|
+
class NodeInterface(DataSpatialInterface):
|
|
153
|
+
(edges): dict[EdgeDir, list[Edge]] = {EdgeDir.IN: [], EdgeDir.OUT: []}
|
|
154
|
+
|
|
155
|
+
def connect_node(self, nd: Node, edg: Edge) -> Node:
|
|
156
|
+
edg.attach(self.py_obj, nd)
|
|
157
|
+
return self
|
|
158
|
+
|
|
159
|
+
def edges_to_nodes(self, dir: EdgeDir) -> list[Node]:
|
|
160
|
+
ret_nodes = []
|
|
161
|
+
if dir in [EdgeDir.OUT, EdgeDir.ANY]:
|
|
162
|
+
for i in self.edges[EdgeDir.OUT]:
|
|
163
|
+
ret_nodes.append(i.target)
|
|
164
|
+
elif dir in [EdgeDir.IN, EdgeDir.ANY]:
|
|
165
|
+
for i in self.edges[EdgeDir.IN]:
|
|
166
|
+
ret_nodes.append(i.source)
|
|
167
|
+
return ret_nodes
|
|
168
|
+
|
|
169
|
+
def __call__(self, walk: Walker) -> None:
|
|
170
|
+
if not isinstance(walk, Walker):
|
|
171
|
+
raise TypeError('Argument must be a Walker instance')
|
|
172
|
+
walk(self)
|
|
173
|
+
|
|
174
|
+
@_JacFeature.make_architype('obj')
|
|
175
|
+
class EdgeInterface(DataSpatialInterface):
|
|
176
|
+
(source): Node = None
|
|
177
|
+
(target): Node = None
|
|
178
|
+
(dir): EdgeDir = None
|
|
179
|
+
|
|
180
|
+
def apply_dir(self, dir: EdgeDir) -> Edge:
|
|
181
|
+
self.dir = dir
|
|
182
|
+
return self
|
|
183
|
+
|
|
184
|
+
def attach(self, src: Node, trg: Node) -> Edge:
|
|
185
|
+
if self.dir == EdgeDir.IN:
|
|
186
|
+
self.source = trg
|
|
187
|
+
self.target = src
|
|
188
|
+
src._jac_.edges[EdgeDir.IN].append(self)
|
|
189
|
+
trg._jac_.edges[EdgeDir.OUT].append(self)
|
|
190
|
+
else:
|
|
191
|
+
self.source = src
|
|
192
|
+
self.target = trg
|
|
193
|
+
src._jac_.edges[EdgeDir.OUT].append(self)
|
|
194
|
+
trg._jac_.edges[EdgeDir.IN].append(self)
|
|
195
|
+
return self
|
|
196
|
+
|
|
197
|
+
def __call__(self, walk: Walker) -> None:
|
|
198
|
+
if not isinstance(walk, Walker):
|
|
199
|
+
raise TypeError('Argument must be a Walker instance')
|
|
200
|
+
walk(self._jac_.target)
|
|
201
|
+
|
|
202
|
+
@_JacFeature.make_architype('obj')
|
|
203
|
+
class WalkerInterface(DataSpatialInterface):
|
|
204
|
+
(path): list[Node] = []
|
|
205
|
+
(next): list[Node] = []
|
|
206
|
+
(ignores): list[Node] = []
|
|
207
|
+
(disengaged): bool = False
|
|
208
|
+
|
|
209
|
+
def visit_node(self, nds: list[Node] | (list[Edge] | (Node | Edge))) -> None:
|
|
210
|
+
if isinstance(nds, list):
|
|
211
|
+
for i in nds:
|
|
212
|
+
if i not in self.ignores:
|
|
213
|
+
self.next.append(i)
|
|
214
|
+
elif nds not in self.ignores:
|
|
215
|
+
self.next.append(nds)
|
|
216
|
+
return len(nds) if isinstance(nds, list) else 1
|
|
217
|
+
|
|
218
|
+
def ignore_node(self, nds: list[Node] | (list[Edge] | (Node | Edge))) -> None:
|
|
219
|
+
if isinstance(nds, list):
|
|
220
|
+
for i in nds:
|
|
221
|
+
self.ignores.append(i)
|
|
222
|
+
else:
|
|
223
|
+
self.ignores.append(nds)
|
|
224
|
+
|
|
225
|
+
def disengage_now(self) -> None:
|
|
226
|
+
self.next = []
|
|
227
|
+
self.disengaged = True
|
|
228
|
+
|
|
229
|
+
def __call__(self, nd: Node) -> None:
|
|
230
|
+
self._jac_.path = []
|
|
231
|
+
self._jac_.next = [nd]
|
|
232
|
+
walker_type = self.__class__.__name__
|
|
233
|
+
while len(self._jac_.next):
|
|
234
|
+
nd = self._jac_.next.pop(0)
|
|
235
|
+
node_type = nd.__class__.__name__
|
|
236
|
+
for i in nd._jac_ds_.ds_entry_funcs:
|
|
237
|
+
if i['func'].__qualname__.split('.')[0] == node_type and type(self) in i['types']:
|
|
238
|
+
i['func'](nd, self)
|
|
239
|
+
if self._jac_.disengaged:
|
|
240
|
+
return
|
|
241
|
+
for i in self._jac_ds_.ds_entry_funcs:
|
|
242
|
+
if i['func'].__qualname__.split('.')[0] == walker_type and (type(nd) in i['types'] or nd in i['types']):
|
|
243
|
+
i['func'](self, nd)
|
|
244
|
+
if self._jac_.disengaged:
|
|
245
|
+
return
|
|
246
|
+
for i in self._jac_ds_.ds_exit_funcs:
|
|
247
|
+
if i['func'].__qualname__.split('.')[0] == walker_type and (type(nd) in i['types'] or nd in i['types']):
|
|
248
|
+
i['func'](self, nd)
|
|
249
|
+
if self._jac_.disengaged:
|
|
250
|
+
return
|
|
251
|
+
for i in nd._jac_ds_.ds_exit_funcs:
|
|
252
|
+
if i['func'].__qualname__.split('.')[0] == node_type and type(self) in i['types']:
|
|
253
|
+
i['func'](nd, self)
|
|
254
|
+
if self._jac_.disengaged:
|
|
255
|
+
return
|
|
256
|
+
self._jac_.path.append(nd)
|
|
257
|
+
self._jac_.ignores = []
|
|
258
|
+
|
|
259
|
+
@_JacFeature.make_architype('obj')
|
|
260
|
+
class Root(AbsRootHook):
|
|
261
|
+
_jac_: NodeInterface
|
|
262
|
+
RootType: type
|
|
263
|
+
|
|
264
|
+
@_JacFeature.make_architype('obj')
|
|
265
|
+
class Master:
|
|
266
|
+
(_jac_): ElementInterface = ElementInterface()
|
|
267
|
+
(root_node): Root = Root(NodeInterface(), Root)
|
|
268
|
+
|
|
269
|
+
@_JacFeature.make_architype('obj')
|
|
270
|
+
class JacPlugin:
|
|
271
|
+
|
|
272
|
+
@staticmethod
|
|
273
|
+
def bind_architype(arch: AT, arch_type: str) -> bool:
|
|
274
|
+
match arch_type:
|
|
275
|
+
case 'obj':
|
|
276
|
+
arch._jac_ = ObjectInterface()
|
|
277
|
+
case 'node':
|
|
278
|
+
arch._jac_ = NodeInterface()
|
|
279
|
+
case 'edge':
|
|
280
|
+
arch._jac_ = EdgeInterface()
|
|
281
|
+
case 'walker':
|
|
282
|
+
arch._jac_ = WalkerInterface()
|
|
283
|
+
case _:
|
|
284
|
+
raise TypeError('Invalid archetype type')
|
|
285
|
+
return True
|
|
286
|
+
|
|
287
|
+
@staticmethod
|
|
288
|
+
def get_root() -> Architype:
|
|
289
|
+
return exec_ctx.get_root()
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"""Jac's Key Elemental Abstractions"""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from enum import Enum as __jac_Enum__, auto as __jac_auto__
|
|
4
|
+
import sys
|
|
5
|
+
from uuid import UUID, uuid4
|
|
6
|
+
from jaclang.jac.constant import EdgeDir
|
|
7
|
+
from jaclang.jac.plugin import hookimpl
|
|
8
|
+
|
|
9
|
+
def o_Memory_c_get_obj(self, caller_id: UUID, item_id: UUID, override: bool=False) -> Element:
|
|
10
|
+
ret = self.index.get(item_id)
|
|
11
|
+
if override or ret.__is_readable(ret is not None and caller_id):
|
|
12
|
+
return ret
|
|
13
|
+
|
|
14
|
+
def o_Memory_c_has_obj(self, item_id: UUID) -> bool:
|
|
15
|
+
return item_id in self.index
|
|
16
|
+
|
|
17
|
+
def o_Memory_c_save_obj(self, caller_id: UUID, item: Element) -> None:
|
|
18
|
+
if item.is_writable(caller_id):
|
|
19
|
+
self.index[item.id] = item
|
|
20
|
+
if item._persist:
|
|
21
|
+
self.save_obj_list.add(item)
|
|
22
|
+
self.mem[item.id] = item
|
|
23
|
+
if item._persist:
|
|
24
|
+
self.save_obj_list.add(item)
|
|
25
|
+
|
|
26
|
+
def o_Memory_c_del_obj(self, caller_id: UUID, item: Element) -> None:
|
|
27
|
+
if item.is_writable(caller_id):
|
|
28
|
+
self.index.pop(item.id)
|
|
29
|
+
if item._persist:
|
|
30
|
+
self.save_obj_list.remove(item)
|
|
31
|
+
|
|
32
|
+
def o_Memory_c_get_object_distribution(self) -> dict:
|
|
33
|
+
dist = {}
|
|
34
|
+
for i in self.index.keys():
|
|
35
|
+
t = type(self.index[i])
|
|
36
|
+
if t in dist:
|
|
37
|
+
dist[t] += 1
|
|
38
|
+
else:
|
|
39
|
+
dist[t] = 1
|
|
40
|
+
return dist
|
|
41
|
+
|
|
42
|
+
def o_Memory_c_get_mem_size(self) -> float:
|
|
43
|
+
return sys.getsizeof(self.index) / 1024.0
|
|
44
|
+
|
|
45
|
+
def o_ExecutionContext_c_get_root(self) -> None:
|
|
46
|
+
if type(self.master) == UUID:
|
|
47
|
+
self.master = Master()
|
|
48
|
+
return self.master.root_node
|
|
49
|
+
|
|
50
|
+
def o_ExecutionContext_c_reset(self) -> None:
|
|
51
|
+
self.__init__()
|
|
52
|
+
|
|
53
|
+
class e_AccessMode(__jac_Enum__):
|
|
54
|
+
READ_ONLY = __jac_auto__()
|
|
55
|
+
READ_WRITE = __jac_auto__()
|
|
56
|
+
PRIVATE = __jac_auto__()
|
|
57
|
+
|
|
58
|
+
def o_ElementInterface_c_make_public_ro(self) -> None:
|
|
59
|
+
self.__jinfo.access_mode = AccessMode.READ_ONLY
|
|
60
|
+
|
|
61
|
+
def o_ElementInterface_c_make_public_rw(self) -> None:
|
|
62
|
+
self.__jinfo.access_mode = AccessMode.READ_WRITE
|
|
63
|
+
|
|
64
|
+
def o_ElementInterface_c_make_private(self) -> None:
|
|
65
|
+
self.__jinfo.access_mode = AccessMode.PRIVATE
|
|
66
|
+
|
|
67
|
+
def o_ElementInterface_c_is_public_ro(self) -> bool:
|
|
68
|
+
return self.__jinfo.access_mode == AccessMode.READ_ONLY
|
|
69
|
+
|
|
70
|
+
def o_ElementInterface_c_is_public_rw(self) -> bool:
|
|
71
|
+
return self.__jinfo.access_mode == AccessMode.READ_WRITE
|
|
72
|
+
|
|
73
|
+
def o_ElementInterface_c_is_private(self) -> bool:
|
|
74
|
+
return self.__jinfo.access_mode == AccessMode.PRIVATE
|
|
75
|
+
|
|
76
|
+
def o_ElementInterface_c_is_readable(self, caller_id: UUID) -> bool:
|
|
77
|
+
return caller_id == self.owner_id or (self.is_public_read() or (caller_id in self.ro_access or caller_id in self.rw_access))
|
|
78
|
+
|
|
79
|
+
def o_ElementInterface_c_is_writable(self, caller_id: UUID) -> bool:
|
|
80
|
+
return caller_id == self.owner_id or (self.is_public_write() or caller_id in self.rw_access)
|
|
81
|
+
|
|
82
|
+
def o_ElementInterface_c_give_access(self, caller_id: UUID, read_write: bool=False) -> None:
|
|
83
|
+
if read_write:
|
|
84
|
+
self.rw_access.add(caller_id)
|
|
85
|
+
else:
|
|
86
|
+
add.ro_access.self(caller_id)
|
|
87
|
+
|
|
88
|
+
def o_ElementInterface_c_revoke_access(self, caller_id: UUID) -> None:
|
|
89
|
+
self.ro_access.discard(caller_id)
|
|
90
|
+
self.rw_access.discard(caller_id)
|
|
91
|
+
|
|
92
|
+
def o_DataSpatialInterface_c_on_entry(self, cls: type, triggers: list) -> None:
|
|
93
|
+
|
|
94
|
+
def decorator(func: callable) -> callable:
|
|
95
|
+
cls.ds_entry_funcs.append({'types': triggers, 'func': func})
|
|
96
|
+
|
|
97
|
+
def wrapper(*args: list, **kwargs: dict) -> callable:
|
|
98
|
+
return func(*args, **kwargs)
|
|
99
|
+
return wrapper
|
|
100
|
+
return decorator
|
|
101
|
+
|
|
102
|
+
def o_DataSpatialInterface_c_on_exit(self, cls: type, triggers: list) -> None:
|
|
103
|
+
|
|
104
|
+
def decorator(func: callable) -> callable:
|
|
105
|
+
cls.ds_exit_funcs.append({'types': triggers, 'func': func})
|
|
106
|
+
|
|
107
|
+
def wrapper(*args: list, **kwargs: dict) -> callable:
|
|
108
|
+
return func(*args, **kwargs)
|
|
109
|
+
return wrapper
|
|
110
|
+
return decorator
|
|
111
|
+
|
|
112
|
+
def o_NodeInterface_c_connect_node(self, nd: Node, edg: Edge) -> Node:
|
|
113
|
+
edg.attach(self.py_obj, nd)
|
|
114
|
+
return self
|
|
115
|
+
|
|
116
|
+
def o_NodeInterface_c_edges_to_nodes(self, dir: EdgeDir) -> list[Node]:
|
|
117
|
+
ret_nodes = []
|
|
118
|
+
if dir in [EdgeDir.OUT, EdgeDir.ANY]:
|
|
119
|
+
for i in self.edges[EdgeDir.OUT]:
|
|
120
|
+
ret_nodes.append(i.target)
|
|
121
|
+
elif dir in [EdgeDir.IN, EdgeDir.ANY]:
|
|
122
|
+
for i in self.edges[EdgeDir.IN]:
|
|
123
|
+
ret_nodes.append(i.source)
|
|
124
|
+
return ret_nodes
|
|
125
|
+
|
|
126
|
+
def o_EdgeInterface_c_apply_dir(self, dir: EdgeDir) -> Edge:
|
|
127
|
+
self.dir = dir
|
|
128
|
+
return self
|
|
129
|
+
|
|
130
|
+
def o_EdgeInterface_c_attach(self, src: Node, trg: Node) -> Edge:
|
|
131
|
+
if self.dir == EdgeDir.IN:
|
|
132
|
+
self.source = trg
|
|
133
|
+
self.target = src
|
|
134
|
+
src._jac_.edges[EdgeDir.IN].append(self)
|
|
135
|
+
trg._jac_.edges[EdgeDir.OUT].append(self)
|
|
136
|
+
else:
|
|
137
|
+
self.source = src
|
|
138
|
+
self.target = trg
|
|
139
|
+
src._jac_.edges[EdgeDir.OUT].append(self)
|
|
140
|
+
trg._jac_.edges[EdgeDir.IN].append(self)
|
|
141
|
+
return self
|
|
142
|
+
|
|
143
|
+
def o_WalkerInterface_c_visit_node(self, nds: list[Node] | (list[Edge] | (Node | Edge))) -> None:
|
|
144
|
+
if isinstance(nds, list):
|
|
145
|
+
for i in nds:
|
|
146
|
+
if i not in self.ignores:
|
|
147
|
+
self.next.append(i)
|
|
148
|
+
elif nds not in self.ignores:
|
|
149
|
+
self.next.append(nds)
|
|
150
|
+
return len(nds) if isinstance(nds, list) else 1
|
|
151
|
+
|
|
152
|
+
def o_WalkerInterface_c_ignore_node(self, nds: list[Node] | (list[Edge] | (Node | Edge))) -> None:
|
|
153
|
+
if isinstance(nds, list):
|
|
154
|
+
for i in nds:
|
|
155
|
+
self.ignores.append(i)
|
|
156
|
+
else:
|
|
157
|
+
self.ignores.append(nds)
|
|
158
|
+
|
|
159
|
+
def o_WalkerInterface_c_disengage_now(self) -> None:
|
|
160
|
+
self.next = []
|
|
161
|
+
self.disengaged = True
|
|
162
|
+
|
|
163
|
+
def o_NodeInterface_c___call__(self, walk: Walker) -> None:
|
|
164
|
+
if not isinstance(walk, Walker):
|
|
165
|
+
raise TypeError('Argument must be a Walker instance')
|
|
166
|
+
walk(self)
|
|
167
|
+
|
|
168
|
+
def o_EdgeInterface_c___call__(self, walk: Walker) -> None:
|
|
169
|
+
if not isinstance(walk, Walker):
|
|
170
|
+
raise TypeError('Argument must be a Walker instance')
|
|
171
|
+
walk(self._jac_.target)
|
|
172
|
+
|
|
173
|
+
def o_WalkerInterface_c___call__(self, nd: Node) -> None:
|
|
174
|
+
self._jac_.path = []
|
|
175
|
+
self._jac_.next = [nd]
|
|
176
|
+
walker_type = self.__class__.__name__
|
|
177
|
+
while len(self._jac_.next):
|
|
178
|
+
nd = self._jac_.next.pop(0)
|
|
179
|
+
node_type = nd.__class__.__name__
|
|
180
|
+
for i in nd._jac_ds_.ds_entry_funcs:
|
|
181
|
+
if i['func'].__qualname__.split('.')[0] == node_type and type(self) in i['types']:
|
|
182
|
+
i['func'](nd, self)
|
|
183
|
+
if self._jac_.disengaged:
|
|
184
|
+
return
|
|
185
|
+
for i in self._jac_ds_.ds_entry_funcs:
|
|
186
|
+
if i['func'].__qualname__.split('.')[0] == walker_type and (type(nd) in i['types'] or nd in i['types']):
|
|
187
|
+
i['func'](self, nd)
|
|
188
|
+
if self._jac_.disengaged:
|
|
189
|
+
return
|
|
190
|
+
for i in self._jac_ds_.ds_exit_funcs:
|
|
191
|
+
if i['func'].__qualname__.split('.')[0] == walker_type and (type(nd) in i['types'] or nd in i['types']):
|
|
192
|
+
i['func'](self, nd)
|
|
193
|
+
if self._jac_.disengaged:
|
|
194
|
+
return
|
|
195
|
+
for i in nd._jac_ds_.ds_exit_funcs:
|
|
196
|
+
if i['func'].__qualname__.split('.')[0] == node_type and type(self) in i['types']:
|
|
197
|
+
i['func'](nd, self)
|
|
198
|
+
if self._jac_.disengaged:
|
|
199
|
+
return
|
|
200
|
+
self._jac_.path.append(nd)
|
|
201
|
+
self._jac_.ignores = []
|
|
202
|
+
|
|
203
|
+
@hookimpl
|
|
204
|
+
def o_JacPlugin_c_bind_architype(self, arch: AT, arch_type: str) -> bool:
|
|
205
|
+
match arch_type:
|
|
206
|
+
case 'obj':
|
|
207
|
+
arch._jac_ = ObjectInterface()
|
|
208
|
+
case 'node':
|
|
209
|
+
arch._jac_ = NodeInterface()
|
|
210
|
+
case 'edge':
|
|
211
|
+
arch._jac_ = EdgeInterface()
|
|
212
|
+
case 'walker':
|
|
213
|
+
arch._jac_ = WalkerInterface()
|
|
214
|
+
case _:
|
|
215
|
+
raise TypeError('Invalid archetype type')
|
|
216
|
+
return True
|
|
217
|
+
|
|
218
|
+
@hookimpl
|
|
219
|
+
def o_JacPlugin_c_get_root(self) -> None:
|
|
220
|
+
return exec_ctx.get_root()
|