jaclang 0.7.17__py3-none-any.whl → 0.7.21__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 (53) hide show
  1. jaclang/cli/cli.py +5 -7
  2. jaclang/compiler/absyntree.py +1 -1
  3. jaclang/compiler/jac.lark +14 -14
  4. jaclang/compiler/parser.py +71 -59
  5. jaclang/compiler/passes/ir_pass.py +2 -0
  6. jaclang/compiler/passes/main/__init__.py +1 -1
  7. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +50 -13
  8. jaclang/compiler/passes/main/import_pass.py +29 -1
  9. jaclang/compiler/passes/main/py_collect_dep_pass.py +8 -0
  10. jaclang/compiler/passes/main/pyast_gen_pass.py +25 -0
  11. jaclang/compiler/passes/main/registry_pass.py +4 -0
  12. jaclang/compiler/passes/main/sym_tab_build_pass.py +0 -18
  13. jaclang/compiler/passes/main/tests/fixtures/mod_type_assign.jac +7 -0
  14. jaclang/compiler/passes/main/tests/fixtures/pygame_mock/__init__.pyi +3 -0
  15. jaclang/compiler/passes/main/tests/test_import_pass.py +10 -10
  16. jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
  17. jaclang/compiler/passes/main/tests/test_typeinfo_pass.py +23 -1
  18. jaclang/compiler/passes/main/type_check_pass.py +4 -4
  19. jaclang/compiler/passes/tool/jac_formatter_pass.py +63 -31
  20. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/line_spacing.jac +57 -0
  21. jaclang/compiler/semtable.py +4 -4
  22. jaclang/compiler/symtable.py +5 -0
  23. jaclang/langserve/engine.py +92 -22
  24. jaclang/langserve/tests/fixtures/import_include_statements.jac +3 -3
  25. jaclang/langserve/tests/test_server.py +11 -7
  26. jaclang/langserve/utils.py +11 -213
  27. jaclang/plugin/builtin.py +8 -4
  28. jaclang/plugin/default.py +17 -3
  29. jaclang/plugin/feature.py +10 -0
  30. jaclang/plugin/spec.py +12 -0
  31. jaclang/plugin/tests/test_jaseci.py +23 -4
  32. jaclang/runtimelib/architype.py +20 -2
  33. jaclang/runtimelib/importer.py +4 -0
  34. jaclang/runtimelib/machine.py +92 -4
  35. jaclang/runtimelib/memory.py +7 -7
  36. jaclang/settings.py +4 -0
  37. jaclang/tests/fixtures/bar.jac +1 -1
  38. jaclang/tests/fixtures/builtin_dotgen.jac +1 -0
  39. jaclang/tests/fixtures/builtins_test.jac +16 -0
  40. jaclang/tests/fixtures/dynamic_architype.jac +34 -0
  41. jaclang/tests/fixtures/entry_exit.jac +36 -0
  42. jaclang/tests/fixtures/foo.jac +0 -1
  43. jaclang/tests/fixtures/match_multi_ex.jac +12 -0
  44. jaclang/tests/fixtures/objref.jac +12 -0
  45. jaclang/tests/fixtures/trailing_comma.jac +88 -0
  46. jaclang/tests/fixtures/walker_update.jac +19 -0
  47. jaclang/tests/test_cli.py +29 -2
  48. jaclang/tests/test_language.py +144 -4
  49. jaclang/utils/treeprinter.py +1 -1
  50. {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/METADATA +6 -2
  51. {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/RECORD +53 -43
  52. {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/WHEEL +0 -0
  53. {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/entry_points.txt +0 -0
jaclang/cli/cli.py CHANGED
@@ -8,7 +8,6 @@ import pickle
8
8
  import shutil
9
9
  import types
10
10
  from typing import Optional
11
- from uuid import UUID
12
11
 
13
12
  import jaclang.compiler.absyntree as ast
14
13
  from jaclang import jac_import
@@ -159,10 +158,9 @@ def get_object(
159
158
  raise ValueError("Not a valid file!\nOnly supports `.jac` and `.jir`")
160
159
 
161
160
  data = {}
162
- if id == "root":
163
- data = jctx.root.__getstate__()
164
- elif obj := jctx.mem.find_by_id(UUID(id)):
165
- data = obj.__getstate__()
161
+ obj = Jac.get_object(id)
162
+ if obj:
163
+ data = obj.__jac__.__getstate__()
166
164
  else:
167
165
  print(f"Object with id {id} not found.")
168
166
 
@@ -431,8 +429,8 @@ def dot(
431
429
 
432
430
  if filename.endswith(".jac"):
433
431
  jac_machine = JacMachine(base)
434
- jac_import(target=mod, base_path=base)
435
- module = jac_machine.loaded_modules.get(mod)
432
+ jac_import(target=mod, base_path=base, override_name="__main__")
433
+ module = jac_machine.loaded_modules.get("__main__")
436
434
  globals().update(vars(module))
437
435
  try:
438
436
  node = globals().get(initial, eval(initial)) if initial else None
@@ -4212,7 +4212,7 @@ class Literal(Token, AtomExpr):
4212
4212
  raise NotImplementedError
4213
4213
 
4214
4214
 
4215
- class BuiltinType(Name, Literal, NameAtom):
4215
+ class BuiltinType(Name, Literal):
4216
4216
  """Type node type for Jac Ast."""
4217
4217
 
4218
4218
  SYMBOL_TYPE = SymbolType.VAR
jaclang/compiler/jac.lark CHANGED
@@ -25,7 +25,7 @@ from_path: (DOT | ELLIPSIS)* import_path
25
25
  | (DOT | ELLIPSIS)+
26
26
 
27
27
  import_path: named_ref (DOT named_ref)* (KW_AS NAME)?
28
- import_items: (import_item COMMA)* import_item
28
+ import_items: (import_item COMMA)* import_item COMMA?
29
29
  import_item: named_ref (KW_AS NAME)?
30
30
  sub_name: COLON NAME
31
31
  include_stmt: KW_INCLUDE sub_name? import_path SEMI
@@ -63,7 +63,7 @@ enum: decorators? enum_decl
63
63
 
64
64
  enum_decl: KW_ENUM access_tag? STRING? NAME inherited_archs? (enum_block | SEMI)
65
65
  enum_def: arch_to_enum_chain enum_block
66
- enum_block: LBRACE ((enum_stmt COMMA)* enum_stmt)? RBRACE
66
+ enum_block: LBRACE ((enum_stmt COMMA)* enum_stmt COMMA?)? RBRACE
67
67
 
68
68
  enum_stmt: NAME (COLON STRING)? EQ expression
69
69
  | NAME (COLON STRING)?
@@ -83,7 +83,7 @@ abstract_ability: KW_OVERRIDE? KW_STATIC? KW_CAN access_tag? STRING? named_ref (
83
83
  genai_ability: KW_OVERRIDE? KW_STATIC? KW_CAN access_tag? STRING? named_ref (func_decl) KW_BY atomic_call SEMI
84
84
  event_clause: KW_WITH expression? (KW_EXIT | KW_ENTRY) (STRING? RETURN_HINT expression)?
85
85
  func_decl: (LPAREN func_decl_params? RPAREN)? (RETURN_HINT (STRING COLON)? expression)?
86
- func_decl_params: (param_var COMMA)* param_var
86
+ func_decl_params: (param_var COMMA)* param_var COMMA?
87
87
  param_var: (STAR_POW | STAR_MUL)? NAME (COLON STRING)? type_tag (EQ expression)?
88
88
 
89
89
  // Global variables
@@ -364,9 +364,9 @@ index_slice: LSQUARE expression? COLON expression? (COLON expression?)? RSQUARE
364
364
  // Function calls
365
365
  atomic_call: atomic_chain LPAREN param_list? (KW_BY atomic_call)? RPAREN
366
366
 
367
- param_list: expr_list COMMA kw_expr_list
368
- | kw_expr_list
369
- | expr_list
367
+ param_list: expr_list COMMA kw_expr_list COMMA?
368
+ | kw_expr_list COMMA?
369
+ | expr_list COMMA?
370
370
 
371
371
  // Atom
372
372
  atom: named_ref
@@ -412,20 +412,20 @@ set_compr: LBRACE expression inner_compr+ RBRACE
412
412
  dict_compr: LBRACE kv_pair inner_compr+ RBRACE
413
413
  inner_compr: KW_ASYNC? KW_FOR atomic_chain KW_IN pipe_call (KW_IF walrus_assign)*
414
414
 
415
- dict_val: LBRACE ((kv_pair COMMA)* kv_pair)? RBRACE
416
- list_val: LSQUARE expr_list? RSQUARE
415
+ dict_val: LBRACE ((kv_pair COMMA)* kv_pair COMMA?)? RBRACE
416
+ list_val: LSQUARE (expr_list COMMA?)? RSQUARE
417
417
  tuple_val: LPAREN tuple_list? RPAREN
418
- set_val: LBRACE expr_list RBRACE
418
+ set_val: LBRACE expr_list COMMA? RBRACE
419
419
 
420
420
  kv_pair: expression COLON expression | STAR_POW expression
421
421
  expr_list: (expr_list COMMA)? expression
422
422
 
423
423
  // Tuples and Jac Tuples
424
- tuple_list: expression COMMA expr_list COMMA kw_expr_list
425
- | expression COMMA kw_expr_list
426
- | expression COMMA expr_list
424
+ tuple_list: expression COMMA expr_list COMMA kw_expr_list COMMA?
425
+ | expression COMMA kw_expr_list COMMA?
426
+ | expression COMMA expr_list COMMA?
427
427
  | expression COMMA
428
- | kw_expr_list
428
+ | kw_expr_list COMMA?
429
429
 
430
430
  kw_expr_list: (kw_expr_list COMMA)? kw_expr
431
431
  kw_expr: named_ref EQ expression | STAR_POW expression
@@ -662,4 +662,4 @@ FSTR_BESC.1: /{{|}}/
662
662
  COMMENT: /#\*(.|\n|\r)*?\*#|#.*/
663
663
  WS.-2: /[ \t\f\r\n]/+
664
664
  %ignore COMMENT
665
- %ignore WS
665
+ %ignore WS
@@ -429,7 +429,7 @@ class JacParser(Pass):
429
429
  ) -> ast.SubNodeList[ast.ModuleItem]:
430
430
  """Grammar rule.
431
431
 
432
- import_items: (import_item COMMA)* import_item
432
+ import_items: (import_item COMMA)* import_item COMMA?
433
433
  """
434
434
  ret = ast.SubNodeList[ast.ModuleItem](
435
435
  items=[i for i in kid if isinstance(i, ast.ModuleItem)],
@@ -693,7 +693,7 @@ class JacParser(Pass):
693
693
  ) -> ast.SubNodeList[ast.EnumBlockStmt]:
694
694
  """Grammar rule.
695
695
 
696
- enum_block: LBRACE ((enum_stmt COMMA)* enum_stmt)? RBRACE
696
+ enum_block: LBRACE ((enum_stmt COMMA)* enum_stmt COMMA?)? RBRACE
697
697
  """
698
698
  ret = ast.SubNodeList[ast.EnumBlockStmt](items=[], delim=Tok.COMMA, kid=kid)
699
699
  ret.items = [i for i in kid if isinstance(i, ast.EnumBlockStmt)]
@@ -1022,7 +1022,7 @@ class JacParser(Pass):
1022
1022
  ) -> ast.SubNodeList[ast.ParamVar]:
1023
1023
  """Grammar rule.
1024
1024
 
1025
- func_decl_params: (param_var COMMA)* param_var
1025
+ func_decl_params: (param_var COMMA)* param_var COMMA?
1026
1026
  """
1027
1027
  ret = ast.SubNodeList[ast.ParamVar](
1028
1028
  items=[i for i in kid if isinstance(i, ast.ParamVar)],
@@ -1267,29 +1267,30 @@ class JacParser(Pass):
1267
1267
  def statement(self, kid: list[ast.AstNode]) -> ast.CodeBlockStmt:
1268
1268
  """Grammar rule.
1269
1269
 
1270
- statement: py_code_block
1271
- | walker_stmt
1272
- | return_stmt SEMI
1273
- | report_stmt SEMI
1274
- | delete_stmt SEMI
1275
- | ctrl_stmt SEMI
1276
- | assert_stmt SEMI
1277
- | raise_stmt SEMI
1278
- | with_stmt
1270
+ statement: import_stmt
1271
+ | ability
1272
+ | architype
1273
+ | if_stmt
1279
1274
  | while_stmt
1280
1275
  | for_stmt
1281
1276
  | try_stmt
1282
- | if_stmt
1283
- | expression SEMI
1284
- | (yield_expr | KW_YIELD) SEMI
1285
- | static_assignment
1286
- | assignment SEMI
1277
+ | match_stmt
1278
+ | with_stmt
1287
1279
  | global_ref SEMI
1288
1280
  | nonlocal_ref SEMI
1289
1281
  | typed_ctx_block
1290
- | ability
1291
- | architype
1292
- | import_stmt
1282
+ | return_stmt SEMI
1283
+ | (yield_expr | KW_YIELD) SEMI
1284
+ | raise_stmt SEMI
1285
+ | assert_stmt SEMI
1286
+ | check_stmt SEMI
1287
+ | assignment SEMI
1288
+ | delete_stmt SEMI
1289
+ | report_stmt SEMI
1290
+ | expression SEMI
1291
+ | ctrl_stmt SEMI
1292
+ | py_code_block
1293
+ | walker_stmt
1293
1294
  | SEMI
1294
1295
  """
1295
1296
  if isinstance(kid[0], ast.CodeBlockStmt) and len(kid) < 2:
@@ -2180,30 +2181,21 @@ class JacParser(Pass):
2180
2181
  def arithmetic(self, kid: list[ast.AstNode]) -> ast.Expr:
2181
2182
  """Grammar rule.
2182
2183
 
2183
- arithmetic: term MINUS arithmetic
2184
- | term PLUS arithmetic
2185
- | term
2184
+ arithmetic: (arithmetic (MINUS | PLUS))? term
2186
2185
  """
2187
2186
  return self.binary_expr_unwind(kid)
2188
2187
 
2189
2188
  def term(self, kid: list[ast.AstNode]) -> ast.Expr:
2190
2189
  """Grammar rule.
2191
2190
 
2192
- term: factor MOD term
2193
- | factor DIV term
2194
- | factor FLOOR_DIV term
2195
- | factor STAR_MUL term
2196
- | factor
2191
+ term: (term (MOD | DIV | FLOOR_DIV | STAR_MUL | DECOR_OP))? power
2197
2192
  """
2198
2193
  return self.binary_expr_unwind(kid)
2199
2194
 
2200
2195
  def factor(self, kid: list[ast.AstNode]) -> ast.Expr:
2201
2196
  """Grammar rule.
2202
2197
 
2203
- factor: power
2204
- | BW_NOT factor
2205
- | MINUS factor
2206
- | PLUS factor
2198
+ factor: (BW_NOT | MINUS | PLUS) factor | connect
2207
2199
  """
2208
2200
  if len(kid) == 2:
2209
2201
  if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.Expr):
@@ -2221,8 +2213,7 @@ class JacParser(Pass):
2221
2213
  def power(self, kid: list[ast.AstNode]) -> ast.Expr:
2222
2214
  """Grammar rule.
2223
2215
 
2224
- power: connect STAR_POW power
2225
- | connect
2216
+ power: (power STAR_POW)? factor
2226
2217
  """
2227
2218
  return self.binary_expr_unwind(kid)
2228
2219
 
@@ -2513,8 +2504,7 @@ class JacParser(Pass):
2513
2504
  def yield_expr(self, kid: list[ast.AstNode]) -> ast.YieldExpr:
2514
2505
  """Grammar rule.
2515
2506
 
2516
- yield_expr:
2517
- | KW_YIELD KW_FROM? expression
2507
+ yield_expr: KW_YIELD KW_FROM? expression
2518
2508
  """
2519
2509
  if isinstance(kid[-1], ast.Expr):
2520
2510
  return self.nu(
@@ -2565,7 +2555,7 @@ class JacParser(Pass):
2565
2555
  def multistring(self, kid: list[ast.AstNode]) -> ast.AtomExpr:
2566
2556
  """Grammar rule.
2567
2557
 
2568
- multistring: (fstring | STRING)+
2558
+ multistring: (fstring | STRING | DOC_STRING)+
2569
2559
  """
2570
2560
  valid_strs = [i for i in kid if isinstance(i, (ast.String, ast.FString))]
2571
2561
  if len(valid_strs) == len(kid):
@@ -2582,6 +2572,7 @@ class JacParser(Pass):
2582
2572
  """Grammar rule.
2583
2573
 
2584
2574
  fstring: FSTR_START fstr_parts FSTR_END
2575
+ | FSTR_SQ_START fstr_sq_parts FSTR_SQ_END
2585
2576
  """
2586
2577
  if len(kid) == 2:
2587
2578
  return self.nu(
@@ -2605,7 +2596,7 @@ class JacParser(Pass):
2605
2596
  ) -> ast.SubNodeList[ast.String | ast.ExprStmt]:
2606
2597
  """Grammar rule.
2607
2598
 
2608
- fstr_parts: (FSTR_PIECE | FSTR_BESC | LBRACE expression RBRACE | fstring)*
2599
+ fstr_parts: (FSTR_PIECE | FSTR_BESC | LBRACE expression RBRACE )*
2609
2600
  """
2610
2601
  valid_parts: list[ast.String | ast.ExprStmt] = [
2611
2602
  (
@@ -2651,7 +2642,7 @@ class JacParser(Pass):
2651
2642
  def list_val(self, kid: list[ast.AstNode]) -> ast.ListVal:
2652
2643
  """Grammar rule.
2653
2644
 
2654
- list_val: LSQUARE expr_list? RSQUARE
2645
+ list_val: LSQUARE (expr_list COMMA?)? RSQUARE
2655
2646
  """
2656
2647
  if len(kid) == 2:
2657
2648
  return self.nu(
@@ -2695,7 +2686,7 @@ class JacParser(Pass):
2695
2686
  def set_val(self, kid: list[ast.AstNode]) -> ast.SetVal:
2696
2687
  """Grammar rule.
2697
2688
 
2698
- set_val: LBRACE expr_list RBRACE
2689
+ set_val: LBRACE expr_list COMMA? RBRACE
2699
2690
  """
2700
2691
  if len(kid) == 2:
2701
2692
  return self.nu(
@@ -2822,25 +2813,37 @@ class JacParser(Pass):
2822
2813
  ) -> ast.SubNodeList[ast.Expr | ast.KWPair]:
2823
2814
  """Grammar rule.
2824
2815
 
2825
- tuple_list: expression COMMA expr_list COMMA kw_expr_list
2826
- | expression COMMA kw_expr_list
2827
- | expression COMMA expr_list
2828
- | expression COMMA
2829
- | kw_expr_list
2816
+ tuple_list: expression COMMA expr_list COMMA kw_expr_list COMMA?
2817
+ | expression COMMA kw_expr_list COMMA?
2818
+ | expression COMMA expr_list COMMA?
2819
+ | expression COMMA
2820
+ | kw_expr_list COMMA?
2830
2821
  """
2831
2822
  chomp = [*kid]
2832
2823
  first_expr = None
2833
2824
  if isinstance(chomp[0], ast.SubNodeList):
2825
+ # The chomp will be like this:
2826
+ # kw_expr_list, [COMMA]
2827
+ if len(chomp) > 1:
2828
+ # Add the comma to the subnode list if it exists, otherwise the last comma will not be a part of
2829
+ # the ast, we need it for formatting.
2830
+ chomp[0].kid.append(chomp[1])
2834
2831
  return self.nu(chomp[0])
2835
2832
  else:
2836
- first_expr = chomp[0]
2837
- chomp = chomp[2:]
2833
+ # The chomp will be like this:
2834
+ # expression, COMMA, [subnode_list, [COMMA, [kw_expr_list, [COMMA]]]]
2835
+ # Pop the first expression from chomp.
2836
+ first_expr = chomp[0] # Get the first expression.
2837
+ chomp = chomp[2:] # Get rid of expr and comma.
2838
+
2839
+ # The chomp will be like this:
2840
+ # [subnode_list, [COMMA, [kw_expr_list, [COMMA]]]]
2838
2841
  expr_list = []
2839
2842
  if len(chomp):
2840
- expr_list = chomp[0].kid
2841
- chomp = chomp[1:]
2843
+ expr_list = chomp[0].kid # Get the kids subnode list.
2844
+ chomp = chomp[2:] # Get rid of the subnode list and a comma if exists.
2842
2845
  if len(chomp):
2843
- chomp = chomp[1:]
2846
+ # The chomp will be like this: [kw_expr_list, [COMMA]]
2844
2847
  expr_list = [*expr_list, *chomp[0].kid]
2845
2848
  expr_list = [first_expr, *expr_list]
2846
2849
  valid_kid = [i for i in expr_list if isinstance(i, (ast.Expr, ast.KWPair))]
@@ -2855,7 +2858,7 @@ class JacParser(Pass):
2855
2858
  def dict_val(self, kid: list[ast.AstNode]) -> ast.DictVal:
2856
2859
  """Grammar rule.
2857
2860
 
2858
- dict_val: LBRACE ((kv_pair COMMA)* kv_pair)? RBRACE
2861
+ dict_val: LBRACE ((kv_pair COMMA)* kv_pair COMMA?)? RBRACE
2859
2862
  """
2860
2863
  ret = ast.DictVal(
2861
2864
  kv_pairs=[],
@@ -2912,7 +2915,7 @@ class JacParser(Pass):
2912
2915
  def gen_compr(self, kid: list[ast.AstNode]) -> ast.GenCompr:
2913
2916
  """Grammar rule.
2914
2917
 
2915
- gen_compr: LSQUARE expression inner_compr+ RSQUARE
2918
+ gen_compr: LPAREN expression inner_compr+ RPAREN
2916
2919
  """
2917
2920
  comprs = [i for i in kid if isinstance(i, ast.InnerCompr)]
2918
2921
  if isinstance(kid[1], ast.Expr):
@@ -2929,7 +2932,7 @@ class JacParser(Pass):
2929
2932
  def set_compr(self, kid: list[ast.AstNode]) -> ast.SetCompr:
2930
2933
  """Grammar rule.
2931
2934
 
2932
- set_compr: LSQUARE expression inner_compr+ RSQUARE
2935
+ set_compr: LBRACE expression inner_compr+ RBRACE
2933
2936
  """
2934
2937
  comprs = [i for i in kid if isinstance(i, ast.InnerCompr)]
2935
2938
  if isinstance(kid[1], ast.Expr) and isinstance(kid[2], ast.InnerCompr):
@@ -2993,12 +2996,21 @@ class JacParser(Pass):
2993
2996
  ) -> ast.SubNodeList[ast.Expr | ast.KWPair]:
2994
2997
  """Grammar rule.
2995
2998
 
2996
- param_list: expr_list COMMA kw_expr_list
2997
- | kw_expr_list
2998
- | expr_list
2999
+ param_list: expr_list COMMA kw_expr_list COMMA?
3000
+ | kw_expr_list COMMA?
3001
+ | expr_list COMMA?
2999
3002
  """
3000
- if len(kid) == 1:
3003
+ ends_with_comma = (
3004
+ len(kid) > 1
3005
+ and isinstance(kid[-1], ast.Token)
3006
+ and kid[-1].name == "COMMA"
3007
+ )
3008
+ if len(kid) == 1 or (len(kid) == 2 and ends_with_comma):
3001
3009
  if isinstance(kid[0], ast.SubNodeList):
3010
+ if (
3011
+ ends_with_comma
3012
+ ): # Append the trailing comma to the subnode list.
3013
+ kid[0].kid.append(kid[1])
3002
3014
  return self.nu(kid[0])
3003
3015
  else:
3004
3016
  raise self.ice()
@@ -3146,7 +3158,7 @@ class JacParser(Pass):
3146
3158
  def type_ref(self, kid: list[ast.AstNode]) -> ast.ArchRef:
3147
3159
  """Grammar rule.
3148
3160
 
3149
- type_ref: TYPE_OP name_ref
3161
+ type_ref: TYPE_OP (named_ref | builtin_type)
3150
3162
  """
3151
3163
  if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.NameAtom):
3152
3164
  return self.nu(
@@ -3587,7 +3599,7 @@ class JacParser(Pass):
3587
3599
  match_case_block: KW_CASE pattern_seq (KW_IF expression)? COLON statement_list
3588
3600
  """
3589
3601
  pattern = kid[1]
3590
- guard = kid[3] if len(kid) > 4 else None
3602
+ guard = kid[3] if isinstance(kid[3], ast.Expr) else None
3591
3603
  stmts = [i for i in kid if isinstance(i, ast.CodeBlockStmt)]
3592
3604
  if isinstance(pattern, ast.MatchPattern) and isinstance(
3593
3605
  guard, (ast.Expr, type(None))
@@ -133,6 +133,8 @@ class Pass(Transform[T]):
133
133
  else:
134
134
  self.prune_signal = False
135
135
  self.cur_node = node
136
+ if self.term_signal:
137
+ return node
136
138
  self.exit_node(node)
137
139
  return node
138
140
 
@@ -13,7 +13,7 @@ from .type_check_pass import JacTypeCheckPass # noqa: I100
13
13
  from .registry_pass import RegistryPass # noqa: I100
14
14
 
15
15
 
16
- pass_schedule = py_code_gen
16
+ pass_schedule = py_code_gen # type: ignore[has-type]
17
17
 
18
18
  __all__ = [
19
19
  "SubNodeTabPass",
@@ -6,6 +6,7 @@ mypy apis into Jac and use jac py ast in it.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
+ import re
9
10
  from typing import Callable, Optional, TypeVar
10
11
 
11
12
  import jaclang.compiler.absyntree as ast
@@ -46,24 +47,24 @@ class FuseTypeInfoPass(Pass):
46
47
  )
47
48
 
48
49
  def __set_sym_table_link(self, node: ast.AstSymbolNode) -> None:
49
- typ = node.sym_type.split(".")
50
50
  typ_sym_table = self.ir.sym_tab
51
+ assert isinstance(self.ir, ast.Module)
51
52
 
52
- if typ[0] == "builtins":
53
- return
53
+ sym_type = node.sym_type
54
+ if re.match(r"builtins.(list|dict|tuple)", sym_type):
55
+ sym_type = re.sub(r"\[.*\]", "", sym_type)
56
+
57
+ typ = sym_type.split(".")
54
58
 
55
59
  if node.sym_type == "types.ModuleType" and node.sym:
56
60
  node.name_spec.type_sym_tab = node.sym.parent_tab.find_scope(node.sym_name)
57
61
 
58
- assert isinstance(self.ir, ast.Module)
59
-
60
- if typ_sym_table:
61
- for i in typ:
62
- if i == self.ir.name:
63
- continue
64
- f = typ_sym_table.find_scope(i)
65
- if f:
66
- typ_sym_table = f
62
+ for i in typ:
63
+ if i == self.ir.name:
64
+ continue
65
+ f = typ_sym_table.find_scope(i)
66
+ if f:
67
+ typ_sym_table = f
67
68
 
68
69
  if typ_sym_table != self.ir.sym_tab:
69
70
  node.name_spec.type_sym_tab = typ_sym_table
@@ -144,6 +145,11 @@ class FuseTypeInfoPass(Pass):
144
145
  self.__set_sym_table_link(node)
145
146
  self.__collect_python_dependencies(node)
146
147
 
148
+ # Special handing for BuiltinType
149
+ elif isinstance(node, ast.BuiltinType):
150
+ func(self, node) # type: ignore
151
+ self.__set_sym_table_link(node)
152
+
147
153
  # Jac node doesn't have mypy nodes linked to it
148
154
  else:
149
155
  self.__debug_print(
@@ -209,10 +215,21 @@ class FuseTypeInfoPass(Pass):
209
215
  f"{type(mypy_node)}"
210
216
  )
211
217
 
218
+ def __check_builltin_symbol(self, node: ast.NameAtom) -> None:
219
+ if isinstance(node.parent, ast.AtomTrailer) and node is node.parent.right:
220
+ return
221
+ builtins_sym_tab = self.ir.sym_tab.find_scope("builtins")
222
+ assert builtins_sym_tab is not None
223
+ builtins_sym = builtins_sym_tab.lookup(node.sym_name)
224
+ if builtins_sym:
225
+ node.name_spec._sym = builtins_sym
226
+
212
227
  @__handle_node
213
228
  def enter_name(self, node: ast.NameAtom) -> None:
214
229
  """Pass handler for name nodes."""
215
230
  self.__collect_type_from_symbol(node)
231
+ if node.sym is None:
232
+ self.__check_builltin_symbol(node)
216
233
 
217
234
  @__handle_node
218
235
  def enter_module_path(self, node: ast.ModulePath) -> None:
@@ -423,7 +440,8 @@ class FuseTypeInfoPass(Pass):
423
440
  @__handle_node
424
441
  def enter_builtin_type(self, node: ast.BuiltinType) -> None:
425
442
  """Pass handler for BuiltinType nodes."""
426
- self.__collect_type_from_symbol(node)
443
+ self.__check_builltin_symbol(node)
444
+ node.name_spec.sym_type = f"builtins.{node.sym_name}"
427
445
 
428
446
  def get_type_from_instance(
429
447
  self, node: ast.AstSymbolNode, mypy_type: MypyTypes.Instance
@@ -483,6 +501,21 @@ class FuseTypeInfoPass(Pass):
483
501
  if self_obj.type_sym_tab and isinstance(right_obj, ast.AstSymbolNode):
484
502
  self_obj.type_sym_tab.def_insert(right_obj)
485
503
 
504
+ # Support adding the correct type symbol table in case of ModuleType
505
+ # This will only work for target=Val & target1=target2=val and
506
+ # target is a moduleType
507
+ # it won't work in case of
508
+ # - target1, target2 = Val1, Val2 <-- tuples need more attention
509
+ # - target = a.b.c <-- will be fixed after thakee's PR
510
+ # - a.b.c = val <-- will be fixed after thakee's PR
511
+ for target in node.target.items:
512
+ if (
513
+ isinstance(target, ast.Name)
514
+ and target.sym_type == "types.ModuleType"
515
+ and isinstance(node.value, ast.Name)
516
+ ):
517
+ target.type_sym_tab = node.value.type_sym_tab
518
+
486
519
  def expand_atom_trailer(self, node_list: list[ast.AstNode]) -> list[ast.AstNode]:
487
520
  """Expand the atom trailer object in a list of AstNode."""
488
521
  out: list[ast.AstNode] = []
@@ -552,6 +585,10 @@ class FuseTypeInfoPass(Pass):
552
585
  type_symtab: Optional[SymbolTable] = self.ir.sym_tab
553
586
  assert isinstance(self.ir, ast.Module)
554
587
  assert isinstance(type_symtab, SymbolTable)
588
+
589
+ if re.match(r"builtins.(list|dict|tuple)", node_type):
590
+ node_type = re.sub(r"\[.*\]", "", node_type)
591
+
555
592
  for j in node_type.split("."):
556
593
  if j == self.ir.name:
557
594
  continue
@@ -7,12 +7,14 @@ symbols are available for matching.
7
7
 
8
8
  import ast as py_ast
9
9
  import os
10
+ import pathlib
10
11
  from typing import Optional
11
12
 
12
13
 
13
14
  import jaclang.compiler.absyntree as ast
14
15
  from jaclang.compiler.passes import Pass
15
16
  from jaclang.compiler.passes.main import SubNodeTabPass, SymTabBuildPass
17
+ from jaclang.settings import settings
16
18
  from jaclang.utils.log import logging
17
19
 
18
20
 
@@ -105,7 +107,7 @@ class JacImportPass(Pass):
105
107
  or test_folder == os.path.dirname(cur_file)
106
108
  ) and cur_file.endswith(".test.jac"):
107
109
  mod = self.import_jac_mod_from_file(cur_file)
108
- if mod:
110
+ if mod and not settings.ignore_test_annex:
109
111
  node.test_mod.append(mod)
110
112
  node.add_kids_right([mod], pos_update=False)
111
113
  mod.parent = node
@@ -199,6 +201,7 @@ class PyImportPass(JacImportPass):
199
201
  def before_pass(self) -> None:
200
202
  """Only run pass if settings are set to raise python."""
201
203
  super().before_pass()
204
+ self.__load_builtins()
202
205
 
203
206
  def __get_current_module(self, node: ast.AstNode) -> str:
204
207
  parent = node.find_parent_of_type(ast.Module)
@@ -295,6 +298,31 @@ class PyImportPass(JacImportPass):
295
298
  raise e
296
299
  return None
297
300
 
301
+ def __load_builtins(self) -> None:
302
+ """Pyraise builtins to help with builtins auto complete."""
303
+ from jaclang.compiler.passes.main import PyastBuildPass
304
+
305
+ assert isinstance(self.ir, ast.Module)
306
+
307
+ file_to_raise = str(
308
+ pathlib.Path(os.path.dirname(__file__)).parent.parent.parent
309
+ / "vendor"
310
+ / "mypy"
311
+ / "typeshed"
312
+ / "stdlib"
313
+ / "builtins.pyi"
314
+ )
315
+ with open(file_to_raise, "r", encoding="utf-8") as f:
316
+ mod = PyastBuildPass(
317
+ input_ir=ast.PythonModuleAst(
318
+ py_ast.parse(f.read()), mod_path=file_to_raise
319
+ ),
320
+ ).ir
321
+ mod.parent = self.ir
322
+ SubNodeTabPass(input_ir=mod, prior=self)
323
+ SymTabBuildPass(input_ir=mod, prior=self)
324
+ mod.parent = None
325
+
298
326
  def annex_impl(self, node: ast.Module) -> None:
299
327
  """Annex impl and test modules."""
300
328
  return None
@@ -7,6 +7,8 @@ that are only relevant to actual references source from Jac code.
7
7
  from __future__ import annotations
8
8
 
9
9
 
10
+ import os
11
+
10
12
  import jaclang.compiler.absyntree as ast
11
13
  from jaclang.compiler.passes import Pass
12
14
  from jaclang.settings import settings
@@ -28,11 +30,15 @@ class PyCollectDepsPass(Pass):
28
30
  if not isinstance(node, ast.AstSymbolNode):
29
31
  return
30
32
 
33
+ # Adding the path of the file related to the py import
31
34
  path: str = ""
32
35
  if isinstance(node, ast.ModulePath):
33
36
  if node.path:
34
37
  path = ".".join([i.value for i in node.path])
35
38
  node.abs_path = self.ir.py_mod_dep_map.get(path)
39
+ if node.abs_path and os.path.isfile(node.abs_path.replace(".pyi", ".py")):
40
+ node.abs_path = node.abs_path.replace(".pyi", ".py")
41
+
36
42
  elif isinstance(node, ast.ModuleItem):
37
43
  imp = node.parent_of_type(ast.Import)
38
44
  mod_path_node = imp.get_all_sub_nodes(ast.ModulePath)[0]
@@ -40,6 +46,8 @@ class PyCollectDepsPass(Pass):
40
46
  path = ".".join([i.value for i in mod_path_node.path])
41
47
  path += f".{node.name.value}"
42
48
  node.abs_path = self.ir.py_mod_dep_map.get(path)
49
+ if node.abs_path and os.path.isfile(node.abs_path.replace(".pyi", ".py")):
50
+ node.abs_path = node.abs_path.replace(".pyi", ".py")
43
51
 
44
52
  if len(node.gen.mypy_ast) == 0:
45
53
  return
@@ -2641,6 +2641,31 @@ class PyastGenPass(Pass):
2641
2641
  ]
2642
2642
  elif node.op.name in [Tok.STAR_POW]:
2643
2643
  node.gen.py_ast = node.operand.gen.py_ast
2644
+ elif node.op.name in [Tok.BW_AND]:
2645
+ node.gen.py_ast = [
2646
+ self.sync(
2647
+ ast3.Call(
2648
+ func=self.sync(
2649
+ ast3.Attribute(
2650
+ value=self.sync(
2651
+ ast3.Name(id=Con.JAC_FEATURE.value, ctx=ast3.Load())
2652
+ ),
2653
+ attr="get_object",
2654
+ ctx=ast3.Load(),
2655
+ )
2656
+ ),
2657
+ args=[],
2658
+ keywords=[
2659
+ self.sync(
2660
+ ast3.keyword(
2661
+ arg="id",
2662
+ value=node.operand.gen.py_ast[0],
2663
+ )
2664
+ ),
2665
+ ],
2666
+ )
2667
+ )
2668
+ ]
2644
2669
  else:
2645
2670
  self.ice(f"Unknown Unary operator {node.op.value}")
2646
2671