bpo-42128: Structural Pattern Matching (PEP 634) (GH-22917)

Co-authored-by: Guido van Rossum <guido@python.org>
Co-authored-by: Talin <viridia@gmail.com>
Co-authored-by: Pablo Galindo <pablogsal@gmail.com>
diff --git a/Lib/ast.py b/Lib/ast.py
index 845c80c..03ae2ec 100644
--- a/Lib/ast.py
+++ b/Lib/ast.py
@@ -1478,6 +1478,13 @@ def visit_Slice(self, node):
             self.write(":")
             self.traverse(node.step)
 
+    def visit_Match(self, node):
+        self.fill("match ")
+        self.traverse(node.subject)
+        with self.block():
+            for case in node.cases:
+                self.traverse(case)
+
     def visit_arg(self, node):
         self.write(node.arg)
         if node.annotation:
@@ -1562,6 +1569,26 @@ def visit_withitem(self, node):
             self.write(" as ")
             self.traverse(node.optional_vars)
 
+    def visit_match_case(self, node):
+        self.fill("case ")
+        self.traverse(node.pattern)
+        if node.guard:
+            self.write(" if ")
+            self.traverse(node.guard)
+        with self.block():
+            self.traverse(node.body)
+
+    def visit_MatchAs(self, node):
+        with self.require_parens(_Precedence.TEST, node):
+            self.set_precedence(_Precedence.BOR, node.pattern)
+            self.traverse(node.pattern)
+            self.write(f" as {node.name}")
+
+    def visit_MatchOr(self, node):
+        with self.require_parens(_Precedence.BOR, node):
+            self.set_precedence(_Precedence.BOR.next(), *node.patterns)
+            self.interleave(lambda: self.write(" | "), self.traverse, node.patterns)
+
 def unparse(ast_obj):
     unparser = _Unparser()
     return unparser.visit(ast_obj)