jaclang 0.7.2__py3-none-any.whl → 0.7.7__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 +2 -2
- jaclang/compiler/absyntree.py +499 -294
- jaclang/compiler/codeloc.py +2 -2
- jaclang/compiler/constant.py +100 -2
- jaclang/compiler/jac.lark +27 -19
- jaclang/compiler/parser.py +119 -92
- jaclang/compiler/passes/main/access_modifier_pass.py +20 -12
- jaclang/compiler/passes/main/def_impl_match_pass.py +28 -14
- jaclang/compiler/passes/main/def_use_pass.py +59 -40
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +65 -43
- jaclang/compiler/passes/main/import_pass.py +8 -6
- jaclang/compiler/passes/main/pyast_gen_pass.py +97 -42
- jaclang/compiler/passes/main/pyast_load_pass.py +47 -12
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +19 -10
- jaclang/compiler/passes/main/registry_pass.py +6 -6
- jaclang/compiler/passes/main/sub_node_tab_pass.py +0 -5
- jaclang/compiler/passes/main/sym_tab_build_pass.py +43 -235
- jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +21 -4
- jaclang/compiler/passes/main/tests/test_def_use_pass.py +5 -10
- jaclang/compiler/passes/main/type_check_pass.py +2 -1
- jaclang/compiler/passes/tool/jac_formatter_pass.py +30 -9
- jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +16 -0
- jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +16 -0
- jaclang/compiler/passes/tool/tests/fixtures/genai/essay_review.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/expert_answer.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/joke_gen.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/odd_word_out.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/personality_finder.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/text_to_type.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/translator.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/wikipedia.jac +1 -1
- jaclang/compiler/passes/transform.py +2 -4
- jaclang/{core/registry.py → compiler/semtable.py} +1 -3
- jaclang/compiler/symtable.py +142 -101
- jaclang/compiler/tests/test_parser.py +2 -2
- jaclang/core/aott.py +15 -11
- jaclang/core/{construct.py → architype.py} +25 -240
- jaclang/core/constructs.py +44 -0
- jaclang/core/context.py +157 -0
- jaclang/core/importer.py +18 -9
- jaclang/core/memory.py +99 -0
- jaclang/core/test.py +90 -0
- jaclang/core/utils.py +2 -2
- jaclang/langserve/engine.py +127 -50
- jaclang/langserve/server.py +34 -61
- jaclang/langserve/tests/fixtures/base_module_structure.jac +28 -0
- jaclang/langserve/tests/fixtures/circle.jac +16 -12
- jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
- jaclang/langserve/tests/fixtures/circle_pure.test.jac +15 -0
- jaclang/langserve/tests/fixtures/import_include_statements.jac +6 -0
- jaclang/langserve/tests/fixtures/py_import.py +26 -0
- jaclang/langserve/tests/test_server.py +93 -18
- jaclang/langserve/utils.py +124 -10
- jaclang/plugin/builtin.py +1 -1
- jaclang/plugin/default.py +23 -9
- jaclang/plugin/feature.py +25 -7
- jaclang/plugin/spec.py +18 -20
- jaclang/settings.py +3 -0
- jaclang/tests/fixtures/abc.jac +16 -12
- jaclang/tests/fixtures/aott_raise.jac +1 -1
- jaclang/tests/fixtures/byllmissue.jac +9 -0
- jaclang/tests/fixtures/edgetypeissue.jac +10 -0
- jaclang/tests/fixtures/hello.jac +1 -1
- jaclang/tests/fixtures/impl_match_confused.impl.jac +1 -0
- jaclang/tests/fixtures/impl_match_confused.jac +5 -0
- jaclang/tests/fixtures/maxfail_run_test.jac +17 -5
- jaclang/tests/fixtures/run_test.jac +17 -5
- jaclang/tests/fixtures/with_llm_function.jac +1 -1
- jaclang/tests/fixtures/with_llm_lower.jac +1 -1
- jaclang/tests/fixtures/with_llm_method.jac +1 -1
- jaclang/tests/fixtures/with_llm_type.jac +1 -1
- jaclang/tests/fixtures/with_llm_vision.jac +1 -1
- jaclang/tests/test_bugs.py +19 -0
- jaclang/tests/test_cli.py +1 -1
- jaclang/tests/test_language.py +161 -96
- jaclang/tests/test_reference.py +1 -1
- jaclang/utils/lang_tools.py +5 -4
- jaclang/utils/test.py +2 -1
- jaclang/utils/treeprinter.py +22 -8
- {jaclang-0.7.2.dist-info → jaclang-0.7.7.dist-info}/METADATA +1 -1
- {jaclang-0.7.2.dist-info → jaclang-0.7.7.dist-info}/RECORD +83 -80
- jaclang/core/llms/__init__.py +0 -20
- jaclang/core/llms/anthropic.py +0 -90
- jaclang/core/llms/base.py +0 -206
- jaclang/core/llms/groq.py +0 -70
- jaclang/core/llms/huggingface.py +0 -76
- jaclang/core/llms/ollama.py +0 -81
- jaclang/core/llms/openai.py +0 -65
- jaclang/core/llms/togetherai.py +0 -63
- jaclang/core/llms/utils.py +0 -9
- {jaclang-0.7.2.dist-info → jaclang-0.7.7.dist-info}/WHEEL +0 -0
- {jaclang-0.7.2.dist-info → jaclang-0.7.7.dist-info}/entry_points.txt +0 -0
|
@@ -12,7 +12,7 @@ import pickle
|
|
|
12
12
|
import jaclang.compiler.absyntree as ast
|
|
13
13
|
from jaclang.compiler.constant import Constants as Con
|
|
14
14
|
from jaclang.compiler.passes import Pass
|
|
15
|
-
from jaclang.
|
|
15
|
+
from jaclang.compiler.semtable import SemInfo, SemRegistry
|
|
16
16
|
from jaclang.core.utils import get_sem_scope
|
|
17
17
|
|
|
18
18
|
|
|
@@ -48,7 +48,7 @@ class RegistryPass(Pass):
|
|
|
48
48
|
seminfo = SemInfo(
|
|
49
49
|
node.name.value,
|
|
50
50
|
node.arch_type.value,
|
|
51
|
-
node.semstr.lit_value if node.semstr else
|
|
51
|
+
node.semstr.lit_value if node.semstr else "",
|
|
52
52
|
)
|
|
53
53
|
if (
|
|
54
54
|
len(self.modules_visited)
|
|
@@ -61,7 +61,7 @@ class RegistryPass(Pass):
|
|
|
61
61
|
"""Save enum information."""
|
|
62
62
|
scope = get_sem_scope(node)
|
|
63
63
|
seminfo = SemInfo(
|
|
64
|
-
node.name.value, "Enum", node.semstr.lit_value if node.semstr else
|
|
64
|
+
node.name.value, "Enum", node.semstr.lit_value if node.semstr else ""
|
|
65
65
|
)
|
|
66
66
|
if (
|
|
67
67
|
len(self.modules_visited)
|
|
@@ -79,7 +79,7 @@ class RegistryPass(Pass):
|
|
|
79
79
|
seminfo = SemInfo(
|
|
80
80
|
node.name.value,
|
|
81
81
|
extracted_type,
|
|
82
|
-
node.semstr.lit_value if node.semstr else
|
|
82
|
+
node.semstr.lit_value if node.semstr else "",
|
|
83
83
|
)
|
|
84
84
|
if len(self.modules_visited) and self.modules_visited[-1].registry:
|
|
85
85
|
self.modules_visited[-1].registry.add(scope, seminfo)
|
|
@@ -100,7 +100,7 @@ class RegistryPass(Pass):
|
|
|
100
100
|
else ""
|
|
101
101
|
),
|
|
102
102
|
extracted_type,
|
|
103
|
-
node.semstr.lit_value if node.semstr else
|
|
103
|
+
node.semstr.lit_value if node.semstr else "",
|
|
104
104
|
)
|
|
105
105
|
if len(self.modules_visited) and self.modules_visited[-1].registry:
|
|
106
106
|
self.modules_visited[-1].registry.add(scope, seminfo)
|
|
@@ -113,7 +113,7 @@ class RegistryPass(Pass):
|
|
|
113
113
|
and node.parent.parent.__class__.__name__ == "Enum"
|
|
114
114
|
):
|
|
115
115
|
scope = get_sem_scope(node)
|
|
116
|
-
seminfo = SemInfo(node.value, None,
|
|
116
|
+
seminfo = SemInfo(node.value, None, "")
|
|
117
117
|
if len(self.modules_visited) and self.modules_visited[-1].registry:
|
|
118
118
|
self.modules_visited[-1].registry.add(scope, seminfo)
|
|
119
119
|
|
|
@@ -6,7 +6,6 @@ pass and is not required for any other pass to work.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
from copy import copy
|
|
9
|
-
from typing import Optional
|
|
10
9
|
|
|
11
10
|
import jaclang.compiler.absyntree as ast
|
|
12
11
|
from jaclang.compiler.passes import Pass
|
|
@@ -15,10 +14,6 @@ from jaclang.compiler.passes import Pass
|
|
|
15
14
|
class SubNodeTabPass(Pass):
|
|
16
15
|
"""AST Enrichment Pass for basic high level semantics."""
|
|
17
16
|
|
|
18
|
-
def before_pass(self) -> None:
|
|
19
|
-
"""Initialize pass."""
|
|
20
|
-
self.cur_module: Optional[ast.Module] = None
|
|
21
|
-
|
|
22
17
|
def enter_node(self, node: ast.AstNode) -> None:
|
|
23
18
|
"""Table builder."""
|
|
24
19
|
super().enter_node(node)
|
|
@@ -4,210 +4,19 @@ This pass builds the symbol table tree for the Jaseci Ast. It also adds symbols
|
|
|
4
4
|
for globals, imports, architypes, and abilities declarations and definitions.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
import ast as ast3
|
|
8
7
|
import builtins
|
|
9
|
-
from typing import Optional, Sequence
|
|
10
8
|
|
|
11
9
|
import jaclang.compiler.absyntree as ast
|
|
12
10
|
from jaclang.compiler.constant import Tokens as Tok
|
|
13
11
|
from jaclang.compiler.passes import Pass
|
|
14
|
-
from jaclang.compiler.symtable import
|
|
12
|
+
from jaclang.compiler.symtable import SymbolTable
|
|
15
13
|
|
|
16
14
|
|
|
17
|
-
class
|
|
18
|
-
"""Jac Ast build pass."""
|
|
19
|
-
|
|
20
|
-
def before_pass(self) -> None:
|
|
21
|
-
"""Before pass."""
|
|
22
|
-
self.unlinked: set[ast.AstSymbolNode] = set() # Failed use lookups
|
|
23
|
-
self.linked: set[ast.AstSymbolNode] = set() # Successful use lookups
|
|
24
|
-
|
|
25
|
-
def seen(self, node: ast.AstSymbolNode) -> bool:
|
|
26
|
-
"""Check if seen."""
|
|
27
|
-
result = node in self.linked or node in self.unlinked
|
|
28
|
-
if node.sym_link and not result:
|
|
29
|
-
self.linked.add(node)
|
|
30
|
-
return True
|
|
31
|
-
return result
|
|
32
|
-
|
|
33
|
-
def inherit_sym_tab(self, scope: SymbolTable, sym_tab: SymbolTable) -> None:
|
|
34
|
-
"""Inherit symbol table."""
|
|
35
|
-
for i in sym_tab.tab.values():
|
|
36
|
-
self.def_insert(i.decl, access_spec=i.access, table_override=scope)
|
|
37
|
-
|
|
38
|
-
def def_insert(
|
|
39
|
-
self,
|
|
40
|
-
node: ast.AstSymbolNode,
|
|
41
|
-
access_spec: Optional[ast.AstAccessNode] | SymbolAccess = None,
|
|
42
|
-
single_decl: Optional[str] = None,
|
|
43
|
-
table_override: Optional[SymbolTable] = None,
|
|
44
|
-
) -> Optional[Symbol]:
|
|
45
|
-
"""Insert into symbol table."""
|
|
46
|
-
table = table_override if table_override else node.sym_tab
|
|
47
|
-
if self.seen(node) and node.sym_link and table == node.sym_link.parent_tab:
|
|
48
|
-
return node.sym_link
|
|
49
|
-
if table:
|
|
50
|
-
table.insert(
|
|
51
|
-
node=node, single=single_decl is not None, access_spec=access_spec
|
|
52
|
-
)
|
|
53
|
-
self.update_py_ctx_for_def(node)
|
|
54
|
-
self.handle_hit_outcome(node)
|
|
55
|
-
return node.sym_link
|
|
56
|
-
|
|
57
|
-
def update_py_ctx_for_def(self, node: ast.AstSymbolNode) -> None:
|
|
58
|
-
"""Update python context for definition."""
|
|
59
|
-
node.py_ctx_func = ast3.Store
|
|
60
|
-
if isinstance(node.sym_name_node, ast.AstSymbolNode):
|
|
61
|
-
node.sym_name_node.py_ctx_func = ast3.Store
|
|
62
|
-
if isinstance(node, (ast.TupleVal, ast.ListVal)) and node.values:
|
|
63
|
-
# Handling of UnaryExpr case for item is only necessary for
|
|
64
|
-
# the generation of Starred nodes in the AST for examples
|
|
65
|
-
# like `(a, *b) = (1, 2, 3, 4)`.
|
|
66
|
-
def fix(item: ast.TupleVal | ast.ListVal | ast.UnaryExpr) -> None:
|
|
67
|
-
if isinstance(item, ast.UnaryExpr):
|
|
68
|
-
if isinstance(item.operand, ast.AstSymbolNode):
|
|
69
|
-
item.operand.py_ctx_func = ast3.Store
|
|
70
|
-
elif isinstance(item, (ast.TupleVal, ast.ListVal)):
|
|
71
|
-
for i in item.values.items if item.values else []:
|
|
72
|
-
if isinstance(i, ast.AstSymbolNode):
|
|
73
|
-
i.py_ctx_func = ast3.Store
|
|
74
|
-
elif isinstance(i, ast.AtomTrailer):
|
|
75
|
-
self.chain_def_insert(self.unwind_atom_trailer(i))
|
|
76
|
-
if isinstance(i, (ast.TupleVal, ast.ListVal, ast.UnaryExpr)):
|
|
77
|
-
fix(i)
|
|
78
|
-
|
|
79
|
-
fix(node)
|
|
80
|
-
|
|
81
|
-
def use_lookup(
|
|
82
|
-
self,
|
|
83
|
-
node: ast.AstSymbolNode,
|
|
84
|
-
sym_table: Optional[SymbolTable] = None,
|
|
85
|
-
) -> Optional[Symbol]:
|
|
86
|
-
"""Link to symbol."""
|
|
87
|
-
if self.seen(node):
|
|
88
|
-
return node.sym_link
|
|
89
|
-
if not sym_table:
|
|
90
|
-
sym_table = node.sym_tab
|
|
91
|
-
if sym_table:
|
|
92
|
-
node.sym_link = (
|
|
93
|
-
sym_table.lookup(name=node.sym_name, deep=True) if sym_table else None
|
|
94
|
-
)
|
|
95
|
-
# If successful lookup mark linked, add to table uses, and link others
|
|
96
|
-
if node.sym_link:
|
|
97
|
-
sym_table.uses.append(node)
|
|
98
|
-
self.handle_hit_outcome(node)
|
|
99
|
-
return node.sym_link
|
|
100
|
-
|
|
101
|
-
def chain_def_insert(self, node_list: Sequence[ast.AstSymbolNode]) -> None:
|
|
102
|
-
"""Link chain of containing names to symbol."""
|
|
103
|
-
if not node_list:
|
|
104
|
-
return
|
|
105
|
-
cur_sym_tab = node_list[0].sym_tab
|
|
106
|
-
node_list[-1].py_ctx_func = ast3.Store
|
|
107
|
-
if isinstance(node_list[-1].sym_name_node, ast.AstSymbolNode):
|
|
108
|
-
node_list[-1].sym_name_node.py_ctx_func = ast3.Store
|
|
109
|
-
|
|
110
|
-
node_list = node_list[:-1] # Just performs lookup mappings of pre assign chain
|
|
111
|
-
for i in node_list:
|
|
112
|
-
if cur_sym_tab is None:
|
|
113
|
-
break
|
|
114
|
-
cur_sym_tab = (
|
|
115
|
-
lookup.decl.sym_tab
|
|
116
|
-
if (
|
|
117
|
-
lookup := self.use_lookup(
|
|
118
|
-
i,
|
|
119
|
-
sym_table=cur_sym_tab,
|
|
120
|
-
)
|
|
121
|
-
)
|
|
122
|
-
else None
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
def chain_use_lookup(self, node_list: Sequence[ast.AstSymbolNode]) -> None:
|
|
126
|
-
"""Link chain of containing names to symbol."""
|
|
127
|
-
if not node_list:
|
|
128
|
-
return
|
|
129
|
-
cur_sym_tab = node_list[0].sym_tab
|
|
130
|
-
for i in node_list:
|
|
131
|
-
if cur_sym_tab is None:
|
|
132
|
-
break
|
|
133
|
-
cur_sym_tab = (
|
|
134
|
-
lookup.decl.sym_tab
|
|
135
|
-
if (
|
|
136
|
-
lookup := self.use_lookup(
|
|
137
|
-
i,
|
|
138
|
-
sym_table=cur_sym_tab,
|
|
139
|
-
)
|
|
140
|
-
)
|
|
141
|
-
else None
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
def unwind_atom_trailer(self, node: ast.AtomTrailer) -> list[ast.AstSymbolNode]:
|
|
145
|
-
"""Sub objects.
|
|
146
|
-
|
|
147
|
-
target: ExprType,
|
|
148
|
-
right: AtomType,
|
|
149
|
-
is_scope_contained: bool,
|
|
150
|
-
"""
|
|
151
|
-
left = node.right if isinstance(node.right, ast.AtomTrailer) else node.target
|
|
152
|
-
right = node.target if isinstance(node.right, ast.AtomTrailer) else node.right
|
|
153
|
-
trag_list: list[ast.AstSymbolNode] = (
|
|
154
|
-
[right] if isinstance(right, ast.AstSymbolNode) else []
|
|
155
|
-
)
|
|
156
|
-
if not trag_list:
|
|
157
|
-
self.ice("Something went very wrong with atom trailer not valid")
|
|
158
|
-
while isinstance(left, ast.AtomTrailer) and left.is_attr:
|
|
159
|
-
if isinstance(left.right, ast.AstSymbolNode):
|
|
160
|
-
trag_list.insert(0, left.right)
|
|
161
|
-
else:
|
|
162
|
-
raise self.ice("Something went very wrong with atom trailer not valid")
|
|
163
|
-
left = left.target
|
|
164
|
-
if isinstance(left, ast.AstSymbolNode):
|
|
165
|
-
trag_list.insert(0, left)
|
|
166
|
-
return trag_list
|
|
167
|
-
|
|
168
|
-
def handle_hit_outcome(
|
|
169
|
-
self,
|
|
170
|
-
node: ast.AstSymbolNode,
|
|
171
|
-
) -> None:
|
|
172
|
-
"""Handle outcome of lookup or insert."""
|
|
173
|
-
# If successful lookup mark linked, add to table uses, and link others
|
|
174
|
-
if node.sym_link:
|
|
175
|
-
self.linked.add(node)
|
|
176
|
-
if isinstance(node.sym_name_node, ast.AstSymbolNode):
|
|
177
|
-
node.sym_name_node.sym_link = node.sym_link
|
|
178
|
-
if not node.sym_link:
|
|
179
|
-
# Mark nodes that were not successfully linked
|
|
180
|
-
self.unlinked.add(node)
|
|
181
|
-
if (
|
|
182
|
-
isinstance(node.sym_name_node, ast.AstSymbolNode)
|
|
183
|
-
and not node.sym_name_node.sym_link
|
|
184
|
-
):
|
|
185
|
-
self.unlinked.add(node.sym_name_node)
|
|
186
|
-
|
|
187
|
-
def already_declared_err(
|
|
188
|
-
self,
|
|
189
|
-
name: str,
|
|
190
|
-
typ: str,
|
|
191
|
-
original: ast.AstNode,
|
|
192
|
-
other_nodes: Optional[list[ast.AstNode]] = None,
|
|
193
|
-
) -> None:
|
|
194
|
-
"""Already declared error."""
|
|
195
|
-
err_msg = (
|
|
196
|
-
f"Name used for {typ} '{name}' already declared at "
|
|
197
|
-
f"{original.loc.mod_path}, line {original.loc.first_line}"
|
|
198
|
-
)
|
|
199
|
-
if other_nodes:
|
|
200
|
-
for i in other_nodes:
|
|
201
|
-
err_msg += f", also see {i.loc.mod_path}, line {i.loc.first_line}"
|
|
202
|
-
self.warning(err_msg)
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
class SymTabBuildPass(SymTabPass):
|
|
15
|
+
class SymTabBuildPass(Pass):
|
|
206
16
|
"""Jac Symbol table build pass."""
|
|
207
17
|
|
|
208
18
|
def before_pass(self) -> None:
|
|
209
19
|
"""Before pass."""
|
|
210
|
-
super().before_pass()
|
|
211
20
|
self.cur_sym_tab: list[SymbolTable] = []
|
|
212
21
|
|
|
213
22
|
def push_scope(self, name: str, key_node: ast.AstNode, fresh: bool = False) -> None:
|
|
@@ -215,19 +24,20 @@ class SymTabBuildPass(SymTabPass):
|
|
|
215
24
|
if fresh:
|
|
216
25
|
self.cur_sym_tab.append(SymbolTable(name, key_node))
|
|
217
26
|
else:
|
|
218
|
-
self.cur_sym_tab.append(self.cur_scope
|
|
27
|
+
self.cur_sym_tab.append(self.cur_scope.push_scope(name, key_node))
|
|
219
28
|
|
|
220
29
|
def pop_scope(self) -> SymbolTable:
|
|
221
30
|
"""Pop scope."""
|
|
222
31
|
return self.cur_sym_tab.pop()
|
|
223
32
|
|
|
33
|
+
@property
|
|
224
34
|
def cur_scope(self) -> SymbolTable:
|
|
225
35
|
"""Return current scope."""
|
|
226
36
|
return self.cur_sym_tab[-1]
|
|
227
37
|
|
|
228
38
|
def sync_node_to_scope(self, node: ast.AstNode) -> None:
|
|
229
39
|
"""Sync node to scope."""
|
|
230
|
-
node.sym_tab = self.cur_scope
|
|
40
|
+
node.sym_tab = self.cur_scope
|
|
231
41
|
|
|
232
42
|
def enter_module(self, node: ast.Module) -> None:
|
|
233
43
|
"""Sub objects.
|
|
@@ -238,7 +48,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
238
48
|
mod_path: str,
|
|
239
49
|
is_imported: bool,
|
|
240
50
|
"""
|
|
241
|
-
self.push_scope(node.name, node, fresh=
|
|
51
|
+
self.push_scope(node.name, node, fresh=(node == self.ir))
|
|
242
52
|
self.sync_node_to_scope(node)
|
|
243
53
|
for obj in dir(builtins):
|
|
244
54
|
builtin = ast.Name(
|
|
@@ -246,13 +56,15 @@ class SymTabBuildPass(SymTabPass):
|
|
|
246
56
|
name=Tok.NAME,
|
|
247
57
|
value=str(obj),
|
|
248
58
|
line=0,
|
|
59
|
+
end_line=0,
|
|
249
60
|
col_start=0,
|
|
250
61
|
col_end=0,
|
|
251
62
|
pos_start=0,
|
|
252
63
|
pos_end=0,
|
|
253
64
|
)
|
|
254
65
|
self.sync_node_to_scope(builtin)
|
|
255
|
-
|
|
66
|
+
builtin.sym_tab.def_insert(builtin)
|
|
67
|
+
# self.def_insert(ast.Name.gen_stub_from_node(node.name, "root"))
|
|
256
68
|
|
|
257
69
|
def exit_module(self, node: ast.Module) -> None:
|
|
258
70
|
"""Sub objects.
|
|
@@ -263,23 +75,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
263
75
|
mod_path: str,
|
|
264
76
|
is_imported: bool,
|
|
265
77
|
"""
|
|
266
|
-
|
|
267
|
-
# If not the main module add all the other modules symbol table
|
|
268
|
-
# as a child to the current symbol table
|
|
269
|
-
if node != self.ir:
|
|
270
|
-
self.cur_scope().kid.append(s)
|
|
271
|
-
s.parent = self.cur_scope()
|
|
272
|
-
|
|
273
|
-
if (
|
|
274
|
-
isinstance(node.parent, ast.Module)
|
|
275
|
-
and node
|
|
276
|
-
in [
|
|
277
|
-
node.parent.impl_mod,
|
|
278
|
-
node.parent.test_mod,
|
|
279
|
-
]
|
|
280
|
-
and node.sym_tab
|
|
281
|
-
):
|
|
282
|
-
self.inherit_sym_tab(scope=self.cur_scope(), sym_tab=node.sym_tab)
|
|
78
|
+
self.pop_scope()
|
|
283
79
|
|
|
284
80
|
def enter_global_vars(self, node: ast.GlobalVars) -> None:
|
|
285
81
|
"""Sub objects.
|
|
@@ -302,7 +98,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
302
98
|
for i in self.get_all_sub_nodes(node, ast.Assignment):
|
|
303
99
|
for j in i.target.items:
|
|
304
100
|
if isinstance(j, ast.AstSymbolNode):
|
|
305
|
-
|
|
101
|
+
j.sym_tab.def_insert(j, access_spec=node, single_decl="global var")
|
|
306
102
|
else:
|
|
307
103
|
self.ice("Expected name type for globabl vars")
|
|
308
104
|
|
|
@@ -328,7 +124,14 @@ class SymTabBuildPass(SymTabPass):
|
|
|
328
124
|
description: Token,
|
|
329
125
|
body: CodeBlock,
|
|
330
126
|
"""
|
|
127
|
+
self.push_scope(node.sym_name, node)
|
|
331
128
|
self.sync_node_to_scope(node)
|
|
129
|
+
import unittest
|
|
130
|
+
|
|
131
|
+
for i in [j for j in dir(unittest.TestCase()) if j.startswith("assert")]:
|
|
132
|
+
node.sym_tab.def_insert(
|
|
133
|
+
ast.Name.gen_stub_from_node(node, i, set_name_of=node)
|
|
134
|
+
)
|
|
332
135
|
|
|
333
136
|
def exit_test(self, node: ast.Test) -> None:
|
|
334
137
|
"""Sub objects.
|
|
@@ -338,9 +141,6 @@ class SymTabBuildPass(SymTabPass):
|
|
|
338
141
|
description: Token,
|
|
339
142
|
body: CodeBlock,
|
|
340
143
|
"""
|
|
341
|
-
self.def_insert(node, single_decl="test")
|
|
342
|
-
self.push_scope(node.name.value, node)
|
|
343
|
-
self.sync_node_to_scope(node)
|
|
344
144
|
self.pop_scope()
|
|
345
145
|
|
|
346
146
|
def enter_module_code(self, node: ast.ModuleCode) -> None:
|
|
@@ -392,22 +192,16 @@ class SymTabBuildPass(SymTabPass):
|
|
|
392
192
|
"""
|
|
393
193
|
if not node.is_absorb:
|
|
394
194
|
for i in node.items.items:
|
|
395
|
-
|
|
195
|
+
i.sym_tab.def_insert(i, single_decl="import item")
|
|
396
196
|
elif node.is_absorb and node.hint.tag.value == "jac":
|
|
397
197
|
source = node.items.items[0]
|
|
398
|
-
if (
|
|
399
|
-
not isinstance(source, ast.ModulePath)
|
|
400
|
-
or not source.sub_module
|
|
401
|
-
or not source.sub_module.sym_tab
|
|
402
|
-
):
|
|
198
|
+
if not isinstance(source, ast.ModulePath) or not source.sub_module:
|
|
403
199
|
self.error(
|
|
404
200
|
f"Module {node.from_loc.path_str if node.from_loc else 'from location'}"
|
|
405
201
|
f" not found to include *, or ICE occurred!"
|
|
406
202
|
)
|
|
407
203
|
else:
|
|
408
|
-
|
|
409
|
-
scope=self.cur_scope(), sym_tab=source.sub_module.sym_tab
|
|
410
|
-
)
|
|
204
|
+
node.sym_tab.inherit_sym_tab(source.sub_module.sym_tab)
|
|
411
205
|
|
|
412
206
|
def enter_module_path(self, node: ast.ModulePath) -> None:
|
|
413
207
|
"""Sub objects.
|
|
@@ -426,9 +220,9 @@ class SymTabBuildPass(SymTabPass):
|
|
|
426
220
|
sub_module: Optional[Module] = None,
|
|
427
221
|
"""
|
|
428
222
|
if node.alias:
|
|
429
|
-
|
|
223
|
+
node.alias.sym_tab.def_insert(node.alias, single_decl="import")
|
|
430
224
|
elif node.path and isinstance(node.path[0], ast.Name):
|
|
431
|
-
|
|
225
|
+
node.path[0].sym_tab.def_insert(node.path[0])
|
|
432
226
|
else:
|
|
433
227
|
pass # Need to support pythonic import symbols with dots in it
|
|
434
228
|
|
|
@@ -453,7 +247,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
453
247
|
body: Optional[ArchBlock],
|
|
454
248
|
"""
|
|
455
249
|
self.sync_node_to_scope(node)
|
|
456
|
-
|
|
250
|
+
node.sym_tab.def_insert(node, access_spec=node, single_decl="architype")
|
|
457
251
|
self.push_scope(node.name.value, node)
|
|
458
252
|
self.sync_node_to_scope(node)
|
|
459
253
|
|
|
@@ -479,7 +273,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
479
273
|
body: ArchBlock,
|
|
480
274
|
"""
|
|
481
275
|
self.sync_node_to_scope(node)
|
|
482
|
-
|
|
276
|
+
node.sym_tab.def_insert(node, single_decl="arch def")
|
|
483
277
|
self.push_scope(node.sym_name, node)
|
|
484
278
|
self.sync_node_to_scope(node)
|
|
485
279
|
|
|
@@ -507,9 +301,16 @@ class SymTabBuildPass(SymTabPass):
|
|
|
507
301
|
body: Optional[CodeBlock],
|
|
508
302
|
"""
|
|
509
303
|
self.sync_node_to_scope(node)
|
|
510
|
-
|
|
304
|
+
node.sym_tab.def_insert(node, access_spec=node, single_decl="ability")
|
|
511
305
|
self.push_scope(node.sym_name, node)
|
|
512
306
|
self.sync_node_to_scope(node)
|
|
307
|
+
if node.is_method:
|
|
308
|
+
node.sym_tab.def_insert(ast.Name.gen_stub_from_node(node, "self"))
|
|
309
|
+
node.sym_tab.def_insert(
|
|
310
|
+
ast.Name.gen_stub_from_node(
|
|
311
|
+
node, "super", set_name_of=node.owner_method
|
|
312
|
+
)
|
|
313
|
+
)
|
|
513
314
|
|
|
514
315
|
def exit_ability(self, node: ast.Ability) -> None:
|
|
515
316
|
"""Sub objects.
|
|
@@ -535,7 +336,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
535
336
|
body: CodeBlock,
|
|
536
337
|
"""
|
|
537
338
|
self.sync_node_to_scope(node)
|
|
538
|
-
|
|
339
|
+
node.sym_tab.def_insert(node, single_decl="ability def")
|
|
539
340
|
self.push_scope(node.sym_name, node)
|
|
540
341
|
self.sync_node_to_scope(node)
|
|
541
342
|
|
|
@@ -595,7 +396,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
595
396
|
body: Optional['EnumBlock'],
|
|
596
397
|
"""
|
|
597
398
|
self.sync_node_to_scope(node)
|
|
598
|
-
|
|
399
|
+
node.sym_tab.def_insert(node, access_spec=node, single_decl="enum")
|
|
599
400
|
self.push_scope(node.sym_name, node)
|
|
600
401
|
self.sync_node_to_scope(node)
|
|
601
402
|
|
|
@@ -619,7 +420,7 @@ class SymTabBuildPass(SymTabPass):
|
|
|
619
420
|
body: EnumBlock,
|
|
620
421
|
"""
|
|
621
422
|
self.sync_node_to_scope(node)
|
|
622
|
-
|
|
423
|
+
node.sym_tab.def_insert(node, single_decl="enum def")
|
|
623
424
|
self.push_scope(node.sym_name, node)
|
|
624
425
|
self.sync_node_to_scope(node)
|
|
625
426
|
|
|
@@ -896,6 +697,13 @@ class SymTabBuildPass(SymTabPass):
|
|
|
896
697
|
"""
|
|
897
698
|
self.sync_node_to_scope(node)
|
|
898
699
|
|
|
700
|
+
def enter_check_stmt(self, node: ast.CheckStmt) -> None:
|
|
701
|
+
"""Sub objects.
|
|
702
|
+
|
|
703
|
+
target: Expr,
|
|
704
|
+
"""
|
|
705
|
+
self.sync_node_to_scope(node)
|
|
706
|
+
|
|
899
707
|
def enter_ctrl_stmt(self, node: ast.CtrlStmt) -> None:
|
|
900
708
|
"""Sub objects.
|
|
901
709
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Test pass module."""
|
|
2
2
|
|
|
3
|
+
import jaclang.compiler.absyntree as ast
|
|
3
4
|
from jaclang.compiler.compile import jac_file_to_pass
|
|
4
5
|
from jaclang.compiler.passes.main import DeclImplMatchPass
|
|
5
6
|
from jaclang.utils.test import TestCase
|
|
@@ -17,15 +18,31 @@ class DeclImplMatchPassTests(TestCase):
|
|
|
17
18
|
state = jac_file_to_pass(self.fixture_abs_path("base.jac"), DeclImplMatchPass)
|
|
18
19
|
self.assertFalse(state.errors_had)
|
|
19
20
|
self.assertIn("(o)Test.(c)say_hi", state.ir.sym_tab.tab)
|
|
20
|
-
self.assertIsNotNone(
|
|
21
|
+
self.assertIsNotNone(
|
|
22
|
+
state.ir.sym_tab.tab["(o)Test.(c)say_hi"].decl.name_of.body
|
|
23
|
+
)
|
|
21
24
|
self.assertIn("(o)Test.(c)__init__", state.ir.sym_tab.tab)
|
|
22
|
-
self.assertIsNotNone(
|
|
25
|
+
self.assertIsNotNone(
|
|
26
|
+
state.ir.sym_tab.tab["(o)Test.(c)__init__"].decl.name_of.body
|
|
27
|
+
)
|
|
23
28
|
|
|
24
29
|
def test_ability_connected_to_decl_post(self) -> None:
|
|
25
30
|
"""Basic test for pass."""
|
|
26
31
|
state = jac_file_to_pass(self.fixture_abs_path("base2.jac"), DeclImplMatchPass)
|
|
27
32
|
self.assertFalse(state.errors_had)
|
|
28
33
|
self.assertIn("(o)Test.(c)say_hi", state.ir.sym_tab.tab)
|
|
29
|
-
self.assertIsNotNone(
|
|
34
|
+
self.assertIsNotNone(
|
|
35
|
+
state.ir.sym_tab.tab["(o)Test.(c)say_hi"].decl.name_of.body
|
|
36
|
+
)
|
|
30
37
|
self.assertIn("(o)Test.(c)__init__", state.ir.sym_tab.tab)
|
|
31
|
-
self.assertIsNotNone(
|
|
38
|
+
self.assertIsNotNone(
|
|
39
|
+
state.ir.sym_tab.tab["(o)Test.(c)__init__"].decl.name_of.body
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
def test_arch_ref_has_sym(self) -> None:
|
|
43
|
+
"""Basic test for pass."""
|
|
44
|
+
state = jac_file_to_pass(
|
|
45
|
+
self.fixture_abs_path("defs_and_uses.jac"), DeclImplMatchPass
|
|
46
|
+
)
|
|
47
|
+
for i in state.ir.get_all_sub_nodes(ast.ArchRef):
|
|
48
|
+
self.assertIsNotNone(i.sym)
|
|
@@ -18,13 +18,8 @@ class DefUsePassTests(TestCase):
|
|
|
18
18
|
file_path=self.fixture_abs_path("defs_and_uses.jac"),
|
|
19
19
|
target=DefUsePass,
|
|
20
20
|
)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
# f", {i.sym_link.decl.loc if i.sym_link else None}"
|
|
27
|
-
# )
|
|
28
|
-
self.assertGreater(len(state.linked), 5)
|
|
29
|
-
self.assertLess(len(state.warnings_had), 50)
|
|
30
|
-
self.assertEqual(len(state.errors_had), 0)
|
|
21
|
+
uses = [i.uses for i in state.ir.sym_tab.kid[0].tab.values()]
|
|
22
|
+
self.assertEqual(len(uses[1]), 1)
|
|
23
|
+
self.assertEqual(len(uses[2]), 1)
|
|
24
|
+
self.assertIn("output", [uses[1][0].sym_name, uses[2][0].sym_name])
|
|
25
|
+
self.assertIn("message", [uses[1][0].sym_name, uses[2][0].sym_name])
|
|
@@ -8,9 +8,9 @@ import os
|
|
|
8
8
|
import pathlib
|
|
9
9
|
import sys
|
|
10
10
|
|
|
11
|
-
|
|
12
11
|
import jaclang.compiler.absyntree as ast
|
|
13
12
|
import jaclang.compiler.passes.utils.mypy_ast_build as myab
|
|
13
|
+
from jaclang.compiler.constant import Constants as Con
|
|
14
14
|
from jaclang.compiler.passes import Pass
|
|
15
15
|
|
|
16
16
|
|
|
@@ -48,6 +48,7 @@ class JacTypeCheckPass(Pass):
|
|
|
48
48
|
"""Call mypy APIs to implement type checking in Jac."""
|
|
49
49
|
# Creating mypy api objects
|
|
50
50
|
options = myab.myb.Options()
|
|
51
|
+
options.cache_dir = Con.JAC_MYPY_CACHE
|
|
51
52
|
errors = myab.Errors(self, options)
|
|
52
53
|
fs_cache = myab.FileSystemCache()
|
|
53
54
|
search_paths = myab.compute_search_paths([], options, str(self.__path))
|
|
@@ -484,7 +484,7 @@ class JacFormatPass(Pass):
|
|
|
484
484
|
|
|
485
485
|
var: Token,
|
|
486
486
|
"""
|
|
487
|
-
self.emit(node, node.
|
|
487
|
+
self.emit(node, node.orig.value)
|
|
488
488
|
|
|
489
489
|
def exit_ability_def(self, node: ast.AbilityDef) -> None:
|
|
490
490
|
"""Sub objects.
|
|
@@ -1871,6 +1871,32 @@ class JacFormatPass(Pass):
|
|
|
1871
1871
|
if isinstance(node.kid[-1], (ast.Semi, ast.CommentToken)):
|
|
1872
1872
|
self.emit_ln(node, "")
|
|
1873
1873
|
|
|
1874
|
+
def exit_check_stmt(self, node: ast.CheckStmt) -> None:
|
|
1875
|
+
"""Sub objects.
|
|
1876
|
+
|
|
1877
|
+
target: ExprType,
|
|
1878
|
+
"""
|
|
1879
|
+
start = True
|
|
1880
|
+
for i in node.kid:
|
|
1881
|
+
if isinstance(i, ast.CommentToken):
|
|
1882
|
+
if i.is_inline:
|
|
1883
|
+
self.emit(node, f" {i.gen.jac}")
|
|
1884
|
+
else:
|
|
1885
|
+
if not node.gen.jac.endswith("\n"):
|
|
1886
|
+
self.emit_ln(node, "")
|
|
1887
|
+
self.emit_ln(node, "")
|
|
1888
|
+
self.emit(node, i.gen.jac)
|
|
1889
|
+
elif isinstance(i, ast.Semi):
|
|
1890
|
+
self.emit(node, i.gen.jac)
|
|
1891
|
+
else:
|
|
1892
|
+
if start:
|
|
1893
|
+
self.emit(node, i.gen.jac)
|
|
1894
|
+
start = False
|
|
1895
|
+
else:
|
|
1896
|
+
self.emit(node, f" {i.gen.jac}")
|
|
1897
|
+
if isinstance(node.kid[-1], (ast.Semi, ast.CommentToken)):
|
|
1898
|
+
self.emit_ln(node, "")
|
|
1899
|
+
|
|
1874
1900
|
def exit_ctrl_stmt(self, node: ast.CtrlStmt) -> None:
|
|
1875
1901
|
"""Sub objects.
|
|
1876
1902
|
|
|
@@ -2002,7 +2028,6 @@ class JacFormatPass(Pass):
|
|
|
2002
2028
|
doc: Optional[Token],
|
|
2003
2029
|
body: CodeBlock,
|
|
2004
2030
|
"""
|
|
2005
|
-
start = True
|
|
2006
2031
|
for i in node.kid:
|
|
2007
2032
|
if isinstance(i, ast.CommentToken):
|
|
2008
2033
|
if i.is_inline:
|
|
@@ -2013,14 +2038,10 @@ class JacFormatPass(Pass):
|
|
|
2013
2038
|
elif isinstance(i, ast.Semi):
|
|
2014
2039
|
self.emit(node, i.gen.jac)
|
|
2015
2040
|
elif isinstance(i, ast.Name):
|
|
2016
|
-
if not i.value.startswith("
|
|
2017
|
-
self.emit(node, f" {i.value}
|
|
2041
|
+
if not i.value.startswith("_jac_gen_"):
|
|
2042
|
+
self.emit(node, f" {i.value}")
|
|
2018
2043
|
else:
|
|
2019
|
-
|
|
2020
|
-
self.emit(node, i.gen.jac)
|
|
2021
|
-
start = False
|
|
2022
|
-
else:
|
|
2023
|
-
self.emit(node, f" {i.gen.jac}")
|
|
2044
|
+
self.emit(node, i.gen.jac)
|
|
2024
2045
|
if isinstance(node.kid[-1], (ast.Semi, ast.CommentToken)):
|
|
2025
2046
|
self.emit_ln(node, "")
|
|
2026
2047
|
|
|
@@ -478,3 +478,19 @@ obj JacPlugin {
|
|
|
478
478
|
(walker_obj: Any, expr: Any) -> bool {
|
|
479
479
|
return walker_obj._jac_.visit_node(expr);
|
|
480
480
|
}
|
|
481
|
+
|
|
482
|
+
glob expected_area = 78.53981633974483;
|
|
483
|
+
|
|
484
|
+
test a1 {
|
|
485
|
+
check assertAlmostEqual(calculate_area(RAD), expected_area);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
test a2 {
|
|
489
|
+
c = Circle(RAD);
|
|
490
|
+
check assertAlmostEqual(c.area(), expected_area);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
test a3 {
|
|
494
|
+
c = Circle(RAD);
|
|
495
|
+
check assertEqual(c.shape_type, ShapeType.CIRCLE);
|
|
496
|
+
}
|