jaclang 0.7.22__py3-none-any.whl → 0.7.25__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 (65) hide show
  1. jaclang/__init__.py +5 -10
  2. jaclang/cli/cli.py +50 -30
  3. jaclang/compiler/__init__.py +2 -2
  4. jaclang/compiler/absyntree.py +87 -48
  5. jaclang/compiler/codeloc.py +7 -2
  6. jaclang/compiler/compile.py +10 -3
  7. jaclang/compiler/parser.py +26 -23
  8. jaclang/compiler/passes/ir_pass.py +2 -2
  9. jaclang/compiler/passes/main/def_impl_match_pass.py +46 -0
  10. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +146 -123
  11. jaclang/compiler/passes/main/import_pass.py +6 -2
  12. jaclang/compiler/passes/main/pyast_load_pass.py +36 -35
  13. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +7 -7
  14. jaclang/compiler/passes/main/registry_pass.py +3 -12
  15. jaclang/compiler/passes/main/tests/fixtures/defn_decl_mismatch.jac +19 -0
  16. jaclang/compiler/passes/main/tests/fixtures/fstrings.jac +2 -0
  17. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +59 -0
  18. jaclang/compiler/passes/main/tests/test_registry_pass.py +2 -10
  19. jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
  20. jaclang/compiler/passes/main/type_check_pass.py +8 -6
  21. jaclang/compiler/passes/transform.py +27 -3
  22. jaclang/compiler/passes/utils/mypy_ast_build.py +246 -26
  23. jaclang/compiler/symtable.py +6 -0
  24. jaclang/compiler/tests/test_importer.py +2 -2
  25. jaclang/langserve/engine.py +14 -12
  26. jaclang/langserve/server.py +7 -2
  27. jaclang/langserve/tests/test_server.py +1 -1
  28. jaclang/langserve/utils.py +17 -3
  29. jaclang/plugin/builtin.py +3 -3
  30. jaclang/plugin/default.py +612 -236
  31. jaclang/plugin/feature.py +274 -99
  32. jaclang/plugin/plugin.md +471 -0
  33. jaclang/plugin/spec.py +231 -86
  34. jaclang/plugin/tests/fixtures/other_root_access.jac +9 -9
  35. jaclang/plugin/tests/test_features.py +2 -2
  36. jaclang/runtimelib/architype.py +1 -370
  37. jaclang/runtimelib/constructs.py +2 -0
  38. jaclang/runtimelib/context.py +2 -4
  39. jaclang/runtimelib/importer.py +7 -2
  40. jaclang/runtimelib/machine.py +78 -6
  41. jaclang/runtimelib/memory.py +2 -4
  42. jaclang/settings.py +3 -0
  43. jaclang/tests/fixtures/arch_create_util.jac +7 -0
  44. jaclang/tests/fixtures/arch_rel_import_creation.jac +30 -0
  45. jaclang/tests/fixtures/builtin_dotgen.jac +6 -6
  46. jaclang/tests/fixtures/create_dynamic_architype.jac +35 -0
  47. jaclang/tests/fixtures/edge_node_walk.jac +1 -1
  48. jaclang/tests/fixtures/edges_walk.jac +1 -1
  49. jaclang/tests/fixtures/enum_inside_archtype.jac +16 -11
  50. jaclang/tests/fixtures/expr_type.jac +54 -0
  51. jaclang/tests/fixtures/gendot_bubble_sort.jac +1 -1
  52. jaclang/tests/fixtures/glob_multivar_statement.jac +15 -0
  53. jaclang/tests/fixtures/registry.jac +20 -8
  54. jaclang/tests/fixtures/visit_order.jac +20 -0
  55. jaclang/tests/foo/__init__.jac +0 -0
  56. jaclang/tests/main.jac +2 -0
  57. jaclang/tests/test_cli.py +68 -4
  58. jaclang/tests/test_language.py +113 -27
  59. jaclang/utils/helpers.py +92 -14
  60. jaclang/utils/lang_tools.py +6 -2
  61. jaclang/utils/treeprinter.py +4 -2
  62. {jaclang-0.7.22.dist-info → jaclang-0.7.25.dist-info}/METADATA +2 -1
  63. {jaclang-0.7.22.dist-info → jaclang-0.7.25.dist-info}/RECORD +65 -55
  64. {jaclang-0.7.22.dist-info → jaclang-0.7.25.dist-info}/WHEEL +1 -1
  65. {jaclang-0.7.22.dist-info → jaclang-0.7.25.dist-info}/entry_points.txt +0 -0
jaclang/__init__.py CHANGED
@@ -1,17 +1,12 @@
1
1
  """The Jac Programming Language."""
2
2
 
3
- from jaclang.plugin.default import ( # noqa: E402
4
- JacBuiltin,
5
- JacCmdDefaults,
6
- JacFeatureDefaults,
7
- )
8
- from jaclang.plugin.feature import JacFeature, pm # noqa: E402
3
+ from jaclang.plugin.default import JacFeatureImpl
4
+ from jaclang.plugin.feature import JacFeature, plugin_manager
9
5
 
10
6
  jac_import = JacFeature.jac_import
11
7
 
12
- pm.register(JacFeatureDefaults)
13
- pm.register(JacBuiltin)
14
- pm.register(JacCmdDefaults)
15
- pm.load_setuptools_entrypoints("jac")
8
+
9
+ plugin_manager.register(JacFeatureImpl)
10
+ plugin_manager.load_setuptools_entrypoints("jac")
16
11
 
17
12
  __all__ = ["jac_import"]
jaclang/cli/cli.py CHANGED
@@ -6,6 +6,7 @@ import marshal
6
6
  import os
7
7
  import pickle
8
8
  import shutil
9
+ import sys
9
10
  import types
10
11
  from typing import Optional
11
12
 
@@ -28,6 +29,7 @@ from jaclang.utils.lang_tools import AstTool
28
29
 
29
30
 
30
31
  Cmd.create_cmd()
32
+ Jac.setup()
31
33
 
32
34
 
33
35
  @cmd_registry.register
@@ -37,7 +39,10 @@ def format(path: str, outfile: str = "", debug: bool = False) -> None:
37
39
  def format_file(filename: str) -> None:
38
40
  code_gen_format = jac_file_to_pass(filename, schedule=format_pass)
39
41
  if code_gen_format.errors_had:
40
- print(f"Errors occurred while formatting the file {filename}.")
42
+ print(
43
+ f"Errors occurred while formatting the file {filename}.",
44
+ file=sys.stderr,
45
+ )
41
46
  elif debug:
42
47
  print(code_gen_format.ir.gen.jac)
43
48
  elif outfile:
@@ -51,7 +56,7 @@ def format(path: str, outfile: str = "", debug: bool = False) -> None:
51
56
  if os.path.exists(path):
52
57
  format_file(path)
53
58
  else:
54
- print("File does not exist.")
59
+ print("File does not exist.", file=sys.stderr)
55
60
  elif os.path.isdir(path):
56
61
  count = 0
57
62
  for root, _, files in os.walk(path):
@@ -60,9 +65,9 @@ def format(path: str, outfile: str = "", debug: bool = False) -> None:
60
65
  file_path = os.path.join(root, file)
61
66
  format_file(file_path)
62
67
  count += 1
63
- print(f"Formatted {count} '.jac' files.")
68
+ print(f"Formatted {count} '.jac' files.", file=sys.stderr)
64
69
  else:
65
- print("Not a .jac file or directory.")
70
+ print("Not a .jac file or directory.", file=sys.stderr)
66
71
 
67
72
 
68
73
  @cmd_registry.register
@@ -88,23 +93,30 @@ def run(
88
93
  jctx = ExecutionContext.create(session=session)
89
94
 
90
95
  if filename.endswith(".jac"):
91
- jac_import(
92
- target=mod,
93
- base_path=base,
94
- cachable=cache,
95
- override_name="__main__" if main else None,
96
- )
97
- elif filename.endswith(".jir"):
98
- with open(filename, "rb") as f:
99
- JacMachine(base).attach_program(
100
- JacProgram(mod_bundle=pickle.load(f), bytecode=None)
101
- )
96
+ try:
102
97
  jac_import(
103
98
  target=mod,
104
99
  base_path=base,
105
100
  cachable=cache,
106
101
  override_name="__main__" if main else None,
107
102
  )
103
+ except Exception as e:
104
+ print(e, file=sys.stderr)
105
+ elif filename.endswith(".jir"):
106
+ try:
107
+ with open(filename, "rb") as f:
108
+ JacMachine(base).attach_program(
109
+ JacProgram(mod_bundle=pickle.load(f), bytecode=None, sem_ir=None)
110
+ )
111
+ jac_import(
112
+ target=mod,
113
+ base_path=base,
114
+ cachable=cache,
115
+ override_name="__main__" if main else None,
116
+ )
117
+ except Exception as e:
118
+ print(e, file=sys.stderr)
119
+
108
120
  else:
109
121
  jctx.close()
110
122
  JacMachine.detach()
@@ -144,7 +156,7 @@ def get_object(
144
156
  elif filename.endswith(".jir"):
145
157
  with open(filename, "rb") as f:
146
158
  JacMachine(base).attach_program(
147
- JacProgram(mod_bundle=pickle.load(f), bytecode=None)
159
+ JacProgram(mod_bundle=pickle.load(f), bytecode=None, sem_ir=None)
148
160
  )
149
161
  jac_import(
150
162
  target=mod,
@@ -162,7 +174,7 @@ def get_object(
162
174
  if obj:
163
175
  data = obj.__jac__.__getstate__()
164
176
  else:
165
- print(f"Object with id {id} not found.")
177
+ print(f"Object with id {id} not found.", file=sys.stderr)
166
178
 
167
179
  jctx.close()
168
180
  JacMachine.detach()
@@ -182,7 +194,7 @@ def build(filename: str) -> None:
182
194
  with open(filename[:-4] + ".jir", "wb") as f:
183
195
  pickle.dump(out.ir, f)
184
196
  else:
185
- print("Not a .jac file.")
197
+ print("Not a .jac file.", file=sys.stderr)
186
198
 
187
199
 
188
200
  @cmd_registry.register
@@ -201,10 +213,10 @@ def check(filename: str, print_errs: bool = True) -> None:
201
213
  warnings = len(out.warnings_had)
202
214
  if print_errs:
203
215
  for e in out.errors_had:
204
- print("Error:", e)
216
+ print("Error:", e, file=sys.stderr)
205
217
  print(f"Errors: {errs}, Warnings: {warnings}")
206
218
  else:
207
- print("Not a .jac file.")
219
+ print("Not a .jac file.", file=sys.stderr)
208
220
 
209
221
 
210
222
  @cmd_registry.register
@@ -261,7 +273,7 @@ def enter(
261
273
  elif filename.endswith(".jir"):
262
274
  with open(filename, "rb") as f:
263
275
  JacMachine(base).attach_program(
264
- JacProgram(mod_bundle=pickle.load(f), bytecode=None)
276
+ JacProgram(mod_bundle=pickle.load(f), bytecode=None, sem_ir=None)
265
277
  )
266
278
  ret_module = jac_import(
267
279
  target=mod,
@@ -277,13 +289,15 @@ def enter(
277
289
  if ret_module:
278
290
  (loaded_mod,) = ret_module
279
291
  if not loaded_mod:
280
- print("Errors occurred while importing the module.")
292
+ print("Errors occurred while importing the module.", file=sys.stderr)
281
293
  else:
282
294
  architype = getattr(loaded_mod, entrypoint)(*args)
283
295
 
284
296
  jctx.set_entry_node(node)
285
297
 
286
- if isinstance(architype, WalkerArchitype) and jctx.validate_access():
298
+ if isinstance(architype, WalkerArchitype) and Jac.check_read_access(
299
+ jctx.entry_node
300
+ ):
287
301
  Jac.spawn_call(jctx.entry_node.architype, architype)
288
302
 
289
303
  jctx.close()
@@ -341,10 +355,12 @@ def tool(tool: str, args: Optional[list] = None) -> None:
341
355
  else:
342
356
  print(getattr(AstTool(), tool)())
343
357
  except Exception as e:
344
- print(f"Error while running ast tool {tool}, check args: {e}")
358
+ print(
359
+ f"Error while running ast tool {tool}, check args: {e}", file=sys.stderr
360
+ )
345
361
  raise e
346
362
  else:
347
- print(f"Ast tool {tool} not found.")
363
+ print(f"Ast tool {tool} not found.", file=sys.stderr)
348
364
 
349
365
 
350
366
  @cmd_registry.register
@@ -382,9 +398,9 @@ def debug(filename: str, main: bool = True, cache: bool = False) -> None:
382
398
  db.runcall(func)
383
399
  print("Done debugging.")
384
400
  else:
385
- print(f"Error while generating bytecode in {filename}.")
401
+ print(f"Error while generating bytecode in {filename}.", file=sys.stderr)
386
402
  else:
387
- print("Not a .jac file.")
403
+ print("Not a .jac file.", file=sys.stderr)
388
404
 
389
405
 
390
406
  @cmd_registry.register
@@ -455,7 +471,7 @@ def dot(
455
471
  file.write(graph)
456
472
  print(f">>> Graph content saved to {os.path.join(os.getcwd(), file_name)}")
457
473
  else:
458
- print("Not a .jac file.")
474
+ print("Not a .jac file.", file=sys.stderr)
459
475
 
460
476
  jctx.close()
461
477
 
@@ -468,8 +484,12 @@ def py2jac(filename: str) -> None:
468
484
  """
469
485
  if filename.endswith(".py"):
470
486
  with open(filename, "r") as f:
487
+ file_source = f.read()
471
488
  code = PyastBuildPass(
472
- input_ir=ast.PythonModuleAst(ast3.parse(f.read()), mod_path=filename),
489
+ input_ir=ast.PythonModuleAst(
490
+ ast3.parse(file_source),
491
+ orig_src=ast.JacSource(file_source, filename),
492
+ ),
473
493
  ).ir.unparse()
474
494
  print(code)
475
495
  else:
@@ -487,7 +507,7 @@ def jac2py(filename: str) -> None:
487
507
  code = jac_file_to_pass(file_path=filename).ir.gen.py
488
508
  print(code)
489
509
  else:
490
- print("Not a .jac file.")
510
+ print("Not a .jac file.", file=sys.stderr)
491
511
 
492
512
 
493
513
  def start_cli() -> None:
@@ -59,7 +59,7 @@ TOKEN_MAP.update(
59
59
  "KW_OR": "|", "ARROW_BI": "<-->", "ARROW_L": "<--",
60
60
  "ARROW_R": "-->", "ARROW_L_P1": "<-:", "ARROW_R_P2": ":->",
61
61
  "ARROW_L_P2": ":-", "ARROW_R_P1": "-:", "CARROW_BI": "<++>",
62
- "CARROW_L": "<++", "CARROW_R": "++>", "CARROW_L_P1": "<+:",
62
+ "CARROW_L_P1": "<+:", "RSHIFT_EQ": ">>=", "ELLIPSIS": "...",
63
63
  "CARROW_R_P2": ":+>", "CARROW_L_P2": ":+", "CARROW_R_P1": "+:",
64
64
  "PIPE_FWD": "|>", "PIPE_BKWD": "<|", "A_PIPE_FWD": ":>",
65
65
  "A_PIPE_BKWD": "<:", "DOT_FWD": ".>", "STAR_POW": "**",
@@ -68,7 +68,7 @@ TOKEN_MAP.update(
68
68
  "STAR_POW_EQ": "**=", "MUL_EQ": "*=", "FLOOR_DIV_EQ": "//=",
69
69
  "DIV_EQ": "/=", "MOD_EQ": "%=", "BW_AND_EQ": "&=",
70
70
  "BW_OR_EQ": "|=", "BW_XOR_EQ": "^=", "BW_NOT_EQ": "~=",
71
- "LSHIFT_EQ": "<<=", "RSHIFT_EQ": ">>=", "ELLIPSIS": "...",
71
+ "LSHIFT_EQ": "<<=",
72
72
  }
73
73
  )
74
74
  # fmt: on