jaclang 0.7.23__py3-none-any.whl → 0.7.26__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 (68) hide show
  1. jaclang/cli/cli.py +46 -29
  2. jaclang/compiler/__init__.py +2 -2
  3. jaclang/compiler/absyntree.py +114 -66
  4. jaclang/compiler/codeloc.py +7 -2
  5. jaclang/compiler/compile.py +10 -3
  6. jaclang/compiler/jac.lark +4 -1
  7. jaclang/compiler/parser.py +63 -43
  8. jaclang/compiler/passes/ir_pass.py +2 -2
  9. jaclang/compiler/passes/main/def_impl_match_pass.py +83 -0
  10. jaclang/compiler/passes/main/def_use_pass.py +1 -2
  11. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +146 -123
  12. jaclang/compiler/passes/main/import_pass.py +6 -2
  13. jaclang/compiler/passes/main/pyast_gen_pass.py +46 -20
  14. jaclang/compiler/passes/main/pyast_load_pass.py +56 -41
  15. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +7 -7
  16. jaclang/compiler/passes/main/registry_pass.py +3 -12
  17. jaclang/compiler/passes/main/sym_tab_build_pass.py +1 -2
  18. jaclang/compiler/passes/main/tests/fixtures/defn_decl_mismatch.jac +19 -0
  19. jaclang/compiler/passes/main/tests/fixtures/fstrings.jac +2 -0
  20. jaclang/compiler/passes/main/tests/fixtures/uninitialized_hasvars.jac +26 -0
  21. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +66 -0
  22. jaclang/compiler/passes/main/tests/test_def_use_pass.py +3 -3
  23. jaclang/compiler/passes/main/tests/test_registry_pass.py +2 -10
  24. jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
  25. jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -2
  26. jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +3 -3
  27. jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +3 -3
  28. jaclang/compiler/passes/transform.py +27 -3
  29. jaclang/compiler/passes/utils/mypy_ast_build.py +246 -26
  30. jaclang/compiler/symtable.py +6 -0
  31. jaclang/compiler/tests/test_importer.py +2 -2
  32. jaclang/compiler/tests/test_parser.py +7 -1
  33. jaclang/langserve/engine.py +14 -12
  34. jaclang/langserve/server.py +7 -2
  35. jaclang/langserve/tests/test_server.py +1 -1
  36. jaclang/langserve/utils.py +17 -3
  37. jaclang/plugin/default.py +80 -43
  38. jaclang/plugin/feature.py +12 -2
  39. jaclang/plugin/plugin.md +471 -0
  40. jaclang/plugin/spec.py +14 -1
  41. jaclang/plugin/tests/fixtures/graph_purger.jac +101 -0
  42. jaclang/plugin/tests/fixtures/other_root_access.jac +9 -0
  43. jaclang/plugin/tests/test_jaseci.py +126 -6
  44. jaclang/runtimelib/architype.py +12 -1
  45. jaclang/runtimelib/context.py +2 -0
  46. jaclang/runtimelib/importer.py +7 -2
  47. jaclang/runtimelib/machine.py +21 -6
  48. jaclang/runtimelib/memory.py +5 -1
  49. jaclang/settings.py +3 -0
  50. jaclang/tests/fixtures/architype_def_bug.jac +17 -0
  51. jaclang/tests/fixtures/builtin_dotgen.jac +6 -6
  52. jaclang/tests/fixtures/decl_defn_param_name.jac +19 -0
  53. jaclang/tests/fixtures/enum_inside_archtype.jac +16 -11
  54. jaclang/tests/fixtures/expr_type.jac +54 -0
  55. jaclang/tests/fixtures/glob_multivar_statement.jac +15 -0
  56. jaclang/tests/fixtures/multi_dim_array_split.jac +19 -0
  57. jaclang/tests/fixtures/registry.jac +20 -8
  58. jaclang/tests/foo/__init__.jac +0 -0
  59. jaclang/tests/main.jac +2 -0
  60. jaclang/tests/test_cli.py +86 -4
  61. jaclang/tests/test_language.py +104 -27
  62. jaclang/utils/helpers.py +92 -14
  63. jaclang/utils/lang_tools.py +6 -2
  64. jaclang/utils/treeprinter.py +4 -2
  65. {jaclang-0.7.23.dist-info → jaclang-0.7.26.dist-info}/METADATA +2 -1
  66. {jaclang-0.7.23.dist-info → jaclang-0.7.26.dist-info}/RECORD +68 -57
  67. {jaclang-0.7.23.dist-info → jaclang-0.7.26.dist-info}/WHEEL +1 -1
  68. {jaclang-0.7.23.dist-info → jaclang-0.7.26.dist-info}/entry_points.txt +0 -0
@@ -22,6 +22,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
22
22
  def __init__(self, input_ir: ast.PythonModuleAst) -> None:
23
23
  """Initialize parser."""
24
24
  self.mod_path = input_ir.loc.mod_path
25
+ self.orig_src = input_ir.loc.orig_src
25
26
  Pass.__init__(self, input_ir=input_ir, prior=None)
26
27
 
27
28
  def nu(self, node: T) -> T:
@@ -151,7 +152,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
151
152
 
152
153
  value = node.name if node.name not in reserved_keywords else f"<>{node.name}"
153
154
  name = ast.Name(
154
- file_path=self.mod_path,
155
+ orig_src=self.orig_src,
155
156
  name=Tok.NAME,
156
157
  value=value,
157
158
  line=node.lineno,
@@ -264,7 +265,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
264
265
  type_params: list[type_param]
265
266
  """
266
267
  name = ast.Name(
267
- file_path=self.mod_path,
268
+ orig_src=self.orig_src,
268
269
  name=Tok.NAME,
269
270
  value=node.name,
270
271
  line=node.lineno,
@@ -275,7 +276,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
275
276
  pos_end=0,
276
277
  )
277
278
  arch_type = ast.Token(
278
- file_path=self.mod_path,
279
+ orig_src=self.orig_src,
279
280
  name=Tok.KW_CLASS,
280
281
  value="class",
281
282
  line=node.lineno,
@@ -293,7 +294,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
293
294
  and body_stmt.name_ref.value == "__init__"
294
295
  ):
295
296
  tok = ast.Name(
296
- file_path=self.mod_path,
297
+ orig_src=self.orig_src,
297
298
  name=Tok.KW_INIT,
298
299
  value="init",
299
300
  line=node.lineno,
@@ -383,7 +384,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
383
384
  ):
384
385
  continue
385
386
  pintok = ast.Token(
386
- file_path=self.mod_path,
387
+ orig_src=self.orig_src,
387
388
  name=Tok.PYNLINE,
388
389
  value=py_ast.unparse(class_body_stmt),
389
390
  line=node.lineno,
@@ -914,7 +915,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
914
915
  and value.target.value == "super"
915
916
  ):
916
917
  tok = ast.Name(
917
- file_path=self.mod_path,
918
+ orig_src=self.orig_src,
918
919
  name=Tok.KW_SUPER,
919
920
  value="super",
920
921
  line=node.lineno,
@@ -927,7 +928,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
927
928
  value = ast.SpecialVarRef(var=tok)
928
929
  # exit()
929
930
  attribute = ast.Name(
930
- file_path=self.mod_path,
931
+ orig_src=self.orig_src,
931
932
  name=Tok.NAME,
932
933
  value=(
933
934
  ("<>" + node.attr)
@@ -1038,7 +1039,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1038
1039
  def proc_break(self, node: py_ast.Break) -> ast.CtrlStmt:
1039
1040
  """Process python node."""
1040
1041
  break_tok = ast.Token(
1041
- file_path=self.mod_path,
1042
+ orig_src=self.orig_src,
1042
1043
  name=Tok.KW_BREAK,
1043
1044
  value="break",
1044
1045
  line=0,
@@ -1155,7 +1156,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1155
1156
  else:
1156
1157
  value = str(node.value)
1157
1158
  return type_mapping[value_type](
1158
- file_path=self.mod_path,
1159
+ orig_src=self.orig_src,
1159
1160
  name=token_type,
1160
1161
  value=value,
1161
1162
  line=node.lineno,
@@ -1167,7 +1168,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1167
1168
  )
1168
1169
  elif node.value == Ellipsis:
1169
1170
  return ast.Ellipsis(
1170
- file_path=self.mod_path,
1171
+ orig_src=self.orig_src,
1171
1172
  name=Tok.ELLIPSIS,
1172
1173
  value="...",
1173
1174
  line=node.lineno,
@@ -1183,7 +1184,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1183
1184
  def proc_continue(self, node: py_ast.Continue) -> ast.CtrlStmt:
1184
1185
  """Process python node."""
1185
1186
  continue_tok = ast.Token(
1186
- file_path=self.mod_path,
1187
+ orig_src=self.orig_src,
1187
1188
  name=Tok.KW_CONTINUE,
1188
1189
  value="continue",
1189
1190
  line=0,
@@ -1260,7 +1261,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1260
1261
  name: ast.Name | None = None
1261
1262
  if not type and not node.name:
1262
1263
  type = ast.Name(
1263
- file_path=self.mod_path,
1264
+ orig_src=self.orig_src,
1264
1265
  name=Tok.NAME,
1265
1266
  value="Exception",
1266
1267
  line=node.lineno,
@@ -1271,7 +1272,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1271
1272
  pos_end=0,
1272
1273
  )
1273
1274
  name = ast.Name(
1274
- file_path=self.mod_path,
1275
+ orig_src=self.orig_src,
1275
1276
  name=Tok.NAME,
1276
1277
  value="e",
1277
1278
  line=node.lineno,
@@ -1283,7 +1284,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1283
1284
  )
1284
1285
  else:
1285
1286
  # type = ast.Name(
1286
- # file_path=self.mod_path,
1287
+ # orig_src=self.orig_src,
1287
1288
  # name=Tok.NAME,
1288
1289
  # value=no,
1289
1290
  # line=node.lineno,
@@ -1295,7 +1296,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1295
1296
  # )
1296
1297
  name = (
1297
1298
  ast.Name(
1298
- file_path=self.mod_path,
1299
+ orig_src=self.orig_src,
1299
1300
  name=Tok.NAME,
1300
1301
  value=node.name,
1301
1302
  line=node.lineno,
@@ -1395,7 +1396,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1395
1396
  for id in node.names:
1396
1397
  names.append(
1397
1398
  ast.Name(
1398
- file_path=self.mod_path,
1399
+ orig_src=self.orig_src,
1399
1400
  name=Tok.NAME,
1400
1401
  value=id,
1401
1402
  line=node.lineno,
@@ -1458,7 +1459,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1458
1459
  else:
1459
1460
  raise self.ice()
1460
1461
  lang = ast.Name(
1461
- file_path=self.mod_path,
1462
+ orig_src=self.orig_src,
1462
1463
  name=Tok.NAME,
1463
1464
  value="py",
1464
1465
  line=node.lineno,
@@ -1488,7 +1489,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1488
1489
  level: int
1489
1490
  """
1490
1491
  lang = ast.Name(
1491
- file_path=self.mod_path,
1492
+ orig_src=self.orig_src,
1492
1493
  name=Tok.NAME,
1493
1494
  value="py",
1494
1495
  line=node.lineno,
@@ -1503,7 +1504,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1503
1504
  for i in node.module.split("."):
1504
1505
  modpaths.append(
1505
1506
  ast.Name(
1506
- file_path=self.mod_path,
1507
+ orig_src=self.orig_src,
1507
1508
  name=Tok.NAME,
1508
1509
  value=i,
1509
1510
  line=node.lineno,
@@ -1667,7 +1668,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1667
1668
  """
1668
1669
  pattern = self.convert(node.pattern) if node.pattern else None
1669
1670
  name = ast.Name(
1670
- file_path=self.mod_path,
1671
+ orig_src=self.orig_src,
1671
1672
  name=Tok.NAME,
1672
1673
  value=node.name if node.name else "_",
1673
1674
  line=node.lineno,
@@ -1721,7 +1722,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1721
1722
  for kwd_attrs in node.kwd_attrs:
1722
1723
  names.append(
1723
1724
  ast.Name(
1724
- file_path=self.mod_path,
1725
+ orig_src=self.orig_src,
1725
1726
  name=Tok.NAME,
1726
1727
  value=kwd_attrs,
1727
1728
  line=node.lineno,
@@ -1781,7 +1782,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1781
1782
  values.append(kv_pair)
1782
1783
  if node.rest:
1783
1784
  name = ast.Name(
1784
- file_path=self.mod_path,
1785
+ orig_src=self.orig_src,
1785
1786
  name=Tok.NAME,
1786
1787
  value=node.rest,
1787
1788
  line=node.lineno,
@@ -1826,7 +1827,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1826
1827
  type = Tok.NULL if node.value is None else Tok.BOOL
1827
1828
  ret_type = ast.Null if node.value is None else ast.Bool
1828
1829
  value = ret_type(
1829
- file_path=self.mod_path,
1830
+ orig_src=self.orig_src,
1830
1831
  name=type,
1831
1832
  value=str(node.value),
1832
1833
  line=node.lineno,
@@ -1848,7 +1849,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1848
1849
  name: _Identifier | None
1849
1850
  """
1850
1851
  name = ast.Name(
1851
- file_path=self.mod_path,
1852
+ orig_src=self.orig_src,
1852
1853
  name=Tok.NAME,
1853
1854
  value=node.name if node.name else "_",
1854
1855
  line=node.lineno,
@@ -1891,7 +1892,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1891
1892
 
1892
1893
  value = node.id if node.id not in reserved_keywords else f"<>{node.id}"
1893
1894
  ret = ast.Name(
1894
- file_path=self.mod_path,
1895
+ orig_src=self.orig_src,
1895
1896
  name=Tok.NAME,
1896
1897
  value=value,
1897
1898
  line=node.lineno,
@@ -1937,7 +1938,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1937
1938
  value = name if name not in reserved_keywords else f"<>{name}"
1938
1939
  names.append(
1939
1940
  ast.Name(
1940
- file_path=self.mod_path,
1941
+ orig_src=self.orig_src,
1941
1942
  name=Tok.NAME,
1942
1943
  value=value,
1943
1944
  line=node.lineno,
@@ -1954,7 +1955,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1954
1955
  def proc_pass(self, node: py_ast.Pass) -> ast.Semi:
1955
1956
  """Process python node."""
1956
1957
  return ast.Semi(
1957
- file_path=self.mod_path,
1958
+ orig_src=self.orig_src,
1958
1959
  name=Tok.SEMI,
1959
1960
  value=";",
1960
1961
  line=0,
@@ -2025,9 +2026,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2025
2026
  and (isinstance(step, ast.Expr) or step is None)
2026
2027
  ):
2027
2028
  return ast.IndexSlice(
2028
- start=lower,
2029
- stop=upper,
2030
- step=step,
2029
+ slices=[ast.IndexSlice.Slice(lower, upper, step)],
2031
2030
  is_range=True,
2032
2031
  kid=valid_kid,
2033
2032
  )
@@ -2060,12 +2059,28 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2060
2059
  slice = self.convert(node.slice)
2061
2060
  if not isinstance(slice, ast.IndexSlice) and isinstance(slice, ast.Expr):
2062
2061
  slice = ast.IndexSlice(
2063
- start=slice,
2064
- stop=None,
2065
- step=None,
2062
+ slices=[ast.IndexSlice.Slice(slice, None, None)],
2066
2063
  is_range=False,
2067
2064
  kid=[slice],
2068
2065
  )
2066
+ if (
2067
+ not isinstance(slice, ast.IndexSlice)
2068
+ and isinstance(slice, ast.TupleVal)
2069
+ and slice.values is not None
2070
+ ):
2071
+
2072
+ slices: list[ast.IndexSlice.Slice] = []
2073
+ for index_slice in slice.values.items:
2074
+ if not isinstance(index_slice, ast.IndexSlice):
2075
+ raise self.ice()
2076
+ slices.append(index_slice.slices[0])
2077
+
2078
+ slice = ast.IndexSlice(
2079
+ slices=slices,
2080
+ is_range=True,
2081
+ kid=[slice],
2082
+ )
2083
+
2069
2084
  if isinstance(value, ast.Expr) and isinstance(slice, ast.IndexSlice):
2070
2085
  return ast.AtomTrailer(
2071
2086
  target=value,
@@ -2222,7 +2237,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2222
2237
  asname: _Identifier | None
2223
2238
  """
2224
2239
  name = ast.Name(
2225
- file_path=self.mod_path,
2240
+ orig_src=self.orig_src,
2226
2241
  name=Tok.NAME,
2227
2242
  value=node.name,
2228
2243
  line=node.lineno,
@@ -2234,7 +2249,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2234
2249
  )
2235
2250
  asname = (
2236
2251
  ast.Name(
2237
- file_path=self.mod_path,
2252
+ orig_src=self.orig_src,
2238
2253
  name=Tok.NAME,
2239
2254
  value=node.asname,
2240
2255
  line=node.lineno,
@@ -2268,7 +2283,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2268
2283
 
2269
2284
  value = node.arg if node.arg not in reserved_keywords else f"<>{node.arg}"
2270
2285
  name = ast.Name(
2271
- file_path=self.mod_path,
2286
+ orig_src=self.orig_src,
2272
2287
  name=Tok.NAME,
2273
2288
  value=value,
2274
2289
  line=node.lineno,
@@ -2282,7 +2297,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2282
2297
  self.convert(node.annotation)
2283
2298
  if node.annotation
2284
2299
  else ast.Name(
2285
- file_path=self.mod_path,
2300
+ orig_src=self.orig_src,
2286
2301
  name=Tok.NAME,
2287
2302
  value="Any",
2288
2303
  line=node.lineno,
@@ -2316,7 +2331,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2316
2331
  vararg = self.convert(node.vararg) if node.vararg else None
2317
2332
  if vararg and isinstance(vararg, ast.ParamVar):
2318
2333
  vararg.unpack = ast.Token(
2319
- file_path=self.mod_path,
2334
+ orig_src=self.orig_src,
2320
2335
  name=Tok.STAR_MUL,
2321
2336
  value="*",
2322
2337
  line=vararg.loc.first_line,
@@ -2342,7 +2357,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2342
2357
  kwarg = self.convert(node.kwarg) if node.kwarg else None
2343
2358
  if kwarg and isinstance(kwarg, ast.ParamVar):
2344
2359
  kwarg.unpack = ast.Token(
2345
- file_path=self.mod_path,
2360
+ orig_src=self.orig_src,
2346
2361
  name=Tok.STAR_POW,
2347
2362
  value="**",
2348
2363
  line=kwarg.loc.first_line,
@@ -2388,7 +2403,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2388
2403
  def operator(self, tok: Tok, value: str) -> ast.Token:
2389
2404
  """Create an operator token."""
2390
2405
  return ast.Token(
2391
- file_path=self.mod_path,
2406
+ orig_src=self.orig_src,
2392
2407
  name=tok,
2393
2408
  value=value,
2394
2409
  line=0,
@@ -2553,7 +2568,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2553
2568
  value: expr
2554
2569
  """
2555
2570
  arg = ast.Name(
2556
- file_path=self.mod_path,
2571
+ orig_src=self.orig_src,
2557
2572
  name=Tok.NAME,
2558
2573
  value=node.arg if node.arg else "_",
2559
2574
  line=node.lineno,
@@ -134,14 +134,14 @@ class PyJacAstLinkPass(Pass):
134
134
  py_nodes=i.name_spec.name_of.sym.decl.gen.py_ast,
135
135
  )
136
136
 
137
- if isinstance(node.parent, ast.Ability) and node.parent.signature:
137
+ if isinstance(node.decl_link, ast.Ability) and node.decl_link.signature:
138
138
  if isinstance(node.signature, ast.FuncSignature) and node.signature.params:
139
139
  for src_prm in node.signature.params.items:
140
140
  if (
141
- isinstance(node.parent.signature, ast.FuncSignature)
142
- and node.parent.signature.params
141
+ isinstance(node.decl_link.signature, ast.FuncSignature)
142
+ and node.decl_link.signature.params
143
143
  ):
144
- for trg_prm in node.parent.signature.params.items:
144
+ for trg_prm in node.decl_link.signature.params.items:
145
145
  if src_prm.name.sym_name == trg_prm.name.sym_name:
146
146
  self.link_jac_py_nodes(
147
147
  jac_node=src_prm, py_nodes=trg_prm.gen.py_ast
@@ -154,12 +154,12 @@ class PyJacAstLinkPass(Pass):
154
154
  isinstance(node.signature, ast.FuncSignature)
155
155
  and node.signature.return_type
156
156
  ) and (
157
- isinstance(node.parent.signature, ast.FuncSignature)
158
- and node.parent.signature.return_type
157
+ isinstance(node.decl_link.signature, ast.FuncSignature)
158
+ and node.decl_link.signature.return_type
159
159
  ):
160
160
  self.link_jac_py_nodes(
161
161
  jac_node=node.signature.return_type,
162
- py_nodes=node.parent.signature.return_type.gen.py_ast,
162
+ py_nodes=node.decl_link.signature.return_type.gen.py_ast,
163
163
  )
164
164
 
165
165
  if isinstance(node.decl_link, ast.Ability) and isinstance(
@@ -6,11 +6,7 @@ semstrings after PyASTGen pass. So we create those as a pickled file for
6
6
  each module
7
7
  """
8
8
 
9
- import os
10
- import pickle
11
-
12
9
  import jaclang.compiler.absyntree as ast
13
- from jaclang.compiler.constant import Constants as Con
14
10
  from jaclang.compiler.passes import Pass
15
11
  from jaclang.compiler.semtable import SemInfo, SemRegistry
16
12
  from jaclang.runtimelib.utils import get_sem_scope
@@ -33,15 +29,10 @@ class RegistryPass(Pass):
33
29
  def exit_module(self, node: ast.Module) -> None:
34
30
  """Save registry for each module."""
35
31
  module_name = node.name
36
- module_dir = os.path.join(
37
- os.path.abspath(os.path.dirname(node.source.file_path)), Con.JAC_GEN_DIR
38
- )
39
32
  try:
40
- os.makedirs(module_dir, exist_ok=True)
41
- with open(
42
- os.path.join(module_dir, f"{module_name}.registry.pkl"), "wb"
43
- ) as f:
44
- pickle.dump(node.registry, f)
33
+ from jaclang.runtimelib.machine import JacMachine
34
+
35
+ JacMachine.get().get_sem_ir(node.registry)
45
36
  except Exception as e:
46
37
  self.warning(f"Can't save registry for {module_name}: {e}")
47
38
  self.modules_visited.pop()
@@ -995,8 +995,7 @@ class SymTabBuildPass(Pass):
995
995
  def enter_index_slice(self, node: ast.IndexSlice) -> None:
996
996
  """Sub objects.
997
997
 
998
- start: Optional[ExprType],
999
- stop: Optional[ExprType],
998
+ slices: list[Slice],
1000
999
  is_range: bool,
1001
1000
  """
1002
1001
  self.sync_node_to_scope(node)
@@ -0,0 +1,19 @@
1
+
2
+
3
+ obj SomeObj {
4
+ can foo(param1: str, param2:int) -> str;
5
+ can bar(param1: str, param2:int) -> str;
6
+ }
7
+
8
+
9
+ # Miss match parameter count.
10
+ :obj:SomeObj:can:foo(param1: str) -> str {
11
+ return "foo";
12
+ }
13
+
14
+
15
+ # Mis matching parameter name.
16
+ :obj:SomeObj:can:bar(param1: str, praam2:int) -> str {
17
+ return "bar";
18
+ }
19
+
@@ -42,6 +42,8 @@ with entry {
42
42
  len(f_s1), len(f_s2)
43
43
  ) ;
44
44
  """sdfsdf\nsdfsdfsdfsd dffgdfgd.""" ;
45
+ c1 = '''hello klkl"""''';
46
+ print(c1) ;
45
47
  }
46
48
  can func() {;
47
49
  }
@@ -0,0 +1,26 @@
1
+
2
+ # 1. Test initialization order.
3
+ obj Test1 {
4
+ has var1: int;
5
+ has var2: int = 42;
6
+ has var3: int; # <-- This should be syntax error.
7
+ }
8
+
9
+
10
+ # 2. Test if postinit is needed but not provided.
11
+ obj Test2 {
12
+ has var1: str;
13
+ has var2: int by postinit;
14
+ }
15
+
16
+ # 3. Postinit should be considered as has default initialization.
17
+ obj Test3 {
18
+ has var1: int;
19
+ has var2: int = 42;
20
+ has var3: int by postinit; # <-- This is fine.
21
+ has var4: int; # <-- This should be syntax error.
22
+
23
+ can postinit() {
24
+ self.var3 = 3;
25
+ }
26
+ }
@@ -13,6 +13,36 @@ class DeclImplMatchPassTests(TestCase):
13
13
  """Set up test."""
14
14
  return super().setUp()
15
15
 
16
+ def test_parameter_count_mismatch(self) -> None:
17
+ """Basic test for pass."""
18
+ state = jac_file_to_pass(
19
+ self.fixture_abs_path("defn_decl_mismatch.jac"), DeclImplMatchPass
20
+ )
21
+
22
+ expected_stdout_values = (
23
+ "Parameter count mismatch for ability (o)SomeObj.(c)foo.",
24
+ " 8 |",
25
+ " 9 | # Miss match parameter count.",
26
+ " 10 | :obj:SomeObj:can:foo(param1: str) -> str {",
27
+ " | ^^^^^^^^^^^^^^^^^^^^",
28
+ ' 11 | return "foo";',
29
+ " 12 | }",
30
+ "From the declaration of foo.",
31
+ " 2 |",
32
+ " 3 | obj SomeObj {",
33
+ " 4 | can foo(param1: str, param2:int) -> str;",
34
+ " | ^^^",
35
+ " 5 | can bar(param1: str, param2:int) -> str;",
36
+ " 6 | }",
37
+ )
38
+
39
+ errors_output = ""
40
+ for error in state.errors_had:
41
+ errors_output += error.pretty_print() + "\n"
42
+
43
+ for exp in expected_stdout_values:
44
+ self.assertIn(exp, errors_output)
45
+
16
46
  def test_ability_connected_to_decl(self) -> None:
17
47
  """Basic test for pass."""
18
48
  state = jac_file_to_pass(self.fixture_abs_path("base.jac"), DeclImplMatchPass)
@@ -46,3 +76,39 @@ class DeclImplMatchPassTests(TestCase):
46
76
  )
47
77
  for i in state.ir.get_all_sub_nodes(ast.ArchRef):
48
78
  self.assertIsNotNone(i.sym)
79
+
80
+ def test_obj_hasvar_initialization(self) -> None:
81
+ """Basic test for pass."""
82
+ state = jac_file_to_pass(
83
+ self.fixture_abs_path("uninitialized_hasvars.jac"), DeclImplMatchPass
84
+ )
85
+ self.assertTrue(state.errors_had)
86
+
87
+ expected_stdout_values = (
88
+ "Non default attribute 'var3' follows default attribute",
89
+ " 4 | has var1: int;",
90
+ " 5 | has var2: int = 42;",
91
+ " 6 | has var3: int; # <-- This should be syntax error.",
92
+ " | ^^^^",
93
+ " 7 | }",
94
+ 'Missing "postinit" method required by un initialized attribute(s).',
95
+ " 11 | obj Test2 {",
96
+ " 12 | has var1: str;",
97
+ " 13 | has var2: int by postinit;",
98
+ " | ^^^^",
99
+ " 14 | }",
100
+ "Non default attribute 'var4' follows default attribute",
101
+ " 19 | has var2: int = 42;",
102
+ " 20 | has var3: int by postinit; # <-- This is fine.",
103
+ " 21 | has var4: int; # <-- This should be syntax error.",
104
+ " | ^^^^",
105
+ " 22 |",
106
+ " 23 | can postinit() {",
107
+ )
108
+
109
+ errors_output = ""
110
+ for error in state.errors_had:
111
+ errors_output += error.pretty_print() + "\n"
112
+
113
+ for exp in expected_stdout_values:
114
+ self.assertIn(exp, errors_output)
@@ -19,7 +19,7 @@ class DefUsePassTests(TestCase):
19
19
  target=DefUsePass,
20
20
  )
21
21
  uses = [i.uses for i in state.ir.sym_tab.kid[0].tab.values()]
22
+ self.assertEqual(len(uses[0]), 1)
22
23
  self.assertEqual(len(uses[1]), 1)
23
- self.assertEqual(len(uses[2]), 1)
24
- self.assertIn("output", [uses[1][0].sym_name, uses[2][0].sym_name])
25
- self.assertIn("message", [uses[1][0].sym_name, uses[2][0].sym_name])
24
+ self.assertIn("output", [uses[0][0].sym_name, uses[1][0].sym_name])
25
+ self.assertIn("message", [uses[0][0].sym_name, uses[1][0].sym_name])
@@ -10,6 +10,7 @@ from jaclang.utils.test import TestCase
10
10
  class RegistryPassTests(TestCase):
11
11
  """Test pass module."""
12
12
 
13
+ # Need change
13
14
  def setUp(self) -> None:
14
15
  """Set up test."""
15
16
  return super().setUp()
@@ -18,7 +19,7 @@ class RegistryPassTests(TestCase):
18
19
  """Basic test for pass."""
19
20
  state = jac_file_to_pass(self.fixture_abs_path("registry.jac"), RegistryPass)
20
21
  self.assertFalse(state.errors_had)
21
- self.assertTrue(
22
+ self.assertFalse(
22
23
  os.path.exists(
23
24
  os.path.join(
24
25
  os.path.dirname(self.fixture_abs_path("registry.jac")),
@@ -27,13 +28,4 @@ class RegistryPassTests(TestCase):
27
28
  )
28
29
  )
29
30
  )
30
- self.assertTrue(
31
- os.path.exists(
32
- os.path.join(
33
- os.path.dirname(self.fixture_abs_path("registry.jac")),
34
- "__jac_gen__",
35
- "fstrings.registry.pkl",
36
- )
37
- )
38
- )
39
31
  self.assertIn("109", str(state.ir.to_dict()))
@@ -59,6 +59,6 @@ class MypyTypeCheckPassTests(TestCase):
59
59
  self.assertIn("HasVar - species - Type: builtins.str", out)
60
60
  self.assertIn("myDog - Type: type_info.Dog", out)
61
61
  self.assertIn("Body - Type: type_info.Dog.Body", out)
62
- self.assertEqual(out.count("Type: builtins.str"), 34)
62
+ self.assertEqual(out.count("Type: builtins.str"), 35)
63
63
  for i in lis:
64
64
  self.assertNotIn(i, out)
@@ -1640,8 +1640,8 @@ class JacFormatPass(Pass):
1640
1640
  def exit_index_slice(self, node: ast.IndexSlice) -> None:
1641
1641
  """Sub objects.
1642
1642
 
1643
- start: ExprType,
1644
- stop: Optional[ExprType],
1643
+ slices: list[Slice],
1644
+ is_range: bool,
1645
1645
  """
1646
1646
  for i in node.kid:
1647
1647
  self.emit(node, i.gen.jac)
@@ -34,6 +34,8 @@ glob exec_ctx = ExecutionContext();
34
34
 
35
35
  obj Anchor :ArchitypeProtocol: {
36
36
  has ob: object,
37
+ ds_entry_funcs: list[DSFunc],
38
+ ds_exit_funcs: list[DSFunc],
37
39
  jid: UUID = :> uuid4,
38
40
  timestamp: datetime = :> datetime.now,
39
41
  persist: bool = False,
@@ -41,9 +43,7 @@ obj Anchor :ArchitypeProtocol: {
41
43
  rw_access: set = :> set,
42
44
  ro_access: set = :> set,
43
45
  owner_id: UUID = exec_ctx.master,
44
- mem: Memory = exec_ctx.memory,
45
- ds_entry_funcs: list[DSFunc],
46
- ds_exit_funcs: list[DSFunc];
46
+ mem: Memory = exec_ctx.memory;
47
47
 
48
48
  static can on_entry(cls: type, triggers: list[type]);
49
49
  static can on_exit(cls: type, triggers: list[type]);
@@ -33,6 +33,8 @@ glob exec_ctx = ExecutionContext();
33
33
 
34
34
  obj Anchor :ArchitypeProtocol: {
35
35
  has ob: object,
36
+ ds_entry_funcs: list[DSFunc],
37
+ ds_exit_funcs: list[DSFunc],
36
38
  jid: UUID = :> uuid4,
37
39
  timestamp: datetime = :> datetime.now,
38
40
  persist: bool = False,
@@ -40,9 +42,7 @@ obj Anchor :ArchitypeProtocol: {
40
42
  rw_access: set = :> set,
41
43
  ro_access: set = :> set,
42
44
  owner_id: UUID = exec_ctx.master,
43
- mem: Memory = exec_ctx.memory,
44
- ds_entry_funcs: list[DSFunc],
45
- ds_exit_funcs: list[DSFunc];
45
+ mem: Memory = exec_ctx.memory;
46
46
 
47
47
  static can on_entry(cls: type, triggers: list[type]);
48
48
  static can on_exit(cls: type, triggers: list[type]);