jaclang 0.5.6__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 (51) hide show
  1. jaclang/__init__.py +6 -1
  2. jaclang/cli/cli.py +63 -20
  3. jaclang/cli/cmdreg.py +42 -12
  4. jaclang/compiler/__init__.py +6 -3
  5. jaclang/compiler/__jac_gen__/jac_parser.py +2 -2
  6. jaclang/compiler/absyntree.py +1740 -61
  7. jaclang/compiler/codeloc.py +7 -0
  8. jaclang/compiler/compile.py +4 -5
  9. jaclang/compiler/constant.py +52 -6
  10. jaclang/compiler/parser.py +220 -129
  11. jaclang/compiler/passes/main/def_impl_match_pass.py +19 -3
  12. jaclang/compiler/passes/main/def_use_pass.py +1 -1
  13. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +357 -0
  14. jaclang/compiler/passes/main/import_pass.py +7 -3
  15. jaclang/compiler/passes/main/pyast_gen_pass.py +333 -93
  16. jaclang/compiler/passes/main/pyast_load_pass.py +1779 -206
  17. jaclang/compiler/passes/main/pyout_pass.py +2 -2
  18. jaclang/compiler/passes/main/schedules.py +2 -1
  19. jaclang/compiler/passes/main/sym_tab_build_pass.py +20 -28
  20. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +4 -4
  21. jaclang/compiler/passes/main/tests/test_pyast_build_pass.py +14 -5
  22. jaclang/compiler/passes/main/tests/test_sym_tab_build_pass.py +8 -8
  23. jaclang/compiler/passes/main/tests/test_typeinfo_pass.py +7 -0
  24. jaclang/compiler/passes/main/type_check_pass.py +0 -1
  25. jaclang/compiler/passes/tool/jac_formatter_pass.py +8 -17
  26. jaclang/compiler/passes/tool/tests/test_unparse_validate.py +43 -0
  27. jaclang/compiler/passes/utils/mypy_ast_build.py +28 -14
  28. jaclang/compiler/symtable.py +23 -2
  29. jaclang/compiler/tests/test_parser.py +53 -0
  30. jaclang/compiler/workspace.py +52 -26
  31. jaclang/core/aott.py +68 -0
  32. jaclang/core/construct.py +58 -6
  33. jaclang/core/importer.py +9 -10
  34. jaclang/core/utils.py +65 -3
  35. jaclang/plugin/builtin.py +42 -0
  36. jaclang/plugin/default.py +163 -18
  37. jaclang/plugin/feature.py +38 -10
  38. jaclang/plugin/spec.py +33 -6
  39. jaclang/utils/helpers.py +25 -0
  40. jaclang/utils/lang_tools.py +4 -1
  41. jaclang/utils/test.py +1 -0
  42. jaclang/utils/tests/test_lang_tools.py +12 -15
  43. jaclang/utils/treeprinter.py +10 -2
  44. {jaclang-0.5.6.dist-info → jaclang-0.5.8.dist-info}/METADATA +1 -1
  45. {jaclang-0.5.6.dist-info → jaclang-0.5.8.dist-info}/RECORD +48 -46
  46. {jaclang-0.5.6.dist-info → jaclang-0.5.8.dist-info}/WHEEL +1 -1
  47. jaclang/compiler/tests/fixtures/__jac_gen__/__init__.py +0 -0
  48. jaclang/compiler/tests/fixtures/__jac_gen__/hello_world.py +0 -5
  49. jaclang/core/jacbuiltins.py +0 -10
  50. {jaclang-0.5.6.dist-info → jaclang-0.5.8.dist-info}/entry_points.txt +0 -0
  51. {jaclang-0.5.6.dist-info → jaclang-0.5.8.dist-info}/top_level.txt +0 -0
@@ -6,10 +6,17 @@ import ast as ast3
6
6
  from types import EllipsisType
7
7
  from typing import Any, Callable, Generic, Optional, Sequence, Type, TypeVar
8
8
 
9
+ from jaclang.compiler import TOKEN_MAP
9
10
  from jaclang.compiler.codeloc import CodeGenTarget, CodeLocInfo
10
11
  from jaclang.compiler.constant import Constants as Con, EdgeDir
11
- from jaclang.compiler.constant import Tokens as Tok
12
- from jaclang.compiler.symtable import Symbol, SymbolAccess, SymbolTable, SymbolType
12
+ from jaclang.compiler.constant import DELIM_MAP, Tokens as Tok
13
+ from jaclang.compiler.symtable import (
14
+ Symbol,
15
+ SymbolAccess,
16
+ SymbolInfo,
17
+ SymbolTable,
18
+ SymbolType,
19
+ )
13
20
  from jaclang.utils.treeprinter import dotgen_ast_tree, print_ast_tree
14
21
 
15
22
 
@@ -74,12 +81,40 @@ class AstNode:
74
81
  else:
75
82
  raise ValueError(f"Empty kid for Token {type(self).__name__}")
76
83
 
84
+ def gen_token(self, name: Tok, value: Optional[str] = None) -> Token:
85
+ """Generate token."""
86
+ value = (
87
+ value
88
+ if value
89
+ else (
90
+ DELIM_MAP[name]
91
+ if name in DELIM_MAP
92
+ else TOKEN_MAP[name.value] if name.value in TOKEN_MAP else name.value
93
+ )
94
+ )
95
+ return Token(
96
+ name=name,
97
+ value=value,
98
+ file_path=self.loc.mod_path,
99
+ col_start=self.loc.col_start,
100
+ col_end=0,
101
+ line=self.loc.first_line,
102
+ pos_start=0,
103
+ pos_end=0,
104
+ )
105
+
77
106
  def get_all_sub_nodes(self, typ: Type[T], brute_force: bool = True) -> list[T]:
78
107
  """Get all sub nodes of type."""
79
108
  from jaclang.compiler.passes import Pass
80
109
 
81
110
  return Pass.get_all_sub_nodes(node=self, typ=typ, brute_force=brute_force)
82
111
 
112
+ def format(self) -> str:
113
+ """Get all sub nodes of type."""
114
+ from jaclang.compiler.passes.tool import JacFormatPass
115
+
116
+ return JacFormatPass(self, None).ir.gen.jac
117
+
83
118
  def to_dict(self) -> dict[str, str]:
84
119
  """Return dict representation of node."""
85
120
  ret = {
@@ -108,6 +143,18 @@ class AstNode:
108
143
  ret += k.flatten()
109
144
  return ret
110
145
 
146
+ def normalize(self, deep: bool = False) -> bool:
147
+ """Normalize ast node."""
148
+ return False
149
+
150
+ def unparse(self) -> str:
151
+ """Unparse ast node."""
152
+ valid = self.normalize()
153
+ res = " ".join([i.unparse() for i in self.kid])
154
+ if not valid:
155
+ raise NotImplementedError(f"Node {type(self).__name__} is not valid.")
156
+ return res
157
+
111
158
 
112
159
  class AstSymbolNode(AstNode):
113
160
  """Nodes that have link to a symbol in symbol table."""
@@ -120,6 +167,7 @@ class AstSymbolNode(AstNode):
120
167
  self.sym_name: str = sym_name
121
168
  self.sym_name_node = sym_name_node
122
169
  self.sym_type: SymbolType = sym_type
170
+ self.sym_info: SymbolInfo = SymbolInfo()
123
171
  self.py_ctx_func: Type[ast3.AST] = ast3.Load
124
172
 
125
173
 
@@ -144,6 +192,9 @@ class AstAccessNode(AstNode):
144
192
  )
145
193
 
146
194
 
195
+ T = TypeVar("T", bound=AstNode)
196
+
197
+
147
198
  class AstDocNode(AstNode):
148
199
  """Nodes that have access."""
149
200
 
@@ -195,11 +246,25 @@ class WalkerStmtOnlyNode(AstNode):
195
246
  class AstImplOnlyNode(AstNode):
196
247
  """ImplOnly node type for Jac Ast."""
197
248
 
198
- def __init__(self, decl_link: Optional[AstNode]) -> None:
249
+ def __init__(self, body: SubNodeList, decl_link: Optional[AstNode]) -> None:
199
250
  """Initialize impl only node."""
251
+ self.body = body
200
252
  self.decl_link = decl_link
201
253
 
202
254
 
255
+ class AstImplNeedingNode(AstSymbolNode, Generic[T]):
256
+ """Impl needing node type for Jac Ast."""
257
+
258
+ def __init__(self, body: Optional[T]) -> None:
259
+ """Initialize impl needing node."""
260
+ self.body = body
261
+
262
+ @property
263
+ def needs_impl(self) -> bool:
264
+ """Need impl."""
265
+ return self.body is None
266
+
267
+
203
268
  class Expr(AstNode):
204
269
  """Expr node type for Jac Ast."""
205
270
 
@@ -240,9 +305,6 @@ class MatchPattern(AstNode):
240
305
  """MatchPattern node type for Jac Ast."""
241
306
 
242
307
 
243
- T = TypeVar("T", bound=AstNode)
244
-
245
-
246
308
  class SubTag(AstNode, Generic[T]):
247
309
  """SubTag node type for Jac Ast."""
248
310
 
@@ -255,18 +317,54 @@ class SubTag(AstNode, Generic[T]):
255
317
  self.tag = tag
256
318
  AstNode.__init__(self, kid=kid)
257
319
 
320
+ def normalize(self, deep: bool = False) -> bool:
321
+ """Normalize sub tag node."""
322
+ res = self.tag.normalize() if deep else True
323
+ AstNode.__init__(self, kid=[self.gen_token(Tok.COLON), self.tag])
324
+ return res
325
+
258
326
 
327
+ # SubNodeList were created to simplify the type safety of the
328
+ # parser's implementation. We basically need to maintain tokens
329
+ # of mixed type in the kid list of the subnodelist as well as
330
+ # separating out typed items of interest in the ast node class body.
259
331
  class SubNodeList(AstNode, Generic[T]):
260
332
  """SubNodeList node type for Jac Ast."""
261
333
 
262
334
  def __init__(
263
335
  self,
264
336
  items: list[T],
337
+ delim: Optional[Tok],
265
338
  kid: Sequence[AstNode],
339
+ left_enc: Optional[Token] = None,
340
+ right_enc: Optional[Token] = None,
266
341
  ) -> None:
267
342
  """Initialize sub node list node."""
268
343
  self.items = items
269
- AstNode.__init__(self, kid=kid)
344
+ self.delim = delim
345
+ self.left_enc = left_enc
346
+ self.right_enc = right_enc
347
+ AstNode.__init__(self, kid=kid)
348
+
349
+ def normalize(self, deep: bool = False) -> bool:
350
+ """Normalize sub node list node."""
351
+ res = True
352
+ if deep:
353
+ for i in self.items:
354
+ res = res and i.normalize()
355
+ new_kid: list[AstNode] = []
356
+ if self.left_enc:
357
+ new_kid.append(self.left_enc)
358
+ for i in self.items:
359
+ new_kid.append(i)
360
+ if self.delim:
361
+ new_kid.append(self.gen_token(self.delim))
362
+ if self.delim and self.items:
363
+ new_kid.pop()
364
+ if self.right_enc:
365
+ new_kid.append(self.right_enc)
366
+ AstNode.__init__(self, kid=new_kid if len(new_kid) else [EmptyToken()])
367
+ return res
270
368
 
271
369
 
272
370
  # AST Mid Level Node Types
@@ -296,6 +394,25 @@ class Module(AstDocNode):
296
394
  AstNode.__init__(self, kid=kid)
297
395
  AstDocNode.__init__(self, doc=doc)
298
396
 
397
+ def normalize(self, deep: bool = False) -> bool:
398
+ """Normalize module node."""
399
+ res = True
400
+ if deep:
401
+ res = self.doc.normalize() if self.doc else True
402
+ for i in self.body:
403
+ res = res and i.normalize()
404
+ new_kid: list[AstNode] = []
405
+ if self.doc:
406
+ new_kid.append(self.doc)
407
+ new_kid.extend(self.body)
408
+ AstNode.__init__(self, kid=new_kid)
409
+ return res
410
+
411
+ def unparse(self) -> str:
412
+ """Unparse module node."""
413
+ super().unparse()
414
+ return self.format()
415
+
299
416
 
300
417
  class GlobalVars(ElementStmt, AstAccessNode):
301
418
  """GlobalVars node type for Jac Ast."""
@@ -315,6 +432,27 @@ class GlobalVars(ElementStmt, AstAccessNode):
315
432
  AstAccessNode.__init__(self, access=access)
316
433
  AstDocNode.__init__(self, doc=doc)
317
434
 
435
+ def normalize(self, deep: bool = False) -> bool:
436
+ """Normalize global var node."""
437
+ res = True
438
+ if deep:
439
+ res = self.access.normalize(deep) if self.access else True
440
+ res = res and self.assignments.normalize(deep)
441
+ res = res and self.doc.normalize(deep) if self.doc else res
442
+ new_kid: list[AstNode] = []
443
+ if self.is_frozen:
444
+ new_kid.append(self.gen_token(Tok.KW_LET))
445
+ else:
446
+ new_kid.append(self.gen_token(Tok.KW_GLOBAL))
447
+ if self.doc:
448
+ new_kid.append(self.doc)
449
+ if self.access:
450
+ new_kid.append(self.access)
451
+ new_kid.append(self.assignments)
452
+ new_kid.append(self.gen_token(Tok.SEMI))
453
+ AstNode.__init__(self, kid=new_kid)
454
+ return res
455
+
318
456
 
319
457
  class Test(AstSymbolNode, ElementStmt):
320
458
  """Test node type for Jac Ast."""
@@ -342,7 +480,6 @@ class Test(AstSymbolNode, ElementStmt):
342
480
  line=name.loc.first_line,
343
481
  pos_start=name.pos_start,
344
482
  pos_end=name.pos_end,
345
- kid=name.kid,
346
483
  )
347
484
  )
348
485
  self.name.parent = self
@@ -359,8 +496,26 @@ class Test(AstSymbolNode, ElementStmt):
359
496
  )
360
497
  AstDocNode.__init__(self, doc=doc)
361
498
 
499
+ def normalize(self, deep: bool = False) -> bool:
500
+ """Normalize test node."""
501
+ res = True
502
+ if deep:
503
+ res = self.name.normalize(deep)
504
+ res = res and self.body.normalize(deep)
505
+ res = res and self.doc.normalize(deep) if self.doc else res
506
+ new_kid: list[AstNode] = []
507
+ if self.doc:
508
+ new_kid.append(self.doc)
509
+ new_kid.append(self.gen_token(Tok.KW_TEST))
510
+ new_kid.append(self.name)
511
+
512
+ new_kid.append(self.body)
513
+
514
+ AstNode.__init__(self, kid=new_kid)
515
+ return res
362
516
 
363
- class ModuleCode(ElementStmt):
517
+
518
+ class ModuleCode(ElementStmt, ArchBlockStmt, EnumBlockStmt):
364
519
  """Free mod code for Jac Ast."""
365
520
 
366
521
  def __init__(
@@ -376,6 +531,26 @@ class ModuleCode(ElementStmt):
376
531
  AstNode.__init__(self, kid=kid)
377
532
  AstDocNode.__init__(self, doc=doc)
378
533
 
534
+ def normalize(self, deep: bool = False) -> bool:
535
+ """Normalize module code node."""
536
+ res = True
537
+ if deep:
538
+ res = self.name.normalize(deep) if self.name else res
539
+ res = res and self.body.normalize(deep)
540
+ res = res and self.doc.normalize(deep) if self.doc else res
541
+ new_kid: list[AstNode] = []
542
+ if self.doc:
543
+ new_kid.append(self.doc)
544
+ new_kid.append(self.gen_token(Tok.KW_WITH))
545
+ new_kid.append(self.gen_token(Tok.KW_ENTRY))
546
+ if self.name:
547
+ new_kid.append(self.name)
548
+
549
+ new_kid.append(self.body)
550
+
551
+ AstNode.__init__(self, kid=new_kid)
552
+ return res
553
+
379
554
 
380
555
  class PyInlineCode(ElementStmt, ArchBlockStmt, EnumBlockStmt, CodeBlockStmt):
381
556
  """Inline Python code node type for Jac Ast."""
@@ -391,6 +566,21 @@ class PyInlineCode(ElementStmt, ArchBlockStmt, EnumBlockStmt, CodeBlockStmt):
391
566
  AstNode.__init__(self, kid=kid)
392
567
  AstDocNode.__init__(self, doc=doc)
393
568
 
569
+ def normalize(self, deep: bool = False) -> bool:
570
+ """Normalize inline python code node."""
571
+ res = True
572
+ if deep:
573
+ res = self.code.normalize(deep)
574
+ res = res and self.doc.normalize(deep) if self.doc else res
575
+ new_kid: list[AstNode] = []
576
+ if self.doc:
577
+ new_kid.append(self.doc)
578
+ new_kid.append(self.gen_token(Tok.PYNLINE))
579
+ new_kid.append(self.code)
580
+ new_kid.append(self.gen_token(Tok.PYNLINE))
581
+ AstNode.__init__(self, kid=new_kid)
582
+ return res
583
+
394
584
 
395
585
  class Import(ElementStmt, CodeBlockStmt):
396
586
  """Import node type for Jac Ast."""
@@ -412,6 +602,36 @@ class Import(ElementStmt, CodeBlockStmt):
412
602
  AstNode.__init__(self, kid=kid)
413
603
  AstDocNode.__init__(self, doc=doc)
414
604
 
605
+ def normalize(self, deep: bool = False) -> bool:
606
+ """Normalize import node."""
607
+ res = True
608
+ if deep:
609
+ res = self.lang.normalize(deep)
610
+ for p in self.paths:
611
+ res = res and p.normalize(deep)
612
+ res = res and self.items.normalize(deep) if self.items else res
613
+ res = res and self.doc.normalize(deep) if self.doc else res
614
+ new_kid: list[AstNode] = []
615
+ if self.doc:
616
+ new_kid.append(self.doc)
617
+ if self.is_absorb:
618
+ new_kid.append(self.gen_token(Tok.KW_INCLUDE))
619
+ else:
620
+ new_kid.append(self.gen_token(Tok.KW_IMPORT))
621
+ new_kid.append(self.lang)
622
+ if self.items:
623
+ new_kid.append(self.gen_token(Tok.KW_FROM))
624
+ for p in self.paths:
625
+ new_kid.append(p)
626
+ new_kid.append(self.gen_token(Tok.COMMA))
627
+ new_kid.pop()
628
+ if self.items:
629
+ new_kid.append(self.gen_token(Tok.COMMA))
630
+ new_kid.append(self.items)
631
+ new_kid.append(self.gen_token(Tok.SEMI))
632
+ AstNode.__init__(self, kid=new_kid)
633
+ return res
634
+
415
635
 
416
636
  class ModulePath(AstSymbolNode):
417
637
  """ModulePath node type for Jac Ast."""
@@ -438,6 +658,29 @@ class ModulePath(AstSymbolNode):
438
658
  sym_type=SymbolType.MODULE,
439
659
  )
440
660
 
661
+ def normalize(self, deep: bool = False) -> bool:
662
+ """Normalize module path node."""
663
+ res = True
664
+ if deep:
665
+ if self.path:
666
+ for p in self.path:
667
+ res = res and p.normalize(deep)
668
+ res = res and self.alias.normalize(deep) if self.alias else res
669
+ new_kid: list[AstNode] = []
670
+ for _ in range(self.level):
671
+ new_kid.append(self.gen_token(Tok.DOT))
672
+ if self.path:
673
+ for p in self.path:
674
+ res = res and p.normalize(deep)
675
+ new_kid.append(p)
676
+ new_kid.append(self.gen_token(Tok.DOT))
677
+ new_kid.pop()
678
+ if self.alias:
679
+ res = res and self.alias.normalize(deep)
680
+ new_kid.append(self.alias)
681
+ AstNode.__init__(self, kid=new_kid)
682
+ return res
683
+
441
684
  @property
442
685
  def path_str(self) -> str:
443
686
  """Get path string."""
@@ -466,8 +709,21 @@ class ModuleItem(AstSymbolNode):
466
709
  sym_type=SymbolType.MOD_VAR,
467
710
  )
468
711
 
469
-
470
- class Architype(ArchSpec, AstAccessNode, ArchBlockStmt):
712
+ def normalize(self, deep: bool = False) -> bool:
713
+ """Normalize module item node."""
714
+ res = True
715
+ if deep:
716
+ res = res and self.name.normalize(deep)
717
+ res = res and self.alias.normalize(deep) if self.alias else res
718
+ new_kid: list[AstNode] = [self.name]
719
+ if self.alias:
720
+ new_kid.append(self.gen_token(Tok.KW_AS))
721
+ new_kid.append(self.alias)
722
+ AstNode.__init__(self, kid=new_kid)
723
+ return res
724
+
725
+
726
+ class Architype(ArchSpec, AstAccessNode, ArchBlockStmt, AstImplNeedingNode):
471
727
  """ObjectArch node type for Jac Ast."""
472
728
 
473
729
  def __init__(
@@ -486,7 +742,6 @@ class Architype(ArchSpec, AstAccessNode, ArchBlockStmt):
486
742
  self.name = name
487
743
  self.arch_type = arch_type
488
744
  self.base_classes = base_classes
489
- self.body = body
490
745
  AstNode.__init__(self, kid=kid)
491
746
  AstSymbolNode.__init__(
492
747
  self,
@@ -510,6 +765,7 @@ class Architype(ArchSpec, AstAccessNode, ArchBlockStmt):
510
765
  )
511
766
  ),
512
767
  )
768
+ AstImplNeedingNode.__init__(self, body=body)
513
769
  AstAccessNode.__init__(self, access=access)
514
770
  AstDocNode.__init__(self, doc=doc)
515
771
  AstSemStrNode.__init__(self, semstr=semstr)
@@ -525,6 +781,41 @@ class Architype(ArchSpec, AstAccessNode, ArchBlockStmt):
525
781
  )
526
782
  return any(isinstance(i, Ability) and i.is_abstract for i in body)
527
783
 
784
+ def normalize(self, deep: bool = False) -> bool:
785
+ """Normalize architype node."""
786
+ res = True
787
+ if deep:
788
+ res = self.name.normalize(deep)
789
+ res = res and self.arch_type.normalize(deep)
790
+ res = res and self.access.normalize(deep) if self.access else res
791
+ res = (
792
+ res and self.base_classes.normalize(deep) if self.base_classes else res
793
+ )
794
+ res = res and self.body.normalize(deep) if self.body else res
795
+ res = res and self.doc.normalize(deep) if self.doc else res
796
+ res = res and self.semstr.normalize(deep) if self.semstr else res
797
+ res = res and self.decorators.normalize(deep) if self.decorators else res
798
+ new_kid: list[AstNode] = []
799
+ if self.doc:
800
+ new_kid.append(self.doc)
801
+ new_kid.append(self.arch_type)
802
+ if self.access:
803
+ new_kid.append(self.access)
804
+ new_kid.append(self.name)
805
+ if self.base_classes:
806
+ new_kid.append(self.gen_token(Tok.COLON))
807
+ new_kid.append(self.base_classes)
808
+ new_kid.append(self.gen_token(Tok.COLON))
809
+ if self.body:
810
+ if isinstance(self.body, AstImplOnlyNode):
811
+ new_kid.append(self.body.body)
812
+ else:
813
+ new_kid.append(self.body)
814
+ else:
815
+ new_kid.append(self.gen_token(Tok.SEMI))
816
+ AstNode.__init__(self, kid=new_kid)
817
+ return res
818
+
528
819
 
529
820
  class ArchDef(ArchSpec, AstImplOnlyNode):
530
821
  """ArchDef node type for Jac Ast."""
@@ -540,7 +831,6 @@ class ArchDef(ArchSpec, AstImplOnlyNode):
540
831
  ) -> None:
541
832
  """Initialize arch def node."""
542
833
  self.target = target
543
- self.body = body
544
834
  AstNode.__init__(self, kid=kid)
545
835
  AstSymbolNode.__init__(
546
836
  self,
@@ -550,10 +840,28 @@ class ArchDef(ArchSpec, AstImplOnlyNode):
550
840
  )
551
841
  AstDocNode.__init__(self, doc=doc)
552
842
  ArchSpec.__init__(self, decorators=decorators)
553
- AstImplOnlyNode.__init__(self, decl_link=decl_link)
843
+ AstImplOnlyNode.__init__(self, body=body, decl_link=decl_link)
844
+
845
+ def normalize(self, deep: bool = False) -> bool:
846
+ """Normalize arch def node."""
847
+ res = True
848
+ if deep:
849
+ res = self.target.normalize(deep)
850
+ res = res and self.body.normalize(deep)
851
+ res = res and self.doc.normalize(deep) if self.doc else res
852
+ res = res and self.decorators.normalize(deep) if self.decorators else res
853
+ new_kid: list[AstNode] = []
854
+ if self.doc:
855
+ new_kid.append(self.doc)
856
+ new_kid.append(self.target)
554
857
 
858
+ new_kid.append(self.body)
555
859
 
556
- class Enum(ArchSpec, AstAccessNode):
860
+ AstNode.__init__(self, kid=new_kid)
861
+ return res
862
+
863
+
864
+ class Enum(ArchSpec, AstAccessNode, AstImplNeedingNode):
557
865
  """Enum node type for Jac Ast."""
558
866
 
559
867
  def __init__(
@@ -570,7 +878,6 @@ class Enum(ArchSpec, AstAccessNode):
570
878
  """Initialize object arch node."""
571
879
  self.name = name
572
880
  self.base_classes = base_classes
573
- self.body = body
574
881
  AstNode.__init__(self, kid=kid)
575
882
  AstSymbolNode.__init__(
576
883
  self,
@@ -578,11 +885,46 @@ class Enum(ArchSpec, AstAccessNode):
578
885
  sym_name_node=name,
579
886
  sym_type=SymbolType.ENUM_ARCH,
580
887
  )
888
+ AstImplNeedingNode.__init__(self, body=body)
581
889
  AstAccessNode.__init__(self, access=access)
582
890
  AstDocNode.__init__(self, doc=doc)
583
891
  AstSemStrNode.__init__(self, semstr=semstr)
584
892
  ArchSpec.__init__(self, decorators=decorators)
585
893
 
894
+ def normalize(self, deep: bool = False) -> bool:
895
+ """Normalize enum node."""
896
+ res = True
897
+ if deep:
898
+ res = self.name.normalize(deep)
899
+ res = res and self.access.normalize(deep) if self.access else res
900
+ res = (
901
+ res and self.base_classes.normalize(deep) if self.base_classes else res
902
+ )
903
+ res = res and self.body.normalize(deep) if self.body else res
904
+ res = res and self.doc.normalize(deep) if self.doc else res
905
+ res = res and self.semstr.normalize(deep) if self.semstr else res
906
+ res = res and self.decorators.normalize(deep) if self.decorators else res
907
+ new_kid: list[AstNode] = []
908
+ if self.doc:
909
+ new_kid.append(self.doc)
910
+ new_kid.append(self.gen_token(Tok.KW_ENUM))
911
+ if self.access:
912
+ new_kid.append(self.access)
913
+ new_kid.append(self.name)
914
+ if self.base_classes:
915
+ new_kid.append(self.gen_token(Tok.COLON))
916
+ new_kid.append(self.base_classes)
917
+ new_kid.append(self.gen_token(Tok.COLON))
918
+ if self.body:
919
+ if isinstance(self.body, AstImplOnlyNode):
920
+ new_kid.append(self.body.body)
921
+ else:
922
+ new_kid.append(self.body)
923
+ else:
924
+ new_kid.append(self.gen_token(Tok.SEMI))
925
+ AstNode.__init__(self, kid=new_kid)
926
+ return res
927
+
586
928
 
587
929
  class EnumDef(ArchSpec, AstImplOnlyNode):
588
930
  """EnumDef node type for Jac Ast."""
@@ -598,7 +940,6 @@ class EnumDef(ArchSpec, AstImplOnlyNode):
598
940
  ) -> None:
599
941
  """Initialize arch def node."""
600
942
  self.target = target
601
- self.body = body
602
943
  AstNode.__init__(self, kid=kid)
603
944
  AstSymbolNode.__init__(
604
945
  self,
@@ -608,31 +949,48 @@ class EnumDef(ArchSpec, AstImplOnlyNode):
608
949
  )
609
950
  AstDocNode.__init__(self, doc=doc)
610
951
  ArchSpec.__init__(self, decorators=decorators)
611
- AstImplOnlyNode.__init__(self, decl_link=decl_link)
952
+ AstImplOnlyNode.__init__(self, body=body, decl_link=decl_link)
953
+
954
+ def normalize(self, deep: bool = False) -> bool:
955
+ """Normalize enum def node."""
956
+ res = True
957
+ if deep:
958
+ res = self.target.normalize(deep)
959
+ res = res and self.body.normalize(deep)
960
+ res = res and self.doc.normalize(deep) if self.doc else res
961
+ res = res and self.decorators.normalize(deep) if self.decorators else res
962
+ new_kid: list[AstNode] = []
963
+ if self.doc:
964
+ new_kid.append(self.doc)
965
+ new_kid.append(self.target)
966
+
967
+ new_kid.append(self.body)
968
+
969
+ AstNode.__init__(self, kid=new_kid)
970
+ return res
612
971
 
613
972
 
614
973
  class Ability(
615
- AstSymbolNode,
616
974
  AstAccessNode,
617
975
  ElementStmt,
618
976
  AstAsyncNode,
619
977
  ArchBlockStmt,
620
978
  CodeBlockStmt,
621
979
  AstSemStrNode,
980
+ AstImplNeedingNode,
622
981
  ):
623
982
  """Ability node type for Jac Ast."""
624
983
 
625
984
  def __init__(
626
985
  self,
627
986
  name_ref: NameSpec,
628
- is_func: bool,
629
987
  is_async: bool,
630
988
  is_override: bool,
631
989
  is_static: bool,
632
990
  is_abstract: bool,
633
991
  access: Optional[SubTag[Token]],
634
992
  signature: Optional[FuncSignature | EventSignature],
635
- body: Optional[SubNodeList[CodeBlockStmt] | AbilityDef],
993
+ body: Optional[SubNodeList[CodeBlockStmt] | AbilityDef | FuncCall],
636
994
  kid: Sequence[AstNode],
637
995
  semstr: Optional[String] = None,
638
996
  doc: Optional[String] = None,
@@ -640,14 +998,13 @@ class Ability(
640
998
  ) -> None:
641
999
  """Initialize func arch node."""
642
1000
  self.name_ref = name_ref
643
- self.is_func = is_func
644
1001
  self.is_override = is_override
645
1002
  self.is_static = is_static
646
1003
  self.is_abstract = is_abstract
647
1004
  self.decorators = decorators
648
1005
  self.signature = signature
649
- self.body = body
650
1006
  AstNode.__init__(self, kid=kid)
1007
+ AstImplNeedingNode.__init__(self, body=body)
651
1008
  AstSemStrNode.__init__(self, semstr=semstr)
652
1009
  AstSymbolNode.__init__(
653
1010
  self,
@@ -669,6 +1026,16 @@ class Ability(
669
1026
  self.sym_type = SymbolType.METHOD
670
1027
  return check
671
1028
 
1029
+ @property
1030
+ def is_func(self) -> bool:
1031
+ """Check if is func."""
1032
+ return isinstance(self.body, FuncSignature)
1033
+
1034
+ @property
1035
+ def is_genai_ability(self) -> bool:
1036
+ """Check if is genai_ability."""
1037
+ return isinstance(self.body, FuncCall)
1038
+
672
1039
  def py_resolve_name(self) -> str:
673
1040
  """Resolve name."""
674
1041
  if isinstance(self.name_ref, Name):
@@ -678,6 +1045,46 @@ class Ability(
678
1045
  else:
679
1046
  raise NotImplementedError
680
1047
 
1048
+ def normalize(self, deep: bool = False) -> bool:
1049
+ """Normalize ast node."""
1050
+ res = True
1051
+ if deep:
1052
+ res = self.name_ref.normalize(deep)
1053
+ res = res and self.access.normalize(deep) if self.access else res
1054
+ res = res and self.signature.normalize(deep) if self.signature else res
1055
+ res = res and self.body.normalize(deep) if self.body else res
1056
+ res = res and self.semstr.normalize(deep) if self.semstr else res
1057
+ res = res and self.decorators.normalize(deep) if self.decorators else res
1058
+ res = res and self.doc.normalize(deep) if self.doc else res
1059
+ new_kid: list[AstNode] = []
1060
+ if self.doc:
1061
+ new_kid.append(self.doc)
1062
+ if self.is_async:
1063
+ new_kid.append(self.gen_token(Tok.KW_ASYNC))
1064
+ if self.is_override:
1065
+ new_kid.append(self.gen_token(Tok.KW_OVERRIDE))
1066
+ if self.is_static:
1067
+ new_kid.append(self.gen_token(Tok.KW_STATIC))
1068
+ new_kid.append(self.gen_token(Tok.KW_CAN))
1069
+ if self.access:
1070
+ new_kid.append(self.access)
1071
+ if self.semstr:
1072
+ new_kid.append(self.semstr)
1073
+ new_kid.append(self.name_ref)
1074
+ if self.signature:
1075
+ new_kid.append(self.signature)
1076
+ if self.body:
1077
+ if isinstance(self.body, AstImplOnlyNode):
1078
+ new_kid.append(self.body.body)
1079
+ else:
1080
+ new_kid.append(self.gen_token(Tok.LBRACE))
1081
+ new_kid.append(self.body)
1082
+ new_kid.append(self.gen_token(Tok.RBRACE))
1083
+ else:
1084
+ new_kid.append(self.gen_token(Tok.SEMI))
1085
+ AstNode.__init__(self, kid=new_kid)
1086
+ return res
1087
+
681
1088
 
682
1089
  class AbilityDef(AstSymbolNode, ElementStmt, AstImplOnlyNode, CodeBlockStmt):
683
1090
  """AbilityDef node type for Jac Ast."""
@@ -695,7 +1102,6 @@ class AbilityDef(AstSymbolNode, ElementStmt, AstImplOnlyNode, CodeBlockStmt):
695
1102
  """Initialize ability def node."""
696
1103
  self.target = target
697
1104
  self.signature = signature
698
- self.body = body
699
1105
  self.decorators = decorators
700
1106
  AstNode.__init__(self, kid=kid)
701
1107
  AstSymbolNode.__init__(
@@ -705,7 +1111,27 @@ class AbilityDef(AstSymbolNode, ElementStmt, AstImplOnlyNode, CodeBlockStmt):
705
1111
  sym_type=SymbolType.IMPL,
706
1112
  )
707
1113
  AstDocNode.__init__(self, doc=doc)
708
- AstImplOnlyNode.__init__(self, decl_link=decl_link)
1114
+ AstImplOnlyNode.__init__(self, body=body, decl_link=decl_link)
1115
+
1116
+ def normalize(self, deep: bool = False) -> bool:
1117
+ """Normalize ability def node."""
1118
+ res = True
1119
+ if deep:
1120
+ res = self.target.normalize(deep)
1121
+ res = res and self.signature.normalize(deep)
1122
+ res = res and self.body.normalize(deep)
1123
+ res = res and self.doc.normalize(deep) if self.doc else res
1124
+ res = res and self.decorators.normalize(deep) if self.decorators else res
1125
+ new_kid: list[AstNode] = []
1126
+ if self.doc:
1127
+ new_kid.append(self.doc)
1128
+ new_kid.append(self.target)
1129
+ new_kid.append(self.signature)
1130
+
1131
+ new_kid.append(self.body)
1132
+
1133
+ AstNode.__init__(self, kid=new_kid)
1134
+ return res
709
1135
 
710
1136
  @property
711
1137
  def is_method(self) -> bool:
@@ -732,6 +1158,23 @@ class FuncSignature(AstSemStrNode):
732
1158
  AstNode.__init__(self, kid=kid)
733
1159
  AstSemStrNode.__init__(self, semstr=semstr)
734
1160
 
1161
+ def normalize(self, deep: bool = False) -> bool:
1162
+ """Normalize ast node."""
1163
+ res = True
1164
+ if deep:
1165
+ res = self.params.normalize(deep) if self.params else res
1166
+ res = res and self.return_type.normalize(deep) if self.return_type else res
1167
+ res = res and self.semstr.normalize(deep) if self.semstr else res
1168
+ new_kid: list[AstNode] = [self.gen_token(Tok.LPAREN)]
1169
+ if self.params:
1170
+ new_kid.append(self.params)
1171
+ new_kid.append(self.gen_token(Tok.RPAREN))
1172
+ if self.return_type:
1173
+ new_kid.append(self.gen_token(Tok.RETURN_HINT))
1174
+ new_kid.append(self.return_type)
1175
+ AstNode.__init__(self, kid=new_kid)
1176
+ return res
1177
+
735
1178
  @property
736
1179
  def is_method(self) -> bool:
737
1180
  """Check if is method."""
@@ -767,6 +1210,30 @@ class EventSignature(AstSemStrNode):
767
1210
  AstNode.__init__(self, kid=kid)
768
1211
  AstSemStrNode.__init__(self, semstr=semstr)
769
1212
 
1213
+ def normalize(self, deep: bool = False) -> bool:
1214
+ """Normalize ast node."""
1215
+ res = True
1216
+ if deep:
1217
+ res = self.event.normalize(deep)
1218
+ res = (
1219
+ res and self.arch_tag_info.normalize(deep)
1220
+ if self.arch_tag_info
1221
+ else res
1222
+ )
1223
+ res = res and self.return_type.normalize(deep) if self.return_type else res
1224
+ res = res and self.semstr.normalize(deep) if self.semstr else res
1225
+ new_kid: list[AstNode] = [self.gen_token(Tok.KW_WITH)]
1226
+ if self.arch_tag_info:
1227
+ new_kid.append(self.arch_tag_info)
1228
+ new_kid.append(self.event)
1229
+ if self.return_type:
1230
+ if self.semstr:
1231
+ new_kid.append(self.semstr)
1232
+ new_kid.append(self.gen_token(Tok.RETURN_HINT))
1233
+ new_kid.append(self.return_type)
1234
+ AstNode.__init__(self, kid=new_kid)
1235
+ return res
1236
+
770
1237
  @property
771
1238
  def is_method(self) -> bool:
772
1239
  """Check if is method."""
@@ -791,6 +1258,18 @@ class ArchRefChain(AstNode):
791
1258
  self.archs = archs
792
1259
  AstNode.__init__(self, kid=kid)
793
1260
 
1261
+ def normalize(self, deep: bool = False) -> bool:
1262
+ """Normalize ast node."""
1263
+ res = True
1264
+ if deep:
1265
+ for a in self.archs:
1266
+ res = res and a.normalize(deep)
1267
+ new_kid: list[AstNode] = []
1268
+ for a in self.archs:
1269
+ new_kid.append(a)
1270
+ AstNode.__init__(self, kid=new_kid)
1271
+ return res
1272
+
794
1273
  def py_resolve_name(self) -> str:
795
1274
  """Resolve name."""
796
1275
 
@@ -836,6 +1315,27 @@ class ParamVar(AstSymbolNode, AstTypedVarNode, AstSemStrNode):
836
1315
  AstTypedVarNode.__init__(self, type_tag=type_tag)
837
1316
  AstSemStrNode.__init__(self, semstr=semstr)
838
1317
 
1318
+ def normalize(self, deep: bool = True) -> bool:
1319
+ """Normalize ast node."""
1320
+ res = True
1321
+ if deep:
1322
+ res = self.name.normalize(deep)
1323
+ res = res and self.unpack.normalize(deep) if self.unpack else res
1324
+ res = res and self.type_tag.normalize(deep) if self.type_tag else res
1325
+ res = res and self.value.normalize(deep) if self.value else res
1326
+ res = res and self.semstr.normalize(deep) if self.semstr else res
1327
+ new_kid: list[AstNode] = []
1328
+ if self.unpack:
1329
+ new_kid.append(self.unpack)
1330
+ new_kid.append(self.name)
1331
+ if self.type_tag:
1332
+ new_kid.append(self.type_tag)
1333
+ if self.value:
1334
+ new_kid.append(self.gen_token(Tok.EQ))
1335
+ new_kid.append(self.value)
1336
+ AstNode.__init__(self, kid=new_kid)
1337
+ return res
1338
+
839
1339
 
840
1340
  class ArchHas(AstAccessNode, AstDocNode, ArchBlockStmt):
841
1341
  """HasStmt node type for Jac Ast."""
@@ -857,6 +1357,30 @@ class ArchHas(AstAccessNode, AstDocNode, ArchBlockStmt):
857
1357
  AstAccessNode.__init__(self, access=access)
858
1358
  AstDocNode.__init__(self, doc=doc)
859
1359
 
1360
+ def normalize(self, deep: bool = False) -> bool:
1361
+ """Normalize has statement node."""
1362
+ res = True
1363
+ if deep:
1364
+ res = self.access.normalize(deep) if self.access else res
1365
+ res = res and self.vars.normalize(deep) if self.vars else res
1366
+ res = res and self.doc.normalize(deep) if self.doc else res
1367
+ new_kid: list[AstNode] = []
1368
+ if self.doc:
1369
+ new_kid.append(self.doc)
1370
+ if self.is_static:
1371
+ new_kid.append(self.gen_token(Tok.KW_STATIC))
1372
+ (
1373
+ new_kid.append(self.gen_token(Tok.KW_LET))
1374
+ if self.is_frozen
1375
+ else new_kid.append(self.gen_token(Tok.KW_HAS))
1376
+ )
1377
+ if self.access:
1378
+ new_kid.append(self.access)
1379
+ new_kid.append(self.vars)
1380
+ new_kid.append(self.gen_token(Tok.SEMI))
1381
+ AstNode.__init__(self, kid=new_kid)
1382
+ return res
1383
+
860
1384
 
861
1385
  class HasVar(AstSymbolNode, AstTypedVarNode, AstSemStrNode):
862
1386
  """HasVar node type for Jac Ast."""
@@ -884,6 +1408,29 @@ class HasVar(AstSymbolNode, AstTypedVarNode, AstSemStrNode):
884
1408
  AstTypedVarNode.__init__(self, type_tag=type_tag)
885
1409
  AstSemStrNode.__init__(self, semstr=semstr)
886
1410
 
1411
+ def normalize(self, deep: bool = False) -> bool:
1412
+ """Normalize has var node."""
1413
+ res = True
1414
+ if deep:
1415
+ res = self.name.normalize(deep)
1416
+ res = res and self.type_tag.normalize(deep) if self.type_tag else res
1417
+ res = res and self.value.normalize(deep) if self.value else res
1418
+ res = res and self.semstr.normalize(deep) if self.semstr else res
1419
+ new_kid: list[AstNode] = [self.name]
1420
+ if self.semstr:
1421
+ new_kid.append(self.gen_token(Tok.COLON))
1422
+ new_kid.append(self.semstr)
1423
+ if self.type_tag:
1424
+ new_kid.append(self.type_tag)
1425
+ if self.value:
1426
+ new_kid.append(self.gen_token(Tok.EQ))
1427
+ new_kid.append(self.value)
1428
+ if self.defer:
1429
+ new_kid.append(self.gen_token(Tok.KW_BY))
1430
+ new_kid.append(self.gen_token(Tok.KW_POST_INIT))
1431
+ AstNode.__init__(self, kid=new_kid)
1432
+ return res
1433
+
887
1434
 
888
1435
  class TypedCtxBlock(CodeBlockStmt):
889
1436
  """TypedCtxBlock node type for Jac Ast."""
@@ -899,6 +1446,20 @@ class TypedCtxBlock(CodeBlockStmt):
899
1446
  self.body = body
900
1447
  AstNode.__init__(self, kid=kid)
901
1448
 
1449
+ def normalize(self, deep: bool = False) -> bool:
1450
+ """Normalize typed context block node."""
1451
+ res = True
1452
+ if deep:
1453
+ res = self.type_ctx.normalize(deep)
1454
+ res = res and self.body.normalize(deep)
1455
+ new_kid: list[AstNode] = [
1456
+ self.gen_token(Tok.RETURN_HINT),
1457
+ self.type_ctx,
1458
+ self.body,
1459
+ ]
1460
+ AstNode.__init__(self, kid=new_kid)
1461
+ return res
1462
+
902
1463
 
903
1464
  class IfStmt(CodeBlockStmt, AstElseBodyNode):
904
1465
  """IfStmt node type for Jac Ast."""
@@ -916,10 +1477,48 @@ class IfStmt(CodeBlockStmt, AstElseBodyNode):
916
1477
  AstNode.__init__(self, kid=kid)
917
1478
  AstElseBodyNode.__init__(self, else_body=else_body)
918
1479
 
1480
+ def normalize(self, deep: bool = False) -> bool:
1481
+ """Normalize if statement node."""
1482
+ res = True
1483
+ if deep:
1484
+ res = self.condition.normalize(deep)
1485
+ res = res and self.body.normalize(deep)
1486
+ res = res and self.else_body.normalize(deep) if self.else_body else res
1487
+ new_kid: list[AstNode] = [
1488
+ self.gen_token(Tok.KW_IF),
1489
+ self.condition,
1490
+ self.gen_token(Tok.LBRACE),
1491
+ self.body,
1492
+ self.gen_token(Tok.RBRACE),
1493
+ ]
1494
+ if self.else_body:
1495
+ new_kid.append(self.else_body)
1496
+ AstNode.__init__(self, kid=new_kid)
1497
+ return res
1498
+
919
1499
 
920
1500
  class ElseIf(IfStmt):
921
1501
  """ElseIfs node type for Jac Ast."""
922
1502
 
1503
+ def normalize(self, deep: bool = False) -> bool:
1504
+ """Normalize else if statement node."""
1505
+ res = True
1506
+ if deep:
1507
+ res = self.condition.normalize(deep)
1508
+ res = res and self.body.normalize(deep)
1509
+ res = res and self.else_body.normalize(deep) if self.else_body else res
1510
+ new_kid: list[AstNode] = [
1511
+ self.gen_token(Tok.KW_ELIF),
1512
+ self.condition,
1513
+ self.gen_token(Tok.LBRACE),
1514
+ self.body,
1515
+ self.gen_token(Tok.RBRACE),
1516
+ ]
1517
+ if self.else_body:
1518
+ new_kid.append(self.else_body)
1519
+ AstNode.__init__(self, kid=new_kid)
1520
+ return res
1521
+
923
1522
 
924
1523
  class ElseStmt(AstNode):
925
1524
  """Else node type for Jac Ast."""
@@ -933,6 +1532,20 @@ class ElseStmt(AstNode):
933
1532
  self.body = body
934
1533
  AstNode.__init__(self, kid=kid)
935
1534
 
1535
+ def normalize(self, deep: bool = False) -> bool:
1536
+ """Normalize else statement node."""
1537
+ res = True
1538
+ if deep:
1539
+ res = self.body.normalize(deep)
1540
+ new_kid: list[AstNode] = [
1541
+ self.gen_token(Tok.KW_ELSE),
1542
+ self.gen_token(Tok.LBRACE),
1543
+ self.body,
1544
+ self.gen_token(Tok.RBRACE),
1545
+ ]
1546
+ AstNode.__init__(self, kid=new_kid)
1547
+ return res
1548
+
936
1549
 
937
1550
  class ExprStmt(CodeBlockStmt):
938
1551
  """ExprStmt node type for Jac Ast."""
@@ -948,6 +1561,20 @@ class ExprStmt(CodeBlockStmt):
948
1561
  self.in_fstring = in_fstring
949
1562
  AstNode.__init__(self, kid=kid)
950
1563
 
1564
+ def normalize(self, deep: bool = True) -> bool:
1565
+ """Normalize ast node."""
1566
+ if deep:
1567
+ res = self.expr.normalize(deep)
1568
+ AstNode.__init__(
1569
+ self,
1570
+ kid=(
1571
+ [self.expr, self.gen_token(Tok.SEMI)]
1572
+ if not self.in_fstring
1573
+ else [self.expr]
1574
+ ),
1575
+ )
1576
+ return res and self.expr is not None
1577
+
951
1578
 
952
1579
  class TryStmt(AstElseBodyNode, CodeBlockStmt):
953
1580
  """TryStmt node type for Jac Ast."""
@@ -967,6 +1594,31 @@ class TryStmt(AstElseBodyNode, CodeBlockStmt):
967
1594
  AstNode.__init__(self, kid=kid)
968
1595
  AstElseBodyNode.__init__(self, else_body=else_body)
969
1596
 
1597
+ def normalize(self, deep: bool = False) -> bool:
1598
+ """Normalize try statement node."""
1599
+ res = True
1600
+ if deep:
1601
+ res = self.body.normalize(deep)
1602
+ res = res and self.excepts.normalize(deep) if self.excepts else res
1603
+ res = res and self.else_body.normalize(deep) if self.else_body else res
1604
+ res = (
1605
+ res and self.finally_body.normalize(deep) if self.finally_body else res
1606
+ )
1607
+ new_kid: list[AstNode] = [
1608
+ self.gen_token(Tok.KW_TRY),
1609
+ ]
1610
+ new_kid.append(self.gen_token(Tok.LBRACE))
1611
+ new_kid.append(self.body)
1612
+ new_kid.append(self.gen_token(Tok.RBRACE))
1613
+ if self.excepts:
1614
+ new_kid.append(self.excepts)
1615
+ if self.else_body:
1616
+ new_kid.append(self.else_body)
1617
+ if self.finally_body:
1618
+ new_kid.append(self.finally_body)
1619
+ AstNode.__init__(self, kid=new_kid)
1620
+ return res
1621
+
970
1622
 
971
1623
  class Except(CodeBlockStmt):
972
1624
  """Except node type for Jac Ast."""
@@ -984,6 +1636,26 @@ class Except(CodeBlockStmt):
984
1636
  self.body = body
985
1637
  AstNode.__init__(self, kid=kid)
986
1638
 
1639
+ def normalize(self, deep: bool = False) -> bool:
1640
+ """Normalize except node."""
1641
+ res = True
1642
+ if deep:
1643
+ res = self.ex_type.normalize(deep)
1644
+ res = res and self.name.normalize(deep) if self.name else res
1645
+ res = res and self.body.normalize(deep) if self.body else res
1646
+ new_kid: list[AstNode] = [
1647
+ self.gen_token(Tok.KW_EXCEPT),
1648
+ self.ex_type,
1649
+ ]
1650
+ if self.name:
1651
+ new_kid.append(self.gen_token(Tok.KW_AS))
1652
+ new_kid.append(self.name)
1653
+ new_kid.append(self.gen_token(Tok.LBRACE))
1654
+ new_kid.append(self.body)
1655
+ new_kid.append(self.gen_token(Tok.RBRACE))
1656
+ AstNode.__init__(self, kid=new_kid)
1657
+ return res
1658
+
987
1659
 
988
1660
  class FinallyStmt(CodeBlockStmt):
989
1661
  """FinallyStmt node type for Jac Ast."""
@@ -997,6 +1669,20 @@ class FinallyStmt(CodeBlockStmt):
997
1669
  self.body = body
998
1670
  AstNode.__init__(self, kid=kid)
999
1671
 
1672
+ def normalize(self, deep: bool = False) -> bool:
1673
+ """Normalize finally statement node."""
1674
+ res = True
1675
+ if deep:
1676
+ res = self.body.normalize(deep)
1677
+ new_kid: list[AstNode] = [
1678
+ self.gen_token(Tok.KW_FINALLY),
1679
+ ]
1680
+ new_kid.append(self.gen_token(Tok.LBRACE))
1681
+ new_kid.append(self.body)
1682
+ new_kid.append(self.gen_token(Tok.RBRACE))
1683
+ AstNode.__init__(self, kid=new_kid)
1684
+ return res
1685
+
1000
1686
 
1001
1687
  class IterForStmt(AstAsyncNode, AstElseBodyNode, CodeBlockStmt):
1002
1688
  """IterFor node type for Jac Ast."""
@@ -1020,6 +1706,32 @@ class IterForStmt(AstAsyncNode, AstElseBodyNode, CodeBlockStmt):
1020
1706
  AstAsyncNode.__init__(self, is_async=is_async)
1021
1707
  AstElseBodyNode.__init__(self, else_body=else_body)
1022
1708
 
1709
+ def normalize(self, deep: bool = False) -> bool:
1710
+ """Normalize iter for node."""
1711
+ res = True
1712
+ if deep:
1713
+ res = self.iter.normalize(deep)
1714
+ res = self.condition.normalize(deep)
1715
+ res = self.count_by.normalize(deep)
1716
+ res = self.body.normalize(deep)
1717
+ res = self.else_body.normalize(deep) if self.else_body else res
1718
+ new_kid: list[AstNode] = []
1719
+ if self.is_async:
1720
+ new_kid.append(self.gen_token(Tok.KW_ASYNC))
1721
+ new_kid.append(self.gen_token(Tok.KW_FOR))
1722
+ new_kid.append(self.iter)
1723
+ new_kid.append(self.gen_token(Tok.KW_TO))
1724
+ new_kid.append(self.condition)
1725
+ new_kid.append(self.gen_token(Tok.KW_BY))
1726
+ new_kid.append(self.count_by)
1727
+ new_kid.append(self.gen_token(Tok.LBRACE))
1728
+ new_kid.append(self.body)
1729
+ new_kid.append(self.gen_token(Tok.RBRACE))
1730
+ if self.else_body:
1731
+ new_kid.append(self.else_body)
1732
+ AstNode.__init__(self, kid=new_kid)
1733
+ return res
1734
+
1023
1735
 
1024
1736
  class InForStmt(AstAsyncNode, AstElseBodyNode, CodeBlockStmt):
1025
1737
  """InFor node type for Jac Ast."""
@@ -1041,6 +1753,32 @@ class InForStmt(AstAsyncNode, AstElseBodyNode, CodeBlockStmt):
1041
1753
  AstAsyncNode.__init__(self, is_async=is_async)
1042
1754
  AstElseBodyNode.__init__(self, else_body=else_body)
1043
1755
 
1756
+ def normalize(self, deep: bool = False) -> bool:
1757
+ """Normalize in for node."""
1758
+ res = True
1759
+ if deep:
1760
+ res = self.target.normalize(deep)
1761
+ res = res and self.collection.normalize(deep)
1762
+ res = res and self.body.normalize(deep)
1763
+ res = res and self.else_body.normalize(deep) if self.else_body else res
1764
+ new_kid: list[AstNode] = []
1765
+ if self.is_async:
1766
+ new_kid.append(self.gen_token(Tok.KW_ASYNC))
1767
+ new_kid.append(self.gen_token(Tok.KW_FOR))
1768
+ new_kid.append(self.target)
1769
+ new_kid.append(self.gen_token(Tok.KW_IN))
1770
+ new_kid.append(self.collection)
1771
+
1772
+ if self.body:
1773
+ new_kid.append(self.gen_token(Tok.LBRACE))
1774
+ new_kid.append(self.body)
1775
+ new_kid.append(self.gen_token(Tok.RBRACE))
1776
+
1777
+ if self.else_body:
1778
+ new_kid.append(self.else_body)
1779
+ AstNode.__init__(self, kid=new_kid)
1780
+ return res
1781
+
1044
1782
 
1045
1783
  class WhileStmt(CodeBlockStmt):
1046
1784
  """WhileStmt node type for Jac Ast."""
@@ -1056,6 +1794,24 @@ class WhileStmt(CodeBlockStmt):
1056
1794
  self.body = body
1057
1795
  AstNode.__init__(self, kid=kid)
1058
1796
 
1797
+ def normalize(self, deep: bool = False) -> bool:
1798
+ """Normalize while statement node."""
1799
+ res = True
1800
+ if deep:
1801
+ res = self.condition.normalize(deep)
1802
+ res = res and self.body.normalize(deep)
1803
+ new_kid: list[AstNode] = [
1804
+ self.gen_token(Tok.KW_WHILE),
1805
+ self.condition,
1806
+ ]
1807
+ if self.body:
1808
+ new_kid.append(self.gen_token(Tok.LBRACE))
1809
+ new_kid.append(self.body)
1810
+ new_kid.append(self.gen_token(Tok.RBRACE))
1811
+
1812
+ AstNode.__init__(self, kid=new_kid)
1813
+ return res
1814
+
1059
1815
 
1060
1816
  class WithStmt(AstAsyncNode, CodeBlockStmt):
1061
1817
  """WithStmt node type for Jac Ast."""
@@ -1073,6 +1829,25 @@ class WithStmt(AstAsyncNode, CodeBlockStmt):
1073
1829
  AstNode.__init__(self, kid=kid)
1074
1830
  AstAsyncNode.__init__(self, is_async=is_async)
1075
1831
 
1832
+ def normalize(self, deep: bool = False) -> bool:
1833
+ """Normalize with statement node."""
1834
+ res = True
1835
+ if deep:
1836
+ res = self.exprs.normalize(deep)
1837
+ res = res and self.body.normalize(deep)
1838
+ new_kid: list[AstNode] = []
1839
+ if self.is_async:
1840
+ new_kid.append(self.gen_token(Tok.KW_ASYNC))
1841
+ new_kid.append(self.gen_token(Tok.KW_WITH))
1842
+ new_kid.append(self.exprs)
1843
+
1844
+ new_kid.append(self.gen_token(Tok.LBRACE))
1845
+ new_kid.append(self.body)
1846
+ new_kid.append(self.gen_token(Tok.RBRACE))
1847
+
1848
+ AstNode.__init__(self, kid=new_kid)
1849
+ return res
1850
+
1076
1851
 
1077
1852
  class ExprAsItem(AstNode):
1078
1853
  """ExprAsItem node type for Jac Ast."""
@@ -1088,6 +1863,19 @@ class ExprAsItem(AstNode):
1088
1863
  self.alias = alias
1089
1864
  AstNode.__init__(self, kid=kid)
1090
1865
 
1866
+ def normalize(self, deep: bool = True) -> bool:
1867
+ """Normalize ast node."""
1868
+ res = True
1869
+ if deep:
1870
+ res = self.expr.normalize(deep)
1871
+ res = res and self.alias.normalize(deep) if self.alias else res
1872
+ new_kid: list[AstNode] = [self.expr]
1873
+ if self.alias:
1874
+ new_kid.append(self.gen_token(Tok.KW_AS))
1875
+ new_kid.append(self.alias)
1876
+ AstNode.__init__(self, kid=new_kid)
1877
+ return res
1878
+
1091
1879
 
1092
1880
  class RaiseStmt(CodeBlockStmt):
1093
1881
  """RaiseStmt node type for Jac Ast."""
@@ -1103,6 +1891,22 @@ class RaiseStmt(CodeBlockStmt):
1103
1891
  self.from_target = from_target
1104
1892
  AstNode.__init__(self, kid=kid)
1105
1893
 
1894
+ def normalize(self, deep: bool = False) -> bool:
1895
+ """Normalize raise statement node."""
1896
+ res = True
1897
+ if deep:
1898
+ res = res and self.cause.normalize(deep) if self.cause else res
1899
+ res = res and self.from_target.normalize(deep) if self.from_target else res
1900
+ new_kid: list[AstNode] = [self.gen_token(Tok.KW_RAISE)]
1901
+ if self.cause:
1902
+ new_kid.append(self.cause)
1903
+ if self.from_target:
1904
+ new_kid.append(self.gen_token(Tok.KW_FROM))
1905
+ new_kid.append(self.from_target)
1906
+ new_kid.append(self.gen_token(Tok.SEMI))
1907
+ AstNode.__init__(self, kid=new_kid)
1908
+ return res
1909
+
1106
1910
 
1107
1911
  class AssertStmt(CodeBlockStmt):
1108
1912
  """AssertStmt node type for Jac Ast."""
@@ -1118,6 +1922,23 @@ class AssertStmt(CodeBlockStmt):
1118
1922
  self.error_msg = error_msg
1119
1923
  AstNode.__init__(self, kid=kid)
1120
1924
 
1925
+ def normalize(self, deep: bool = False) -> bool:
1926
+ """Normalize assert statement node."""
1927
+ res = True
1928
+ if deep:
1929
+ res = self.condition.normalize(deep)
1930
+ res = res and self.error_msg.normalize(deep) if self.error_msg else res
1931
+ new_kid: list[AstNode] = [
1932
+ self.gen_token(Tok.KW_ASSERT),
1933
+ self.condition,
1934
+ ]
1935
+ if self.error_msg:
1936
+ new_kid.append(self.gen_token(Tok.COMMA))
1937
+ new_kid.append(self.error_msg)
1938
+ new_kid.append(self.gen_token(Tok.SEMI))
1939
+ AstNode.__init__(self, kid=new_kid)
1940
+ return res
1941
+
1121
1942
 
1122
1943
  class CtrlStmt(CodeBlockStmt):
1123
1944
  """CtrlStmt node type for Jac Ast."""
@@ -1131,6 +1952,15 @@ class CtrlStmt(CodeBlockStmt):
1131
1952
  self.ctrl = ctrl
1132
1953
  AstNode.__init__(self, kid=kid)
1133
1954
 
1955
+ def normalize(self, deep: bool = False) -> bool:
1956
+ """Normalize control statement node."""
1957
+ res = True
1958
+ if deep:
1959
+ res = self.ctrl.normalize(deep)
1960
+ new_kid: list[AstNode] = [self.ctrl, self.gen_token(Tok.SEMI)]
1961
+ AstNode.__init__(self, kid=new_kid)
1962
+ return res
1963
+
1134
1964
 
1135
1965
  class DeleteStmt(CodeBlockStmt):
1136
1966
  """DeleteStmt node type for Jac Ast."""
@@ -1144,6 +1974,19 @@ class DeleteStmt(CodeBlockStmt):
1144
1974
  self.target = target
1145
1975
  AstNode.__init__(self, kid=kid)
1146
1976
 
1977
+ def normalize(self, deep: bool = False) -> bool:
1978
+ """Normalize delete statement node."""
1979
+ res = True
1980
+ if deep:
1981
+ res = self.target.normalize(deep)
1982
+ new_kid: list[AstNode] = [
1983
+ self.gen_token(Tok.KW_DELETE),
1984
+ self.target,
1985
+ self.gen_token(Tok.SEMI),
1986
+ ]
1987
+ AstNode.__init__(self, kid=new_kid)
1988
+ return res
1989
+
1147
1990
 
1148
1991
  class ReportStmt(CodeBlockStmt):
1149
1992
  """ReportStmt node type for Jac Ast."""
@@ -1157,6 +2000,19 @@ class ReportStmt(CodeBlockStmt):
1157
2000
  self.expr = expr
1158
2001
  AstNode.__init__(self, kid=kid)
1159
2002
 
2003
+ def normalize(self, deep: bool = False) -> bool:
2004
+ """Normalize report statement node."""
2005
+ res = True
2006
+ if deep:
2007
+ res = self.expr.normalize(deep)
2008
+ new_kid: list[AstNode] = [
2009
+ self.gen_token(Tok.KW_REPORT),
2010
+ self.expr,
2011
+ self.gen_token(Tok.SEMI),
2012
+ ]
2013
+ AstNode.__init__(self, kid=new_kid)
2014
+ return res
2015
+
1160
2016
 
1161
2017
  class ReturnStmt(CodeBlockStmt):
1162
2018
  """ReturnStmt node type for Jac Ast."""
@@ -1170,6 +2026,20 @@ class ReturnStmt(CodeBlockStmt):
1170
2026
  self.expr = expr
1171
2027
  AstNode.__init__(self, kid=kid)
1172
2028
 
2029
+ def normalize(self, deep: bool = False) -> bool:
2030
+ """Normalize return statement node."""
2031
+ res = True
2032
+ if deep:
2033
+ res = self.expr.normalize(deep) if self.expr else res
2034
+ new_kid: list[AstNode] = [
2035
+ self.gen_token(Tok.KW_RETURN),
2036
+ ]
2037
+ if self.expr:
2038
+ new_kid.append(self.expr)
2039
+ new_kid.append(self.gen_token(Tok.SEMI))
2040
+ AstNode.__init__(self, kid=new_kid)
2041
+ return res
2042
+
1173
2043
 
1174
2044
  class IgnoreStmt(WalkerStmtOnlyNode, CodeBlockStmt):
1175
2045
  """IgnoreStmt node type for Jac Ast."""
@@ -1184,6 +2054,19 @@ class IgnoreStmt(WalkerStmtOnlyNode, CodeBlockStmt):
1184
2054
  AstNode.__init__(self, kid=kid)
1185
2055
  WalkerStmtOnlyNode.__init__(self)
1186
2056
 
2057
+ def normalize(self, deep: bool = False) -> bool:
2058
+ """Normalize ignore statement node."""
2059
+ res = True
2060
+ if deep:
2061
+ res = self.target.normalize(deep)
2062
+ new_kid: list[AstNode] = [
2063
+ self.gen_token(Tok.KW_IGNORE),
2064
+ self.target,
2065
+ self.gen_token(Tok.SEMI),
2066
+ ]
2067
+ AstNode.__init__(self, kid=new_kid)
2068
+ return res
2069
+
1187
2070
 
1188
2071
  class VisitStmt(WalkerStmtOnlyNode, AstElseBodyNode, CodeBlockStmt):
1189
2072
  """VisitStmt node type for Jac Ast."""
@@ -1202,6 +2085,26 @@ class VisitStmt(WalkerStmtOnlyNode, AstElseBodyNode, CodeBlockStmt):
1202
2085
  WalkerStmtOnlyNode.__init__(self)
1203
2086
  AstElseBodyNode.__init__(self, else_body=else_body)
1204
2087
 
2088
+ def normalize(self, deep: bool = False) -> bool:
2089
+ """Normalize visit statement node."""
2090
+ res = True
2091
+ if deep:
2092
+ res = self.vis_type.normalize(deep) if self.vis_type else res
2093
+ res = self.target.normalize(deep)
2094
+ res = res and self.else_body.normalize(deep) if self.else_body else res
2095
+ new_kid: list[AstNode] = []
2096
+ new_kid.append(self.gen_token(Tok.KW_VISIT))
2097
+ if self.vis_type:
2098
+ new_kid.append(self.gen_token(Tok.COLON))
2099
+ new_kid.append(self.vis_type)
2100
+ new_kid.append(self.gen_token(Tok.COLON))
2101
+ new_kid.append(self.target)
2102
+ new_kid.append(self.gen_token(Tok.SEMI))
2103
+ if self.else_body:
2104
+ new_kid.append(self.else_body)
2105
+ AstNode.__init__(self, kid=new_kid)
2106
+ return res
2107
+
1205
2108
 
1206
2109
  class RevisitStmt(WalkerStmtOnlyNode, AstElseBodyNode, CodeBlockStmt):
1207
2110
  """ReVisitStmt node type for Jac Ast."""
@@ -1218,6 +2121,21 @@ class RevisitStmt(WalkerStmtOnlyNode, AstElseBodyNode, CodeBlockStmt):
1218
2121
  WalkerStmtOnlyNode.__init__(self)
1219
2122
  AstElseBodyNode.__init__(self, else_body=else_body)
1220
2123
 
2124
+ def normalize(self, deep: bool = False) -> bool:
2125
+ """Normalize revisit statement node."""
2126
+ res = True
2127
+ if deep:
2128
+ res = self.hops.normalize(deep) if self.hops else res
2129
+ res = res and self.else_body.normalize(deep) if self.else_body else res
2130
+ new_kid: list[AstNode] = [self.gen_token(Tok.KW_REVISIT)]
2131
+ if self.hops:
2132
+ new_kid.append(self.hops)
2133
+ if self.else_body:
2134
+ new_kid.append(self.else_body)
2135
+ new_kid.append(self.gen_token(Tok.SEMI))
2136
+ AstNode.__init__(self, kid=new_kid)
2137
+ return res
2138
+
1221
2139
 
1222
2140
  class DisengageStmt(WalkerStmtOnlyNode, CodeBlockStmt):
1223
2141
  """DisengageStmt node type for Jac Ast."""
@@ -1230,6 +2148,15 @@ class DisengageStmt(WalkerStmtOnlyNode, CodeBlockStmt):
1230
2148
  AstNode.__init__(self, kid=kid)
1231
2149
  WalkerStmtOnlyNode.__init__(self)
1232
2150
 
2151
+ def normalize(self, deep: bool = False) -> bool:
2152
+ """Normalize disengage statement node."""
2153
+ new_kid: list[AstNode] = [
2154
+ self.gen_token(Tok.KW_DISENGAGE),
2155
+ self.gen_token(Tok.SEMI),
2156
+ ]
2157
+ AstNode.__init__(self, kid=new_kid)
2158
+ return True
2159
+
1233
2160
 
1234
2161
  class AwaitExpr(Expr):
1235
2162
  """AwaitStmt node type for Jac Ast."""
@@ -1243,6 +2170,18 @@ class AwaitExpr(Expr):
1243
2170
  self.target = target
1244
2171
  AstNode.__init__(self, kid=kid)
1245
2172
 
2173
+ def normalize(self, deep: bool = False) -> bool:
2174
+ """Normalize sync statement node."""
2175
+ res = True
2176
+ if deep:
2177
+ res = self.target.normalize(deep)
2178
+ new_kid: list[AstNode] = [
2179
+ self.gen_token(Tok.KW_AWAIT),
2180
+ self.target,
2181
+ ]
2182
+ AstNode.__init__(self, kid=new_kid)
2183
+ return res
2184
+
1246
2185
 
1247
2186
  class GlobalStmt(CodeBlockStmt):
1248
2187
  """GlobalStmt node type for Jac Ast."""
@@ -1256,12 +2195,38 @@ class GlobalStmt(CodeBlockStmt):
1256
2195
  self.target = target
1257
2196
  AstNode.__init__(self, kid=kid)
1258
2197
 
2198
+ def normalize(self, deep: bool = False) -> bool:
2199
+ """Normalize global statement node."""
2200
+ res = True
2201
+ if deep:
2202
+ res = self.target.normalize(deep)
2203
+ new_kid: list[AstNode] = [
2204
+ self.gen_token(Tok.GLOBAL_OP),
2205
+ self.target,
2206
+ self.gen_token(Tok.SEMI),
2207
+ ]
2208
+ AstNode.__init__(self, kid=new_kid)
2209
+ return res
2210
+
1259
2211
 
1260
2212
  class NonLocalStmt(GlobalStmt):
1261
2213
  """NonlocalStmt node type for Jac Ast."""
1262
2214
 
1263
-
1264
- class Assignment(AstTypedVarNode, EnumBlockStmt, CodeBlockStmt):
2215
+ def normalize(self, deep: bool = False) -> bool:
2216
+ """Normalize nonlocal statement node."""
2217
+ res = True
2218
+ if deep:
2219
+ res = self.target.normalize(deep)
2220
+ new_kid: list[AstNode] = [
2221
+ self.gen_token(Tok.NONLOCAL_OP),
2222
+ self.target,
2223
+ self.gen_token(Tok.SEMI),
2224
+ ]
2225
+ AstNode.__init__(self, kid=new_kid)
2226
+ return res
2227
+
2228
+
2229
+ class Assignment(AstSemStrNode, AstTypedVarNode, EnumBlockStmt, CodeBlockStmt):
1265
2230
  """Assignment node type for Jac Ast."""
1266
2231
 
1267
2232
  def __init__(
@@ -1272,15 +2237,43 @@ class Assignment(AstTypedVarNode, EnumBlockStmt, CodeBlockStmt):
1272
2237
  kid: Sequence[AstNode],
1273
2238
  mutable: bool = True,
1274
2239
  aug_op: Optional[Token] = None,
2240
+ semstr: Optional[String] = None,
2241
+ is_enum_stmt: bool = False,
1275
2242
  ) -> None:
1276
2243
  """Initialize assignment node."""
1277
2244
  self.target = target
1278
2245
  self.value = value
1279
2246
  self.mutable = mutable
1280
2247
  self.aug_op = aug_op
2248
+ self.is_enum_stmt = is_enum_stmt
1281
2249
  AstNode.__init__(self, kid=kid)
2250
+ AstSemStrNode.__init__(self, semstr=semstr)
1282
2251
  AstTypedVarNode.__init__(self, type_tag=type_tag)
1283
2252
 
2253
+ def normalize(self, deep: bool = True) -> bool:
2254
+ """Normalize ast node."""
2255
+ res = True
2256
+ if deep:
2257
+ res = self.target.normalize(deep)
2258
+ res = res and self.value.normalize(deep) if self.value else res
2259
+ res = res and self.type_tag.normalize(deep) if self.type_tag else res
2260
+ res = res and self.aug_op.normalize(deep) if self.aug_op else res
2261
+ new_kid: list[AstNode] = []
2262
+ new_kid.append(self.target)
2263
+ if self.type_tag:
2264
+ new_kid.append(self.type_tag)
2265
+ if self.aug_op:
2266
+ new_kid.append(self.aug_op)
2267
+ new_kid.append(self.gen_token(Tok.EQ))
2268
+ else:
2269
+ new_kid.append(self.gen_token(Tok.EQ))
2270
+ if self.value:
2271
+ new_kid.append(self.value)
2272
+ if not isinstance(self.parent, (GlobalVars)):
2273
+ new_kid.append(self.gen_token(Tok.SEMI))
2274
+ AstNode.__init__(self, kid=new_kid)
2275
+ return res
2276
+
1284
2277
 
1285
2278
  class BinaryExpr(Expr):
1286
2279
  """ExprBinary node type for Jac Ast."""
@@ -1298,6 +2291,23 @@ class BinaryExpr(Expr):
1298
2291
  self.op = op
1299
2292
  AstNode.__init__(self, kid=kid)
1300
2293
 
2294
+ def normalize(self, deep: bool = False) -> bool:
2295
+ """Normalize ast node."""
2296
+ res = True
2297
+ if deep:
2298
+ res = self.left.normalize(deep)
2299
+ res = res and self.right.normalize(deep) if self.right else res
2300
+ res = res and self.op.normalize(deep) if self.op else res
2301
+ new_kid: list[AstNode] = [
2302
+ self.gen_token(Tok.LPAREN),
2303
+ self.left,
2304
+ self.op,
2305
+ self.right,
2306
+ self.gen_token(Tok.RPAREN),
2307
+ ]
2308
+ AstNode.__init__(self, kid=new_kid)
2309
+ return res
2310
+
1301
2311
 
1302
2312
  class CompareExpr(Expr):
1303
2313
  """CompareExpr node type for Jac Ast."""
@@ -1315,6 +2325,22 @@ class CompareExpr(Expr):
1315
2325
  self.ops = ops
1316
2326
  AstNode.__init__(self, kid=kid)
1317
2327
 
2328
+ def normalize(self, deep: bool = False) -> bool:
2329
+ """Normalize ast node."""
2330
+ res = True
2331
+ if deep:
2332
+ res = self.left.normalize(deep)
2333
+ for right in self.rights:
2334
+ res = res and right.normalize(deep)
2335
+ for op in self.ops:
2336
+ res = res and op.normalize(deep)
2337
+ new_kid: list[AstNode] = [self.left]
2338
+ for i, right in enumerate(self.rights):
2339
+ new_kid.append(self.ops[i])
2340
+ new_kid.append(right)
2341
+ AstNode.__init__(self, kid=new_kid)
2342
+ return res
2343
+
1318
2344
 
1319
2345
  class BoolExpr(Expr):
1320
2346
  """BoolExpr node type for Jac Ast."""
@@ -1330,6 +2356,21 @@ class BoolExpr(Expr):
1330
2356
  self.op = op
1331
2357
  AstNode.__init__(self, kid=kid)
1332
2358
 
2359
+ def normalize(self, deep: bool = False) -> bool:
2360
+ """Normalize ast node."""
2361
+ res = True
2362
+ if deep:
2363
+ for value in self.values:
2364
+ res = res and value.normalize(deep)
2365
+ res = res and self.op.normalize(deep) if self.op else res
2366
+ new_kid: list[AstNode] = []
2367
+ for i, value in enumerate(self.values):
2368
+ if i > 0:
2369
+ new_kid.append(self.op)
2370
+ new_kid.append(value)
2371
+ AstNode.__init__(self, kid=new_kid)
2372
+ return res
2373
+
1333
2374
 
1334
2375
  class LambdaExpr(Expr):
1335
2376
  """ExprLambda node type for Jac Ast."""
@@ -1345,6 +2386,22 @@ class LambdaExpr(Expr):
1345
2386
  self.body = body
1346
2387
  AstNode.__init__(self, kid=kid)
1347
2388
 
2389
+ def normalize(self, deep: bool = False) -> bool:
2390
+ """Normalize ast node."""
2391
+ res = True
2392
+ if deep:
2393
+ res = self.signature.normalize(deep)
2394
+ res = res and self.body.normalize(deep)
2395
+ new_kid: list[AstNode] = [
2396
+ self.gen_token(Tok.KW_WITH),
2397
+ self.signature,
2398
+ self.gen_token(Tok.KW_CAN),
2399
+ self.body,
2400
+ self.gen_token(Tok.SEMI),
2401
+ ]
2402
+ AstNode.__init__(self, kid=new_kid)
2403
+ return res
2404
+
1348
2405
 
1349
2406
  class UnaryExpr(Expr):
1350
2407
  """ExprUnary node type for Jac Ast."""
@@ -1360,6 +2417,16 @@ class UnaryExpr(Expr):
1360
2417
  self.op = op
1361
2418
  AstNode.__init__(self, kid=kid)
1362
2419
 
2420
+ def normalize(self, deep: bool = False) -> bool:
2421
+ """Normalize ast node."""
2422
+ res = True
2423
+ if deep:
2424
+ res = self.operand.normalize(deep)
2425
+ res = res and self.op.normalize(deep) if self.op else res
2426
+ new_kid: list[AstNode] = [self.op, self.operand]
2427
+ AstNode.__init__(self, kid=new_kid)
2428
+ return res
2429
+
1363
2430
 
1364
2431
  class IfElseExpr(Expr):
1365
2432
  """ExprIfElse node type for Jac Ast."""
@@ -1377,6 +2444,23 @@ class IfElseExpr(Expr):
1377
2444
  self.else_value = else_value
1378
2445
  AstNode.__init__(self, kid=kid)
1379
2446
 
2447
+ def normalize(self, deep: bool = False) -> bool:
2448
+ """Normalize ast node."""
2449
+ res = True
2450
+ if deep:
2451
+ res = self.condition.normalize(deep)
2452
+ res = res and self.value.normalize(deep)
2453
+ res = res and self.else_value.normalize(deep)
2454
+ new_kid: list[AstNode] = [
2455
+ self.value,
2456
+ self.gen_token(Tok.KW_IF),
2457
+ self.condition,
2458
+ self.gen_token(Tok.KW_ELSE),
2459
+ self.else_value,
2460
+ ]
2461
+ AstNode.__init__(self, kid=new_kid)
2462
+ return res
2463
+
1380
2464
 
1381
2465
  class MultiString(AtomExpr):
1382
2466
  """ExprMultiString node type for Jac Ast."""
@@ -1396,8 +2480,20 @@ class MultiString(AtomExpr):
1396
2480
  sym_type=SymbolType.STRING,
1397
2481
  )
1398
2482
 
2483
+ def normalize(self, deep: bool = False) -> bool:
2484
+ """Normalize ast node."""
2485
+ res = True
2486
+ if deep:
2487
+ for string in self.strings:
2488
+ res = res and string.normalize(deep)
2489
+ new_kid: list[AstNode] = []
2490
+ for string in self.strings:
2491
+ new_kid.append(string)
2492
+ AstNode.__init__(self, kid=new_kid)
2493
+ return res
1399
2494
 
1400
- class FString(AstSymbolNode):
2495
+
2496
+ class FString(AtomExpr):
1401
2497
  """FString node type for Jac Ast."""
1402
2498
 
1403
2499
  def __init__(
@@ -1415,18 +2511,16 @@ class FString(AstSymbolNode):
1415
2511
  sym_type=SymbolType.STRING,
1416
2512
  )
1417
2513
 
1418
-
1419
- class ExprList(AstNode):
1420
- """ExprList node type for Jac Ast."""
1421
-
1422
- def __init__(
1423
- self,
1424
- values: Optional[SubNodeList[Expr]],
1425
- kid: Sequence[AstNode],
1426
- ) -> None:
1427
- """Initialize expr value node."""
1428
- self.values = values
1429
- AstNode.__init__(self, kid=kid)
2514
+ def normalize(self, deep: bool = False) -> bool:
2515
+ """Normalize ast node."""
2516
+ res = True
2517
+ if deep:
2518
+ res = self.parts.normalize(deep) if self.parts else res
2519
+ new_kid: list[AstNode] = []
2520
+ if self.parts:
2521
+ new_kid.append(self.parts)
2522
+ AstNode.__init__(self, kid=new_kid)
2523
+ return res
1430
2524
 
1431
2525
 
1432
2526
  class ListVal(AtomExpr):
@@ -1447,6 +2541,20 @@ class ListVal(AtomExpr):
1447
2541
  sym_type=SymbolType.SEQUENCE,
1448
2542
  )
1449
2543
 
2544
+ def normalize(self, deep: bool = False) -> bool:
2545
+ """Normalize ast node."""
2546
+ res = True
2547
+ if deep:
2548
+ res = self.values.normalize(deep) if self.values else res
2549
+ new_kid: list[AstNode] = [
2550
+ self.gen_token(Tok.LSQUARE),
2551
+ ]
2552
+ if self.values:
2553
+ new_kid.append(self.values)
2554
+ new_kid.append(self.gen_token(Tok.RSQUARE))
2555
+ AstNode.__init__(self, kid=new_kid)
2556
+ return res
2557
+
1450
2558
 
1451
2559
  class SetVal(AtomExpr):
1452
2560
  """SetVal node type for Jac Ast."""
@@ -1466,6 +2574,18 @@ class SetVal(AtomExpr):
1466
2574
  sym_type=SymbolType.SEQUENCE,
1467
2575
  )
1468
2576
 
2577
+ def normalize(self, deep: bool = False) -> bool:
2578
+ """Normalize ast node."""
2579
+ res = True
2580
+ if deep:
2581
+ res = self.values.normalize(deep) if self.values else res
2582
+ new_kid: list[AstNode] = []
2583
+ if self.values:
2584
+ new_kid.append(self.values)
2585
+
2586
+ AstNode.__init__(self, kid=new_kid)
2587
+ return res
2588
+
1469
2589
 
1470
2590
  class TupleVal(AtomExpr):
1471
2591
  """TupleVal node type for Jac Ast."""
@@ -1485,6 +2605,22 @@ class TupleVal(AtomExpr):
1485
2605
  sym_type=SymbolType.SEQUENCE,
1486
2606
  )
1487
2607
 
2608
+ def normalize(self, deep: bool = False) -> bool:
2609
+ """Normalize ast node."""
2610
+ res = True
2611
+ if deep:
2612
+ res = self.values.normalize(deep) if self.values else res
2613
+ new_kid: list[AstNode] = [
2614
+ self.gen_token(Tok.LPAREN),
2615
+ ]
2616
+ if self.values:
2617
+ new_kid.append(self.values)
2618
+ if len(self.values.items) < 2:
2619
+ new_kid.append(self.gen_token(Tok.COMMA))
2620
+ new_kid.append(self.gen_token(Tok.RPAREN))
2621
+ AstNode.__init__(self, kid=new_kid)
2622
+ return res
2623
+
1488
2624
 
1489
2625
  class DictVal(AtomExpr):
1490
2626
  """ExprDict node type for Jac Ast."""
@@ -1504,6 +2640,23 @@ class DictVal(AtomExpr):
1504
2640
  sym_type=SymbolType.SEQUENCE,
1505
2641
  )
1506
2642
 
2643
+ def normalize(self, deep: bool = False) -> bool:
2644
+ """Normalize ast node."""
2645
+ res = True
2646
+ if deep:
2647
+ for kv_pair in self.kv_pairs:
2648
+ res = res and kv_pair.normalize(deep)
2649
+ new_kid: list[AstNode] = [
2650
+ self.gen_token(Tok.LBRACE),
2651
+ ]
2652
+ for i, kv_pair in enumerate(self.kv_pairs):
2653
+ new_kid.append(kv_pair)
2654
+ if i < len(self.kv_pairs) - 1:
2655
+ new_kid.append(self.gen_token(Tok.COMMA))
2656
+ new_kid.append(self.gen_token(Tok.RBRACE))
2657
+ AstNode.__init__(self, kid=new_kid)
2658
+ return res
2659
+
1507
2660
 
1508
2661
  class KVPair(AstNode):
1509
2662
  """ExprKVPair node type for Jac Ast."""
@@ -1519,6 +2672,22 @@ class KVPair(AstNode):
1519
2672
  self.value = value
1520
2673
  AstNode.__init__(self, kid=kid)
1521
2674
 
2675
+ def normalize(self, deep: bool = False) -> bool:
2676
+ """Normalize ast node."""
2677
+ res = True
2678
+ if deep:
2679
+ res = self.key.normalize(deep) if self.key else res
2680
+ res = res and self.value.normalize(deep)
2681
+ new_kid: list[AstNode] = []
2682
+ if self.key:
2683
+ new_kid.append(self.key)
2684
+ new_kid.append(self.gen_token(Tok.COLON))
2685
+ else:
2686
+ new_kid.append(self.gen_token(Tok.STAR_POW))
2687
+ new_kid.append(self.value)
2688
+ AstNode.__init__(self, kid=new_kid)
2689
+ return res
2690
+
1522
2691
 
1523
2692
  class KWPair(AstNode):
1524
2693
  """ExprKWPair node type for Jac Ast."""
@@ -1534,6 +2703,20 @@ class KWPair(AstNode):
1534
2703
  self.value = value
1535
2704
  AstNode.__init__(self, kid=kid)
1536
2705
 
2706
+ def normalize(self, deep: bool = False) -> bool:
2707
+ """Normalize ast node."""
2708
+ res = True
2709
+ if deep:
2710
+ res = self.key.normalize(deep) if self.key else res
2711
+ res = res and self.value.normalize(deep)
2712
+ new_kid: list[AstNode] = []
2713
+ if self.key:
2714
+ new_kid.append(self.key)
2715
+ new_kid.append(self.gen_token(Tok.EQ))
2716
+ new_kid.append(self.value)
2717
+ AstNode.__init__(self, kid=new_kid)
2718
+ return res
2719
+
1537
2720
 
1538
2721
  class InnerCompr(AstAsyncNode):
1539
2722
  """ListCompr node type for Jac Ast."""
@@ -1543,7 +2726,7 @@ class InnerCompr(AstAsyncNode):
1543
2726
  is_async: bool,
1544
2727
  target: Expr,
1545
2728
  collection: Expr,
1546
- conditional: Optional[Expr],
2729
+ conditional: Optional[list[Expr]],
1547
2730
  kid: Sequence[AstNode],
1548
2731
  ) -> None:
1549
2732
  """Initialize comprehension expression node."""
@@ -1553,6 +2736,26 @@ class InnerCompr(AstAsyncNode):
1553
2736
  AstNode.__init__(self, kid=kid)
1554
2737
  AstAsyncNode.__init__(self, is_async=is_async)
1555
2738
 
2739
+ def normalize(self, deep: bool = False) -> bool:
2740
+ """Normalize ast node."""
2741
+ res = True
2742
+ if deep:
2743
+ res = self.target.normalize(deep)
2744
+ res = res and self.collection.normalize(deep)
2745
+ for cond in self.conditional if self.conditional else []:
2746
+ res = res and cond.normalize(deep)
2747
+ new_kid: list[AstNode] = []
2748
+ if self.is_async:
2749
+ new_kid.append(self.gen_token(Tok.KW_ASYNC))
2750
+ new_kid.append(self.gen_token(Tok.KW_FOR))
2751
+ new_kid.append(self.target)
2752
+ new_kid.append(self.gen_token(Tok.KW_IN))
2753
+ new_kid.append(self.collection)
2754
+ for cond in self.conditional if self.conditional else []:
2755
+ new_kid.append(cond)
2756
+ AstNode.__init__(self, kid=new_kid)
2757
+ return res
2758
+
1556
2759
 
1557
2760
  class ListCompr(AtomExpr):
1558
2761
  """ListCompr node type for Jac Ast."""
@@ -1574,14 +2777,64 @@ class ListCompr(AtomExpr):
1574
2777
  sym_type=SymbolType.SEQUENCE,
1575
2778
  )
1576
2779
 
2780
+ def normalize(self, deep: bool = False) -> bool:
2781
+ """Normalize ast node."""
2782
+ res = True
2783
+ if deep:
2784
+ res = self.out_expr.normalize(deep)
2785
+ for comp in self.compr:
2786
+ res = res and comp.normalize(deep)
2787
+ new_kid: list[AstNode] = [
2788
+ self.gen_token(Tok.LSQUARE),
2789
+ self.out_expr,
2790
+ ]
2791
+ for comp in self.compr:
2792
+ new_kid.append(comp)
2793
+ new_kid.append(self.gen_token(Tok.RSQUARE))
2794
+ AstNode.__init__(self, kid=new_kid)
2795
+ return res
2796
+
1577
2797
 
1578
2798
  class GenCompr(ListCompr):
1579
2799
  """GenCompr node type for Jac Ast."""
1580
2800
 
2801
+ def normalize(self, deep: bool = False) -> bool:
2802
+ """Normalize ast node."""
2803
+ res = True
2804
+ if deep:
2805
+ res = self.out_expr.normalize(deep)
2806
+ for comp in self.compr:
2807
+ res = res and comp.normalize(deep)
2808
+ new_kid: list[AstNode] = [
2809
+ self.gen_token(Tok.LPAREN),
2810
+ self.out_expr,
2811
+ ]
2812
+ for comp in self.compr:
2813
+ new_kid.append(comp)
2814
+ new_kid.append(self.gen_token(Tok.RPAREN))
2815
+ AstNode.__init__(self, kid=new_kid)
2816
+ return res
2817
+
1581
2818
 
1582
2819
  class SetCompr(ListCompr):
1583
2820
  """SetCompr node type for Jac Ast."""
1584
2821
 
2822
+ def normalize(self, deep: bool = False) -> bool:
2823
+ """Normalize ast node."""
2824
+ res = True
2825
+ if deep:
2826
+ res = self.out_expr.normalize(deep)
2827
+ for comp in self.compr:
2828
+ res = res and comp.normalize(deep)
2829
+ new_kid: list[AstNode] = [
2830
+ self.out_expr,
2831
+ ]
2832
+ for comp in self.compr:
2833
+ new_kid.append(comp)
2834
+
2835
+ AstNode.__init__(self, kid=new_kid)
2836
+ return res
2837
+
1585
2838
 
1586
2839
  class DictCompr(AtomExpr):
1587
2840
  """DictCompr node type for Jac Ast."""
@@ -1603,6 +2856,21 @@ class DictCompr(AtomExpr):
1603
2856
  sym_type=SymbolType.SEQUENCE,
1604
2857
  )
1605
2858
 
2859
+ def normalize(self, deep: bool = False) -> bool:
2860
+ """Normalize ast node."""
2861
+ res = True
2862
+ res = self.kv_pair.normalize(deep)
2863
+ for comp in self.compr:
2864
+ res = res and comp.normalize(deep)
2865
+ new_kid: list[AstNode] = [
2866
+ self.kv_pair,
2867
+ ]
2868
+ for comp in self.compr:
2869
+ new_kid.append(comp)
2870
+
2871
+ AstNode.__init__(self, kid=new_kid)
2872
+ return res
2873
+
1606
2874
 
1607
2875
  class AtomTrailer(Expr):
1608
2876
  """AtomTrailer node type for Jac Ast."""
@@ -1611,7 +2879,7 @@ class AtomTrailer(Expr):
1611
2879
  self,
1612
2880
  target: Expr,
1613
2881
  right: AtomExpr | Expr,
1614
- is_attr: Optional[Token],
2882
+ is_attr: bool,
1615
2883
  is_null_ok: bool,
1616
2884
  kid: Sequence[AstNode],
1617
2885
  ) -> None:
@@ -1622,6 +2890,22 @@ class AtomTrailer(Expr):
1622
2890
  self.is_null_ok = is_null_ok
1623
2891
  AstNode.__init__(self, kid=kid)
1624
2892
 
2893
+ def normalize(self, deep: bool = True) -> bool:
2894
+ """Normalize ast node."""
2895
+ res = True
2896
+ if deep:
2897
+ res = self.target.normalize(deep)
2898
+ res = res and self.right.normalize(deep) if self.right else res
2899
+ new_kid: list[AstNode] = [self.target]
2900
+ if self.is_null_ok:
2901
+ new_kid.append(self.gen_token(Tok.NULL_OK))
2902
+ if self.is_attr:
2903
+ new_kid.append(self.gen_token(Tok.DOT))
2904
+ if self.right:
2905
+ new_kid.append(self.right)
2906
+ AstNode.__init__(self, kid=new_kid)
2907
+ return res
2908
+
1625
2909
 
1626
2910
  class AtomUnit(Expr):
1627
2911
  """AtomUnit node type for Jac Ast."""
@@ -1629,14 +2913,24 @@ class AtomUnit(Expr):
1629
2913
  def __init__(
1630
2914
  self,
1631
2915
  value: Expr | YieldExpr,
1632
- is_paren: bool,
1633
2916
  kid: Sequence[AstNode],
1634
2917
  ) -> None:
1635
2918
  """Initialize atom unit expression node."""
1636
2919
  self.value = value
1637
- self.is_paren = is_paren
1638
2920
  AstNode.__init__(self, kid=kid)
1639
2921
 
2922
+ def normalize(self, deep: bool = True) -> bool:
2923
+ """Normalize ast node."""
2924
+ res = True
2925
+ if deep:
2926
+ res = self.value.normalize(deep)
2927
+ new_kid: list[AstNode] = []
2928
+ new_kid.append(self.gen_token(Tok.LPAREN))
2929
+ new_kid.append(self.value)
2930
+ new_kid.append(self.gen_token(Tok.RPAREN))
2931
+ AstNode.__init__(self, kid=new_kid)
2932
+ return res
2933
+
1640
2934
 
1641
2935
  class YieldExpr(Expr):
1642
2936
  """YieldStmt node type for Jac Ast."""
@@ -1652,6 +2946,20 @@ class YieldExpr(Expr):
1652
2946
  self.with_from = with_from
1653
2947
  AstNode.__init__(self, kid=kid)
1654
2948
 
2949
+ def normalize(self, deep: bool = False) -> bool:
2950
+ """Normalize yield statement node."""
2951
+ res = True
2952
+ if deep:
2953
+ res = self.expr.normalize(deep) if self.expr else res
2954
+ new_kid: list[AstNode] = [self.gen_token(Tok.KW_YIELD)]
2955
+ if self.with_from:
2956
+ new_kid.append(self.gen_token(Tok.KW_FROM))
2957
+ if self.expr:
2958
+ new_kid.append(self.expr)
2959
+ new_kid.append(self.gen_token(Tok.SEMI))
2960
+ AstNode.__init__(self, kid=new_kid)
2961
+ return res
2962
+
1655
2963
 
1656
2964
  class FuncCall(Expr):
1657
2965
  """FuncCall node type for Jac Ast."""
@@ -1667,6 +2975,17 @@ class FuncCall(Expr):
1667
2975
  self.params = params
1668
2976
  AstNode.__init__(self, kid=kid)
1669
2977
 
2978
+ def normalize(self, deep: bool = True) -> bool:
2979
+ """Normalize ast node."""
2980
+ if deep:
2981
+ res = self.target.normalize(deep)
2982
+ res = res and (not self.params or self.params.normalize(deep))
2983
+ AstNode.__init__(self, kid=[self.target, self.gen_token(Tok.LPAREN, "(")])
2984
+ if self.params: # TODO: Fix
2985
+ self.kid.append(self.params)
2986
+ self.kid.append(self.gen_token(Tok.RPAREN, ")"))
2987
+ return res
2988
+
1670
2989
 
1671
2990
  class IndexSlice(AtomExpr):
1672
2991
  """IndexSlice node type for Jac Ast."""
@@ -1692,6 +3011,32 @@ class IndexSlice(AtomExpr):
1692
3011
  sym_name_node=self,
1693
3012
  )
1694
3013
 
3014
+ def normalize(self, deep: bool = True) -> bool:
3015
+ """Normalize ast node."""
3016
+ res = True
3017
+ if deep:
3018
+ res = self.start.normalize(deep) if self.start else res
3019
+ res = res and self.stop.normalize(deep) if self.stop else res
3020
+ res = res and self.step.normalize(deep) if self.step else res
3021
+ new_kid: list[AstNode] = []
3022
+ new_kid.append(self.gen_token(Tok.LSQUARE))
3023
+ if self.is_range:
3024
+ if self.start:
3025
+ new_kid.append(self.start)
3026
+ new_kid.append(self.gen_token(Tok.COLON))
3027
+ if self.stop:
3028
+ new_kid.append(self.stop)
3029
+ new_kid.append(self.gen_token(Tok.COLON))
3030
+ if self.step:
3031
+ new_kid.append(self.step)
3032
+ elif self.start:
3033
+ new_kid.append(self.start)
3034
+ else:
3035
+ res = False
3036
+ new_kid.append(self.gen_token(Tok.RSQUARE))
3037
+ AstNode.__init__(self, kid=new_kid)
3038
+ return res
3039
+
1695
3040
 
1696
3041
  class ArchRef(NameSpec):
1697
3042
  """ArchRef node type for Jac Ast."""
@@ -1713,6 +3058,15 @@ class ArchRef(NameSpec):
1713
3058
  sym_type=SymbolType.TYPE,
1714
3059
  )
1715
3060
 
3061
+ def normalize(self, deep: bool = False) -> bool:
3062
+ """Normalize ast node."""
3063
+ res = True
3064
+ if deep:
3065
+ res = self.name_ref.normalize(deep)
3066
+ new_kid: list[AstNode] = [self.arch, self.name_ref]
3067
+ AstNode.__init__(self, kid=new_kid)
3068
+ return res
3069
+
1716
3070
  def py_resolve_name(self) -> str:
1717
3071
  """Resolve name."""
1718
3072
  if isinstance(self.name_ref, Name):
@@ -1741,19 +3095,28 @@ class SpecialVarRef(NameSpec):
1741
3095
  sym_type=SymbolType.VAR,
1742
3096
  )
1743
3097
 
3098
+ def normalize(self, deep: bool = False) -> bool:
3099
+ """Normalize ast node."""
3100
+ res = True
3101
+ if deep:
3102
+ res = self.var.normalize(deep)
3103
+ new_kid: list[AstNode] = [self.var]
3104
+ AstNode.__init__(self, kid=new_kid)
3105
+ return res
3106
+
1744
3107
  def py_resolve_name(self) -> str:
1745
3108
  """Resolve name."""
1746
- if self.var.name == Tok.SELF_OP:
3109
+ if self.var.name == Tok.KW_SELF:
1747
3110
  return "self"
1748
- elif self.var.name == Tok.SUPER_OP:
3111
+ elif self.var.name == Tok.KW_SUPER:
1749
3112
  return "super()"
1750
- elif self.var.name == Tok.ROOT_OP:
3113
+ elif self.var.name == Tok.KW_ROOT:
1751
3114
  return Con.ROOT.value
1752
- elif self.var.name == Tok.HERE_OP:
3115
+ elif self.var.name == Tok.KW_HERE:
1753
3116
  return Con.HERE.value
1754
- elif self.var.name == Tok.INIT_OP:
3117
+ elif self.var.name == Tok.KW_INIT:
1755
3118
  return "__init__"
1756
- elif self.var.name == Tok.POST_INIT_OP:
3119
+ elif self.var.name == Tok.KW_POST_INIT:
1757
3120
  return "__post_init__"
1758
3121
  else:
1759
3122
  raise NotImplementedError("ICE: Special var reference not implemented")
@@ -1764,7 +3127,7 @@ class EdgeRefTrailer(Expr):
1764
3127
 
1765
3128
  def __init__(
1766
3129
  self,
1767
- chain: list[Expr],
3130
+ chain: list[Expr | FilterCompr],
1768
3131
  edges_only: bool,
1769
3132
  kid: Sequence[AstNode],
1770
3133
  ) -> None:
@@ -1773,6 +3136,21 @@ class EdgeRefTrailer(Expr):
1773
3136
  self.edges_only = edges_only
1774
3137
  AstNode.__init__(self, kid=kid)
1775
3138
 
3139
+ def normalize(self, deep: bool = True) -> bool:
3140
+ """Normalize ast node."""
3141
+ res = True
3142
+ for expr in self.chain:
3143
+ res = res and expr.normalize(deep)
3144
+ new_kid: list[AstNode] = []
3145
+ if self.edges_only:
3146
+ new_kid.append(self.gen_token(Tok.EDGE_OP))
3147
+ self.gen_token(Tok.LSQUARE)
3148
+ for expr in self.chain:
3149
+ new_kid.append(expr)
3150
+ self.gen_token(Tok.RSQUARE)
3151
+ AstNode.__init__(self, kid=new_kid)
3152
+ return res
3153
+
1776
3154
 
1777
3155
  class EdgeOpRef(WalkerStmtOnlyNode, AtomExpr):
1778
3156
  """EdgeOpRef node type for Jac Ast."""
@@ -1795,6 +3173,36 @@ class EdgeOpRef(WalkerStmtOnlyNode, AtomExpr):
1795
3173
  sym_type=SymbolType.SEQUENCE,
1796
3174
  )
1797
3175
 
3176
+ def normalize(self, deep: bool = False) -> bool:
3177
+ """Normalize ast node."""
3178
+ res = True
3179
+ if deep:
3180
+ res = self.filter_cond.normalize(deep) if self.filter_cond else res
3181
+ new_kid: list[AstNode] = []
3182
+ if self.edge_dir == EdgeDir.IN:
3183
+ if not self.filter_cond:
3184
+ new_kid.append(self.gen_token(Tok.ARROW_L))
3185
+ else:
3186
+ new_kid.append(self.gen_token(Tok.ARROW_L_P1))
3187
+ new_kid.append(self.filter_cond)
3188
+ new_kid.append(self.gen_token(Tok.ARROW_L_P2))
3189
+ elif self.edge_dir == EdgeDir.OUT:
3190
+ if not self.filter_cond:
3191
+ new_kid.append(self.gen_token(Tok.ARROW_R))
3192
+ else:
3193
+ new_kid.append(self.gen_token(Tok.ARROW_R_P1))
3194
+ new_kid.append(self.filter_cond)
3195
+ new_kid.append(self.gen_token(Tok.ARROW_R_P2))
3196
+ else:
3197
+ if not self.filter_cond:
3198
+ new_kid.append(self.gen_token(Tok.ARROW_BI))
3199
+ else:
3200
+ new_kid.append(self.gen_token(Tok.ARROW_L_P1))
3201
+ new_kid.append(self.filter_cond)
3202
+ new_kid.append(self.gen_token(Tok.ARROW_R_P2))
3203
+ AstNode.__init__(self, kid=new_kid)
3204
+ return res
3205
+
1798
3206
 
1799
3207
  class DisconnectOp(WalkerStmtOnlyNode):
1800
3208
  """DisconnectOpRef node type for Jac Ast."""
@@ -1809,6 +3217,15 @@ class DisconnectOp(WalkerStmtOnlyNode):
1809
3217
  AstNode.__init__(self, kid=kid)
1810
3218
  WalkerStmtOnlyNode.__init__(self)
1811
3219
 
3220
+ def normalize(self, deep: bool = False) -> bool:
3221
+ """Normalize ast node."""
3222
+ res = True
3223
+ if deep:
3224
+ res = self.edge_spec.normalize(deep)
3225
+ new_kid: list[AstNode] = [self.gen_token(Tok.NOT), self.edge_spec]
3226
+ AstNode.__init__(self, kid=new_kid)
3227
+ return res
3228
+
1812
3229
 
1813
3230
  class ConnectOp(AstNode):
1814
3231
  """ConnectOpRef node type for Jac Ast."""
@@ -1826,6 +3243,49 @@ class ConnectOp(AstNode):
1826
3243
  self.edge_dir = edge_dir
1827
3244
  AstNode.__init__(self, kid=kid)
1828
3245
 
3246
+ def normalize(self, deep: bool = False) -> bool:
3247
+ """Normalize ast node."""
3248
+ res = True
3249
+ if deep:
3250
+ res = self.conn_type.normalize(deep) if self.conn_type else res
3251
+ res = res and self.conn_assign.normalize(deep) if self.conn_assign else res
3252
+ new_kid: list[AstNode] = []
3253
+ if self.edge_dir == EdgeDir.IN:
3254
+ if not self.conn_assign and not self.conn_type:
3255
+ new_kid.append(self.gen_token(Tok.CARROW_L))
3256
+ else:
3257
+ new_kid.append(self.gen_token(Tok.CARROW_L_P1))
3258
+ if self.conn_type:
3259
+ new_kid.append(self.conn_type)
3260
+ if self.conn_assign:
3261
+ new_kid.append(self.gen_token(Tok.COLON))
3262
+ new_kid.append(self.conn_assign)
3263
+ new_kid.append(self.gen_token(Tok.CARROW_L_P2))
3264
+ elif self.edge_dir == EdgeDir.OUT:
3265
+ if not self.conn_assign and not self.conn_type:
3266
+ new_kid.append(self.gen_token(Tok.CARROW_R))
3267
+ else:
3268
+ new_kid.append(self.gen_token(Tok.CARROW_R_P1))
3269
+ if self.conn_type:
3270
+ new_kid.append(self.conn_type)
3271
+ if self.conn_assign:
3272
+ new_kid.append(self.gen_token(Tok.COLON))
3273
+ new_kid.append(self.conn_assign)
3274
+ new_kid.append(self.gen_token(Tok.CARROW_R_P2))
3275
+ else:
3276
+ if not self.conn_assign and not self.conn_type:
3277
+ new_kid.append(self.gen_token(Tok.CARROW_BI))
3278
+ else:
3279
+ new_kid.append(self.gen_token(Tok.CARROW_L_P1))
3280
+ if self.conn_type:
3281
+ new_kid.append(self.conn_type)
3282
+ if self.conn_assign:
3283
+ new_kid.append(self.gen_token(Tok.COLON))
3284
+ new_kid.append(self.conn_assign)
3285
+ new_kid.append(self.gen_token(Tok.CARROW_R_P2))
3286
+ AstNode.__init__(self, kid=new_kid)
3287
+ return res
3288
+
1829
3289
 
1830
3290
  class FilterCompr(AtomExpr):
1831
3291
  """FilterCtx node type for Jac Ast."""
@@ -1847,6 +3307,26 @@ class FilterCompr(AtomExpr):
1847
3307
  sym_type=SymbolType.SEQUENCE,
1848
3308
  )
1849
3309
 
3310
+ def normalize(self, deep: bool = False) -> bool:
3311
+ """Normalize ast node."""
3312
+ res = True
3313
+ if deep:
3314
+ res = self.f_type.normalize(deep) if self.f_type else res
3315
+ res = res and self.compares.normalize(deep) if self.compares else res
3316
+ new_kid: list[AstNode] = []
3317
+ new_kid.append(self.gen_token(Tok.LPAREN))
3318
+ if self.f_type:
3319
+ new_kid.append(self.gen_token(Tok.TYPE_OP))
3320
+ new_kid.append(self.gen_token(Tok.NULL_OK))
3321
+ if self.f_type:
3322
+ new_kid.append(self.f_type)
3323
+ new_kid.append(self.gen_token(Tok.COLON))
3324
+ if self.compares:
3325
+ new_kid.append(self.compares)
3326
+ new_kid.append(self.gen_token(Tok.RPAREN))
3327
+ AstNode.__init__(self, kid=new_kid)
3328
+ return res
3329
+
1850
3330
 
1851
3331
  class AssignCompr(AtomExpr):
1852
3332
  """AssignCtx node type for Jac Ast."""
@@ -1866,6 +3346,19 @@ class AssignCompr(AtomExpr):
1866
3346
  sym_type=SymbolType.SEQUENCE,
1867
3347
  )
1868
3348
 
3349
+ def normalize(self, deep: bool = False) -> bool:
3350
+ """Normalize ast node."""
3351
+ res = True
3352
+ if deep:
3353
+ res = self.assigns.normalize(deep)
3354
+ new_kid: list[AstNode] = []
3355
+ new_kid.append(self.gen_token(Tok.LPAREN))
3356
+ new_kid.append(self.gen_token(Tok.EQ))
3357
+ new_kid.append(self.assigns)
3358
+ new_kid.append(self.gen_token(Tok.RPAREN))
3359
+ AstNode.__init__(self, kid=new_kid)
3360
+ return res
3361
+
1869
3362
 
1870
3363
  # Match Nodes
1871
3364
  # ------------
@@ -1885,6 +3378,23 @@ class MatchStmt(CodeBlockStmt):
1885
3378
  self.cases = cases
1886
3379
  AstNode.__init__(self, kid=kid)
1887
3380
 
3381
+ def normalize(self, deep: bool = False) -> bool:
3382
+ """Normalize match statement node."""
3383
+ res = True
3384
+ if deep:
3385
+ res = self.target.normalize(deep)
3386
+ for case in self.cases:
3387
+ res = res and case.normalize(deep)
3388
+ new_kid: list[AstNode] = [
3389
+ self.gen_token(Tok.KW_MATCH),
3390
+ self.target,
3391
+ ]
3392
+ for case in self.cases:
3393
+ new_kid.append(case)
3394
+
3395
+ AstNode.__init__(self, kid=new_kid)
3396
+ return res
3397
+
1888
3398
 
1889
3399
  class MatchCase(AstNode):
1890
3400
  """MatchCase node type for Jac Ast."""
@@ -1893,7 +3403,7 @@ class MatchCase(AstNode):
1893
3403
  self,
1894
3404
  pattern: MatchPattern,
1895
3405
  guard: Optional[Expr],
1896
- body: SubNodeList[CodeBlockStmt],
3406
+ body: list[CodeBlockStmt],
1897
3407
  kid: Sequence[AstNode],
1898
3408
  ) -> None:
1899
3409
  """Initialize match case node."""
@@ -1902,6 +3412,24 @@ class MatchCase(AstNode):
1902
3412
  self.body = body
1903
3413
  AstNode.__init__(self, kid=kid)
1904
3414
 
3415
+ def normalize(self, deep: bool = False) -> bool:
3416
+ """Normalize match case node."""
3417
+ res = True
3418
+ if deep:
3419
+ res = self.pattern.normalize(deep)
3420
+ res = res and self.guard.normalize(deep) if self.guard else res
3421
+ for stmt in self.body:
3422
+ res = res and stmt.normalize(deep)
3423
+ new_kid: list[AstNode] = [self.gen_token(Tok.KW_CASE), self.pattern]
3424
+ if self.guard:
3425
+ new_kid.append(self.gen_token(Tok.KW_IF))
3426
+ new_kid.append(self.guard)
3427
+ new_kid.append(self.gen_token(Tok.COLON))
3428
+ if self.body:
3429
+ new_kid.extend([*self.body])
3430
+ AstNode.__init__(self, kid=new_kid)
3431
+ return res
3432
+
1905
3433
 
1906
3434
  class MatchOr(MatchPattern):
1907
3435
  """MatchOr node type for Jac Ast."""
@@ -1915,6 +3443,20 @@ class MatchOr(MatchPattern):
1915
3443
  self.patterns = patterns
1916
3444
  AstNode.__init__(self, kid=kid)
1917
3445
 
3446
+ def normalize(self, deep: bool = False) -> bool:
3447
+ """Normalize match or node."""
3448
+ res = True
3449
+ if deep:
3450
+ for pattern in self.patterns:
3451
+ res = res and pattern.normalize(deep)
3452
+ new_kid: list[AstNode] = []
3453
+ for pattern in self.patterns:
3454
+ new_kid.append(pattern)
3455
+ new_kid.append(self.gen_token(Tok.KW_OR))
3456
+ new_kid.pop()
3457
+ AstNode.__init__(self, kid=new_kid)
3458
+ return res
3459
+
1918
3460
 
1919
3461
  class MatchAs(MatchPattern):
1920
3462
  """MatchAs node type for Jac Ast."""
@@ -1930,10 +3472,43 @@ class MatchAs(MatchPattern):
1930
3472
  self.pattern = pattern
1931
3473
  AstNode.__init__(self, kid=kid)
1932
3474
 
3475
+ def normalize(self, deep: bool = False) -> bool:
3476
+ """Normalize match as node."""
3477
+ res = True
3478
+ if deep:
3479
+ res = self.name.normalize(deep)
3480
+ res = res and self.pattern.normalize(deep) if self.pattern else res
3481
+ new_kid: list[AstNode] = []
3482
+ if self.pattern:
3483
+ new_kid.append(self.pattern)
3484
+ new_kid.append(self.gen_token(Tok.KW_AS))
3485
+ new_kid.append(self.name)
3486
+ AstNode.__init__(self, kid=new_kid)
3487
+ return res
3488
+
1933
3489
 
1934
3490
  class MatchWild(MatchPattern):
1935
3491
  """Match wild card node type for Jac Ast."""
1936
3492
 
3493
+ def normalize(self, deep: bool = False) -> bool:
3494
+ """Normalize match wild card node."""
3495
+ AstNode.__init__(
3496
+ self,
3497
+ kid=[
3498
+ Name(
3499
+ file_path=self.loc.mod_path,
3500
+ name=Tok.NAME,
3501
+ value="_",
3502
+ col_start=self.loc.col_start,
3503
+ col_end=self.loc.col_end,
3504
+ line=self.loc.first_line,
3505
+ pos_start=self.loc.pos_start,
3506
+ pos_end=self.loc.pos_end,
3507
+ )
3508
+ ],
3509
+ )
3510
+ return True
3511
+
1937
3512
 
1938
3513
  class MatchValue(MatchPattern):
1939
3514
  """MatchValue node type for Jac Ast."""
@@ -1947,6 +3522,14 @@ class MatchValue(MatchPattern):
1947
3522
  self.value = value
1948
3523
  AstNode.__init__(self, kid=kid)
1949
3524
 
3525
+ def normalize(self, deep: bool = False) -> bool:
3526
+ """Normalize match value node."""
3527
+ res = True
3528
+ if deep:
3529
+ res = self.value.normalize(deep)
3530
+ AstNode.__init__(self, kid=[self.value])
3531
+ return res
3532
+
1950
3533
 
1951
3534
  class MatchSingleton(MatchPattern):
1952
3535
  """MatchSingleton node type for Jac Ast."""
@@ -1960,6 +3543,12 @@ class MatchSingleton(MatchPattern):
1960
3543
  self.value = value
1961
3544
  AstNode.__init__(self, kid=kid)
1962
3545
 
3546
+ def normalize(self, deep: bool = False) -> bool:
3547
+ """Normalize match singleton node."""
3548
+ res = True
3549
+ AstNode.__init__(self, kid=[self.value])
3550
+ return res
3551
+
1963
3552
 
1964
3553
  class MatchSequence(MatchPattern):
1965
3554
  """MatchSequence node type for Jac Ast."""
@@ -1973,6 +3562,21 @@ class MatchSequence(MatchPattern):
1973
3562
  self.values = values
1974
3563
  AstNode.__init__(self, kid=kid)
1975
3564
 
3565
+ def normalize(self, deep: bool = False) -> bool:
3566
+ """Normalize match sequence node."""
3567
+ res = True
3568
+ if deep:
3569
+ for value in self.values:
3570
+ res = res and value.normalize(deep)
3571
+ new_kid: list[AstNode] = [self.gen_token(Tok.LSQUARE)]
3572
+ for value in self.values:
3573
+ new_kid.append(value)
3574
+ new_kid.append(self.gen_token(Tok.COMMA))
3575
+ new_kid.pop()
3576
+ new_kid.append(self.gen_token(Tok.RSQUARE))
3577
+ AstNode.__init__(self, kid=new_kid)
3578
+ return res
3579
+
1976
3580
 
1977
3581
  class MatchMapping(MatchPattern):
1978
3582
  """MatchMapping node type for Jac Ast."""
@@ -1986,6 +3590,21 @@ class MatchMapping(MatchPattern):
1986
3590
  self.values = values
1987
3591
  AstNode.__init__(self, kid=kid)
1988
3592
 
3593
+ def normalize(self, deep: bool = False) -> bool:
3594
+ """Normalize match mapping node."""
3595
+ res = True
3596
+ if deep:
3597
+ for value in self.values:
3598
+ res = res and value.normalize(deep)
3599
+ new_kid: list[AstNode] = [self.gen_token(Tok.LBRACE)]
3600
+ for value in self.values:
3601
+ new_kid.append(value)
3602
+ new_kid.append(self.gen_token(Tok.COMMA))
3603
+ new_kid.pop()
3604
+ new_kid.append(self.gen_token(Tok.RBRACE))
3605
+ AstNode.__init__(self, kid=new_kid)
3606
+ return res
3607
+
1989
3608
 
1990
3609
  class MatchKVPair(MatchPattern):
1991
3610
  """MatchKVPair node type for Jac Ast."""
@@ -2001,6 +3620,18 @@ class MatchKVPair(MatchPattern):
2001
3620
  self.value = value
2002
3621
  AstNode.__init__(self, kid=kid)
2003
3622
 
3623
+ def normalize(self, deep: bool = False) -> bool:
3624
+ """Normalize match key value pair node."""
3625
+ res = True
3626
+ if deep:
3627
+ res = (
3628
+ self.key.normalize(deep) if isinstance(self.key, MatchPattern) else True
3629
+ )
3630
+ res = res and self.value.normalize(deep)
3631
+ new_kid: list[AstNode] = [self.key, self.gen_token(Tok.COLON), self.value]
3632
+ AstNode.__init__(self, kid=new_kid)
3633
+ return res
3634
+
2004
3635
 
2005
3636
  class MatchStar(MatchPattern):
2006
3637
  """MatchStar node type for Jac Ast."""
@@ -2016,6 +3647,18 @@ class MatchStar(MatchPattern):
2016
3647
  self.is_list = is_list
2017
3648
  AstNode.__init__(self, kid=kid)
2018
3649
 
3650
+ def normalize(self, deep: bool = False) -> bool:
3651
+ """Normalize match star node."""
3652
+ res = True
3653
+ if deep:
3654
+ res = self.name.normalize(deep)
3655
+ new_kid: list[AstNode] = [
3656
+ self.gen_token(Tok.STAR_MUL if self.is_list else Tok.STAR_POW)
3657
+ ]
3658
+ new_kid.append(self.name)
3659
+ AstNode.__init__(self, kid=new_kid)
3660
+ return res
3661
+
2019
3662
 
2020
3663
  class MatchArch(MatchPattern):
2021
3664
  """MatchClass node type for Jac Ast."""
@@ -2033,6 +3676,26 @@ class MatchArch(MatchPattern):
2033
3676
  self.kw_patterns = kw_patterns
2034
3677
  AstNode.__init__(self, kid=kid)
2035
3678
 
3679
+ def normalize(self, deep: bool = False) -> bool:
3680
+ """Normalize match class node."""
3681
+ res = True
3682
+ if deep:
3683
+ res = self.name.normalize(deep)
3684
+ res = res and (not self.arg_patterns or self.arg_patterns.normalize(deep))
3685
+ res = res and (not self.kw_patterns or self.kw_patterns.normalize(deep))
3686
+ new_kid: list[AstNode] = [self.name]
3687
+ new_kid.append(self.gen_token(Tok.LPAREN))
3688
+ if self.arg_patterns:
3689
+ new_kid.append(self.arg_patterns)
3690
+ new_kid.append(self.gen_token(Tok.COMMA))
3691
+ if self.kw_patterns:
3692
+ new_kid.append(self.kw_patterns)
3693
+ else:
3694
+ new_kid.pop()
3695
+ new_kid.append(self.gen_token(Tok.RPAREN))
3696
+ AstNode.__init__(self, kid=new_kid)
3697
+ return res
3698
+
2036
3699
 
2037
3700
  # AST Terminal Node Types
2038
3701
  # --------------------------
@@ -2049,7 +3712,6 @@ class Token(AstNode):
2049
3712
  col_end: int,
2050
3713
  pos_start: int,
2051
3714
  pos_end: int,
2052
- kid: Sequence[AstNode],
2053
3715
  ) -> None:
2054
3716
  """Initialize token."""
2055
3717
  self.file_path = file_path
@@ -2060,7 +3722,15 @@ class Token(AstNode):
2060
3722
  self.c_end = col_end
2061
3723
  self.pos_start = pos_start
2062
3724
  self.pos_end = pos_end
2063
- AstNode.__init__(self, kid=kid)
3725
+ AstNode.__init__(self, kid=[])
3726
+
3727
+ def normalize(self, deep: bool = True) -> bool:
3728
+ """Normalize token."""
3729
+ return bool(self.value and self.name)
3730
+
3731
+ def unparse(self) -> str:
3732
+ """Unparse token."""
3733
+ return self.value
2064
3734
 
2065
3735
 
2066
3736
  class Name(Token, NameSpec):
@@ -2076,7 +3746,6 @@ class Name(Token, NameSpec):
2076
3746
  col_end: int,
2077
3747
  pos_start: int,
2078
3748
  pos_end: int,
2079
- kid: Sequence[AstNode],
2080
3749
  is_enum_singleton: bool = False,
2081
3750
  is_kwesc: bool = False,
2082
3751
  ) -> None:
@@ -2093,7 +3762,6 @@ class Name(Token, NameSpec):
2093
3762
  col_end=col_end,
2094
3763
  pos_start=pos_start,
2095
3764
  pos_end=pos_end,
2096
- kid=kid,
2097
3765
  )
2098
3766
  AstSymbolNode.__init__(
2099
3767
  self,
@@ -2102,6 +3770,13 @@ class Name(Token, NameSpec):
2102
3770
  sym_type=SymbolType.VAR,
2103
3771
  )
2104
3772
 
3773
+ def unparse(self) -> str:
3774
+ """Unparse name."""
3775
+ super().unparse()
3776
+ return (f"<>{self.value}" if self.is_kwesc else self.value) + (
3777
+ ",\n" if self.is_enum_singleton else ""
3778
+ )
3779
+
2105
3780
 
2106
3781
  class Literal(Token, AtomExpr):
2107
3782
  """Literal node type for Jac Ast."""
@@ -2131,7 +3806,6 @@ class Literal(Token, AtomExpr):
2131
3806
  col_end: int,
2132
3807
  pos_start: int,
2133
3808
  pos_end: int,
2134
- kid: Sequence[AstNode],
2135
3809
  ) -> None:
2136
3810
  """Initialize token."""
2137
3811
  Token.__init__(
@@ -2144,7 +3818,6 @@ class Literal(Token, AtomExpr):
2144
3818
  col_end=col_end,
2145
3819
  pos_start=pos_start,
2146
3820
  pos_end=pos_end,
2147
- kid=kid,
2148
3821
  )
2149
3822
  AstSymbolNode.__init__(
2150
3823
  self,
@@ -2176,7 +3849,6 @@ class TokenSymbol(Token, AstSymbolNode):
2176
3849
  col_end: int,
2177
3850
  pos_start: int,
2178
3851
  pos_end: int,
2179
- kid: Sequence[AstNode],
2180
3852
  ) -> None:
2181
3853
  """Initialize token."""
2182
3854
  Token.__init__(
@@ -2189,7 +3861,6 @@ class TokenSymbol(Token, AstSymbolNode):
2189
3861
  col_end=col_end,
2190
3862
  pos_start=pos_start,
2191
3863
  pos_end=pos_end,
2192
- kid=kid,
2193
3864
  )
2194
3865
  AstSymbolNode.__init__(
2195
3866
  self,
@@ -2257,6 +3928,15 @@ class String(Literal):
2257
3928
  ret_str = ret_str.encode().decode("unicode_escape")
2258
3929
  return ret_str
2259
3930
 
3931
+ def normalize(self, deep: bool = True) -> bool:
3932
+ """Normalize string."""
3933
+ return True
3934
+
3935
+ def unparse(self) -> str:
3936
+ """Unparse string."""
3937
+ super().unparse()
3938
+ return repr(self.value)
3939
+
2260
3940
 
2261
3941
  class Bool(Literal):
2262
3942
  """Bool node type for Jac Ast."""
@@ -2305,7 +3985,6 @@ class EmptyToken(Token):
2305
3985
  col_end=0,
2306
3986
  pos_start=0,
2307
3987
  pos_end=0,
2308
- kid=[],
2309
3988
  )
2310
3989
 
2311
3990