private static void ParenthesizedVisit(this ICSharpPrintingVisitor visitor, CSharpPattern parent, CSharpPattern nodeToVisit)
 {
     if (nodeToVisit.GetPrecedence() < parent.GetPrecedence())
     {
         visitor.Out("(");
         visitor.Visit(nodeToVisit);
         visitor.Out(")");
     }
     else
     {
         visitor.Visit(nodeToVisit);
     }
 }
        public static void Visit(this ICSharpPrintingVisitor visitor, CSharpPattern pattern)
        {
            switch (pattern.PatternType)
            {
            case CSharpPatternType.Constant:
                visitor.Visit((ConstantCSharpPattern)pattern);
                break;

            case CSharpPatternType.Discard:
                visitor.Out("_");
                break;

            case CSharpPatternType.Type:
                visitor.Visit((TypeCSharpPattern)pattern);
                break;

            case CSharpPatternType.And:
            case CSharpPatternType.Or:
                visitor.Visit((BinaryCSharpPattern)pattern);
                break;

            case CSharpPatternType.Not:
                visitor.Visit((NotCSharpPattern)pattern);
                break;

            case CSharpPatternType.LessThan:
            case CSharpPatternType.LessThanOrEqual:
            case CSharpPatternType.GreaterThan:
            case CSharpPatternType.GreaterThanOrEqual:
                visitor.Visit((RelationalCSharpPattern)pattern);
                break;

            case CSharpPatternType.Declaration:
                visitor.Visit((DeclarationCSharpPattern)pattern);
                break;

            case CSharpPatternType.Var:
                visitor.Visit((VarCSharpPattern)pattern);
                break;

            case CSharpPatternType.Recursive:
                visitor.Visit((RecursiveCSharpPattern)pattern);
                break;

            case CSharpPatternType.ITuple:
                visitor.Visit((ITupleCSharpPattern)pattern);
                break;

            case CSharpPatternType.List:
                visitor.Visit((ListCSharpPattern)pattern);
                break;

            case CSharpPatternType.Slice:
                visitor.Visit((SliceCSharpPattern)pattern);
                break;

            default:
                break;
            }
        }
        private static void Visit(this ICSharpPrintingVisitor visitor, BinaryCSharpPattern pattern)
        {
            var op = pattern.PatternType switch
            {
                CSharpPatternType.And => " and ",
                CSharpPatternType.Or => " or ",
                _ => throw ContractUtils.Unreachable,
            };

            visitor.ParenthesizedVisit(pattern, pattern.Left);
            visitor.Out(op);
            visitor.ParenthesizedVisit(pattern, pattern.Right);
        }
 private static void Visit(this ICSharpPrintingVisitor visitor, NotCSharpPattern pattern)
 {
     visitor.Out("not ");
     visitor.ParenthesizedVisit(pattern, pattern.Negated);
 }