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/cli/cli.py
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
import ast as ast3
|
|
4
4
|
import importlib
|
|
5
|
+
import inspect
|
|
5
6
|
import marshal
|
|
6
7
|
import os
|
|
7
8
|
import pickle
|
|
8
9
|
import shutil
|
|
9
10
|
import types
|
|
10
11
|
from typing import Optional
|
|
12
|
+
from uuid import UUID
|
|
11
13
|
|
|
12
14
|
import jaclang.compiler.absyntree as ast
|
|
13
15
|
from jaclang import jac_import
|
|
@@ -17,6 +19,7 @@ from jaclang.compiler.constant import Constants
|
|
|
17
19
|
from jaclang.compiler.passes.main.pyast_load_pass import PyastBuildPass
|
|
18
20
|
from jaclang.compiler.passes.main.schedules import py_code_gen_typed
|
|
19
21
|
from jaclang.compiler.passes.tool.schedules import format_pass
|
|
22
|
+
from jaclang.core.construct import Architype
|
|
20
23
|
from jaclang.plugin.builtin import dotgen
|
|
21
24
|
from jaclang.plugin.feature import JacCmd as Cmd
|
|
22
25
|
from jaclang.plugin.feature import JacFeature as Jac
|
|
@@ -63,13 +66,33 @@ def format(path: str, outfile: str = "", debug: bool = False) -> None:
|
|
|
63
66
|
|
|
64
67
|
|
|
65
68
|
@cmd_registry.register
|
|
66
|
-
def run(
|
|
69
|
+
def run(
|
|
70
|
+
filename: str,
|
|
71
|
+
session: str = "",
|
|
72
|
+
main: bool = True,
|
|
73
|
+
cache: bool = True,
|
|
74
|
+
walker: str = "",
|
|
75
|
+
node: str = "",
|
|
76
|
+
) -> None:
|
|
67
77
|
"""Run the specified .jac file."""
|
|
78
|
+
# if no session specified, check if it was defined when starting the command shell
|
|
79
|
+
# otherwise default to jaclang.session
|
|
80
|
+
if session == "":
|
|
81
|
+
session = (
|
|
82
|
+
cmd_registry.args.session
|
|
83
|
+
if hasattr(cmd_registry, "args")
|
|
84
|
+
and hasattr(cmd_registry.args, "session")
|
|
85
|
+
and cmd_registry.args.session
|
|
86
|
+
else ""
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
Jac.context().init_memory(session)
|
|
90
|
+
|
|
68
91
|
base, mod = os.path.split(filename)
|
|
69
92
|
base = base if base else "./"
|
|
70
93
|
mod = mod[:-4]
|
|
71
94
|
if filename.endswith(".jac"):
|
|
72
|
-
jac_import(
|
|
95
|
+
loaded_mod = jac_import(
|
|
73
96
|
target=mod,
|
|
74
97
|
base_path=base,
|
|
75
98
|
cachable=cache,
|
|
@@ -78,7 +101,7 @@ def run(filename: str, main: bool = True, cache: bool = True) -> None:
|
|
|
78
101
|
elif filename.endswith(".jir"):
|
|
79
102
|
with open(filename, "rb") as f:
|
|
80
103
|
ir = pickle.load(f)
|
|
81
|
-
jac_import(
|
|
104
|
+
loaded_mod = jac_import(
|
|
82
105
|
target=mod,
|
|
83
106
|
base_path=base,
|
|
84
107
|
cachable=cache,
|
|
@@ -87,6 +110,49 @@ def run(filename: str, main: bool = True, cache: bool = True) -> None:
|
|
|
87
110
|
)
|
|
88
111
|
else:
|
|
89
112
|
print("Not a .jac file.")
|
|
113
|
+
return
|
|
114
|
+
|
|
115
|
+
if not node or node == "root":
|
|
116
|
+
entrypoint: Architype = Jac.get_root()
|
|
117
|
+
else:
|
|
118
|
+
obj = Jac.context().get_obj(UUID(node))
|
|
119
|
+
if obj is None:
|
|
120
|
+
print(f"Entrypoint {node} not found.")
|
|
121
|
+
return
|
|
122
|
+
entrypoint = obj
|
|
123
|
+
|
|
124
|
+
# TODO: handle no override name
|
|
125
|
+
if walker:
|
|
126
|
+
walker_module = dict(inspect.getmembers(loaded_mod)).get(walker)
|
|
127
|
+
if walker_module:
|
|
128
|
+
Jac.spawn_call(entrypoint, walker_module())
|
|
129
|
+
else:
|
|
130
|
+
print(f"Walker {walker} not found.")
|
|
131
|
+
|
|
132
|
+
Jac.reset_context()
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@cmd_registry.register
|
|
136
|
+
def get_object(id: str, session: str = "") -> dict:
|
|
137
|
+
"""Get the object with the specified id."""
|
|
138
|
+
if session == "":
|
|
139
|
+
session = cmd_registry.args.session if "session" in cmd_registry.args else ""
|
|
140
|
+
|
|
141
|
+
Jac.context().init_memory(session)
|
|
142
|
+
|
|
143
|
+
if id == "root":
|
|
144
|
+
id_uuid = UUID(int=0)
|
|
145
|
+
else:
|
|
146
|
+
id_uuid = UUID(id)
|
|
147
|
+
|
|
148
|
+
obj = Jac.context().get_obj(id_uuid)
|
|
149
|
+
if obj is None:
|
|
150
|
+
print(f"Object with id {id} not found.")
|
|
151
|
+
Jac.reset_context()
|
|
152
|
+
return {}
|
|
153
|
+
else:
|
|
154
|
+
Jac.reset_context()
|
|
155
|
+
return obj.__getstate__()
|
|
90
156
|
|
|
91
157
|
|
|
92
158
|
@cmd_registry.register
|
|
@@ -106,7 +172,7 @@ def build(filename: str) -> None:
|
|
|
106
172
|
|
|
107
173
|
|
|
108
174
|
@cmd_registry.register
|
|
109
|
-
def check(filename: str) -> None:
|
|
175
|
+
def check(filename: str, print_errs: bool = True) -> None:
|
|
110
176
|
"""Run type checker for a specified .jac file.
|
|
111
177
|
|
|
112
178
|
:param filename: The path to the .jac file.
|
|
@@ -119,7 +185,9 @@ def check(filename: str) -> None:
|
|
|
119
185
|
|
|
120
186
|
errs = len(out.errors_had)
|
|
121
187
|
warnings = len(out.warnings_had)
|
|
122
|
-
|
|
188
|
+
if print_errs:
|
|
189
|
+
for e in out.errors_had:
|
|
190
|
+
print("Error:", e)
|
|
123
191
|
print(f"Errors: {errs}, Warnings: {warnings}")
|
|
124
192
|
else:
|
|
125
193
|
print("Not a .jac file.")
|
|
@@ -240,6 +308,7 @@ def debug(filename: str, main: bool = True, cache: bool = False) -> None:
|
|
|
240
308
|
@cmd_registry.register
|
|
241
309
|
def dot(
|
|
242
310
|
filename: str,
|
|
311
|
+
session: str = "",
|
|
243
312
|
initial: str = "",
|
|
244
313
|
depth: int = -1,
|
|
245
314
|
traverse: bool = False,
|
|
@@ -261,6 +330,17 @@ def dot(
|
|
|
261
330
|
:param node_limit: The maximum number of nodes allowed in the graph.
|
|
262
331
|
:param saveto: Path to save the generated graph.
|
|
263
332
|
"""
|
|
333
|
+
if session == "":
|
|
334
|
+
session = (
|
|
335
|
+
cmd_registry.args.session
|
|
336
|
+
if hasattr(cmd_registry, "args")
|
|
337
|
+
and hasattr(cmd_registry.args, "session")
|
|
338
|
+
and cmd_registry.args.session
|
|
339
|
+
else ""
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
Jac.context().init_memory(session)
|
|
343
|
+
|
|
264
344
|
base, mod = os.path.split(filename)
|
|
265
345
|
base = base if base else "./"
|
|
266
346
|
mod = mod[:-4]
|
|
@@ -284,6 +364,10 @@ def dot(
|
|
|
284
364
|
)
|
|
285
365
|
except Exception as e:
|
|
286
366
|
print(f"Error while generating graph: {e}")
|
|
367
|
+
import traceback
|
|
368
|
+
|
|
369
|
+
traceback.print_exc()
|
|
370
|
+
Jac.reset_context()
|
|
287
371
|
return
|
|
288
372
|
file_name = saveto if saveto else f"{mod}.dot"
|
|
289
373
|
with open(file_name, "w") as file:
|
|
@@ -292,6 +376,8 @@ def dot(
|
|
|
292
376
|
else:
|
|
293
377
|
print("Not a .jac file.")
|
|
294
378
|
|
|
379
|
+
Jac.reset_context()
|
|
380
|
+
|
|
295
381
|
|
|
296
382
|
@cmd_registry.register
|
|
297
383
|
def py_to_jac(filename: str, tree: bool = False) -> None:
|
|
@@ -319,10 +405,13 @@ def start_cli() -> None:
|
|
|
319
405
|
"""
|
|
320
406
|
parser = cmd_registry.parser
|
|
321
407
|
args = parser.parse_args()
|
|
408
|
+
cmd_registry.args = args
|
|
322
409
|
command = cmd_registry.get(args.command)
|
|
323
410
|
if command:
|
|
324
411
|
args_dict = vars(args)
|
|
325
412
|
args_dict.pop("command")
|
|
413
|
+
if command not in ["run"]:
|
|
414
|
+
args_dict.pop("session")
|
|
326
415
|
ret = command.call(**args_dict)
|
|
327
416
|
if ret:
|
|
328
417
|
print(ret)
|
jaclang/cli/cmdreg.py
CHANGED
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import argparse
|
|
6
6
|
import cmd
|
|
7
7
|
import inspect
|
|
8
|
+
import pprint
|
|
8
9
|
from typing import Callable, Optional
|
|
9
10
|
|
|
10
11
|
|
|
@@ -30,12 +31,17 @@ class CommandRegistry:
|
|
|
30
31
|
registry: dict[str, Command]
|
|
31
32
|
sub_parsers: argparse._SubParsersAction
|
|
32
33
|
parser: argparse.ArgumentParser
|
|
34
|
+
args: argparse.Namespace
|
|
33
35
|
|
|
34
36
|
def __init__(self) -> None:
|
|
35
37
|
"""Initialize a CommandRegistry instance."""
|
|
36
38
|
self.registry = {}
|
|
37
|
-
self.parser = argparse.ArgumentParser(prog="
|
|
39
|
+
self.parser = argparse.ArgumentParser(prog="jac")
|
|
40
|
+
self.parser.add_argument(
|
|
41
|
+
"--session", help="Session file path", nargs="?", default=""
|
|
42
|
+
)
|
|
38
43
|
self.sub_parsers = self.parser.add_subparsers(title="commands", dest="command")
|
|
44
|
+
self.args = argparse.Namespace()
|
|
39
45
|
|
|
40
46
|
def register(self, func: Callable) -> Callable:
|
|
41
47
|
"""Register a command in the registry."""
|
|
@@ -48,6 +54,11 @@ class CommandRegistry:
|
|
|
48
54
|
first = True
|
|
49
55
|
for param_name, param in cmd.sig.parameters.items():
|
|
50
56
|
arg_msg = f"type: {param.annotation.__name__}"
|
|
57
|
+
# shorthand is first character by default,
|
|
58
|
+
# If already taken, use the first 2 characters
|
|
59
|
+
shorthand = param_name[:1]
|
|
60
|
+
if f"-{shorthand}" in cmd_parser._option_string_actions:
|
|
61
|
+
shorthand = param_name[:2]
|
|
51
62
|
if param_name == "args":
|
|
52
63
|
cmd_parser.add_argument("args", nargs=argparse.REMAINDER, help=arg_msg)
|
|
53
64
|
elif param_name == "filepath":
|
|
@@ -76,7 +87,7 @@ class CommandRegistry:
|
|
|
76
87
|
)
|
|
77
88
|
else:
|
|
78
89
|
cmd_parser.add_argument(
|
|
79
|
-
f"-{
|
|
90
|
+
f"-{shorthand}",
|
|
80
91
|
f"--{param_name}",
|
|
81
92
|
required=True,
|
|
82
93
|
type=(
|
|
@@ -99,14 +110,14 @@ class CommandRegistry:
|
|
|
99
110
|
arg_msg += f", default: {param.default}"
|
|
100
111
|
if param.annotation == bool:
|
|
101
112
|
cmd_parser.add_argument(
|
|
102
|
-
f"-{
|
|
113
|
+
f"-{shorthand}",
|
|
103
114
|
f"--{param_name}",
|
|
104
115
|
default=param.default,
|
|
105
116
|
action="store_true",
|
|
106
117
|
help=arg_msg,
|
|
107
118
|
)
|
|
108
119
|
cmd_parser.add_argument(
|
|
109
|
-
f"-n{
|
|
120
|
+
f"-n{shorthand}",
|
|
110
121
|
f"--no-{param_name}",
|
|
111
122
|
dest=param_name,
|
|
112
123
|
action="store_false",
|
|
@@ -114,7 +125,7 @@ class CommandRegistry:
|
|
|
114
125
|
)
|
|
115
126
|
else:
|
|
116
127
|
cmd_parser.add_argument(
|
|
117
|
-
f"-{
|
|
128
|
+
f"-{shorthand}",
|
|
118
129
|
f"--{param_name}",
|
|
119
130
|
default=param.default,
|
|
120
131
|
help=arg_msg,
|
|
@@ -168,7 +179,8 @@ class CommandShell(cmd.Cmd):
|
|
|
168
179
|
args.pop("command")
|
|
169
180
|
ret = command.call(**args)
|
|
170
181
|
if ret:
|
|
171
|
-
|
|
182
|
+
ret_str = pprint.pformat(ret, indent=2)
|
|
183
|
+
self.stdout.write(f"{ret_str}\n")
|
|
172
184
|
except Exception as e:
|
|
173
185
|
print(e)
|
|
174
186
|
|
jaclang/compiler/__init__.py
CHANGED
|
@@ -86,17 +86,24 @@ TOKEN_MAP.update(
|
|
|
86
86
|
"A_PIPE_FWD": ":>",
|
|
87
87
|
"A_PIPE_BKWD": "<:",
|
|
88
88
|
"DOT_FWD": ".>",
|
|
89
|
+
"STAR_POW": "**",
|
|
90
|
+
"STAR_MUL": "*",
|
|
91
|
+
"FLOOR_DIV": "//",
|
|
92
|
+
"DIV": "/",
|
|
93
|
+
"PYNLINE": "::py::",
|
|
94
|
+
"ADD_EQ": "+=",
|
|
95
|
+
"SUB_EQ": "-=",
|
|
89
96
|
"STAR_POW_EQ": "**=",
|
|
90
97
|
"MUL_EQ": "*=",
|
|
91
98
|
"FLOOR_DIV_EQ": "//=",
|
|
92
99
|
"DIV_EQ": "/=",
|
|
100
|
+
"MOD_EQ": "%=",
|
|
101
|
+
"BW_AND_EQ": "&=",
|
|
93
102
|
"BW_OR_EQ": "|=",
|
|
94
103
|
"BW_XOR_EQ": "^=",
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"DIV": "/",
|
|
99
|
-
"PYNLINE": "::py::",
|
|
104
|
+
"BW_NOT_EQ": "~=",
|
|
105
|
+
"LSHIFT_EQ": "<<=",
|
|
106
|
+
"RSHIFT_EQ": ">>=",
|
|
100
107
|
}
|
|
101
108
|
)
|
|
102
109
|
|
jaclang/compiler/absyntree.py
CHANGED
|
@@ -194,10 +194,10 @@ class AstAccessNode(AstNode):
|
|
|
194
194
|
"""Get access spec."""
|
|
195
195
|
return (
|
|
196
196
|
SymbolAccess.PRIVATE
|
|
197
|
-
if self.access and self.access.tag.
|
|
197
|
+
if self.access and self.access.tag.name == Tok.KW_PRIV
|
|
198
198
|
else (
|
|
199
199
|
SymbolAccess.PROTECTED
|
|
200
|
-
if self.access and self.access.tag.
|
|
200
|
+
if self.access and self.access.tag.name == Tok.KW_PROT
|
|
201
201
|
else SymbolAccess.PUBLIC
|
|
202
202
|
)
|
|
203
203
|
)
|
|
@@ -391,7 +391,6 @@ class Module(AstDocNode):
|
|
|
391
391
|
body: Sequence[ElementStmt | String | EmptyToken],
|
|
392
392
|
is_imported: bool,
|
|
393
393
|
kid: Sequence[AstNode],
|
|
394
|
-
impl_mod: Optional[Module] = None,
|
|
395
394
|
test_mod: Optional[Module] = None,
|
|
396
395
|
registry: Optional[SemRegistry] = None,
|
|
397
396
|
) -> None:
|
|
@@ -400,7 +399,7 @@ class Module(AstDocNode):
|
|
|
400
399
|
self.source = source
|
|
401
400
|
self.body = body
|
|
402
401
|
self.is_imported = is_imported
|
|
403
|
-
self.impl_mod =
|
|
402
|
+
self.impl_mod: list[Module] = []
|
|
404
403
|
self.test_mod = test_mod
|
|
405
404
|
self.mod_deps: dict[str, Module] = {}
|
|
406
405
|
self.registry = registry
|
|
@@ -3716,7 +3715,7 @@ class MatchArch(MatchPattern):
|
|
|
3716
3715
|
|
|
3717
3716
|
def __init__(
|
|
3718
3717
|
self,
|
|
3719
|
-
name: NameSpec,
|
|
3718
|
+
name: AtomTrailer | NameSpec,
|
|
3720
3719
|
arg_patterns: Optional[SubNodeList[MatchPattern]],
|
|
3721
3720
|
kw_patterns: Optional[SubNodeList[MatchKVPair]],
|
|
3722
3721
|
kid: Sequence[AstNode],
|