jaclang 0.5.18__py3-none-any.whl → 0.6.0__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 (47) hide show
  1. jaclang/cli/cli.py +4 -2
  2. jaclang/compiler/__init__.py +12 -5
  3. jaclang/compiler/absyntree.py +3 -3
  4. jaclang/compiler/generated/jac_parser.py +2 -2
  5. jaclang/compiler/jac.lark +2 -2
  6. jaclang/compiler/parser.py +47 -7
  7. jaclang/compiler/passes/main/__init__.py +3 -2
  8. jaclang/compiler/passes/main/access_modifier_pass.py +173 -0
  9. jaclang/compiler/passes/main/import_pass.py +32 -19
  10. jaclang/compiler/passes/main/pyast_gen_pass.py +41 -26
  11. jaclang/compiler/passes/main/pyast_load_pass.py +136 -73
  12. jaclang/compiler/passes/main/pyout_pass.py +14 -13
  13. jaclang/compiler/passes/main/registry_pass.py +8 -3
  14. jaclang/compiler/passes/main/schedules.py +5 -3
  15. jaclang/compiler/passes/main/sym_tab_build_pass.py +23 -26
  16. jaclang/compiler/passes/main/tests/test_import_pass.py +2 -2
  17. jaclang/compiler/passes/tool/jac_formatter_pass.py +83 -21
  18. jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +11 -4
  19. jaclang/compiler/passes/transform.py +2 -0
  20. jaclang/compiler/symtable.py +10 -3
  21. jaclang/compiler/tests/test_importer.py +9 -0
  22. jaclang/compiler/workspace.py +17 -5
  23. jaclang/core/aott.py +34 -63
  24. jaclang/core/importer.py +73 -65
  25. jaclang/core/llms/__init__.py +20 -0
  26. jaclang/core/llms/anthropic.py +61 -0
  27. jaclang/core/llms/base.py +206 -0
  28. jaclang/core/llms/groq.py +67 -0
  29. jaclang/core/llms/huggingface.py +73 -0
  30. jaclang/core/llms/ollama.py +78 -0
  31. jaclang/core/llms/openai.py +61 -0
  32. jaclang/core/llms/togetherai.py +60 -0
  33. jaclang/core/llms/utils.py +9 -0
  34. jaclang/core/utils.py +16 -1
  35. jaclang/plugin/default.py +37 -14
  36. jaclang/plugin/feature.py +9 -6
  37. jaclang/plugin/spec.py +8 -1
  38. jaclang/settings.py +1 -1
  39. jaclang/utils/helpers.py +6 -2
  40. jaclang/utils/treeprinter.py +9 -6
  41. jaclang-0.6.0.dist-info/METADATA +17 -0
  42. {jaclang-0.5.18.dist-info → jaclang-0.6.0.dist-info}/RECORD +45 -36
  43. jaclang/core/llms.py +0 -111
  44. jaclang-0.5.18.dist-info/METADATA +0 -7
  45. {jaclang-0.5.18.dist-info → jaclang-0.6.0.dist-info}/WHEEL +0 -0
  46. {jaclang-0.5.18.dist-info → jaclang-0.6.0.dist-info}/entry_points.txt +0 -0
  47. {jaclang-0.5.18.dist-info → jaclang-0.6.0.dist-info}/top_level.txt +0 -0
@@ -6,6 +6,8 @@ import ast as py_ast
6
6
  import os
7
7
  from typing import Optional, Sequence, TypeAlias, TypeVar
8
8
 
9
+ # from icecream import ic
10
+
9
11
  import jaclang.compiler.absyntree as ast
10
12
  from jaclang.compiler.constant import Tokens as Tok
11
13
  from jaclang.compiler.passes.ir_pass import Pass
@@ -44,6 +46,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
44
46
  raise self.ice(f"Unknown node type {type(node).__name__}")
45
47
  # print(f"finshed {type(node).__name__} ---------------------")
46
48
  # print("normalizing", ret.__class__.__name__)
49
+ # ic("normalizing", ret.__class__.__name__)
47
50
  # print(ret.unparse())
48
51
  # ret.unparse()
49
52
  return ret
@@ -140,10 +143,13 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
140
143
  if sys.version_info >= (3, 12):
141
144
  type_params: list[type_param]
142
145
  """
146
+ # ic("----")
143
147
  name = ast.Name(
144
148
  file_path=self.mod_path,
145
149
  name=Tok.NAME,
146
- value=node.name,
150
+ value=(
151
+ node.name if node.name != "root" else "root_"
152
+ ), # root is a reserved keyword
147
153
  line=node.lineno,
148
154
  col_start=node.col_offset,
149
155
  col_end=node.col_offset + len(node.name),
@@ -160,12 +166,12 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
160
166
  and isinstance(valid[0], ast.ExprStmt)
161
167
  and isinstance(valid[0].expr, ast.String)
162
168
  ):
163
- doc = valid[0].expr
164
- self.convert_to_doc(doc)
169
+ self.convert_to_doc(valid[0].expr)
170
+ doc = valid[0]
165
171
  valid_body = ast.SubNodeList[ast.CodeBlockStmt](
166
- items=valid[1:],
172
+ items=[doc] + valid[1:],
167
173
  delim=Tok.WS,
168
- kid=valid[1:],
174
+ kid=valid[1:] + [doc],
169
175
  left_enc=self.operator(Tok.LBRACE, "{"),
170
176
  right_enc=self.operator(Tok.RBRACE, "}"),
171
177
  )
@@ -213,7 +219,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
213
219
  signature=sig,
214
220
  body=valid_body,
215
221
  decorators=valid_decorators,
216
- doc=doc,
222
+ doc=None,
217
223
  kid=kid,
218
224
  )
219
225
  return ret
@@ -262,8 +268,8 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
262
268
  )
263
269
  arch_type = ast.Token(
264
270
  file_path=self.mod_path,
265
- name=Tok.KW_OBJECT,
266
- value="obj",
271
+ name=Tok.KW_CLASS,
272
+ value="class",
267
273
  line=node.lineno,
268
274
  col_start=0,
269
275
  col_end=0,
@@ -309,7 +315,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
309
315
  body = body[1:] if doc else body
310
316
  valid: list[ast.ArchBlockStmt] = (
311
317
  self.extract_with_entry(body, ast.ArchBlockStmt)
312
- if not (isinstance(body[0], ast.Semi) and len(body) == 1)
318
+ if body and not (isinstance(body[0], ast.Semi) and len(body) == 1)
313
319
  else []
314
320
  )
315
321
  empty_block: Sequence[ast.AstNode] = [
@@ -491,8 +497,12 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
491
497
  op: operator
492
498
  value: expr
493
499
  """
500
+ from jaclang.compiler import TOKEN_MAP
501
+
494
502
  target = self.convert(node.target)
495
503
  op = self.convert(node.op)
504
+ if isinstance(op, ast.Token):
505
+ op.name = self.aug_op_map(TOKEN_MAP, op)
496
506
  value = self.convert(node.value)
497
507
  if (
498
508
  isinstance(value, ast.Expr)
@@ -750,9 +760,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
750
760
  condition=test,
751
761
  body=body2,
752
762
  else_body=else_body,
753
- kid=(
754
- [test, body2, else_body] if else_body is not None else [test, body2]
755
- ),
763
+ kid=([test, body2, else_body] if else_body else [test, body2]),
756
764
  )
757
765
  else:
758
766
  raise self.ice()
@@ -837,11 +845,11 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
837
845
  if (isinstance(cause, ast.Expr) or cause is None) and (
838
846
  isinstance(exc, ast.Expr) or exc is None
839
847
  ):
840
- if node.exc and not node.cause:
848
+ if exc and not node.cause:
841
849
  return ast.RaiseStmt(
842
- cause=None,
850
+ cause=exc,
843
851
  from_target=None,
844
- kid=[self.operator(Tok.KW_RAISE, "raise")],
852
+ kid=[self.operator(Tok.KW_RAISE, "raise"), exc],
845
853
  )
846
854
  else:
847
855
  return ast.RaiseStmt(cause=cause, from_target=exc, kid=kid)
@@ -856,12 +864,12 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
856
864
  msg: expr | None
857
865
  """
858
866
  test = self.convert(node.test)
859
- msg = self.convert(node.msg) if node.msg is not None else None
867
+ msg = self.convert(node.msg) if node.msg else None
860
868
  if isinstance(test, ast.Expr) and (isinstance(msg, ast.Expr) or msg is None):
861
869
  return ast.AssertStmt(
862
870
  condition=test,
863
871
  error_msg=msg,
864
- kid=[test, msg] if msg is not None else [test],
872
+ kid=[test, msg] if msg else [test],
865
873
  )
866
874
  else:
867
875
  raise self.ice()
@@ -877,11 +885,31 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
877
885
  ctx: expr_context
878
886
  """
879
887
  value = self.convert(node.value)
880
-
888
+ if (
889
+ isinstance(value, ast.FuncCall)
890
+ and isinstance(value.target, ast.Name)
891
+ and value.target.value == "super"
892
+ ):
893
+ tok = ast.Token(
894
+ file_path=self.mod_path,
895
+ name=Tok.KW_SUPER,
896
+ value="super",
897
+ line=node.lineno,
898
+ col_start=node.col_offset,
899
+ col_end=node.col_offset + len("super"),
900
+ pos_start=0,
901
+ pos_end=0,
902
+ )
903
+ value = ast.SpecialVarRef(var=tok, kid=[tok])
904
+ # exit()
881
905
  attribute = ast.Name(
882
906
  file_path=self.mod_path,
883
907
  name=Tok.NAME,
884
- value=node.attr,
908
+ value=(
909
+ ("<>" + node.attr)
910
+ if node.attr == "init"
911
+ else "init" if node.attr == "__init__" else node.attr
912
+ ),
885
913
  line=node.lineno,
886
914
  col_start=node.col_offset,
887
915
  col_end=node.col_offset + len(node.attr),
@@ -911,7 +939,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
911
939
  else:
912
940
  raise self.ice()
913
941
 
914
- def proc_bin_op(self, node: py_ast.BinOp) -> ast.BinaryExpr:
942
+ def proc_bin_op(self, node: py_ast.BinOp) -> ast.AtomUnit:
915
943
  """Process python node.
916
944
 
917
945
  class BinOp(expr):
@@ -929,12 +957,20 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
929
957
  and isinstance(op, ast.Token)
930
958
  and isinstance(right, ast.Expr)
931
959
  ):
932
- return ast.BinaryExpr(
960
+ value = ast.BinaryExpr(
933
961
  left=left,
934
962
  op=op,
935
963
  right=right,
936
964
  kid=[left, op, right],
937
965
  )
966
+ return ast.AtomUnit(
967
+ value=value,
968
+ kid=[
969
+ self.operator(Tok.RPAREN, "("),
970
+ value,
971
+ self.operator(Tok.LPAREN, ")"),
972
+ ],
973
+ )
938
974
  else:
939
975
  raise self.ice()
940
976
 
@@ -1134,11 +1170,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1134
1170
  kvp = ast.KVPair(
1135
1171
  key=key_pluck,
1136
1172
  value=valid_values[i],
1137
- kid=(
1138
- [key_pluck, valid_values[i]]
1139
- if key_pluck is not None
1140
- else [valid_values[i]]
1141
- ),
1173
+ kid=([key_pluck, valid_values[i]] if key_pluck else [valid_values[i]]),
1142
1174
  )
1143
1175
  kvpair.append(kvp)
1144
1176
  return ast.DictVal(
@@ -1182,32 +1214,54 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1182
1214
  name: _Identifier | None
1183
1215
  body: list[stmt]
1184
1216
  """
1185
- type = self.convert(node.type) if node.type is not None else None
1186
- if not type:
1217
+ type = self.convert(node.type) if node.type else None
1218
+ name: ast.Name | None = None
1219
+ if not type and not node.name:
1187
1220
  type = ast.Name(
1188
1221
  file_path=self.mod_path,
1189
1222
  name=Tok.NAME,
1190
- value="Any",
1223
+ value="Exception",
1191
1224
  line=node.lineno,
1192
1225
  col_start=node.col_offset,
1193
- col_end=node.col_offset + 3,
1226
+ col_end=node.col_offset + 9,
1194
1227
  pos_start=0,
1195
1228
  pos_end=0,
1196
1229
  )
1197
- name = (
1198
- ast.Name(
1230
+ name = ast.Name(
1199
1231
  file_path=self.mod_path,
1200
1232
  name=Tok.NAME,
1201
- value=node.name,
1233
+ value="e",
1202
1234
  line=node.lineno,
1203
1235
  col_start=node.col_offset,
1204
- col_end=node.col_offset + len(node.name),
1236
+ col_end=node.col_offset + 1,
1205
1237
  pos_start=0,
1206
1238
  pos_end=0,
1207
1239
  )
1208
- if node.name is not None
1209
- else None
1210
- )
1240
+ else:
1241
+ # type = ast.Name(
1242
+ # file_path=self.mod_path,
1243
+ # name=Tok.NAME,
1244
+ # value=no,
1245
+ # line=node.lineno,
1246
+ # col_start=node.col_offset,
1247
+ # col_end=node.col_offset + 9,
1248
+ # pos_start=0,
1249
+ # pos_end=0,
1250
+ # )
1251
+ name = (
1252
+ ast.Name(
1253
+ file_path=self.mod_path,
1254
+ name=Tok.NAME,
1255
+ value=node.name,
1256
+ line=node.lineno,
1257
+ col_start=node.col_offset,
1258
+ col_end=node.col_offset + len(node.name),
1259
+ pos_start=0,
1260
+ pos_end=0,
1261
+ )
1262
+ if node.name
1263
+ else None
1264
+ )
1211
1265
 
1212
1266
  body = [self.convert(i) for i in node.body]
1213
1267
  valid = [i for i in body if isinstance(i, (ast.CodeBlockStmt))]
@@ -1220,12 +1274,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1220
1274
  left_enc=self.operator(Tok.LBRACE, "{"),
1221
1275
  right_enc=self.operator(Tok.RBRACE, "}"),
1222
1276
  )
1223
- kid = []
1224
- if type:
1225
- kid.append(type)
1226
- if name:
1227
- kid.append(name)
1228
- kid.append(valid_body)
1277
+ kid = [item for item in [type, name, valid_body] if item]
1229
1278
  if isinstance(type, ast.Expr) and (isinstance(name, ast.Name) or not name):
1230
1279
  return ast.Except(
1231
1280
  ex_type=type,
@@ -1432,7 +1481,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1432
1481
  valid_names.append(
1433
1482
  ast.ModuleItem(
1434
1483
  name=name.expr,
1435
- alias=name.alias if name.alias is not None else None,
1484
+ alias=name.alias if name.alias else None,
1436
1485
  kid=[i for i in name.kid if i],
1437
1486
  )
1438
1487
  )
@@ -1448,6 +1497,18 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1448
1497
  if not items:
1449
1498
  raise self.ice("No valid names in import from")
1450
1499
  pytag = ast.SubTag[ast.Name](tag=lang, kid=[lang])
1500
+ if len(node.names) == 1 and node.names[0].name == "*":
1501
+ path_in = ast.SubNodeList[ast.ModulePath](
1502
+ items=[path], delim=Tok.COMMA, kid=[path]
1503
+ )
1504
+ ret = ast.Import(
1505
+ hint=pytag,
1506
+ from_loc=None,
1507
+ items=path_in,
1508
+ is_absorb=True,
1509
+ kid=[pytag, path_in],
1510
+ )
1511
+ return ret
1451
1512
  ret = ast.Import(
1452
1513
  hint=pytag,
1453
1514
  from_loc=path,
@@ -1635,7 +1696,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1635
1696
  kid.append(kw_patterns)
1636
1697
  else:
1637
1698
  kw_patterns = None
1638
- if isinstance(cls, ast.NameSpec):
1699
+ if isinstance(cls, (ast.NameSpec, ast.AtomTrailer)):
1639
1700
  return ast.MatchArch(
1640
1701
  name=cls, arg_patterns=patterns_sub, kw_patterns=kw_patterns, kid=kid
1641
1702
  )
@@ -1733,10 +1794,10 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1733
1794
  name = ast.Name(
1734
1795
  file_path=self.mod_path,
1735
1796
  name=Tok.NAME,
1736
- value=node.name if node.name is not None else "_",
1797
+ value=node.name if node.name else "_",
1737
1798
  line=node.lineno,
1738
1799
  col_start=node.col_offset,
1739
- col_end=node.col_offset + len(node.name if node.name is not None else "_"),
1800
+ col_end=node.col_offset + len(node.name if node.name else "_"),
1740
1801
  pos_start=0,
1741
1802
  pos_end=0,
1742
1803
  )
@@ -1766,7 +1827,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1766
1827
  ret = ast.Name(
1767
1828
  file_path=self.mod_path,
1768
1829
  name=Tok.NAME,
1769
- value=node.id,
1830
+ value=node.id if node.id != "root" else "root_", # reserved word
1770
1831
  line=node.lineno,
1771
1832
  col_start=node.col_offset,
1772
1833
  col_end=node.col_offset + len(node.id),
@@ -1988,6 +2049,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1988
2049
  left_enc=self.operator(Tok.LBRACE, "{"),
1989
2050
  right_enc=self.operator(Tok.RBRACE, "}"),
1990
2051
  )
2052
+ elsestmt = ast.ElseStmt(body=else_body, kid=[else_body])
1991
2053
  kid.append(else_body)
1992
2054
  else:
1993
2055
  else_body = None
@@ -2006,23 +2068,19 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2006
2068
  left_enc=self.operator(Tok.LBRACE, "{"),
2007
2069
  right_enc=self.operator(Tok.RBRACE, "}"),
2008
2070
  )
2009
- kid.append(finally_body)
2071
+ finally_stmt = ast.FinallyStmt(body=finally_body, kid=[finally_body])
2072
+
2073
+ kid.append(finally_stmt)
2010
2074
  else:
2011
2075
  finally_body = None
2012
-
2013
- return ast.TryStmt(
2076
+ ret = ast.TryStmt(
2014
2077
  body=valid_body,
2015
2078
  excepts=excepts,
2016
- else_body=(
2017
- ast.ElseStmt(body=else_body, kid=[else_body]) if else_body else None
2018
- ),
2019
- finally_body=(
2020
- ast.FinallyStmt(body=finally_body, kid=[finally_body])
2021
- if finally_body
2022
- else None
2023
- ),
2079
+ else_body=elsestmt if else_body else None,
2080
+ finally_body=finally_stmt if finally_body else None,
2024
2081
  kid=kid,
2025
2082
  )
2083
+ return ret
2026
2084
 
2027
2085
  def proc_try_star(self, node: py_ast.TryStar) -> ast.TryStmt:
2028
2086
  """Process python node.
@@ -2123,7 +2181,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2123
2181
  name = ast.Name(
2124
2182
  file_path=self.mod_path,
2125
2183
  name=Tok.NAME,
2126
- value=node.arg,
2184
+ value=node.arg if node.arg != "root" else "root_", # reserved word
2127
2185
  line=node.lineno,
2128
2186
  col_start=node.col_offset,
2129
2187
  col_end=node.col_offset + len(node.arg),
@@ -2202,9 +2260,12 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2202
2260
  pos_end=0,
2203
2261
  )
2204
2262
  kwarg.add_kids_left([kwarg.unpack])
2205
- defaults = [self.convert(expr) for expr in node.defaults if type(expr) is None]
2206
-
2263
+ defaults = [self.convert(expr) for expr in node.defaults]
2207
2264
  params = [*args]
2265
+ for param, default in zip(params[::-1], defaults[::-1]):
2266
+ if isinstance(default, ast.Expr) and isinstance(param, ast.ParamVar):
2267
+ param.value = default
2268
+ param.add_kids_right([default])
2208
2269
  if vararg:
2209
2270
  params.append(vararg)
2210
2271
  params += kwonlyargs
@@ -2213,8 +2274,6 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2213
2274
  params += defaults
2214
2275
 
2215
2276
  valid_params = [param for param in params if isinstance(param, ast.ParamVar)]
2216
- if len(valid_params) != len(params):
2217
- raise self.ice("Length mismatch in arguments")
2218
2277
  if valid_params:
2219
2278
  fs_params = ast.SubNodeList[ast.ParamVar](
2220
2279
  items=valid_params, delim=Tok.COMMA, kid=valid_params
@@ -2402,10 +2461,10 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2402
2461
  arg = ast.Name(
2403
2462
  file_path=self.mod_path,
2404
2463
  name=Tok.NAME,
2405
- value=node.arg if node.arg is not None else "_",
2464
+ value=node.arg if node.arg else "_",
2406
2465
  line=node.lineno,
2407
2466
  col_start=node.col_offset,
2408
- col_end=node.col_offset + len(node.arg if node.arg is not None else "_"),
2467
+ col_end=node.col_offset + len(node.arg if node.arg else "_"),
2409
2468
  pos_start=0,
2410
2469
  pos_end=0,
2411
2470
  )
@@ -2424,7 +2483,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2424
2483
  body: list[stmt]
2425
2484
  """
2426
2485
  pattern = self.convert(node.pattern)
2427
- guard = self.convert(node.guard) if node.guard is not None else None
2486
+ guard = self.convert(node.guard) if node.guard else None
2428
2487
  body = [self.convert(i) for i in node.body]
2429
2488
  valid = [i for i in body if isinstance(i, ast.CodeBlockStmt)]
2430
2489
  if isinstance(pattern, ast.MatchPattern) and (
@@ -2434,9 +2493,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2434
2493
  pattern=pattern,
2435
2494
  guard=guard,
2436
2495
  body=valid,
2437
- kid=(
2438
- [pattern, guard, *valid] if guard is not None else [pattern, *valid]
2439
- ),
2496
+ kid=([pattern, guard, *valid] if guard else [pattern, *valid]),
2440
2497
  )
2441
2498
  else:
2442
2499
  raise self.ice()
@@ -2449,9 +2506,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2449
2506
  optional_vars: expr | None
2450
2507
  """
2451
2508
  context_expr = self.convert(node.context_expr)
2452
- optional_vars = (
2453
- self.convert(node.optional_vars) if node.optional_vars is not None else None
2454
- )
2509
+ optional_vars = self.convert(node.optional_vars) if node.optional_vars else None
2455
2510
  if isinstance(context_expr, ast.Expr) and (
2456
2511
  isinstance(optional_vars, ast.Expr) or optional_vars is None
2457
2512
  ):
@@ -2478,3 +2533,11 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2478
2533
  def convert_to_doc(self, string: ast.String) -> None:
2479
2534
  """Convert a string to a docstring."""
2480
2535
  string.value = f'""{string.value}""'
2536
+
2537
+ def aug_op_map(self, tok_dict: dict, op: ast.Token) -> str:
2538
+ """aug_mapper."""
2539
+ op.value += "="
2540
+ for _key, value in tok_dict.items():
2541
+ if value == op.value:
2542
+ break
2543
+ return _key
@@ -5,7 +5,6 @@ also creates bytecode files from the Python code, and manages the caching of
5
5
  relevant files.
6
6
  """
7
7
 
8
- import ast as ast3
9
8
  import os
10
9
 
11
10
 
@@ -43,18 +42,17 @@ class PyOutPass(Pass):
43
42
  out_path_pyc
44
43
  ) > os.path.getmtime(mod_path):
45
44
  continue
46
- self.gen_python(mod, out_path=out_path_py)
47
- self.dump_bytecode(mod, mod_path=mod_path, out_path=out_path_pyc)
45
+ try:
46
+ self.gen_python(mod, out_path=out_path_py)
47
+ self.dump_bytecode(mod, mod_path=mod_path, out_path=out_path_pyc)
48
+ except Exception as e:
49
+ self.warning(f"Error in generating Python code: {e}", node)
48
50
  self.terminate()
49
51
 
50
52
  def gen_python(self, node: ast.Module, out_path: str) -> None:
51
53
  """Generate Python."""
52
- try:
53
- with open(out_path, "w") as f:
54
- f.write(node.gen.py)
55
- except Exception as e:
56
- print(ast3.dump(node.gen.py_ast[0], indent=2))
57
- raise e
54
+ with open(out_path, "w") as f:
55
+ f.write(node.gen.py)
58
56
 
59
57
  def dump_bytecode(self, node: ast.Module, mod_path: str, out_path: str) -> None:
60
58
  """Generate Python."""
@@ -70,14 +68,17 @@ class PyOutPass(Pass):
70
68
  """Get output targets."""
71
69
  base_path, file_name = os.path.split(node.loc.mod_path)
72
70
  gen_path = os.path.join(base_path, Con.JAC_GEN_DIR)
73
- os.makedirs(gen_path, exist_ok=True)
74
- with open(os.path.join(gen_path, "__init__.py"), "w"):
75
- pass
76
71
  mod_dir, file_name = os.path.split(node.loc.mod_path)
77
72
  mod_dir = mod_dir.replace(base_path, "").lstrip(os.sep)
78
73
  base_name, _ = os.path.splitext(file_name)
79
74
  out_dir = os.path.join(gen_path, mod_dir)
80
- os.makedirs(out_dir, exist_ok=True)
75
+ try:
76
+ os.makedirs(gen_path, exist_ok=True)
77
+ with open(os.path.join(gen_path, "__init__.py"), "w"):
78
+ pass
79
+ os.makedirs(out_dir, exist_ok=True)
80
+ except Exception as e:
81
+ self.warning(f"Can't create directory {out_dir}: {e}", node)
81
82
  out_path_py = os.path.join(out_dir, f"{base_name}.py")
82
83
  out_path_pyc = os.path.join(out_dir, f"{base_name}.jbc")
83
84
  return node.loc.mod_path, out_path_py, out_path_pyc
@@ -32,9 +32,14 @@ class RegistryPass(Pass):
32
32
  module_dir = os.path.join(
33
33
  os.path.abspath(os.path.dirname(node.source.file_path)), Con.JAC_GEN_DIR
34
34
  )
35
- os.makedirs(module_dir, exist_ok=True)
36
- with open(os.path.join(module_dir, f"{module_name}.registry.pkl"), "wb") as f:
37
- pickle.dump(node.registry, f)
35
+ try:
36
+ os.makedirs(module_dir, exist_ok=True)
37
+ with open(
38
+ os.path.join(module_dir, f"{module_name}.registry.pkl"), "wb"
39
+ ) as f:
40
+ pickle.dump(node.registry, f)
41
+ except Exception as e:
42
+ self.warning(f"Can't save registry for {module_name}: {e}")
38
43
  self.modules_visited.pop()
39
44
 
40
45
  def exit_architype(self, node: ast.Architype) -> None:
@@ -7,7 +7,7 @@ from __future__ import annotations
7
7
 
8
8
 
9
9
  from .sub_node_tab_pass import SubNodeTabPass # noqa: I100
10
- from .import_pass import ImportPass # noqa: I100
10
+ from .import_pass import JacImportPass, PyImportPass # noqa: I100
11
11
  from .sym_tab_build_pass import SymTabBuildPass # noqa: I100
12
12
  from .def_impl_match_pass import DeclDefMatchPass # noqa: I100
13
13
  from .def_use_pass import DefUsePass # noqa: I100
@@ -17,10 +17,12 @@ from .pyast_gen_pass import PyastGenPass # noqa: I100
17
17
  from .type_check_pass import JacTypeCheckPass # noqa: I100
18
18
  from .fuse_typeinfo_pass import FuseTypeInfoPass # noqa: I100
19
19
  from .registry_pass import RegistryPass # noqa: I100
20
+ from .access_modifier_pass import AccessCheckPass # noqa: I100
20
21
 
21
22
  py_code_gen = [
22
23
  SubNodeTabPass,
23
- ImportPass,
24
+ JacImportPass,
25
+ PyImportPass,
24
26
  SymTabBuildPass,
25
27
  DeclDefMatchPass,
26
28
  DefUsePass,
@@ -29,5 +31,5 @@ py_code_gen = [
29
31
  PyBytecodeGenPass,
30
32
  ]
31
33
 
32
- py_code_gen_typed = [*py_code_gen, JacTypeCheckPass, FuseTypeInfoPass]
34
+ py_code_gen_typed = [*py_code_gen, JacTypeCheckPass, FuseTypeInfoPass, AccessCheckPass]
33
35
  py_compiler = [*py_code_gen, PyOutPass]