jaclang 0.6.0__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 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(filename: str, main: bool = True, cache: bool = True) -> None:
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
@@ -242,6 +308,7 @@ def debug(filename: str, main: bool = True, cache: bool = False) -> None:
242
308
  @cmd_registry.register
243
309
  def dot(
244
310
  filename: str,
311
+ session: str = "",
245
312
  initial: str = "",
246
313
  depth: int = -1,
247
314
  traverse: bool = False,
@@ -263,6 +330,17 @@ def dot(
263
330
  :param node_limit: The maximum number of nodes allowed in the graph.
264
331
  :param saveto: Path to save the generated graph.
265
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
+
266
344
  base, mod = os.path.split(filename)
267
345
  base = base if base else "./"
268
346
  mod = mod[:-4]
@@ -286,6 +364,10 @@ def dot(
286
364
  )
287
365
  except Exception as e:
288
366
  print(f"Error while generating graph: {e}")
367
+ import traceback
368
+
369
+ traceback.print_exc()
370
+ Jac.reset_context()
289
371
  return
290
372
  file_name = saveto if saveto else f"{mod}.dot"
291
373
  with open(file_name, "w") as file:
@@ -294,6 +376,8 @@ def dot(
294
376
  else:
295
377
  print("Not a .jac file.")
296
378
 
379
+ Jac.reset_context()
380
+
297
381
 
298
382
  @cmd_registry.register
299
383
  def py_to_jac(filename: str, tree: bool = False) -> None:
@@ -321,10 +405,13 @@ def start_cli() -> None:
321
405
  """
322
406
  parser = cmd_registry.parser
323
407
  args = parser.parse_args()
408
+ cmd_registry.args = args
324
409
  command = cmd_registry.get(args.command)
325
410
  if command:
326
411
  args_dict = vars(args)
327
412
  args_dict.pop("command")
413
+ if command not in ["run"]:
414
+ args_dict.pop("session")
328
415
  ret = command.call(**args_dict)
329
416
  if ret:
330
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="CLI")
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"-{param_name[:1]}",
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"-{param_name[:1]}",
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{param_name[:1]}",
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"-{param_name[:1]}",
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
- self.stdout.write(ret + "\n")
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
 
@@ -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 = 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