jaclang 0.5.7__py3-none-any.whl → 0.5.8__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 (41) hide show
  1. jaclang/cli/cli.py +55 -7
  2. jaclang/cli/cmdreg.py +12 -0
  3. jaclang/compiler/__init__.py +6 -3
  4. jaclang/compiler/__jac_gen__/jac_parser.py +2 -2
  5. jaclang/compiler/absyntree.py +1725 -55
  6. jaclang/compiler/codeloc.py +7 -0
  7. jaclang/compiler/compile.py +1 -1
  8. jaclang/compiler/constant.py +17 -0
  9. jaclang/compiler/parser.py +131 -112
  10. jaclang/compiler/passes/main/def_impl_match_pass.py +19 -3
  11. jaclang/compiler/passes/main/def_use_pass.py +1 -1
  12. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +357 -0
  13. jaclang/compiler/passes/main/import_pass.py +7 -3
  14. jaclang/compiler/passes/main/pyast_gen_pass.py +112 -76
  15. jaclang/compiler/passes/main/pyast_load_pass.py +1779 -206
  16. jaclang/compiler/passes/main/schedules.py +2 -1
  17. jaclang/compiler/passes/main/sym_tab_build_pass.py +20 -28
  18. jaclang/compiler/passes/main/tests/test_pyast_build_pass.py +14 -5
  19. jaclang/compiler/passes/main/tests/test_sym_tab_build_pass.py +8 -8
  20. jaclang/compiler/passes/main/tests/test_typeinfo_pass.py +7 -0
  21. jaclang/compiler/passes/main/type_check_pass.py +0 -1
  22. jaclang/compiler/passes/tool/jac_formatter_pass.py +8 -17
  23. jaclang/compiler/passes/tool/tests/test_unparse_validate.py +43 -0
  24. jaclang/compiler/passes/utils/mypy_ast_build.py +28 -14
  25. jaclang/compiler/symtable.py +23 -2
  26. jaclang/compiler/tests/test_parser.py +53 -0
  27. jaclang/compiler/workspace.py +52 -26
  28. jaclang/core/construct.py +54 -2
  29. jaclang/plugin/default.py +51 -13
  30. jaclang/plugin/feature.py +16 -2
  31. jaclang/plugin/spec.py +9 -5
  32. jaclang/utils/helpers.py +25 -0
  33. jaclang/utils/lang_tools.py +4 -1
  34. jaclang/utils/test.py +1 -0
  35. jaclang/utils/tests/test_lang_tools.py +11 -14
  36. jaclang/utils/treeprinter.py +10 -2
  37. {jaclang-0.5.7.dist-info → jaclang-0.5.8.dist-info}/METADATA +1 -1
  38. {jaclang-0.5.7.dist-info → jaclang-0.5.8.dist-info}/RECORD +41 -38
  39. {jaclang-0.5.7.dist-info → jaclang-0.5.8.dist-info}/WHEEL +1 -1
  40. {jaclang-0.5.7.dist-info → jaclang-0.5.8.dist-info}/entry_points.txt +0 -0
  41. {jaclang-0.5.7.dist-info → jaclang-0.5.8.dist-info}/top_level.txt +0 -0
@@ -210,9 +210,18 @@ class PyastGenPass(Pass):
210
210
  i.col_offset = jac_node.loc.col_start
211
211
  i.end_lineno = jac_node.loc.last_line
212
212
  i.end_col_offset = jac_node.loc.col_end
213
- i.jac_link = jac_node # type: ignore
213
+ i.jac_link: list[ast3.AST] = [jac_node] # type: ignore
214
214
  return py_node
215
215
 
216
+ def link_jac_py_nodes(
217
+ self, jac_node: ast.AstNode, py_nodes: list[ast3.AST]
218
+ ) -> None:
219
+ """Link jac name ast to py ast nodes."""
220
+ jac_node.gen.py_ast = py_nodes
221
+ for i in py_nodes:
222
+ if isinstance(i.jac_link, list): # type: ignore
223
+ i.jac_link.append(jac_node) # type: ignore
224
+
216
225
  def pyinline_sync(
217
226
  self,
218
227
  py_nodes: list[ast3.AST],
@@ -225,7 +234,7 @@ class PyastGenPass(Pass):
225
234
  i.lineno += self.cur_node.loc.first_line
226
235
  if hasattr(i, "end_lineno") and i.end_lineno is not None:
227
236
  i.end_lineno += self.cur_node.loc.first_line
228
- i.jac_link = self.cur_node # type: ignore
237
+ i.jac_link: ast3.AST = [self.cur_node] # type: ignore
229
238
  return py_nodes
230
239
 
231
240
  def resolve_stmt_block(
@@ -247,7 +256,7 @@ class PyastGenPass(Pass):
247
256
  [
248
257
  x.gen.py_ast
249
258
  for x in node.items
250
- # if not isinstance(x, ast.AstImplOnlyNode)
259
+ if not isinstance(x, ast.AstImplOnlyNode)
251
260
  ]
252
261
  )
253
262
  if node and isinstance(node.gen.py_ast, list)
@@ -305,7 +314,8 @@ class PyastGenPass(Pass):
305
314
  body: Sequence[ElementStmt],
306
315
  is_imported: bool,
307
316
  """
308
- pre_body = [*node.impl_mod.body, *node.body] if node.impl_mod else node.body
317
+ clean_body = [i for i in node.body if not isinstance(i, ast.AstImplOnlyNode)]
318
+ pre_body = [*node.impl_mod.body, *clean_body] if node.impl_mod else clean_body
309
319
  pre_body = [*pre_body, *node.test_mod.body] if node.test_mod else pre_body
310
320
  body = (
311
321
  [
@@ -567,6 +577,8 @@ class PyastGenPass(Pass):
567
577
  )
568
578
  )
569
579
  ]
580
+ if node.alias:
581
+ self.link_jac_py_nodes(jac_node=node.alias, py_nodes=node.gen.py_ast)
570
582
 
571
583
  def exit_module_item(self, node: ast.ModuleItem) -> None:
572
584
  """Sub objects.
@@ -691,6 +703,9 @@ class PyastGenPass(Pass):
691
703
  )
692
704
  )
693
705
  ]
706
+ self.link_jac_py_nodes(jac_node=node.name, py_nodes=node.gen.py_ast)
707
+ if isinstance(node.body, ast.ArchDef):
708
+ self.link_jac_py_nodes(jac_node=node.body, py_nodes=node.gen.py_ast)
694
709
 
695
710
  def collect_events(
696
711
  self, node: ast.Architype
@@ -743,6 +758,12 @@ class PyastGenPass(Pass):
743
758
  doc: Optional[String],
744
759
  decorators: Optional[SubNodeList[ExprType]],
745
760
  """
761
+ for i in node.target.archs:
762
+ if i.sym_link:
763
+ self.link_jac_py_nodes(jac_node=i, py_nodes=i.sym_link.decl.gen.py_ast)
764
+ self.link_jac_py_nodes(
765
+ jac_node=i.name_ref, py_nodes=i.sym_link.decl.gen.py_ast
766
+ )
746
767
 
747
768
  def exit_enum(self, node: ast.Enum) -> None:
748
769
  """Sub objects.
@@ -783,6 +804,8 @@ class PyastGenPass(Pass):
783
804
  )
784
805
  )
785
806
  ]
807
+ if isinstance(node.body, ast.EnumDef):
808
+ self.link_jac_py_nodes(jac_node=node.body, py_nodes=node.gen.py_ast)
786
809
 
787
810
  def exit_enum_def(self, node: ast.EnumDef) -> None:
788
811
  """Sub objects.
@@ -792,6 +815,12 @@ class PyastGenPass(Pass):
792
815
  doc: Optional[String],
793
816
  decorators: Optional[SubNodeList[ExprType]],
794
817
  """
818
+ for i in node.target.archs:
819
+ if i.sym_link:
820
+ self.link_jac_py_nodes(jac_node=i, py_nodes=i.sym_link.decl.gen.py_ast)
821
+ self.link_jac_py_nodes(
822
+ jac_node=i.name_ref, py_nodes=i.sym_link.decl.gen.py_ast
823
+ )
795
824
 
796
825
  def exit_ability(self, node: ast.Ability) -> None:
797
826
  """Sub objects.
@@ -815,12 +844,12 @@ class PyastGenPass(Pass):
815
844
  [
816
845
  self.sync(
817
846
  ast3.Expr(value=node.doc.gen.py_ast[0]), jac_node=node.doc
818
- ), # type: ignore
819
- self.sync(ast3.Pass(), node.body), # type: ignore
847
+ ),
848
+ self.sync(ast3.Pass(), node.body),
820
849
  ]
821
850
  if node.doc and node.is_abstract
822
851
  else (
823
- [self.sync(ast3.Pass(), node.body)] # type: ignore
852
+ [self.sync(ast3.Pass(), node.body)]
824
853
  if node.is_abstract
825
854
  else self.resolve_stmt_block(
826
855
  (
@@ -875,6 +904,7 @@ class PyastGenPass(Pass):
875
904
  )
876
905
  if not body and not isinstance(node.body, ast.FuncCall):
877
906
  self.error("Ability has no body. Perhaps an impl must be imported.", node)
907
+ body = [self.sync(ast3.Pass(), node)]
878
908
 
879
909
  node.gen.py_ast = [
880
910
  self.sync(
@@ -892,6 +922,9 @@ class PyastGenPass(Pass):
892
922
  )
893
923
  )
894
924
  ]
925
+ self.link_jac_py_nodes(jac_node=node.name_ref, py_nodes=node.gen.py_ast)
926
+ if isinstance(node.body, ast.AbilityDef):
927
+ self.link_jac_py_nodes(jac_node=node.body, py_nodes=node.gen.py_ast)
895
928
 
896
929
  def gen_llm_body(self, node: ast.Ability) -> list[ast3.AST]:
897
930
  """Generate llm body."""
@@ -1077,6 +1110,15 @@ class PyastGenPass(Pass):
1077
1110
  doc: Optional[String],
1078
1111
  decorators: Optional[SubNodeList[ExprType]],
1079
1112
  """
1113
+ for i in node.target.archs:
1114
+ if i.sym_link:
1115
+ self.link_jac_py_nodes(jac_node=i, py_nodes=i.sym_link.decl.gen.py_ast)
1116
+ self.link_jac_py_nodes(
1117
+ jac_node=i.name_ref, py_nodes=i.sym_link.decl.gen.py_ast
1118
+ )
1119
+ if isinstance(node.parent, ast.Ability) and node.parent.signature:
1120
+ # TODO: Here we need to do a link for each subnode to the original parent signature
1121
+ pass
1080
1122
 
1081
1123
  def exit_func_signature(self, node: ast.FuncSignature) -> None:
1082
1124
  """Sub objects.
@@ -1233,6 +1275,7 @@ class PyastGenPass(Pass):
1233
1275
  )
1234
1276
  )
1235
1277
  ]
1278
+ self.link_jac_py_nodes(jac_node=node.name, py_nodes=node.gen.py_ast)
1236
1279
 
1237
1280
  def exit_arch_has(self, node: ast.ArchHas) -> None:
1238
1281
  """Sub objects.
@@ -1488,6 +1531,8 @@ class PyastGenPass(Pass):
1488
1531
  )
1489
1532
  )
1490
1533
  ]
1534
+ if node.name:
1535
+ self.link_jac_py_nodes(jac_node=node.name, py_nodes=node.gen.py_ast)
1491
1536
 
1492
1537
  def exit_finally_stmt(self, node: ast.FinallyStmt) -> None:
1493
1538
  """Sub objects.
@@ -1595,6 +1640,9 @@ class PyastGenPass(Pass):
1595
1640
  )
1596
1641
  )
1597
1642
  ]
1643
+ self.link_jac_py_nodes(jac_node=node.expr, py_nodes=node.gen.py_ast)
1644
+ if node.alias:
1645
+ self.link_jac_py_nodes(jac_node=node.alias, py_nodes=node.gen.py_ast)
1598
1646
 
1599
1647
  def exit_raise_stmt(self, node: ast.RaiseStmt) -> None:
1600
1648
  """Sub objects.
@@ -1852,6 +1900,7 @@ class PyastGenPass(Pass):
1852
1900
  jac_node=x,
1853
1901
  )
1854
1902
  )
1903
+ self.link_jac_py_nodes(jac_node=x, py_nodes=[py_nodes[-1]])
1855
1904
  node.gen.py_ast = [*py_nodes]
1856
1905
 
1857
1906
  def exit_non_local_stmt(self, node: ast.NonLocalStmt) -> None:
@@ -1867,6 +1916,7 @@ class PyastGenPass(Pass):
1867
1916
  jac_node=x,
1868
1917
  )
1869
1918
  )
1919
+ self.link_jac_py_nodes(jac_node=x, py_nodes=[py_nodes[-1]])
1870
1920
  node.gen.py_ast = [*py_nodes]
1871
1921
 
1872
1922
  def exit_assignment(self, node: ast.Assignment) -> None:
@@ -1877,6 +1927,21 @@ class PyastGenPass(Pass):
1877
1927
  type_tag: Optional[SubTag[ExprType]],
1878
1928
  mutable: bool =True,
1879
1929
  """
1930
+ value = (
1931
+ node.value.gen.py_ast[0]
1932
+ if node.value
1933
+ else (
1934
+ self.sync(
1935
+ ast3.Call(
1936
+ func=self.sync(ast3.Name(id="__jac_auto__", ctx=ast3.Load())),
1937
+ args=[],
1938
+ keywords=[],
1939
+ )
1940
+ )
1941
+ if node.is_enum_stmt
1942
+ else self.ice()
1943
+ )
1944
+ )
1880
1945
  if node.type_tag:
1881
1946
  node.gen.py_ast = [
1882
1947
  self.sync(
@@ -1888,25 +1953,19 @@ class PyastGenPass(Pass):
1888
1953
  )
1889
1954
  )
1890
1955
  ]
1891
- elif not node.value:
1892
- self.ice()
1893
1956
  elif node.aug_op:
1894
1957
  node.gen.py_ast = [
1895
1958
  self.sync(
1896
1959
  ast3.AugAssign(
1897
1960
  target=node.target.items[0].gen.py_ast[0],
1898
1961
  op=node.aug_op.gen.py_ast[0],
1899
- value=node.value.gen.py_ast[0],
1962
+ value=value,
1900
1963
  )
1901
1964
  )
1902
1965
  ]
1903
1966
  else:
1904
1967
  node.gen.py_ast = [
1905
- self.sync(
1906
- ast3.Assign(
1907
- targets=node.target.gen.py_ast, value=node.value.gen.py_ast[0]
1908
- )
1909
- )
1968
+ self.sync(ast3.Assign(targets=node.target.gen.py_ast, value=value))
1910
1969
  ]
1911
1970
 
1912
1971
  def exit_binary_expr(self, node: ast.BinaryExpr) -> None:
@@ -2037,7 +2096,9 @@ class PyastGenPass(Pass):
2037
2096
  params=(
2038
2097
  node.left.values
2039
2098
  if isinstance(node.left, ast.TupleVal)
2040
- else ast.SubNodeList(items=[node.left], kid=[node.left])
2099
+ else ast.SubNodeList(
2100
+ items=[node.left], delim=Tok.COMMA, kid=[node.left]
2101
+ )
2041
2102
  ),
2042
2103
  kid=node.kid,
2043
2104
  )
@@ -2071,7 +2132,9 @@ class PyastGenPass(Pass):
2071
2132
  params=(
2072
2133
  node.right.values
2073
2134
  if isinstance(node.right, ast.TupleVal)
2074
- else ast.SubNodeList(items=[node.right], kid=[node.right])
2135
+ else ast.SubNodeList(
2136
+ items=[node.right], delim=Tok.COMMA, kid=[node.right]
2137
+ )
2075
2138
  ),
2076
2139
  kid=node.kid,
2077
2140
  )
@@ -2293,13 +2356,6 @@ class PyastGenPass(Pass):
2293
2356
  else [self.sync(ast3.Constant(value=""))]
2294
2357
  )
2295
2358
 
2296
- def exit_expr_list(self, node: ast.ExprList) -> None:
2297
- """Sub objects.
2298
-
2299
- values: Optional[SubNodeList[ExprType]],
2300
- """
2301
- node.gen.py_ast = node.values.gen.py_ast if node.values else []
2302
-
2303
2359
  def exit_list_val(self, node: ast.ListVal) -> None:
2304
2360
  """Sub objects.
2305
2361
 
@@ -2380,6 +2436,8 @@ class PyastGenPass(Pass):
2380
2436
  )
2381
2437
  )
2382
2438
  ]
2439
+ if node.key:
2440
+ self.link_jac_py_nodes(jac_node=node.key, py_nodes=node.gen.py_ast)
2383
2441
 
2384
2442
  def exit_inner_compr(self, node: ast.InnerCompr) -> None:
2385
2443
  """Sub objects.
@@ -2394,7 +2452,11 @@ class PyastGenPass(Pass):
2394
2452
  ast3.comprehension(
2395
2453
  target=node.target.gen.py_ast[0],
2396
2454
  iter=node.collection.gen.py_ast[0],
2397
- ifs=node.conditional.gen.py_ast if node.conditional else [],
2455
+ ifs=(
2456
+ [x.gen.py_ast[0] for x in node.conditional]
2457
+ if node.conditional
2458
+ else []
2459
+ ),
2398
2460
  is_async=0,
2399
2461
  )
2400
2462
  )
@@ -2404,7 +2466,7 @@ class PyastGenPass(Pass):
2404
2466
  """Sub objects.
2405
2467
 
2406
2468
  out_expr: ExprType,
2407
- compr: InnerCompr,
2469
+ compr: list[InnerCompr]
2408
2470
  """
2409
2471
  node.gen.py_ast = [
2410
2472
  self.sync(
@@ -2419,7 +2481,7 @@ class PyastGenPass(Pass):
2419
2481
  """Sub objects.
2420
2482
 
2421
2483
  out_expr: ExprType,
2422
- compr: InnerCompr,
2484
+ compr: list[InnerCompr]
2423
2485
  """
2424
2486
  node.gen.py_ast = [
2425
2487
  self.sync(
@@ -2434,7 +2496,7 @@ class PyastGenPass(Pass):
2434
2496
  """Sub objects.
2435
2497
 
2436
2498
  out_expr: ExprType,
2437
- compr: InnerCompr,
2499
+ compr: list[InnerCompr]
2438
2500
  """
2439
2501
  node.gen.py_ast = [
2440
2502
  self.sync(
@@ -2468,27 +2530,25 @@ class PyastGenPass(Pass):
2468
2530
 
2469
2531
  target: Expr,
2470
2532
  right: AtomExpr | Expr,
2471
- is_attr: Optional[Token],
2533
+ is_attr: bool,
2472
2534
  is_null_ok: bool,
2473
2535
  """
2474
2536
  if node.is_attr:
2475
- node.gen.py_ast = [
2476
- self.sync(
2477
- ast3.Attribute(
2478
- value=node.target.gen.py_ast[0],
2479
- attr=(
2480
- node.right.sym_name
2481
- if isinstance(node.right, ast.AstSymbolNode)
2482
- else ""
2483
- ),
2484
- ctx=(
2485
- node.right.py_ctx_func()
2486
- if isinstance(node.right, ast.AstSymbolNode)
2487
- else ast3.Load()
2488
- ),
2537
+ if isinstance(node.right, ast.AstSymbolNode):
2538
+ node.gen.py_ast = [
2539
+ self.sync(
2540
+ ast3.Attribute(
2541
+ value=node.target.gen.py_ast[0],
2542
+ attr=(node.right.sym_name),
2543
+ ctx=(node.right.py_ctx_func()),
2544
+ )
2489
2545
  )
2546
+ ]
2547
+ self.link_jac_py_nodes(
2548
+ jac_node=node.right.sym_name_node, py_nodes=node.gen.py_ast
2490
2549
  )
2491
- ]
2550
+ else:
2551
+ self.error("Invalid attribute access")
2492
2552
  elif isinstance(node.right, ast.FilterCompr):
2493
2553
  node.gen.py_ast = [
2494
2554
  self.sync(
@@ -2568,19 +2628,11 @@ class PyastGenPass(Pass):
2568
2628
  target: Expr,
2569
2629
  params: Optional[SubNodeList[Expr | KWPair]],
2570
2630
  """
2571
- node.gen.py_ast = [self.sync(self.gen_func_call(node.target, node.params))]
2572
-
2573
- def gen_func_call(
2574
- self,
2575
- target: ast.Expr,
2576
- params: Optional[ast.SubNodeList[ast.Expr | ast.KWPair]],
2577
- ) -> ast3.Call:
2578
- """Generate a function call."""
2579
- func = target.gen.py_ast[0]
2631
+ func = node.target.gen.py_ast[0]
2580
2632
  args = []
2581
2633
  keywords = []
2582
- if params and len(params.items) > 0:
2583
- for x in params.items:
2634
+ if node.params and len(node.params.items) > 0:
2635
+ for x in node.params.items:
2584
2636
  if isinstance(x, ast.UnaryExpr) and x.op.name == Tok.STAR_POW:
2585
2637
  keywords.append(
2586
2638
  self.sync(ast3.keyword(value=x.operand.gen.py_ast[0]), x)
@@ -2593,7 +2645,9 @@ class PyastGenPass(Pass):
2593
2645
  keywords.append(x.gen.py_ast[0])
2594
2646
  else:
2595
2647
  self.ice("Invalid Parameter")
2596
- return ast3.Call(func=func, args=args, keywords=keywords)
2648
+ node.gen.py_ast = [
2649
+ self.sync(ast3.Call(func=func, args=args, keywords=keywords))
2650
+ ]
2597
2651
 
2598
2652
  def exit_index_slice(self, node: ast.IndexSlice) -> None:
2599
2653
  """Sub objects.
@@ -2976,14 +3030,14 @@ class PyastGenPass(Pass):
2976
3030
 
2977
3031
  pattern: MatchPattern,
2978
3032
  guard: Optional[ExprType],
2979
- body: SubNodeList[CodeBlockStmt],
3033
+ body: list[CodeBlockStmt],
2980
3034
  """
2981
3035
  node.gen.py_ast = [
2982
3036
  self.sync(
2983
3037
  ast3.match_case(
2984
3038
  pattern=node.pattern.gen.py_ast[0],
2985
3039
  guard=node.guard.gen.py_ast[0] if node.guard else None,
2986
- body=self.resolve_stmt_block(node.body),
3040
+ body=[x.gen.py_ast[0] for x in node.body],
2987
3041
  )
2988
3042
  )
2989
3043
  ]
@@ -3204,24 +3258,6 @@ class PyastGenPass(Pass):
3204
3258
  node.gen.py_ast = [
3205
3259
  self.sync(ast3.Name(id=node.sym_name, ctx=node.py_ctx_func()))
3206
3260
  ]
3207
- if node.is_enum_singleton and isinstance(node.gen.py_ast[0], ast3.Name):
3208
- node.gen.py_ast[0].ctx = ast3.Store()
3209
- node.gen.py_ast = [
3210
- self.sync(
3211
- ast3.Assign(
3212
- targets=node.gen.py_ast,
3213
- value=self.sync(
3214
- ast3.Call(
3215
- func=self.sync(
3216
- ast3.Name(id="__jac_auto__", ctx=ast3.Load())
3217
- ),
3218
- args=[],
3219
- keywords=[],
3220
- )
3221
- ),
3222
- )
3223
- )
3224
- ]
3225
3261
 
3226
3262
  def exit_float(self, node: ast.Float) -> None:
3227
3263
  """Sub objects.