jaclang 0.5.7__py3-none-any.whl → 0.5.9__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.

Files changed (49) hide show
  1. jaclang/cli/cli.py +113 -7
  2. jaclang/cli/cmdreg.py +12 -0
  3. jaclang/compiler/__init__.py +58 -2
  4. jaclang/compiler/absyntree.py +1775 -61
  5. jaclang/compiler/codeloc.py +7 -0
  6. jaclang/compiler/compile.py +1 -1
  7. jaclang/compiler/constant.py +17 -0
  8. jaclang/compiler/parser.py +134 -112
  9. jaclang/compiler/passes/ir_pass.py +18 -0
  10. jaclang/compiler/passes/main/__init__.py +2 -0
  11. jaclang/compiler/passes/main/def_impl_match_pass.py +19 -3
  12. jaclang/compiler/passes/main/def_use_pass.py +1 -1
  13. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +357 -0
  14. jaclang/compiler/passes/main/import_pass.py +7 -3
  15. jaclang/compiler/passes/main/pyast_gen_pass.py +350 -109
  16. jaclang/compiler/passes/main/pyast_load_pass.py +1779 -206
  17. jaclang/compiler/passes/main/registry_pass.py +126 -0
  18. jaclang/compiler/passes/main/schedules.py +4 -1
  19. jaclang/compiler/passes/main/sym_tab_build_pass.py +20 -28
  20. jaclang/compiler/passes/main/tests/test_pyast_build_pass.py +14 -5
  21. jaclang/compiler/passes/main/tests/test_registry_pass.py +39 -0
  22. jaclang/compiler/passes/main/tests/test_sym_tab_build_pass.py +8 -8
  23. jaclang/compiler/passes/main/tests/test_typeinfo_pass.py +7 -0
  24. jaclang/compiler/passes/main/type_check_pass.py +0 -1
  25. jaclang/compiler/passes/tool/jac_formatter_pass.py +8 -17
  26. jaclang/compiler/passes/tool/tests/test_unparse_validate.py +65 -0
  27. jaclang/compiler/passes/utils/mypy_ast_build.py +28 -14
  28. jaclang/compiler/symtable.py +23 -2
  29. jaclang/compiler/tests/test_parser.py +53 -0
  30. jaclang/compiler/workspace.py +52 -26
  31. jaclang/core/aott.py +193 -28
  32. jaclang/core/construct.py +59 -2
  33. jaclang/core/registry.py +115 -0
  34. jaclang/core/utils.py +25 -0
  35. jaclang/plugin/default.py +108 -26
  36. jaclang/plugin/feature.py +22 -4
  37. jaclang/plugin/spec.py +13 -7
  38. jaclang/utils/helpers.py +66 -3
  39. jaclang/utils/lang_tools.py +6 -38
  40. jaclang/utils/test.py +1 -0
  41. jaclang/utils/tests/test_lang_tools.py +11 -14
  42. jaclang/utils/treeprinter.py +10 -2
  43. {jaclang-0.5.7.dist-info → jaclang-0.5.9.dist-info}/METADATA +1 -1
  44. {jaclang-0.5.7.dist-info → jaclang-0.5.9.dist-info}/RECORD +47 -43
  45. {jaclang-0.5.7.dist-info → jaclang-0.5.9.dist-info}/WHEEL +1 -1
  46. jaclang/compiler/__jac_gen__/__init__.py +0 -0
  47. jaclang/compiler/__jac_gen__/jac_parser.py +0 -4069
  48. {jaclang-0.5.7.dist-info → jaclang-0.5.9.dist-info}/entry_points.txt +0 -0
  49. {jaclang-0.5.7.dist-info → jaclang-0.5.9.dist-info}/top_level.txt +0 -0
jaclang/cli/cli.py CHANGED
@@ -1,8 +1,11 @@
1
1
  """Command line interface tool for the Jac language."""
2
2
 
3
+ import importlib
4
+ import marshal
3
5
  import os
4
6
  import pickle
5
7
  import shutil
8
+ import types
6
9
  from typing import Optional
7
10
 
8
11
  from jaclang import jac_import
@@ -11,8 +14,10 @@ from jaclang.compiler.compile import jac_file_to_pass
11
14
  from jaclang.compiler.constant import Constants
12
15
  from jaclang.compiler.passes.main.schedules import py_code_gen_typed
13
16
  from jaclang.compiler.passes.tool.schedules import format_pass
17
+ from jaclang.plugin.builtin import dotgen
14
18
  from jaclang.plugin.feature import JacCmd as Cmd
15
19
  from jaclang.plugin.feature import JacFeature as Jac
20
+ from jaclang.utils.helpers import debugger as db
16
21
  from jaclang.utils.lang_tools import AstTool
17
22
 
18
23
 
@@ -90,8 +95,7 @@ def build(filename: str) -> None:
90
95
  warnings = len(out.warnings_had)
91
96
  print(f"Errors: {errs}, Warnings: {warnings}")
92
97
  for i in out.ir.flatten():
93
- i.gen.mypy_ast = []
94
- i.gen.py = ""
98
+ i.gen.clean()
95
99
  with open(filename[:-4] + ".jir", "wb") as f:
96
100
  pickle.dump(out.ir, f)
97
101
  else:
@@ -141,12 +145,33 @@ def enter(filename: str, entrypoint: str, args: list) -> None:
141
145
 
142
146
 
143
147
  @cmd_registry.register
144
- def test(filename: str) -> None:
148
+ def test(
149
+ filepath: str,
150
+ filter: str = "",
151
+ xit: bool = False,
152
+ maxfail: int = None, # type:ignore
153
+ directory: str = "",
154
+ verbose: bool = False,
155
+ ) -> None:
145
156
  """Run the test suite in the specified .jac file.
146
157
 
147
- :param filename: The path to the .jac file.
158
+ :param filepath: Path/to/file.jac
159
+ :param filter: Filter the files using Unix shell style conventions.
160
+ :param xit(exit): Stop(exit) running tests as soon as finds an error.
161
+ :param maxfail: Stop running tests after n failures.
162
+ :param directory: Run tests from the specified directory.
163
+ :param verbose: Show more info.
164
+
165
+ jac test => jac test -d .
148
166
  """
149
- Jac.run_test(filename)
167
+ Jac.run_test(
168
+ filepath=filepath,
169
+ filter=filter,
170
+ xit=xit,
171
+ maxfail=maxfail,
172
+ directory=directory,
173
+ verbose=verbose,
174
+ )
150
175
 
151
176
 
152
177
  @cmd_registry.register
@@ -162,8 +187,9 @@ def tool(tool: str, args: Optional[list] = None) -> None:
162
187
  print(getattr(AstTool(), tool)(args))
163
188
  else:
164
189
  print(getattr(AstTool(), tool)())
165
- except Exception:
166
- print(f"Error while running ast tool {tool}, check args.")
190
+ except Exception as e:
191
+ print(f"Error while running ast tool {tool}, check args: {e}")
192
+ raise e
167
193
  else:
168
194
  print(f"Ast tool {tool} not found.")
169
195
 
@@ -184,6 +210,86 @@ def clean() -> None:
184
210
  print("Done cleaning.")
185
211
 
186
212
 
213
+ @cmd_registry.register
214
+ def debug(filename: str, main: bool = True, cache: bool = False) -> None:
215
+ """Debug the specified .jac file using pdb."""
216
+ base, mod = os.path.split(filename)
217
+ base = base if base else "./"
218
+ mod = mod[:-4]
219
+ if filename.endswith(".jac"):
220
+ bytecode = jac_file_to_pass(filename).ir.gen.py_bytecode
221
+ if bytecode:
222
+ code = marshal.loads(bytecode)
223
+ if db.has_breakpoint(bytecode):
224
+ run(filename, main, cache)
225
+ else:
226
+ func = types.FunctionType(code, globals())
227
+
228
+ print("Debugging with Jac debugger.\n")
229
+ db.runcall(func)
230
+ print("Done debugging.")
231
+ else:
232
+ print(f"Error while generating bytecode in {filename}.")
233
+ else:
234
+ print("Not a .jac file.")
235
+
236
+
237
+ @cmd_registry.register
238
+ def graph(
239
+ filename: str,
240
+ initial: str = "",
241
+ depth: int = -1,
242
+ traverse: bool = False,
243
+ connection: list[str] = [], # noqa: B006
244
+ bfs: bool = False,
245
+ edge_limit: int = 512,
246
+ node_limit: int = 512,
247
+ saveto: str = "",
248
+ ) -> None:
249
+ """Generate and Visualize a graph based on the specified .jac file contents and parameters.
250
+
251
+ :param filename: The name of the file to generate the graph from.
252
+ :param initial: The initial node for graph traversal (default is root node).
253
+ :param depth: The maximum depth for graph traversal (-1 for unlimited depth, default is -1).
254
+ :param traverse: Flag to indicate whether to traverse the graph (default is False).
255
+ :param connection: List of node connections(edge type) to include in the graph (default is an empty list).
256
+ :param bfs: Flag to indicate whether to use breadth-first search for traversal (default is False).
257
+ :param edge_limit: The maximum number of edges allowed in the graph.
258
+ :param node_limit: The maximum number of nodes allowed in the graph.
259
+ :param saveto: Path to save the generated graph.
260
+ """
261
+ base, mod = os.path.split(filename)
262
+ base = base if base else "./"
263
+ mod = mod[:-4]
264
+ if filename.endswith(".jac"):
265
+ jac_import(
266
+ target=mod,
267
+ base_path=base,
268
+ )
269
+ module = importlib.import_module(mod)
270
+ globals().update(vars(module))
271
+ try:
272
+ node = globals().get(initial, eval(initial)) if initial else None
273
+ graph = dotgen(
274
+ node=node,
275
+ depth=depth,
276
+ traverse=traverse,
277
+ edge_type=connection,
278
+ bfs=bfs,
279
+ edge_limit=edge_limit,
280
+ node_limit=node_limit,
281
+ )
282
+ except Exception as e:
283
+ print(f"Error while generating graph: {e}")
284
+ return
285
+ file_name = saveto if saveto else f"{mod}.dot"
286
+ with open(file_name, "w") as file:
287
+ file.write(graph)
288
+ print(f">>> Graph content saved to {os.path.join(os.getcwd(), file_name)}")
289
+ else:
290
+ print("Not a .jac file.")
291
+
292
+
187
293
  def start_cli() -> None:
188
294
  """
189
295
  Start the command line interface.
jaclang/cli/cmdreg.py CHANGED
@@ -50,6 +50,18 @@ class CommandRegistry:
50
50
  arg_msg = f"type: {param.annotation.__name__}"
51
51
  if param_name == "args":
52
52
  cmd_parser.add_argument("args", nargs=argparse.REMAINDER, help=arg_msg)
53
+ elif param_name == "filepath":
54
+ first = False
55
+ cmd_parser.add_argument(
56
+ f"{param_name}",
57
+ type=(
58
+ eval(param.annotation)
59
+ if isinstance(param.annotation, str)
60
+ else param.annotation
61
+ ),
62
+ help=arg_msg,
63
+ nargs="?",
64
+ )
53
65
  elif param.default is param.empty:
54
66
  if first:
55
67
  first = False
@@ -1,5 +1,5 @@
1
- # type: ignore
2
1
  """Jac compiler tools."""
2
+
3
3
  import contextlib
4
4
  import logging
5
5
  import os
@@ -8,6 +8,7 @@ import sys
8
8
  cur_dir = os.path.dirname(__file__)
9
9
  if not os.path.exists(os.path.join(cur_dir, "__jac_gen__", "jac_parser.py")):
10
10
  from jaclang.vendor.lark.tools import standalone
11
+ from jaclang.utils.helpers import auto_generate_refs
11
12
 
12
13
  os.makedirs(os.path.join(cur_dir, "__jac_gen__"), exist_ok=True)
13
14
  with open(os.path.join(cur_dir, "__jac_gen__", "__init__.py"), "w"):
@@ -22,11 +23,66 @@ if not os.path.exists(os.path.join(cur_dir, "__jac_gen__", "jac_parser.py")):
22
23
  ]
23
24
  standalone.main() # type: ignore
24
25
  sys.argv = save_argv
26
+ auto_generate_refs()
27
+
25
28
 
26
29
  from .__jac_gen__ import jac_parser as jac_lark # noqa: E402
27
30
 
28
31
 
29
32
  jac_lark.logger.setLevel(logging.DEBUG)
30
33
  contextlib.suppress(AttributeError)
34
+ TOKEN_MAP = {
35
+ x.name: x.pattern.value
36
+ for x in jac_lark.Lark_StandAlone().parser.lexer_conf.terminals
37
+ }
38
+
39
+ TOKEN_MAP.update(
40
+ {
41
+ "CARROW_L": "<++",
42
+ "CARROW_R": "++>",
43
+ "GLOBAL_OP": ":global:",
44
+ "NONLOCAL_OP": ":nonlocal:",
45
+ "WALKER_OP": ":walker:",
46
+ "NODE_OP": ":node:",
47
+ "EDGE_OP": ":edge:",
48
+ "CLASS_OP": ":class:",
49
+ "OBJECT_OP": ":obj:",
50
+ "TYPE_OP": "`",
51
+ "ABILITY_OP": ":can:",
52
+ "ELVIS_OP": "?:",
53
+ "NULL_OK": "?",
54
+ "KW_OR": "|",
55
+ "ARROW_BI": "<-->",
56
+ "ARROW_L": "<--",
57
+ "ARROW_R": "-->",
58
+ "ARROW_L_P1": "<-:",
59
+ "ARROW_R_P2": ":->",
60
+ "ARROW_L_P2": ":-",
61
+ "ARROW_R_P1": "-:",
62
+ "CARROW_BI": "<++>",
63
+ "CARROW_L": "<++",
64
+ "CARROW_R": "++>",
65
+ "CARROW_L_P1": "<+:",
66
+ "CARROW_R_P2": ":+>",
67
+ "CARROW_L_P2": ":+",
68
+ "CARROW_R_P1": "+:",
69
+ "PIPE_FWD": "|>",
70
+ "PIPE_BKWD": "<|",
71
+ "A_PIPE_FWD": ":>",
72
+ "A_PIPE_BKWD": "<:",
73
+ "DOT_FWD": ".>",
74
+ "STAR_POW_EQ": "**=",
75
+ "MUL_EQ": "*=",
76
+ "FLOOR_DIV_EQ": "//=",
77
+ "DIV_EQ": "/=",
78
+ "BW_OR_EQ": "|=",
79
+ "BW_XOR_EQ": "^=",
80
+ "STAR_POW": "**",
81
+ "STAR_MUL": "*",
82
+ "FLOOR_DIV": "//",
83
+ "DIV": "/",
84
+ }
85
+ )
86
+
31
87
 
32
- __all__ = ["jac_lark"]
88
+ __all__ = ["jac_lark", "TOKEN_MAP"]