jaclang 0.5.18__py3-none-any.whl → 0.6.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 +94 -5
- jaclang/cli/cmdreg.py +18 -6
- jaclang/compiler/__init__.py +12 -5
- jaclang/compiler/absyntree.py +4 -5
- jaclang/compiler/generated/jac_parser.py +2 -2
- jaclang/compiler/jac.lark +2 -2
- jaclang/compiler/parser.py +48 -8
- jaclang/compiler/passes/main/__init__.py +3 -2
- jaclang/compiler/passes/main/access_modifier_pass.py +173 -0
- jaclang/compiler/passes/main/def_impl_match_pass.py +4 -1
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +10 -7
- jaclang/compiler/passes/main/import_pass.py +70 -40
- jaclang/compiler/passes/main/pyast_gen_pass.py +47 -83
- jaclang/compiler/passes/main/pyast_load_pass.py +136 -73
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +218 -0
- jaclang/compiler/passes/main/pyout_pass.py +14 -13
- jaclang/compiler/passes/main/registry_pass.py +8 -3
- jaclang/compiler/passes/main/schedules.py +7 -3
- jaclang/compiler/passes/main/sym_tab_build_pass.py +32 -29
- jaclang/compiler/passes/main/tests/test_import_pass.py +13 -2
- jaclang/compiler/passes/tool/jac_formatter_pass.py +83 -21
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +11 -4
- jaclang/compiler/passes/transform.py +2 -0
- jaclang/compiler/symtable.py +10 -3
- jaclang/compiler/tests/test_importer.py +9 -0
- jaclang/compiler/workspace.py +17 -5
- jaclang/core/aott.py +43 -63
- jaclang/core/construct.py +157 -21
- jaclang/core/importer.py +77 -65
- jaclang/core/llms/__init__.py +20 -0
- jaclang/core/llms/anthropic.py +61 -0
- jaclang/core/llms/base.py +206 -0
- jaclang/core/llms/groq.py +67 -0
- jaclang/core/llms/huggingface.py +73 -0
- jaclang/core/llms/ollama.py +78 -0
- jaclang/core/llms/openai.py +61 -0
- jaclang/core/llms/togetherai.py +60 -0
- jaclang/core/llms/utils.py +9 -0
- jaclang/core/memory.py +48 -0
- jaclang/core/shelve_storage.py +55 -0
- jaclang/core/utils.py +16 -1
- jaclang/plugin/__init__.py +1 -2
- jaclang/plugin/builtin.py +1 -1
- jaclang/plugin/default.py +134 -18
- jaclang/plugin/feature.py +35 -13
- jaclang/plugin/spec.py +52 -10
- jaclang/plugin/tests/test_jaseci.py +219 -0
- jaclang/settings.py +1 -1
- jaclang/utils/helpers.py +6 -2
- jaclang/utils/treeprinter.py +14 -6
- jaclang-0.6.1.dist-info/METADATA +17 -0
- {jaclang-0.5.18.dist-info → jaclang-0.6.1.dist-info}/RECORD +55 -42
- jaclang/core/llms.py +0 -111
- jaclang-0.5.18.dist-info/METADATA +0 -7
- {jaclang-0.5.18.dist-info → jaclang-0.6.1.dist-info}/WHEEL +0 -0
- {jaclang-0.5.18.dist-info → jaclang-0.6.1.dist-info}/entry_points.txt +0 -0
- {jaclang-0.5.18.dist-info → jaclang-0.6.1.dist-info}/top_level.txt +0 -0
jaclang/compiler/jac.lark
CHANGED
|
@@ -195,8 +195,8 @@ list_inner_pattern: (pattern_seq | STAR_MUL NAME)
|
|
|
195
195
|
dict_inner_pattern: (literal_pattern COLON pattern_seq | STAR_POW NAME)
|
|
196
196
|
|
|
197
197
|
// Match class patterns
|
|
198
|
-
class_pattern: NAME LPAREN kw_pattern_list? RPAREN
|
|
199
|
-
| NAME LPAREN pattern_list (COMMA kw_pattern_list)? RPAREN
|
|
198
|
+
class_pattern: NAME (DOT NAME)* LPAREN kw_pattern_list? RPAREN
|
|
199
|
+
| NAME (DOT NAME)* LPAREN pattern_list (COMMA kw_pattern_list)? RPAREN
|
|
200
200
|
|
|
201
201
|
pattern_list: (pattern_list COMMA)? pattern_seq
|
|
202
202
|
kw_pattern_list: (kw_pattern_list COMMA)? named_ref EQ pattern_seq
|
jaclang/compiler/parser.py
CHANGED
|
@@ -140,7 +140,7 @@ class JacParser(Pass):
|
|
|
140
140
|
body = kid[1:] if doc else kid
|
|
141
141
|
body = [i for i in body if isinstance(i, ast.ElementStmt)]
|
|
142
142
|
mod = ast.Module(
|
|
143
|
-
name=self.parse_ref.mod_path.split(os.path.sep)[-1].
|
|
143
|
+
name=self.parse_ref.mod_path.split(os.path.sep)[-1].rstrip(".jac"),
|
|
144
144
|
source=self.parse_ref.source,
|
|
145
145
|
doc=doc,
|
|
146
146
|
body=body,
|
|
@@ -3739,12 +3739,43 @@ class JacParser(Pass):
|
|
|
3739
3739
|
def class_pattern(self, kid: list[ast.AstNode]) -> ast.MatchArch:
|
|
3740
3740
|
"""Grammar rule.
|
|
3741
3741
|
|
|
3742
|
-
class_pattern: NAME LPAREN kw_pattern_list? RPAREN
|
|
3743
|
-
| NAME LPAREN pattern_list (COMMA kw_pattern_list)? RPAREN
|
|
3742
|
+
class_pattern: NAME (DOT NAME)* LPAREN kw_pattern_list? RPAREN
|
|
3743
|
+
| NAME (DOT NAME)* LPAREN pattern_list (COMMA kw_pattern_list)? RPAREN
|
|
3744
3744
|
"""
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3745
|
+
chomp = [*kid]
|
|
3746
|
+
cur_element = chomp[0]
|
|
3747
|
+
chomp = chomp[1:]
|
|
3748
|
+
while not (isinstance(chomp[0], ast.Token) and chomp[0].name == Tok.LPAREN):
|
|
3749
|
+
if isinstance(chomp[0], ast.Token) and chomp[0].name == Tok.DOT:
|
|
3750
|
+
target_ = cur_element
|
|
3751
|
+
right_ = chomp[1]
|
|
3752
|
+
if isinstance(right_, (ast.Expr, ast.AtomExpr)) and isinstance(
|
|
3753
|
+
target_, ast.Expr
|
|
3754
|
+
):
|
|
3755
|
+
cur_element = ast.AtomTrailer(
|
|
3756
|
+
target=target_,
|
|
3757
|
+
right=right_,
|
|
3758
|
+
is_attr=True,
|
|
3759
|
+
is_null_ok=False,
|
|
3760
|
+
kid=[target_, chomp[0], right_],
|
|
3761
|
+
)
|
|
3762
|
+
chomp = chomp[2:]
|
|
3763
|
+
else:
|
|
3764
|
+
raise self.ice()
|
|
3765
|
+
elif isinstance(cur_element, ast.NameSpec):
|
|
3766
|
+
chomp = chomp[1:]
|
|
3767
|
+
else:
|
|
3768
|
+
break
|
|
3769
|
+
name = cur_element
|
|
3770
|
+
lparen = chomp[0]
|
|
3771
|
+
rapren = chomp[-1]
|
|
3772
|
+
first = chomp[1]
|
|
3773
|
+
if len(chomp) > 4:
|
|
3774
|
+
second = chomp[3]
|
|
3775
|
+
comma = chomp[2]
|
|
3776
|
+
else:
|
|
3777
|
+
second = None
|
|
3778
|
+
comma = None
|
|
3748
3779
|
arg = (
|
|
3749
3780
|
first
|
|
3750
3781
|
if isinstance(first, ast.SubNodeList)
|
|
@@ -3762,13 +3793,22 @@ class JacParser(Pass):
|
|
|
3762
3793
|
else None
|
|
3763
3794
|
)
|
|
3764
3795
|
)
|
|
3765
|
-
if isinstance(name, ast.NameSpec):
|
|
3796
|
+
if isinstance(name, (ast.NameSpec, ast.AtomTrailer)):
|
|
3797
|
+
kid_nodes = [name, lparen]
|
|
3798
|
+
if arg:
|
|
3799
|
+
kid_nodes.append(arg)
|
|
3800
|
+
if kw:
|
|
3801
|
+
kid_nodes.extend([comma, kw]) if comma else kid_nodes.append(kw)
|
|
3802
|
+
elif kw:
|
|
3803
|
+
kid_nodes.append(kw)
|
|
3804
|
+
kid_nodes.append(rapren)
|
|
3805
|
+
|
|
3766
3806
|
return self.nu(
|
|
3767
3807
|
ast.MatchArch(
|
|
3768
3808
|
name=name,
|
|
3769
3809
|
arg_patterns=arg,
|
|
3770
3810
|
kw_patterns=kw,
|
|
3771
|
-
kid=
|
|
3811
|
+
kid=kid_nodes,
|
|
3772
3812
|
)
|
|
3773
3813
|
)
|
|
3774
3814
|
else:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Collection of passes for Jac IR."""
|
|
2
2
|
|
|
3
3
|
from .sub_node_tab_pass import SubNodeTabPass
|
|
4
|
-
from .import_pass import
|
|
4
|
+
from .import_pass import JacImportPass, PyImportPass # noqa: I100
|
|
5
5
|
from .sym_tab_build_pass import SymTabBuildPass # noqa: I100
|
|
6
6
|
from .def_impl_match_pass import DeclDefMatchPass # noqa: I100
|
|
7
7
|
from .def_use_pass import DefUsePass # noqa: I100
|
|
@@ -17,7 +17,8 @@ pass_schedule = py_code_gen
|
|
|
17
17
|
|
|
18
18
|
__all__ = [
|
|
19
19
|
"SubNodeTabPass",
|
|
20
|
-
"
|
|
20
|
+
"JacImportPass",
|
|
21
|
+
"PyImportPass",
|
|
21
22
|
"SymTabBuildPass",
|
|
22
23
|
"DeclDefMatchPass",
|
|
23
24
|
"DefUsePass",
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"""Access check pass for the Jac compiler.
|
|
2
|
+
|
|
3
|
+
This pass checks for access to attributes in the Jac language.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
import jaclang.compiler.absyntree as ast
|
|
10
|
+
from jaclang.compiler.passes.main.sym_tab_build_pass import SymTabPass, SymbolAccess
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AccessCheckPass(SymTabPass):
|
|
14
|
+
"""Jac Ast Access Check pass."""
|
|
15
|
+
|
|
16
|
+
def after_pass(self) -> None:
|
|
17
|
+
"""After pass."""
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
def access_check(self, node: ast.Name) -> None:
|
|
21
|
+
"""Access check."""
|
|
22
|
+
node_info = (
|
|
23
|
+
node.sym_tab.lookup(node.sym_name)
|
|
24
|
+
if isinstance(node.sym_tab, ast.SymbolTable)
|
|
25
|
+
else None
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
if node.sym_link:
|
|
29
|
+
decl_package_path = os.path.dirname(
|
|
30
|
+
os.path.abspath(node.sym_link.defn[-1].loc.mod_path)
|
|
31
|
+
)
|
|
32
|
+
use_package_path = os.path.dirname(os.path.abspath(node.loc.mod_path))
|
|
33
|
+
else:
|
|
34
|
+
decl_package_path = use_package_path = ""
|
|
35
|
+
|
|
36
|
+
if (
|
|
37
|
+
node_info
|
|
38
|
+
and node.sym_link
|
|
39
|
+
and node_info.access == SymbolAccess.PROTECTED
|
|
40
|
+
and decl_package_path != use_package_path
|
|
41
|
+
):
|
|
42
|
+
return self.error(
|
|
43
|
+
f'Can not access protected variable "{node.sym_name}" from {decl_package_path}'
|
|
44
|
+
f" to {use_package_path}."
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if (
|
|
48
|
+
node_info
|
|
49
|
+
and node.sym_link
|
|
50
|
+
and node_info.access == SymbolAccess.PRIVATE
|
|
51
|
+
and node.sym_link.defn[-1].loc.mod_path != node.loc.mod_path
|
|
52
|
+
):
|
|
53
|
+
return self.error(
|
|
54
|
+
f'Can not access private variable "{node.sym_name}" from {node.sym_link.defn[-1].loc.mod_path}'
|
|
55
|
+
f" to {node.loc.mod_path}."
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
def access_register(
|
|
59
|
+
self, node: ast.AstSymbolNode, acc_tag: Optional[SymbolAccess] = None
|
|
60
|
+
) -> None:
|
|
61
|
+
"""Access register."""
|
|
62
|
+
node.sym_info.acc_tag = acc_tag
|
|
63
|
+
|
|
64
|
+
def enter_global_vars(self, node: ast.GlobalVars) -> None:
|
|
65
|
+
"""Sub objects.
|
|
66
|
+
|
|
67
|
+
access: Optional[SubTag[Token]],
|
|
68
|
+
assignments: SubNodeList[Assignment],
|
|
69
|
+
is_frozen: bool,
|
|
70
|
+
"""
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
def enter_module(self, node: ast.Module) -> None:
|
|
74
|
+
"""Sub objects.
|
|
75
|
+
|
|
76
|
+
name: str,
|
|
77
|
+
doc: Token,
|
|
78
|
+
body: Optional['Elements'],
|
|
79
|
+
mod_path: str,
|
|
80
|
+
is_imported: bool,
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
def enter_architype(self, node: ast.Architype) -> None:
|
|
84
|
+
"""Sub objects.
|
|
85
|
+
|
|
86
|
+
name: Name,
|
|
87
|
+
arch_type: Token,
|
|
88
|
+
access: Optional[SubTag[Token]],
|
|
89
|
+
base_classes: Optional[SubNodeList[Expr]],
|
|
90
|
+
body: Optional[SubNodeList[ArchBlockStmt] | ArchDef],
|
|
91
|
+
decorators: Optional[SubNodeList[Expr]] = None,
|
|
92
|
+
"""
|
|
93
|
+
pass
|
|
94
|
+
|
|
95
|
+
def enter_enum(self, node: ast.Enum) -> None:
|
|
96
|
+
"""Sub objects.
|
|
97
|
+
|
|
98
|
+
name: Name,
|
|
99
|
+
access: Optional[SubTag[Token]],
|
|
100
|
+
base_classes: Optional[SubNodeList[Expr]],
|
|
101
|
+
body: Optional[SubNodeList[EnumBlockStmt] | EnumDef],
|
|
102
|
+
decorators: Optional[SubNodeList[Expr]] = None,
|
|
103
|
+
"""
|
|
104
|
+
pass
|
|
105
|
+
|
|
106
|
+
def enter_ability(self, node: ast.Ability) -> None:
|
|
107
|
+
"""Sub objects.
|
|
108
|
+
|
|
109
|
+
name_ref: NameSpec,
|
|
110
|
+
is_func: bool,
|
|
111
|
+
is_async: bool,
|
|
112
|
+
is_override: bool,
|
|
113
|
+
is_static: bool,
|
|
114
|
+
is_abstract: bool,
|
|
115
|
+
access: Optional[SubTag[Token]],
|
|
116
|
+
signature: Optional[FuncSignature | EventSignature],
|
|
117
|
+
body: Optional[SubNodeList[CodeBlockStmt] | AbilityDef],
|
|
118
|
+
decorators: Optional[SubNodeList[Expr]] = None,
|
|
119
|
+
"""
|
|
120
|
+
pass
|
|
121
|
+
|
|
122
|
+
def enter_sub_node_list(self, node: ast.SubNodeList) -> None:
|
|
123
|
+
"""Sub objects.
|
|
124
|
+
|
|
125
|
+
items: list[T]
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
def enter_arch_has(self, node: ast.ArchHas) -> None:
|
|
129
|
+
"""Sub objects.
|
|
130
|
+
|
|
131
|
+
is_static: bool,
|
|
132
|
+
access: Optional[SubTag[Token]],
|
|
133
|
+
vars: SubNodeList[HasVar],
|
|
134
|
+
is_frozen: bool,
|
|
135
|
+
"""
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
def enter_atom_trailer(self, node: ast.AtomTrailer) -> None:
|
|
139
|
+
"""Sub objects.
|
|
140
|
+
|
|
141
|
+
access: Optional[SubTag[Token]],
|
|
142
|
+
"""
|
|
143
|
+
pass
|
|
144
|
+
|
|
145
|
+
def enter_func_call(self, node: ast.FuncCall) -> None:
|
|
146
|
+
"""Sub objects.
|
|
147
|
+
|
|
148
|
+
target: Expr,
|
|
149
|
+
params: Optional[SubNodeList[Expr | KWPair]],
|
|
150
|
+
genai_call: Optional[FuncCall],
|
|
151
|
+
kid: Sequence[AstNode],
|
|
152
|
+
"""
|
|
153
|
+
pass
|
|
154
|
+
|
|
155
|
+
def enter_name(self, node: ast.Name) -> None:
|
|
156
|
+
"""Sub objects.
|
|
157
|
+
|
|
158
|
+
name: str,
|
|
159
|
+
value: str,
|
|
160
|
+
col_start: int,
|
|
161
|
+
col_end: int,
|
|
162
|
+
pos_start: int,
|
|
163
|
+
pos_end: int,
|
|
164
|
+
"""
|
|
165
|
+
from jaclang.compiler.passes import Pass
|
|
166
|
+
|
|
167
|
+
if isinstance(node.parent, ast.FuncCall):
|
|
168
|
+
self.access_check(node)
|
|
169
|
+
|
|
170
|
+
if node.sym_link and Pass.has_parent_of_type(
|
|
171
|
+
node=node.sym_link.defn[-1], typ=ast.GlobalVars
|
|
172
|
+
):
|
|
173
|
+
self.access_check(node)
|
|
@@ -72,7 +72,10 @@ class DeclDefMatchPass(Pass):
|
|
|
72
72
|
continue
|
|
73
73
|
decl_node.body = sym.decl # type: ignore
|
|
74
74
|
sym.decl.decl_link = decl_node # type: ignore
|
|
75
|
-
|
|
75
|
+
source_node = sym.decl.parent
|
|
76
|
+
decl_node.add_kids_right([sym.decl]) # type: ignore
|
|
77
|
+
if source_node and sym.decl in source_node.kid:
|
|
78
|
+
source_node.kid.remove(sym.decl)
|
|
76
79
|
decl_node.sym_tab.tab = sym.decl.sym_tab.tab # type: ignore
|
|
77
80
|
for i in sym_tab.kid:
|
|
78
81
|
self.connect_def_impl(i)
|
|
@@ -48,8 +48,16 @@ class FuseTypeInfoPass(Pass):
|
|
|
48
48
|
def __set_sym_table_link(self, node: ast.AstSymbolNode) -> None:
|
|
49
49
|
typ = node.sym_info.typ.split(".")
|
|
50
50
|
typ_sym_table = self.ir.sym_tab
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
|
|
52
|
+
if typ[0] == "builtins":
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
assert isinstance(self.ir, ast.Module)
|
|
56
|
+
|
|
57
|
+
if typ_sym_table:
|
|
58
|
+
for i in typ:
|
|
59
|
+
if i == self.ir.name:
|
|
60
|
+
continue
|
|
53
61
|
f = typ_sym_table.find_scope(i)
|
|
54
62
|
if f:
|
|
55
63
|
typ_sym_table = f
|
|
@@ -159,11 +167,6 @@ class FuseTypeInfoPass(Pass):
|
|
|
159
167
|
type(mypy_node),
|
|
160
168
|
)
|
|
161
169
|
|
|
162
|
-
def enter_import(self, node: ast.Import) -> None:
|
|
163
|
-
"""Pass handler for import nodes."""
|
|
164
|
-
# Pruning the import nodes
|
|
165
|
-
self.prune()
|
|
166
|
-
|
|
167
170
|
@__handle_node
|
|
168
171
|
def enter_name(self, node: ast.NameSpec) -> None:
|
|
169
172
|
"""Pass handler for name nodes."""
|
|
@@ -7,8 +7,8 @@ symbols are available for matching.
|
|
|
7
7
|
|
|
8
8
|
import ast as py_ast
|
|
9
9
|
import importlib.util
|
|
10
|
+
import os
|
|
10
11
|
import sys
|
|
11
|
-
from os import path
|
|
12
12
|
from typing import Optional
|
|
13
13
|
|
|
14
14
|
|
|
@@ -19,8 +19,8 @@ from jaclang.settings import settings
|
|
|
19
19
|
from jaclang.utils.helpers import import_target_to_relative_path
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
class
|
|
23
|
-
"""Jac statically imports
|
|
22
|
+
class JacImportPass(Pass):
|
|
23
|
+
"""Jac statically imports Jac modules."""
|
|
24
24
|
|
|
25
25
|
def before_pass(self) -> None:
|
|
26
26
|
"""Run once before pass."""
|
|
@@ -29,6 +29,7 @@ class ImportPass(Pass):
|
|
|
29
29
|
def enter_module(self, node: ast.Module) -> None:
|
|
30
30
|
"""Run Importer."""
|
|
31
31
|
self.cur_node = node
|
|
32
|
+
self.import_table[node.loc.mod_path] = node
|
|
32
33
|
self.annex_impl(node)
|
|
33
34
|
self.terminate() # Turns off auto traversal for deliberate traversal
|
|
34
35
|
self.run_again = True
|
|
@@ -36,48 +37,63 @@ class ImportPass(Pass):
|
|
|
36
37
|
self.run_again = False
|
|
37
38
|
all_imports = self.get_all_sub_nodes(node, ast.ModulePath)
|
|
38
39
|
for i in all_imports:
|
|
39
|
-
|
|
40
|
-
if lang == "jac" and not i.sub_module:
|
|
41
|
-
self.run_again = True
|
|
42
|
-
mod = self.import_module(
|
|
43
|
-
node=i,
|
|
44
|
-
mod_path=node.loc.mod_path,
|
|
45
|
-
)
|
|
46
|
-
if not mod:
|
|
47
|
-
self.run_again = False
|
|
48
|
-
continue
|
|
49
|
-
self.annex_impl(mod)
|
|
50
|
-
i.sub_module = mod
|
|
51
|
-
i.add_kids_right([mod], pos_update=False)
|
|
52
|
-
elif lang == "py" and settings.jac_proc_debug:
|
|
53
|
-
mod = self.import_py_module(node=i, mod_path=node.loc.mod_path)
|
|
54
|
-
i.sub_module = mod
|
|
55
|
-
i.add_kids_right([mod], pos_update=False)
|
|
40
|
+
self.process_import(node, i)
|
|
56
41
|
self.enter_module_path(i)
|
|
57
42
|
SubNodeTabPass(prior=self, input_ir=node)
|
|
58
|
-
self.annex_impl(node)
|
|
59
43
|
node.mod_deps = self.import_table
|
|
60
44
|
|
|
45
|
+
def process_import(self, node: ast.Module, i: ast.ModulePath) -> None:
|
|
46
|
+
"""Process an import."""
|
|
47
|
+
lang = i.parent_of_type(ast.Import).hint.tag.value
|
|
48
|
+
if lang == "jac" and not i.sub_module:
|
|
49
|
+
mod = self.import_module(
|
|
50
|
+
node=i,
|
|
51
|
+
mod_path=node.loc.mod_path,
|
|
52
|
+
)
|
|
53
|
+
if mod:
|
|
54
|
+
self.run_again = True
|
|
55
|
+
i.sub_module = mod
|
|
56
|
+
i.add_kids_right([mod], pos_update=False)
|
|
57
|
+
|
|
61
58
|
def annex_impl(self, node: ast.Module) -> None:
|
|
62
59
|
"""Annex impl and test modules."""
|
|
63
60
|
if not node.loc.mod_path:
|
|
64
61
|
self.error("Module has no path")
|
|
65
|
-
if node.loc.mod_path.endswith(".jac")
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
62
|
+
if not node.loc.mod_path.endswith(".jac"):
|
|
63
|
+
return
|
|
64
|
+
base_path = node.loc.mod_path[:-4]
|
|
65
|
+
directory = os.path.dirname(node.loc.mod_path)
|
|
66
|
+
if not directory:
|
|
67
|
+
directory = os.getcwd()
|
|
68
|
+
base_path = os.path.join(directory, base_path)
|
|
69
|
+
impl_folder = base_path + ".impl"
|
|
70
|
+
search_files = [
|
|
71
|
+
os.path.join(directory, impl_file) for impl_file in os.listdir(directory)
|
|
72
|
+
]
|
|
73
|
+
if os.path.exists(impl_folder):
|
|
74
|
+
search_files += [
|
|
75
|
+
os.path.join(impl_folder, impl_file)
|
|
76
|
+
for impl_file in os.listdir(impl_folder)
|
|
77
|
+
]
|
|
78
|
+
for impl_file in search_files:
|
|
79
|
+
if node.loc.mod_path.endswith(impl_file):
|
|
80
|
+
continue
|
|
81
|
+
if (
|
|
82
|
+
impl_file.startswith(f"{base_path}.") or impl_folder in impl_file
|
|
83
|
+
) and impl_file.endswith(".impl.jac"):
|
|
84
|
+
mod = self.import_mod_from_file(impl_file)
|
|
85
|
+
if mod:
|
|
86
|
+
node.impl_mod.append(mod)
|
|
87
|
+
node.add_kids_left([mod], pos_update=False)
|
|
88
|
+
mod.parent = node
|
|
89
|
+
if (
|
|
90
|
+
impl_file.startswith(f"{base_path}.") or impl_folder in impl_file
|
|
91
|
+
) and impl_file.endswith(".test.jac"):
|
|
92
|
+
mod = self.import_mod_from_file(impl_file)
|
|
93
|
+
if mod:
|
|
94
|
+
node.test_mod = mod
|
|
95
|
+
node.add_kids_right([mod], pos_update=False)
|
|
96
|
+
mod.parent = node
|
|
81
97
|
|
|
82
98
|
def enter_module_path(self, node: ast.ModulePath) -> None:
|
|
83
99
|
"""Sub objects.
|
|
@@ -97,7 +113,7 @@ class ImportPass(Pass):
|
|
|
97
113
|
"""Import a module."""
|
|
98
114
|
self.cur_node = node # impacts error reporting
|
|
99
115
|
target = import_target_to_relative_path(
|
|
100
|
-
node.level, node.path_str, path.dirname(node.loc.mod_path)
|
|
116
|
+
node.level, node.path_str, os.path.dirname(node.loc.mod_path)
|
|
101
117
|
)
|
|
102
118
|
return self.import_mod_from_file(target)
|
|
103
119
|
|
|
@@ -106,7 +122,7 @@ class ImportPass(Pass):
|
|
|
106
122
|
from jaclang.compiler.compile import jac_file_to_pass
|
|
107
123
|
from jaclang.compiler.passes.main import SubNodeTabPass
|
|
108
124
|
|
|
109
|
-
if not path.exists(target):
|
|
125
|
+
if not os.path.exists(target):
|
|
110
126
|
self.error(f"Could not find module {target}")
|
|
111
127
|
return None
|
|
112
128
|
if target in self.import_table:
|
|
@@ -134,7 +150,7 @@ class ImportPass(Pass):
|
|
|
134
150
|
"""Import a module."""
|
|
135
151
|
from jaclang.compiler.passes.main import PyastBuildPass
|
|
136
152
|
|
|
137
|
-
base_dir = path.dirname(mod_path)
|
|
153
|
+
base_dir = os.path.dirname(mod_path)
|
|
138
154
|
sys.path.append(base_dir)
|
|
139
155
|
|
|
140
156
|
try:
|
|
@@ -165,3 +181,17 @@ class ImportPass(Pass):
|
|
|
165
181
|
)
|
|
166
182
|
raise e
|
|
167
183
|
return None
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class PyImportPass(JacImportPass):
|
|
187
|
+
"""Jac statically imports Python modules."""
|
|
188
|
+
|
|
189
|
+
def process_import(self, node: ast.Module, i: ast.ModulePath) -> None:
|
|
190
|
+
"""Process an import."""
|
|
191
|
+
lang = i.parent_of_type(ast.Import).hint.tag.value
|
|
192
|
+
if lang == "py" and not i.sub_module and settings.py_raise:
|
|
193
|
+
mod = self.import_py_module(node=i, mod_path=node.loc.mod_path)
|
|
194
|
+
if mod:
|
|
195
|
+
# self.run_again = True
|
|
196
|
+
i.sub_module = mod
|
|
197
|
+
i.add_kids_right([mod], pos_update=False)
|