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
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""Core constructs for Jac Language."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from pickle import dumps
|
|
7
|
+
from shelve import Shelf, open
|
|
8
|
+
from typing import Callable, Generator, Generic, Iterable, TypeVar
|
|
9
|
+
from uuid import UUID
|
|
10
|
+
|
|
11
|
+
from .architype import Anchor, NodeAnchor, Root, TANCH
|
|
12
|
+
|
|
13
|
+
ID = TypeVar("ID")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class Memory(Generic[ID, TANCH]):
|
|
18
|
+
"""Generic Memory Handler."""
|
|
19
|
+
|
|
20
|
+
__mem__: dict[ID, TANCH] = field(default_factory=dict)
|
|
21
|
+
__gc__: set[ID] = field(default_factory=set)
|
|
22
|
+
|
|
23
|
+
def close(self) -> None:
|
|
24
|
+
"""Close memory handler."""
|
|
25
|
+
self.__mem__.clear()
|
|
26
|
+
self.__gc__.clear()
|
|
27
|
+
|
|
28
|
+
def find(
|
|
29
|
+
self,
|
|
30
|
+
ids: ID | Iterable[ID],
|
|
31
|
+
filter: Callable[[TANCH], TANCH] | None = None,
|
|
32
|
+
) -> Generator[TANCH, None, None]:
|
|
33
|
+
"""Find anchors from memory by ids with filter."""
|
|
34
|
+
if not isinstance(ids, Iterable):
|
|
35
|
+
ids = [ids]
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
anchor
|
|
39
|
+
for id in ids
|
|
40
|
+
if (anchor := self.__mem__.get(id)) and (not filter or filter(anchor))
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
def find_one(
|
|
44
|
+
self,
|
|
45
|
+
ids: ID | Iterable[ID],
|
|
46
|
+
filter: Callable[[TANCH], TANCH] | None = None,
|
|
47
|
+
) -> TANCH | None:
|
|
48
|
+
"""Find one anchor from memory by ids with filter."""
|
|
49
|
+
return next(self.find(ids, filter), None)
|
|
50
|
+
|
|
51
|
+
def find_by_id(self, id: ID) -> TANCH | None:
|
|
52
|
+
"""Find one by id."""
|
|
53
|
+
return self.__mem__.get(id)
|
|
54
|
+
|
|
55
|
+
def set(self, id: ID, data: TANCH) -> None:
|
|
56
|
+
"""Save anchor to memory."""
|
|
57
|
+
self.__mem__[id] = data
|
|
58
|
+
|
|
59
|
+
def remove(self, ids: ID | Iterable[ID]) -> None:
|
|
60
|
+
"""Remove anchor/s from memory."""
|
|
61
|
+
if not isinstance(ids, Iterable):
|
|
62
|
+
ids = [ids]
|
|
63
|
+
|
|
64
|
+
for id in ids:
|
|
65
|
+
self.__mem__.pop(id, None)
|
|
66
|
+
self.__gc__.add(id)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@dataclass
|
|
70
|
+
class ShelfStorage(Memory[UUID, Anchor]):
|
|
71
|
+
"""Shelf Handler."""
|
|
72
|
+
|
|
73
|
+
__shelf__: Shelf[Anchor] | None = None
|
|
74
|
+
|
|
75
|
+
def __init__(self, session: str | None = None) -> None:
|
|
76
|
+
"""Initialize memory handler."""
|
|
77
|
+
super().__init__()
|
|
78
|
+
self.__shelf__ = open(session) if session else None # noqa: SIM115
|
|
79
|
+
|
|
80
|
+
def close(self) -> None:
|
|
81
|
+
"""Close memory handler."""
|
|
82
|
+
if isinstance(self.__shelf__, Shelf):
|
|
83
|
+
from jaclang.plugin.feature import JacFeature as Jac
|
|
84
|
+
|
|
85
|
+
root = Jac.get_root().__jac__
|
|
86
|
+
|
|
87
|
+
for id in self.__gc__:
|
|
88
|
+
self.__shelf__.pop(str(id), None)
|
|
89
|
+
self.__mem__.pop(id, None)
|
|
90
|
+
|
|
91
|
+
for d in self.__mem__.values():
|
|
92
|
+
if d.persistent and d.hash != hash(dumps(d)):
|
|
93
|
+
_id = str(d.id)
|
|
94
|
+
if p_d := self.__shelf__.get(_id):
|
|
95
|
+
if (
|
|
96
|
+
isinstance(p_d, NodeAnchor)
|
|
97
|
+
and isinstance(d, NodeAnchor)
|
|
98
|
+
and p_d.edges != d.edges
|
|
99
|
+
and root.has_connect_access(d)
|
|
100
|
+
):
|
|
101
|
+
if not d.edges:
|
|
102
|
+
self.__shelf__.pop(_id, None)
|
|
103
|
+
continue
|
|
104
|
+
p_d.edges = d.edges
|
|
105
|
+
|
|
106
|
+
if root.has_write_access(d):
|
|
107
|
+
if hash(dumps(p_d.access)) != hash(dumps(d.access)):
|
|
108
|
+
p_d.access = d.access
|
|
109
|
+
if hash(dumps(d.architype)) != hash(dumps(d.architype)):
|
|
110
|
+
p_d.architype = d.architype
|
|
111
|
+
|
|
112
|
+
self.__shelf__[_id] = p_d
|
|
113
|
+
elif not (
|
|
114
|
+
isinstance(d, NodeAnchor)
|
|
115
|
+
and not isinstance(d.architype, Root)
|
|
116
|
+
and not d.edges
|
|
117
|
+
):
|
|
118
|
+
self.__shelf__[_id] = d
|
|
119
|
+
|
|
120
|
+
self.__shelf__.close()
|
|
121
|
+
super().close()
|
|
122
|
+
|
|
123
|
+
def find(
|
|
124
|
+
self,
|
|
125
|
+
ids: UUID | Iterable[UUID],
|
|
126
|
+
filter: Callable[[Anchor], Anchor] | None = None,
|
|
127
|
+
) -> Generator[Anchor, None, None]:
|
|
128
|
+
"""Find anchors from datasource by ids with filter."""
|
|
129
|
+
if not isinstance(ids, Iterable):
|
|
130
|
+
ids = [ids]
|
|
131
|
+
|
|
132
|
+
if isinstance(self.__shelf__, Shelf):
|
|
133
|
+
for id in ids:
|
|
134
|
+
anchor = self.__mem__.get(id)
|
|
135
|
+
|
|
136
|
+
if (
|
|
137
|
+
not anchor
|
|
138
|
+
and id not in self.__gc__
|
|
139
|
+
and (_anchor := self.__shelf__.get(str(id)))
|
|
140
|
+
):
|
|
141
|
+
self.__mem__[id] = anchor = _anchor
|
|
142
|
+
if anchor and (not filter or filter(anchor)):
|
|
143
|
+
yield anchor
|
|
144
|
+
else:
|
|
145
|
+
yield from super().find(ids, filter)
|
|
146
|
+
|
|
147
|
+
def find_by_id(self, id: UUID) -> Anchor | None:
|
|
148
|
+
"""Find one by id."""
|
|
149
|
+
data = super().find_by_id(id)
|
|
150
|
+
|
|
151
|
+
if (
|
|
152
|
+
not data
|
|
153
|
+
and isinstance(self.__shelf__, Shelf)
|
|
154
|
+
and (data := self.__shelf__.get(str(id)))
|
|
155
|
+
):
|
|
156
|
+
self.__mem__[id] = data
|
|
157
|
+
|
|
158
|
+
return data
|
|
@@ -11,7 +11,7 @@ import jaclang.compiler.absyntree as ast
|
|
|
11
11
|
from jaclang.compiler.semtable import SemScope
|
|
12
12
|
|
|
13
13
|
if TYPE_CHECKING:
|
|
14
|
-
from jaclang.
|
|
14
|
+
from jaclang.runtimelib.constructs import NodeAnchor, NodeArchitype
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
@contextmanager
|
|
@@ -37,12 +37,16 @@ def collect_node_connections(
|
|
|
37
37
|
visited_nodes.add(current_node)
|
|
38
38
|
edges = current_node.edges
|
|
39
39
|
for edge_ in edges:
|
|
40
|
-
target = edge_.
|
|
40
|
+
target = edge_.target
|
|
41
41
|
if target:
|
|
42
42
|
connections.add(
|
|
43
|
-
(
|
|
43
|
+
(
|
|
44
|
+
current_node.architype,
|
|
45
|
+
target.architype,
|
|
46
|
+
edge_.__class__.__name__,
|
|
47
|
+
)
|
|
44
48
|
)
|
|
45
|
-
collect_node_connections(target
|
|
49
|
+
collect_node_connections(target, visited_nodes, connections)
|
|
46
50
|
|
|
47
51
|
|
|
48
52
|
def traverse_graph(
|
|
@@ -61,17 +65,20 @@ def traverse_graph(
|
|
|
61
65
|
edge_limit: int,
|
|
62
66
|
) -> None:
|
|
63
67
|
"""Traverse the graph using Breadth-First Search (BFS) or Depth-First Search (DFS)."""
|
|
64
|
-
for edge in node.
|
|
65
|
-
is_self_loop = id(edge.
|
|
66
|
-
is_in_edge = edge.
|
|
67
|
-
if (traverse and is_in_edge) or edge.
|
|
68
|
+
for edge in node.__jac__.edges:
|
|
69
|
+
is_self_loop = id(edge.source) == id(edge.target)
|
|
70
|
+
is_in_edge = edge.target == node.__jac__
|
|
71
|
+
if (traverse and is_in_edge) or edge.architype.__class__.__name__ in edge_type:
|
|
68
72
|
continue
|
|
69
73
|
if is_self_loop:
|
|
70
74
|
continue # lets skip self loop for a while, need to handle it later
|
|
71
|
-
else
|
|
72
|
-
other_nd
|
|
75
|
+
elif (other_nda := edge.target if not is_in_edge else edge.source) and (
|
|
76
|
+
other_nd := other_nda.architype
|
|
77
|
+
):
|
|
73
78
|
new_con = (
|
|
74
|
-
(node, other_nd, edge)
|
|
79
|
+
(node, other_nd, edge.architype)
|
|
80
|
+
if not is_in_edge
|
|
81
|
+
else (other_nd, node, edge.architype)
|
|
75
82
|
)
|
|
76
83
|
if node in node_depths and node_depths[node] is not None:
|
|
77
84
|
if other_nd in node_depths:
|
|
@@ -113,18 +120,26 @@ def get_sem_scope(node: ast.AstNode) -> SemScope:
|
|
|
113
120
|
a = (
|
|
114
121
|
node.name
|
|
115
122
|
if isinstance(node, ast.Module)
|
|
116
|
-
else
|
|
123
|
+
else (
|
|
124
|
+
node.name.value
|
|
125
|
+
if isinstance(node, (ast.Enum, ast.Architype))
|
|
126
|
+
else node.name_ref.sym_name if isinstance(node, ast.Ability) else ""
|
|
127
|
+
)
|
|
117
128
|
)
|
|
118
129
|
if isinstance(node, ast.Module):
|
|
119
130
|
return SemScope(a, "Module", None)
|
|
120
|
-
elif isinstance(node, (ast.Enum, ast.Architype)):
|
|
131
|
+
elif isinstance(node, (ast.Enum, ast.Architype, ast.Ability)):
|
|
121
132
|
node_type = (
|
|
122
133
|
node.__class__.__name__
|
|
123
134
|
if isinstance(node, ast.Enum)
|
|
124
|
-
else node.arch_type.value
|
|
135
|
+
else ("Ability" if isinstance(node, ast.Ability) else node.arch_type.value)
|
|
125
136
|
)
|
|
126
137
|
if node.parent:
|
|
127
|
-
return SemScope(
|
|
138
|
+
return SemScope(
|
|
139
|
+
a,
|
|
140
|
+
node_type,
|
|
141
|
+
get_sem_scope(node.parent),
|
|
142
|
+
)
|
|
128
143
|
else:
|
|
129
144
|
if node.parent:
|
|
130
145
|
return get_sem_scope(node.parent)
|
jaclang/settings.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Main settings of
|
|
1
|
+
"""Main settings of jac lang."""
|
|
2
2
|
|
|
3
3
|
import configparser
|
|
4
4
|
import os
|
|
@@ -14,10 +14,11 @@ class Settings:
|
|
|
14
14
|
filter_sym_builtins: bool = True
|
|
15
15
|
ast_symbol_info_detailed: bool = False
|
|
16
16
|
pass_timer: bool = False
|
|
17
|
+
collect_py_dep_debug: bool = False
|
|
18
|
+
print_py_raised_ast: bool = False
|
|
17
19
|
|
|
18
|
-
#
|
|
19
|
-
|
|
20
|
-
py_raise_deep: bool = False
|
|
20
|
+
# Formatter configuration
|
|
21
|
+
max_line_length: int = 88
|
|
21
22
|
|
|
22
23
|
# LSP configuration
|
|
23
24
|
lsp_debug: bool = False
|
jaclang/tests/fixtures/abc.jac
CHANGED
|
@@ -63,15 +63,15 @@ with entry:__main__ {
|
|
|
63
63
|
glob expected_area = 78.53981633974483;
|
|
64
64
|
|
|
65
65
|
test calc_area {
|
|
66
|
-
check
|
|
66
|
+
check almostEqual(calculate_area(RAD), expected_area);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
test circle_area {
|
|
70
70
|
c = Circle(RAD);
|
|
71
|
-
check
|
|
71
|
+
check almostEqual(c.area(), expected_area);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
test circle_type {
|
|
75
75
|
c = Circle(RAD);
|
|
76
|
-
check
|
|
76
|
+
check c.shape_type == ShapeType.CIRCLE;
|
|
77
77
|
}
|
|
@@ -1,19 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return "private method";
|
|
9
|
-
}
|
|
10
|
-
can :priv overide_check() {
|
|
11
|
-
return "inside access_check";
|
|
12
|
-
}
|
|
13
|
-
glob :priv b=1;
|
|
14
|
-
glob :priv p=0;
|
|
1
|
+
|
|
2
|
+
obj :pub ModulePublObj {}
|
|
3
|
+
obj :priv ModulePrivObj {}
|
|
4
|
+
|
|
5
|
+
glob :pub module_publ_glob:int = 0;
|
|
6
|
+
glob :priv module_priv_glob:int = 0;
|
|
7
|
+
|
|
15
8
|
with entry {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
ModulePrivObj(); # <-- okey.
|
|
10
|
+
ModulePublObj(); # <-- okey.
|
|
11
|
+
|
|
12
|
+
module_publ_glob; # <-- okey.
|
|
13
|
+
module_priv_glob; # <-- okey.
|
|
19
14
|
}
|
|
@@ -1,49 +1,104 @@
|
|
|
1
1
|
include:jac access_checker;
|
|
2
|
-
obj Animal {
|
|
3
|
-
has :pub species: str;
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
3
|
+
obj SomeObj {
|
|
4
|
+
obj :pub InnerPublObj {}
|
|
5
|
+
obj :priv InnerPrivObj {}
|
|
6
|
+
obj :protect InnerProtObj {}
|
|
7
|
+
|
|
8
|
+
enum :pub InnerPublEnum { FOO = "FOO" }
|
|
9
|
+
enum :priv InnerPrivEnum { BAR = "BAR" }
|
|
10
|
+
enum :protect InnerProtEnum { BAZ = "BAZ" }
|
|
8
11
|
|
|
12
|
+
can :pub publ_ability() -> None {}
|
|
13
|
+
can :priv priv_ability() -> None {}
|
|
14
|
+
can :protect prot_ability() -> None {}
|
|
9
15
|
|
|
16
|
+
has :pub publ_attrib:int = 0;
|
|
17
|
+
has :priv priv_attrib:int = 0;
|
|
18
|
+
has :protect prot_attrib:int = 0;
|
|
10
19
|
}
|
|
11
20
|
|
|
12
|
-
obj Dog: Animal: {
|
|
13
|
-
has :pub breed: str;
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
obj BaseClass {
|
|
23
|
+
has :pub publ_attrib:int = 0;
|
|
24
|
+
has :priv priv_attrib:int = 0;
|
|
25
|
+
has :protect prot_attrib:int = 0;
|
|
19
26
|
|
|
20
|
-
can
|
|
21
|
-
|
|
27
|
+
can do_base() -> None {
|
|
28
|
+
self.publ_attrib; # <-- okey.
|
|
29
|
+
self.priv_attrib; # <-- okey.
|
|
30
|
+
self.prot_attrib; # <-- okey.
|
|
22
31
|
}
|
|
32
|
+
}
|
|
23
33
|
|
|
24
|
-
|
|
25
|
-
|
|
34
|
+
|
|
35
|
+
obj DrivedClass1 :BaseClass: {
|
|
36
|
+
can do_driv1() -> None {
|
|
37
|
+
self.publ_attrib; # <-- okey.
|
|
38
|
+
self.priv_attrib; # <-- not okey.
|
|
39
|
+
self.prot_attrib; # <-- okey.
|
|
26
40
|
}
|
|
27
|
-
|
|
28
|
-
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# Check if the protect works from inherited chain.
|
|
45
|
+
obj DrivedClass2 :BaseClass: {
|
|
46
|
+
can do_driv2() -> None {
|
|
47
|
+
self.publ_attrib; # <-- okey.
|
|
48
|
+
self.priv_attrib; # <-- not okey.
|
|
49
|
+
self.prot_attrib; # <-- okey.
|
|
29
50
|
}
|
|
30
51
|
}
|
|
31
|
-
|
|
32
|
-
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
obj :pub Chain1 {
|
|
56
|
+
has :priv priv_val:int = 0; # <-- the private in the chain.
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
obj :pub Chain2 {
|
|
60
|
+
has :pub chain1:Chain1 = Chain1();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
obj :pub Chain3 {
|
|
64
|
+
has :pub chain2:Chain2 = Chain2();
|
|
33
65
|
}
|
|
34
|
-
|
|
66
|
+
|
|
67
|
+
|
|
35
68
|
with entry {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
69
|
+
SomeObj.InnerPublObj; # <-- okey.
|
|
70
|
+
SomeObj.InnerPrivObj; # <-- not okey.
|
|
71
|
+
SomeObj.InnerProtObj; # <-- not okey.
|
|
72
|
+
|
|
73
|
+
SomeObj.InnerPublEnum; # <-- okey.
|
|
74
|
+
SomeObj.InnerPrivEnum; # <-- not okey.
|
|
75
|
+
SomeObj.InnerProtEnum; # <-- not okey.
|
|
76
|
+
|
|
77
|
+
some_obj = SomeObj();
|
|
78
|
+
|
|
79
|
+
some_obj.InnerPublObj; # <-- okey.
|
|
80
|
+
some_obj.InnerPrivObj; # <-- not okey.
|
|
81
|
+
some_obj.InnerProtObj; # <-- not okey.
|
|
82
|
+
|
|
83
|
+
some_obj.InnerPublEnum; # <-- okey.
|
|
84
|
+
some_obj.InnerPrivEnum; # <-- not okey.
|
|
85
|
+
some_obj.InnerProtEnum; # <-- not okey.
|
|
86
|
+
|
|
87
|
+
some_obj.publ_attrib; # <-- okey.
|
|
88
|
+
some_obj.priv_attrib; # <-- not okey.
|
|
89
|
+
some_obj.prot_attrib; # <-- not okey.
|
|
90
|
+
|
|
91
|
+
some_obj.publ_ability(); # <-- okey.
|
|
92
|
+
some_obj.priv_ability(); # <-- not okey.
|
|
93
|
+
some_obj.prot_ability(); # <-- not okey.
|
|
94
|
+
|
|
95
|
+
chain3: Chain3 = Chain3();
|
|
96
|
+
chain3.chain2.chain1; # <-- okey.
|
|
97
|
+
chain3.chain2.chain1.priv_val; # <-- not okey.
|
|
98
|
+
|
|
99
|
+
access_checker.ModulePublObj(); # <-- okey.
|
|
100
|
+
access_checker.ModulePrivObj(); # <-- not okey.
|
|
101
|
+
|
|
102
|
+
access_checker.module_priv_glob; # <-- okey.
|
|
103
|
+
access_checker.module_priv_glob; # <-- not okey.
|
|
49
104
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Define a simple node type called `Item`
|
|
2
|
+
node Item {
|
|
3
|
+
has value: int = 0;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
# Define an edge type called `Link`
|
|
7
|
+
edge Link {}
|
|
8
|
+
|
|
9
|
+
# Define the `bar` walker
|
|
10
|
+
walker bar_walk {
|
|
11
|
+
has count: int = 0;
|
|
12
|
+
|
|
13
|
+
# Start walking from the root node or an Item node
|
|
14
|
+
can start with `root | Item entry {
|
|
15
|
+
here ++> Item();
|
|
16
|
+
if self.count < 5 {
|
|
17
|
+
visit [-->];
|
|
18
|
+
} else {
|
|
19
|
+
"Created 5 items." |> print;
|
|
20
|
+
disengage;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
# Walk over Item nodes and update their values
|
|
25
|
+
can walk with Item entry {
|
|
26
|
+
here.value = self.count;
|
|
27
|
+
f"Item value: {here.value}" |> print;
|
|
28
|
+
self.count += 1;
|
|
29
|
+
visit [-->] else {
|
|
30
|
+
"Finished walking over all items." |> print;
|
|
31
|
+
disengage;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import:py re;
|
|
2
2
|
|
|
3
|
-
glob a: int=5;
|
|
3
|
+
glob a: int = 5;
|
|
4
4
|
|
|
5
5
|
with entry {
|
|
6
|
-
arguments = {x:None for x in re.findall(
|
|
7
|
-
|
|
6
|
+
arguments = {x: None for x in re.findall(
|
|
7
|
+
r'\{([A-Za-z0-9_]+)\}',
|
|
8
|
+
"Apple {apple} pineapple {pineapple}"
|
|
9
|
+
)};
|
|
10
|
+
a: int = 5;
|
|
8
11
|
if False {
|
|
9
12
|
with open(f"Apple{apple}.txt") as f { # Fix syntax highlighting
|
|
10
13
|
|
|
@@ -12,15 +15,13 @@ with entry {
|
|
|
12
15
|
}
|
|
13
16
|
}
|
|
14
17
|
print(arguments);
|
|
15
|
-
print(
|
|
16
|
-
|
|
17
|
-
line of code."""
|
|
18
|
-
);
|
|
18
|
+
print("""This is a long
|
|
19
|
+
line of code.""");
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
with entry{
|
|
22
|
-
a={"a":"apple", "b":"ball", "c":"cat"};
|
|
23
|
-
y={**a, "d":"dog", "e":"elephant"};
|
|
22
|
+
with entry {
|
|
23
|
+
a = {"a": "apple", "b": "ball", "c": "cat"};
|
|
24
|
+
y = {**a, "d": "dog", "e": "elephant"};
|
|
24
25
|
print(y);
|
|
25
26
|
}
|
|
26
27
|
# Use before def error would be nice
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Test file for class method."""
|
|
2
|
+
|
|
3
|
+
class MyClass {
|
|
4
|
+
can simple_method() -> str {
|
|
5
|
+
return "Hello, World1!";
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
@classmethod
|
|
9
|
+
can my_method(cls: Type[MyClass]) -> str {
|
|
10
|
+
x = cls.__name__;
|
|
11
|
+
print(x);
|
|
12
|
+
return "Hello, World2!";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
with entry {
|
|
17
|
+
a = MyClass.simple_method();
|
|
18
|
+
b = MyClass.my_method();
|
|
19
|
+
print(a, b);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
class MyClass2 {
|
|
23
|
+
can Ability_1(self: MyClass2) -> str;
|
|
24
|
+
@classmethod
|
|
25
|
+
can Ability_2(cls: Type[MyClass2]) -> str;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
:obj:MyClass2:can:Ability_1
|
|
29
|
+
(self: MyClass2) -> str {
|
|
30
|
+
return "Hello, World!";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
:obj:MyClass2:can:Ability_2 {
|
|
34
|
+
return "Hello, World22!";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
with entry {
|
|
38
|
+
a = MyClass2().Ability_1();
|
|
39
|
+
b = MyClass2.Ability_2();
|
|
40
|
+
print(a, b);
|
|
41
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import:jac from .deeper, snd_lev as snd_lev;
|
|
2
|
-
import:jac from ..deep, deeper;
|
|
3
|
-
import:jac from ., deeper as mydeeper;
|
|
2
|
+
# import:jac from ..deep, deeper;
|
|
3
|
+
# import:jac from ., deeper as mydeeper;
|
|
4
4
|
|
|
5
5
|
can olprint -> str {
|
|
6
6
|
# deeper.snd_lev.slprint(); FIXME:
|
|
7
7
|
return "one level deeper" + snd_lev.slprint();
|
|
8
|
-
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import:py sys;
|
|
2
|
+
|
|
3
|
+
with entry {
|
|
4
|
+
before_mod = list(sys.modules.keys());
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
import:jac deep.one_lev as one_lev;
|
|
8
|
+
import:jac from deep.one_lev, olprint;
|
|
9
|
+
|
|
10
|
+
with entry {
|
|
11
|
+
after_mod = [m for m in sys.modules.keys() if m not in before_mod];
|
|
12
|
+
print(after_mod);
|
|
13
|
+
}
|
|
@@ -22,7 +22,7 @@ edge MyEdge {
|
|
|
22
22
|
for j=0 to j<3 by j+=1 {
|
|
23
23
|
end +:MyEdge:val=random.randint(1, 15), val2=random.randint(1, 5):+> node_a(value=j + 10);
|
|
24
24
|
}
|
|
25
|
-
print([(
|
|
25
|
+
print([(arch.val, arch.val2) for i in end.__jac__.edges if isinstance(arch := i.architype, MyEdge)]);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
for i=0 to i<3 by i+=1 {
|