summaryrefslogblamecommitdiff
path: root/test/files/run/regularpatmat.scala
blob: 129e325abc405ee8873ec5c30d50322342e13b5f (plain) (tree)
1
2
3
4

                                                  
                              
 











                                                                 





















                                                               
                           


































                                                                                   


                     




































                                                                      
                                                                            



















                                                                      
                                                                                        
 
                                                                    




















































































                                                                       
                                                           



















                                                                  
                                                                         
                                                                        
                                                          






























                                                                  
                                                            

                                            
                                                             

                                                   
                                                                      











































































































































































































































































































                                                                                  




                                              
                                                    



                                             




                                                         

                  
                                                    


                                                             
 









                                                   







                           
                   
                                                                              




                                                                               
                                                              





                                                                                   




                                                                            
 




      



















                                                               











                                         
                
                


      
// Burak's test suite for regular pattern matching

// contains 17 visitors plus X

// analyzer related (no execution)
object bug179 {
  case class One();
  object Foo with Executable {
    def test(xs: List[Any]) = xs match {
      case List(((((One(), One())*) | (One(), One())), One())) =>
	Console.println("case")
      case _ =>
	Console.println("default");
    }
  }
}
// testW? are for recognition only ( no variables )
// testB? are for variables binding

object values  { // test values reused in nearly all test cases

    val s0:List[Char] = Nil ;
    val s1:List[Char] = 'a'::'b'::'c'::Nil ;
    val s2:List[Char] = 'a'::'b'::'c'::s1 ;
    val s3:List[Char] = 'a'::'a'::'a'::Nil ;
    val s4:List[Char] = 'b'::'c'::Nil ;
    val s5:List[Char] = 'b'::Nil ;
    val s6:List[Char] = 'b'::'a'::'a'::'a'::Nil ;

    val s7:List[Int]  = 1::2::7::Nil ;
    val s8:List[Int]  = 1::0::1::0::Nil;
    val s9:List[Int]  = Nil ;

    val s10:List[Char] = '7'::'0'::'1'::'.'::'2'::'4'::Nil ;


}

// matching without binding

// 2do            case [ 'a'; x; y ]   => 100
//                case [ z @ ('a'; x; y) ]   => 100
// 2do             case [ 'a'*; x @ ( _;('a'; 'b')* ); y @ 'b'* ]   => 100
//                case _               => 321 // 20022 // this never happens

object testBK  {

        import values._ ;

        import scala.testing.UnitTest._ ;

    def doit1(e: List[Char]):Int = e.match {

                case List( 'a'*, x @ ( 'a',('a', 'b')* ), y @ ('b'*) )   => { 100 }

                case List( _ * )         => 321
        };

    def test1:Unit = {
                System.out.println("testBK");
                test[List[Char],Int]( doit1, s0, 321);
                test[List[Char],Int]( doit1, s1, 321);
                test[List[Char],Int]( doit1, s2, 321);
                test[List[Char],Int]( doit1, s3, 100);
                test[List[Char],Int]( doit1, s4, 321);
                test[List[Char],Int]( doit1, s5, 321);
                test[List[Char],Int]( doit1, s6, 321)
    };

    def main( args:Array[ String ] ) = {
         test1;
    }

}

// tests with binding

object testBL {

  import scala.testing.UnitTest._ ;

  def preTest(a:String,b:String):boolean = (a==b);

  def doit( x:List[String] ):String = x.match {

    case List( z @ "John" ) => z

  }

        // BEWARE: main type should be specified...
        // often, last thing is not () then you have a problem

  def main(args:Array[String]):Unit = {

       val a = "John";
       val b = "John";

        test2[String,String,boolean](preTest,a,b,true);
        test[List[String],String]( doit, List( b ), "John" )


  }
}
object testBM  {

    import scala.testing.UnitTest._ ;
    import values._ ;

    def doit1(e: List[Char]):List[Char] = e.match {

                case List( 'a'*, x @ ( 'a',('a', 'b')* ), y @ ('b'*) )

                        => { x }

                case List( 'a'*, x @ (('a', 'b')*) , y @ (('a','b','c') *) )

                        => { y }

                case List( _ * )

                        => Nil
        };

    def test1:Unit = {
                System.out.println("testBM");
                test[List[Char],List[Char]]( doit1, s0, Nil);
                test[List[Char],List[Char]]( doit1, s1, s1);
                test[List[Char],List[Char]]( doit1, s2, s2);

                test[List[Char],List[Char]]( doit1, s3, List('a'));
                test[List[Char],List[Char]]( doit1, s4, Nil);
                test[List[Char],List[Char]]( doit1, s5, Nil);
                test[List[Char],List[Char]]( doit1, s6, Nil);

                val t7:List[Char] = 'a'::'a'::'a'::'b'::'b'::'b'::Nil;
                //val t7ex:List[Char] = 'a'::'a'::'b'::Nil; // with longest match policy

                test[List[Char],List[Char]]( doit1, t7, List('a') );
                ()
    };

    def main( args:Array[ String ] ) = {
         test1;
    }

}
object testBN {

    import scala.testing.UnitTest._ ;
    import values._ ;

        class testClass;

        case class testA( arg:List[Char] ) extends testClass;

    def doit1(e: testClass):List[Char] = e.match {
                case testA(List( 'a', x, y ))   => x::y::Nil
                case _                      => Nil
        };

    def test1:Unit = {
                System.out.print("BN preTest: ");
                System.out.println( Nil == Nil );
                System.out.println("testBN");

                test[testClass,List[Char]]
                        ( doit1, testA(s0), Nil);

                test[testClass,List[Char]]
                        ( doit1, testA(s1), 'b'::'c'::Nil);

                test[testClass,List[Char]]
                        ( doit1, testA(s2), Nil);

                test[testClass,List[Char]]
                        ( doit1, testA(s3), 'a'::'a'::Nil);

                test[testClass,List[Char]]
                        ( doit1, testA(s4), Nil);

                test[testClass,List[Char]]
                        ( doit1, testA(s5), Nil);

                test[testClass,List[Char]]
                        ( doit1, testA(s6), Nil);

    };


    def main( args:Array[String] ) = {

                test1

    }

}

object testBO  {

        // example suggested by Matthias
        import scala.testing.UnitTest._ ;


        case class Person( firstname:String, lastname:String );

        def onlyJohn( db:List[ Person ] ):List[ String ] = {

           db.match {

                case List( Person( "John", lastname  ) )

                        => lastname::Nil

                case _
                        => Nil

           }

        }

        /** first longest match policy -> the star is greedy/hungry/...
         */

        def searchFirstJohn( db:List[ Person ] ):String = {

           db.match {

                case List( _ *, Person( "John", lastname  ), _ * )
                        => lastname

                case _
                        => "<not found>"

           }

        }

        /** first longest match policy -> star is a greedy/hungry
         */

        def searchJohns( db:List[Person]):List[String] = {

           db.match {

                case List( _ *, Person( "John", lastname  ), rest@(_ *) )
                        => { //System.out.print("before is : "+before );
                             lastname::searchJohns( rest )
                                }

                case _
                        => Nil

           }

        }

        def main( args:Array[String] ) = {

                val p1 = Person("Albert",  "Camus");
                val p2 = Person("Henry",   "Miller");
                val p3 = Person("John",    "Le Carre");
                val p4 = Person("Herbert", "Franke");
                val p5 = Person("John",    "Smith");
                val p6 = Person("William", "Gibson");

                val db:List[Person] = p1::p2::p3::p4::p5::p6::Nil;

                val db2:List[Person] = p3::Nil;

                System.out.println("testBO");

                test[ List[Person], List[ String ]]
                        ( onlyJohn, db, Nil );

                test[ List[Person], List[ String ]]
                        ( onlyJohn, db2, "Le Carre"::Nil );

                test[ List[Person], String ]
                        ( searchFirstJohn, db, "Le Carre" );

                test[ List[Person], String ]
                        ( searchFirstJohn, db2, "Le Carre" );

                test[ List[Person], List[ String ]]
                        ( searchJohns, db, "Le Carre"::"Smith"::Nil );

                test[ List[Person], List[ String ]]
                        ( searchJohns, db2, "Le Carre"::Nil );

        }

}
object testWR  {

        import values._ ;

        import scala.testing.UnitTest._ ;

    def doit1(e: List[Char]):Int = e.match {
                case List( 'a', 'b', 'c' ) => 100
                case _                     => 321
        };

    def test1:Unit = {
                System.out.println("testWR_1");
                test[List[Char],Int]( doit1, s0, 321);
                test[List[Char],Int]( doit1, s1, 100);
                test[List[Char],Int]( doit1, s2, 321);
                test[List[Char],Int]( doit1, s3, 321);
                test[List[Char],Int]( doit1, s4, 321);
                test[List[Char],Int]( doit1, s5, 321);
                test[List[Char],Int]( doit1, s6, 321)
    };

    def doit2(e: List[Char]):Int = e.match {
                case List( ('a', 'b','c')? ) => 1000
                case _                       => 321
	}

    def test2:Unit = {
                System.out.println("testWR_2");
                test[List[Char],Int]( doit2, s0, 1000);
                test[List[Char],Int]( doit2, s1, 1000);
                test[List[Char],Int]( doit2, s2, 321);
                test[List[Char],Int]( doit2, s3, 321);
                test[List[Char],Int]( doit2, s4, 321);
                test[List[Char],Int]( doit2, s5, 321);
                test[List[Char],Int]( doit2, s6, 321);
    }


    def doit3(e: List[Char]):String = e.match {
                case List( ('a', 'a','a')? ) => "ok"
                case _                   => "fail"
	}

    def test3:Unit = {
                System.out.println("testWR_3");
                test[List[Char],String]( doit3, s0, "ok");
                test[List[Char],String]( doit3, s1, "fail");
                test[List[Char],String]( doit3, s2, "fail");
                test[List[Char],String]( doit3, s3, "ok");
                test[List[Char],String]( doit3, s4, "fail");
                test[List[Char],String]( doit3, s5, "fail");
                test[List[Char],String]( doit3, s6, "fail");
    }

    def doit4(e: List[Char]):String = e.match {
                case List( ('a'|'b')*,('a'|'b'|'c')+ ) => "ga!!!!"
                case _                             => "gu"
	}

    def test4:Unit = {
                System.out.println("testWR_4");
                test[List[Char],String]( doit4, s0, "gu");
                test[List[Char],String]( doit4, s1, "ga!!!!");
                test[List[Char],String]( doit4, s2, "ga!!!!");
                test[List[Char],String]( doit4, s3, "ga!!!!");
                test[List[Char],String]( doit4, s4, "ga!!!!");
                test[List[Char],String]( doit4, s5, "ga!!!!");
                test[List[Char],String]( doit4, s6, "ga!!!!");
    }

    def doit5(e: List[Int]):String = e.match {
                case List( (0|1)+ )               => "binary"
                case _                        => "not binary"
	}

    def test5:Unit = {
                System.out.println("testWR_5");
                test[List[Int],String]( doit5, s7, "not binary");
                test[List[Int],String]( doit5, s8, "binary");
                test[List[Int],String]( doit5, s9, "not binary");
    }

    //  { ('0'..'9')*;'.';('0'..'9');('0'..'9')* ]
    def doit6(e: List[Char]):String = e.match {
                case List( ('0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9')*,
                       '.',
                       ('0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'),
                       ('0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9')* )

                                              => "decimal number"
                case _                        => "not decimal"
	}

    def test6:Unit = {
                System.out.println("testWR_6");
                test[List[Char],String]( doit6, s3, "not decimal");
                test[List[Char],String]( doit6, s10, "decimal number");
    }

    def main( args:Array[String] ) = {
        test1;
        test2;
        test3;
        test4;
        test5;
        test6
    }



}
object testWS {

        import values._ ;

        import scala.testing.UnitTest._ ;

        /* strings:

            "blabla" == [ "bla";"bla" ] == [ 'b';'l';'a';'b';'l';'a' ]

            [ "blabla";'x';'y'? ] == [ ('b';'l';'a';'b';'l';'a'); 'x'; 'y'? ]

        */

        /*
            def isIdentifierStart(c:char) ;

            case [ ... ; _isIdentifierStart_ ; ... ]

            calls method is..., needs to have type (elementType)Boolean

            translated to pattern

                 [ ... ; Apply(is..., Tree.Empty) ; ... ]

         */

         /* for tree automata:

        [ t0; t1; ...; tn ]  with ti = labeli ( argsi )

        gets translated to

        [ _isTree$0_ ; _isTree$1_ ; ... ; _isTree$n_ ]

        where isTree$i( t ) = t.is[ labeli ] ... (algebraic matcher)

        special case: sequences

        [ ...; seq ; ... ] where seq = [ ... ]

        gets translated to

        [ ...; _seq$0_ ; ...] with seq$0( s ) = t.is[ Sequence ] and
                                                seq$0match( s.newIterator )

        subroutines return
          1) d'abord true or false,
          2) later ( true|false, environment )
                       assume order on variables, enviroment is a tuple/sequence
        */

    def doit1(e: List[Char]):Int = e.match {
                case List( 'a', 'b', 'c' )        => 100
                case List( ('a', 'b','c')? )      => 1004
                case List( ('a', 'a','a')? )      => 50
                case List( ('a'|'b')*,('a'|'b') ) => 700
                case _                        => 321
        };

    def test1:Unit = {
                System.out.println("testWS");
                test[List[Char],Int]( doit1, s0, 1004);
                test[List[Char],Int]( doit1, s1, 100);
                test[List[Char],Int]( doit1, s2, 321);
                test[List[Char],Int]( doit1, s3, 50);
                test[List[Char],Int]( doit1, s4, 321);
                test[List[Char],Int]( doit1, s5, 700);
                test[List[Char],Int]( doit1, s6, 700);
    };

    def main( args:Array[String] ) = {
        test1;
    }



}
object testWT  {

        import values._ ;

        import scala.testing.UnitTest._ ;

    def doit1(e: List[Char]):Int = e.match {
                case List( 'a', _, _ )   => 100
                case List( _ * )         => 321
                case _               => 20022 // this never happens
        };

    def test1:Unit = {
                System.out.println("testWT");
                test[List[Char],Int]( doit1, s0, 321);
                test[List[Char],Int]( doit1, s1, 100);
                test[List[Char],Int]( doit1, s2, 321);
                test[List[Char],Int]( doit1, s3, 100);
                test[List[Char],Int]( doit1, s4, 321);
                test[List[Char],Int]( doit1, s5, 321);
                test[List[Char],Int]( doit1, s6, 321)
    };

    def main( args:Array[ String ] ) = {
         test1;
    }

}
object testWV {

        import values._ ;

        import scala.testing.UnitTest._ ;

        class testClass;

        case class testA( arg:List[Char] ) extends testClass;

    def doit1( e: testClass ):Int = e.match {

                case testA( List( 'a', 'b', 'c' ))        => 100
                case testA( List( ('a', 'b','c')? ))      => 1004
                case testA( List( ('a', 'a','a')? ))      => 50
                case testA( List( ('a'|'b')*,('a'|'b') )) => 700
                case testA( _ )                        => 321

        };

    def test1:Unit = {
                System.out.println("testWV");
                test[testClass,Int]( doit1, testA(s0), 1004);
                test[testClass,Int]( doit1, testA(s1), 100);
                test[testClass,Int]( doit1, testA(s2), 321);
                test[testClass,Int]( doit1, testA(s3), 50);
                test[testClass,Int]( doit1, testA(s4), 321);
                test[testClass,Int]( doit1, testA(s5), 700);
                test[testClass,Int]( doit1, testA(s6), 700);
    };


    def main( args:Array[String] ) = {

                test1

    }

}

object testWW {

        import values._ ;

        import scala.testing.UnitTest._ ;

        class testClass;
        case class testA( arg:List[Char] ) extends testClass;

        def doit1(e: List[testClass]):Int = e.match {

                case List( testA(List()), testA( List( 'a', 'b' )) )        => 100
                case _                                                      => 321

        };

        def test1:Unit = {
                val x1 = List( testA(s0) );

                System.out.println("testWW");

                test[List[testClass],Int]( doit1, x1, 321 );

                val x2 = List( testA(Nil), testA('a'::'b'::Nil) );

                test[List[testClass],Int]( doit1, x2, 100 );

        }

        def main( args:Array[String] ) = {
                test1;
        }

}

object testMZ {
        import scala.testing.UnitTest.test ;
  class Expr;
  case class One(xs: List[Expr]) extends Expr;
  case class Two() extends Expr;
  def testFoo(xs: List[Expr]) = xs match { //bug#132
    case List(Two()?,a,Two()?) => "a = " + a;
    case List(Two()*,b,Two()*) => "b = " + b;
    case List(_*) => "no match";
  }
  case class OneN();
  def bind(xs: List[Any]):String = xs match { // bug#133b
    case List(x@(OneN()*), y@(OneN())) => "case";
    case _ => "default";
  }
  case class On();
  case class Tw();
  def testBar(xs: List[Any]) = xs match { // bug#180
    case List(((On(), Tw())* | (On(), On())), On()) => "case"
    case _ => "default";
  }


  def mat195(x:Expr) = x match { // bug#195
    case One(x@List(_*)) =>
    	"x = " + x;

	case _ =>"default";

  }

  def mat196(xs: List[Any]) = xs match { // bug#196
    case List(b@(()|())) =>
    	"case, b = " + b;

	case _ =>"default";

  }


  def main:Unit = {
                System.out.println("testMZ - bugs #132 #133b #180 #195 #196");
    test[List[Expr],String](testFoo, List(Two(),Two(),Two(),Two()), "b = Two");
    test[List[Expr],String](testFoo, List(Two(),Two(),Two()), "a = Two");
    test[List[Expr],String](testFoo, List(Two(),Two()), "a = Two");
    test[List[Expr],String](testFoo, List(Two()), "a = Two");
    test[List[Expr],String](testFoo, List(), "no match");
    test[List[Any],String](bind, List(OneN(),OneN()), "case");
    test[List[Any],String](testBar, List(), "default");
    test[List[Any],String](testBar, List(On()), "case");
    test[List[Any],String](testBar, List(On(), On()), "default");
    test[List[Any],String](testBar, List(On(), On(), On()), "case");
    test[List[Any],String](testBar, List(On(), On(), On(), On()), "default");
    test[List[Any],String](testBar, List(On(), On(), On(), On(), On()), "default");
    test[Expr, String](mat195, One(List(Two(),Two())), "x = List(Two,Two)");
    test[Expr, String](mat195, One(List()), "x = List()");
    test[Expr, String](mat195, Two(), "default");
    test[List[Any], String](mat196, List(1), "default");
    test[List[Any], String](mat196, List(), "case, b = List()");

    ()
  }

}

object testNN {
 import scala.testing.UnitTest._ ;
  abstract class K;
  case class F(x:K*) extends K;
  case class G() extends K;

  def mtch(k:K):boolean = k.match {
      case F(F(G()*),G(),F(G()*)) => true;
      case _ => false;
  }

  def main:Unit = {
                System.out.println("testNN");
    test[K,boolean](mtch, F(F(G()),G(),F(G())), true);
    test[K,boolean](mtch, F(F(),G(),F(G(),G(),G(),G())), true);
    test[K,boolean](mtch, G(), false);
    test[K,boolean](mtch, F(G()), false);
  }
}

object Test {
  def main(args: Array[String]): Unit = {
    testWR.main( args );
    testWS.main( args );
    testWT.main( args );
    testWV.main( args );
    testWW.main( args );
    testBK.main( args );
    testBL.main( args );
    testBM.main( args );
    testBN.main( args );
    testBO.main( args );
    testMZ.main;
    testNN.main;
    ()
  }
}