aboutsummaryrefslogtreecommitdiff
path: root/tests/run
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2015-06-25 09:45:27 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2015-07-13 15:31:16 +0200
commitef536f00d9d480f28db3093b9dc09a90041cfb74 (patch)
treeca82afa7a37ce866978b0b66904941672f2dacc3 /tests/run
parent9185428b63b138f8c05ade5592e59956296b5128 (diff)
downloaddotty-ef536f00d9d480f28db3093b9dc09a90041cfb74.tar.gz
dotty-ef536f00d9d480f28db3093b9dc09a90041cfb74.tar.bz2
dotty-ef536f00d9d480f28db3093b9dc09a90041cfb74.zip
Enable 61 tests that succeed.
Diffstat (limited to 'tests/run')
-rw-r--r--tests/run/Course-2002-02.check187
-rw-r--r--tests/run/Course-2002-02.scala551
-rw-r--r--tests/run/Course-2002-07.check137
-rw-r--r--tests/run/Course-2002-07.scala722
-rw-r--r--tests/run/Course-2002-13.check14
-rw-r--r--tests/run/Course-2002-13.scala322
-rw-r--r--tests/run/WeakHashSetTest.scala174
-rw-r--r--tests/run/bytecodecs.scala39
-rw-r--r--tests/run/caseclasses.check3
-rw-r--r--tests/run/caseclasses.scala51
-rw-r--r--tests/run/dead-code-elimination.flags1
-rw-r--r--tests/run/dead-code-elimination.scala33
-rw-r--r--tests/run/exceptions-2.check59
-rw-r--r--tests/run/exceptions-2.scala349
-rw-r--r--tests/run/exceptions.check1
-rw-r--r--tests/run/exceptions.scala52
-rw-r--r--tests/run/hashCodeDistribution.scala17
-rw-r--r--tests/run/matcharraytail.check2
-rw-r--r--tests/run/matcharraytail.scala7
-rw-r--r--tests/run/matchonstream.check1
-rw-r--r--tests/run/matchonstream.scala3
-rw-r--r--tests/run/mixin-bridge-methods.scala14
-rw-r--r--tests/run/null-and-intersect.check9
-rw-r--r--tests/run/null-and-intersect.scala34
-rw-r--r--tests/run/option-fold.check5
-rw-r--r--tests/run/option-fold.scala20
-rw-r--r--tests/run/proxy.check6
-rw-r--r--tests/run/proxy.scala17
-rw-r--r--tests/run/range.scala83
-rw-r--r--tests/run/t0325.check35
-rw-r--r--tests/run/t0325.scala53
-rw-r--r--tests/run/t0631.check3
-rw-r--r--tests/run/t0631.scala16
-rw-r--r--tests/run/t1333.check3
-rw-r--r--tests/run/t1333.scala14
-rw-r--r--tests/run/t1697.scala19
-rw-r--r--tests/run/t1909b.scala9
-rw-r--r--tests/run/t2074_2.check3
-rw-r--r--tests/run/t2074_2.scala22
-rw-r--r--tests/run/t2175.scala20
-rw-r--r--tests/run/t2316_run.scala32
-rw-r--r--tests/run/t2417.check12
-rw-r--r--tests/run/t2417.scala77
-rw-r--r--tests/run/t2544.check10
-rw-r--r--tests/run/t2544.scala25
-rw-r--r--tests/run/t2788.check1
-rw-r--r--tests/run/t2788.scala3
-rw-r--r--tests/run/t3038d.flags1
-rw-r--r--tests/run/t3038d.scala58
-rw-r--r--tests/run/t3580.scala17
-rw-r--r--tests/run/t3613.scala22
-rw-r--r--tests/run/t3714.scala33
-rw-r--r--tests/run/t3832.scala17
-rw-r--r--tests/run/t3984.scala52
-rw-r--r--tests/run/t4415.scala86
-rw-r--r--tests/run/t4482.check1
-rw-r--r--tests/run/t4482.scala15
-rw-r--r--tests/run/t4753.check1
-rw-r--r--tests/run/t4753.scala12
-rw-r--r--tests/run/t4859.check8
-rw-r--r--tests/run/t4859.scala29
-rw-r--r--tests/run/t4871.check2
-rw-r--r--tests/run/t4871.scala12
-rw-r--r--tests/run/t5158.check1
-rw-r--r--tests/run/t5158.scala17
-rw-r--r--tests/run/t5293-map.scala88
-rw-r--r--tests/run/t5293.scala83
-rw-r--r--tests/run/t5407.check2
-rw-r--r--tests/run/t5407.scala17
-rw-r--r--tests/run/t6070.check1
-rw-r--r--tests/run/t6070.scala36
-rw-r--r--tests/run/t6198.scala24
-rw-r--r--tests/run/t6206.check4
-rw-r--r--tests/run/t6206.scala37
-rw-r--r--tests/run/t6253a.scala64
-rw-r--r--tests/run/t6253b.scala62
-rw-r--r--tests/run/t6253c.scala63
-rw-r--r--tests/run/t6337a.scala16
-rw-r--r--tests/run/t6385.scala13
-rw-r--r--tests/run/t6628.check2
-rw-r--r--tests/run/t6628.scala11
-rw-r--r--tests/run/t6793.scala9
-rw-r--r--tests/run/t7200.scala34
-rw-r--r--tests/run/t7214.scala57
-rw-r--r--tests/run/t7571.scala12
-rw-r--r--tests/run/t8177f.scala20
-rw-r--r--tests/run/t8197.scala16
-rw-r--r--tests/run/try-catch-unify.check4
-rw-r--r--tests/run/try-catch-unify.scala16
-rw-r--r--tests/run/unapplyArray.scala31
-rw-r--r--tests/run/verify-ctor.check1
-rw-r--r--tests/run/verify-ctor.scala13
-rw-r--r--tests/run/virtpatmat_try.check2
-rw-r--r--tests/run/virtpatmat_try.flags1
-rw-r--r--tests/run/virtpatmat_try.scala47
95 files changed, 4440 insertions, 0 deletions
diff --git a/tests/run/Course-2002-02.check b/tests/run/Course-2002-02.check
new file mode 100644
index 000000000..7d9695071
--- /dev/null
+++ b/tests/run/Course-2002-02.check
@@ -0,0 +1,187 @@
+7
+120
+
+10.0
+100.0
+2.083333333333333
+3025.7687714031754
+pi = 3.1659792728432152
+
+10.0
+100.0
+2.083333333333333
+3025.7687714031754
+pi = 3.1659792728432152
+
+10.0
+100.0
+2.083333333333333
+3025.7687714031754
+pi = 3.1659792728432152
+
+10.0
+100.0
+2.083333333333333
+3025.7687714031754
+pi = 3.1659792728432152
+
+10.0
+100.0
+2.083333333333333
+3025.7687714031754
+pi = 3.1659792728432152
+
+10.0
+100.0
+2.083333333333333
+3025.7687714031754
+pi = 3.1659792728432152
+
+10.0
+100.0
+2.083333333333333
+3025.7687714031754
+pi = 3.1659792728432152
+
+pi = 3.181104885577714
+pi = 3.181104885577714
+
+10.0
+100.0
+2.083333333333333
+3025.7687714031754
+pi = 3.1659792728432152
+pi = 3.181104885577714
+pi = 3.181104885577714
+
+1.5
+1.4166666666666665
+1.4142156862745097
+1.4142135623746899
+sqrt(2) = 1.4142135623746899
+
+1.5
+1.4166666666666665
+1.4142156862745097
+1.4142135623746899
+sqrt(2) = 1.4142135623746899
+
+1 + 2 + .. + 5 = 15.0
+1 * 2 * .. * 5 = 120.0
+
+1^2 + 2^2 + .. + 5^2 = 55.0
+1^2 * 2^2 * .. * 5^2 = 14400.0
+
+factorial(0) = 1.0
+factorial(1) = 1.0
+factorial(2) = 2.0
+factorial(3) = 6.0
+factorial(4) = 24.0
+factorial(5) = 120.0
+
+1 + 2 + .. + 5 = 15.0
+1 * 2 * .. * 5 = 120.0
+
+1^2 + 2^2 + .. + 5^2 = 55.0
+1^2 * 2^2 * .. * 5^2 = 14400.0
+
+factorial(0) = 1.0
+factorial(1) = 1.0
+factorial(2) = 2.0
+factorial(3) = 6.0
+factorial(4) = 24.0
+factorial(5) = 120.0
+
+1 + 2 + .. + 5 = 15.0
+1 * 2 * .. * 5 = 120.0
+
+1^2 + 2^2 + .. + 5^2 = 55.0
+1^2 * 2^2 * .. * 5^2 = 14400.0
+
+factorial(0) = 1.0
+factorial(1) = 1.0
+factorial(2) = 2.0
+factorial(3) = 6.0
+factorial(4) = 24.0
+factorial(5) = 120.0
+
+fib(0) = 0
+fib(1) = 1
+fib(2) = 1
+fib(3) = 2
+fib(4) = 3
+fib(5) = 5
+fib(6) = 8
+fib(7) = 13
+fib(8) = 21
+fib(9) = 34
+fib(0) = 0
+fib(1) = 1
+fib(2) = 1
+fib(3) = 2
+fib(4) = 3
+fib(5) = 5
+fib(6) = 8
+fib(7) = 13
+fib(8) = 21
+fib(9) = 34
+power(0,0) = 1.0
+power(0,1) = 0.0
+power(0,2) = 0.0
+power(0,3) = 0.0
+power(0,4) = 0.0
+power(0,5) = 0.0
+power(0,6) = 0.0
+power(0,7) = 0.0
+power(0,8) = 0.0
+
+power(1,0) = 1.0
+power(1,1) = 1.0
+power(1,2) = 1.0
+power(1,3) = 1.0
+power(1,4) = 1.0
+power(1,5) = 1.0
+power(1,6) = 1.0
+power(1,7) = 1.0
+power(1,8) = 1.0
+
+power(2,0) = 1.0
+power(2,1) = 2.0
+power(2,2) = 4.0
+power(2,3) = 8.0
+power(2,4) = 16.0
+power(2,5) = 32.0
+power(2,6) = 64.0
+power(2,7) = 128.0
+power(2,8) = 256.0
+
+power(3,0) = 1.0
+power(3,1) = 3.0
+power(3,2) = 9.0
+power(3,3) = 27.0
+power(3,4) = 81.0
+power(3,5) = 243.0
+power(3,6) = 729.0
+power(3,7) = 2187.0
+power(3,8) = 6561.0
+
+power(4,0) = 1.0
+power(4,1) = 4.0
+power(4,2) = 16.0
+power(4,3) = 64.0
+power(4,4) = 256.0
+power(4,5) = 1024.0
+power(4,6) = 4096.0
+power(4,7) = 16384.0
+power(4,8) = 65536.0
+
+power(5,0) = 1.0
+power(5,1) = 5.0
+power(5,2) = 25.0
+power(5,3) = 125.0
+power(5,4) = 625.0
+power(5,5) = 3125.0
+power(5,6) = 15625.0
+power(5,7) = 78125.0
+power(5,8) = 390625.0
+
diff --git a/tests/run/Course-2002-02.scala b/tests/run/Course-2002-02.scala
new file mode 100644
index 000000000..b8650108e
--- /dev/null
+++ b/tests/run/Course-2002-02.scala
@@ -0,0 +1,551 @@
+//############################################################################
+// Programmation IV - 2002 - Week 02
+//############################################################################
+
+object M0 {
+ def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
+ def factorial(n: Int): Int = if (n == 0) 1 else n * factorial(n - 1)
+
+ Console.println(gcd(14,21))
+ Console.println(factorial(5))
+ Console.println
+}
+
+//############################################################################
+
+object M1 {
+ def cube(x: Int): Double = x * x * x
+
+ def sumInts(a: Int, b: Int): Double = if (a > b) 0
+ else a + sumInts(a + 1, b);
+
+ def sumCubes(a: Int, b: Int): Double = if (a > b) 0
+ else cube(a) + sumCubes(a + 1, b);
+
+ def sumReciprocals(a: Int, b: Int): Double = if (a > b) 0
+ else 1.0/a + sumReciprocals(a + 1, b);
+
+ def sumPi(n: Int): Double = {
+ def element(x: Int): Double = 4.0/(4*x+1) - 4.0/(4*x-1);
+ def sumElements(a: Int, b: Int): Double =
+ if (a > b) 0
+ else element(a) + sumElements(a + 1, b);
+ 4 + sumElements(1,n)
+ }
+
+ Console.println(sumInts(1,4))
+ Console.println(sumCubes(1,4))
+ Console.println(sumReciprocals(1,4))
+ Console.println(sumCubes(1, 10) + sumReciprocals(10, 20))
+ Console.println("pi = " + sumPi(20))
+ Console.println
+}
+
+//############################################################################
+
+object M2 {
+ def id(x: Int): Double = x;
+ def cube(x: Int): Double = x * x * x;
+ def reciprocal(x: Int): Double = 1.0/x;
+
+ def sum(f: Int => Double, a: Int, b: Int): Double =
+ if (a > b) 0
+ else f(a) + sum(f, a + 1, b);
+
+ def sumInts(a: Int, b: Int): Double = sum(id, a, b);
+ def sumCubes(a: Int, b: Int): Double = sum(cube, a, b);
+ def sumReciprocals(a: Int, b: Int): Double = sum(reciprocal, a, b);
+ def sumPi(n: Int): Double = {
+ def element(x: Int): Double = 4.0/(4*x+1) - 4.0/(4*x-1);
+ 4 + sum(element, 1, n)
+ }
+
+ Console.println(sumInts(1,4))
+ Console.println(sumCubes(1,4))
+ Console.println(sumReciprocals(1,4))
+ Console.println(sumCubes(1, 10) + sumReciprocals(10, 20))
+ Console.println("pi = " + sumPi(20))
+ Console.println
+}
+
+//############################################################################
+
+object M3 {
+ def sum(f: Int => Double, a: Int, b: Int): Double =
+ if (a > b) 0
+ else f(a) + sum(f, a + 1, b);
+
+ def sumInts(a: Int, b: Int): Double = sum((xXXXXX => xXXXXX), a, b);
+ def sumCubes(a: Int, b: Int): Double = sum((x => x * x * x), a, b);
+ def sumReciprocals(a: Int, b: Int): Double = sum((x => 1.0/x), a, b);
+ def sumPi(n: Int): Double = 4 + sum((x => 4.0/(4*x+1) - 4.0/(4*x-1)), 1, n);
+
+ Console.println(sumInts(1,4))
+ Console.println(sumCubes(1,4))
+ Console.println(sumReciprocals(1,4))
+ Console.println(sumCubes(1, 10) + sumReciprocals(10, 20))
+ Console.println("pi = " + sumPi(20))
+ Console.println
+}
+
+//############################################################################
+
+object M4 {
+ def sum(f: Int => Double): (Int, Int) => Double = {
+ def sumF(a: Int, b: Int): Double =
+ if (a > b) 0
+ else f(a) + sumF(a + 1, b);
+ sumF
+ }
+
+ def sumInts = sum(x => x)
+ def sumCubes = sum(x => x * x * x)
+ def sumReciprocals = sum(1.0/_)
+ def sumPi = { n: Int => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }
+
+ Console.println(sumInts(1,4))
+ Console.println(sumCubes(1,4))
+ Console.println(sumReciprocals(1,4))
+ Console.println(sumCubes(1, 10) + sumReciprocals(10, 20))
+ Console.println("pi = " + sumPi(20))
+ Console.println
+}
+
+//############################################################################
+
+object M5 {
+ def sum(f: Int => Double): (Int, Int) => Double = { (a, b) =>
+ if (a > b) 0
+ else f(a) + sum(f)(a + 1, b)
+ }
+
+ def sumInts = sum(x => x)
+ def sumCubes = sum(x => x * x * x)
+ def sumReciprocals = sum(x => 1.0/x)
+ def sumPi = { n: Int => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }
+
+ Console.println(sumInts(1,4))
+ Console.println(sumCubes(1,4))
+ Console.println(sumReciprocals(1,4))
+ Console.println(sumCubes(1, 10) + sumReciprocals(10, 20))
+ Console.println("pi = " + sumPi(20))
+ Console.println
+}
+
+//############################################################################
+
+object M6 {
+ def sum(f: Int => Double)(a: Int, b: Int): Double =
+ if (a > b) 0
+ else f(a) + sum(f)(a + 1, b);
+
+ def sumInts = sum(x => x)_
+ def sumCubes = sum(x => x * x * x)_
+ def sumReciprocals = sum(x => 1.0/x)_
+ def sumPi = { n: Int => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }
+
+ Console.println(sumInts(1,4))
+ Console.println(sumCubes(1,4))
+ Console.println(sumReciprocals(1,4))
+ Console.println(sumCubes(1, 10) + sumReciprocals(10, 20))
+ Console.println("pi = " + sumPi(20))
+ Console.println
+}
+
+//############################################################################
+
+object M7 {
+ def sum(f: Int => Double)(a: Int, b: Int): Double = {
+ def iter(a: Int, result: Double): Double =
+ if (a > b) result
+ else iter(a + 1, f(a) + result);
+ iter(a, 0)
+ }
+
+ def sumInts = sum(x => x)_
+ def sumCubes = sum(x => x * x * x)_
+ def sumReciprocals = sum(x => 1.0/x)_
+ def sumPi = { n: Int => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }
+
+ Console.println(sumInts(1,4))
+ Console.println(sumCubes(1,4))
+ Console.println(sumReciprocals(1,4))
+ Console.println(sumCubes(1, 10) + sumReciprocals(10, 20))
+ Console.println("pi = " + sumPi(20))
+ Console.println
+}
+
+//############################################################################
+
+object M8 {
+ def product(f: Int => Double)(a: Int, step: Int, b: Int): Double =
+ if (a > b) 1
+ else f(a) * product(f)(a + step, step, b);
+
+ def productPi = { n: Int => product(x=>4.0*x*x/(2*x-1)/(2*x-1))(1,1,n)/n }
+
+ val pi = 2 * product(x => x * x)(2, 2, 40) / product(x => x * x)(1, 2,40)/40;
+
+ Console.println("pi = " + productPi(20))
+ Console.println("pi = " + pi)
+ Console.println
+}
+
+//############################################################################
+
+object M9 {
+ def accumulate[t](combiner: (t, t) => t, nullValue: t, f: Int => t,
+ next: Int => Int)(a: Int, b: Int): t =
+ if (a > b) nullValue
+ else combiner(f(a), accumulate(combiner, nullValue, f, next)(next(a), b))
+
+ def inc(x: Int) = x + 1
+
+ def sum(f: Int => Double): (Int, Int) => Double =
+ accumulate((x: Double, y: Double) => x + y, 0d, f, inc)
+
+ def product(f: Int => Double): (Int, Int) => Double =
+ accumulate((x: Double, y: Double) => x * y, 1d, f, inc)
+
+ def sumInts = sum(x => x)
+ def sumCubes = sum(x => x * x * x)
+ def sumReciprocals = sum(x => 1.0 / x)
+ def sumPi = { n: Int => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }
+
+ def productPi = { n: Int => product(x=>4.0*x*x/(2*x-1)/(2*x-1))(1,n)/n }
+
+ val pi = 2*product(x => 2*x*2*x)(1,20)/product(x =>(2*x-1)*(2*x-1))(1,20)/40
+
+ Console.println(sumInts(1, 4))
+ Console.println(sumCubes(1, 4))
+ Console.println(sumReciprocals(1, 4))
+ Console.println(sumCubes(1, 10) + sumReciprocals(10, 20))
+ Console.println("pi = " + sumPi(20))
+ Console.println("pi = " + productPi(20))
+ Console.println("pi = " + pi)
+ Console.println
+}
+
+//############################################################################
+
+object MA {
+ val tolerance = 0.0001
+ def abs(x: Double) = if (x < 0) -x else x
+ def isCloseEnough(x: Double, y: Double) = abs((x - y) / x) < tolerance
+ def fixedPoint(f: Double => Double)(firstGuess: Double) = {
+ def iterate(guess: Double): Double = {
+ val next = f(guess);
+ Console.println(next);
+ if (isCloseEnough(guess, next)) next
+ else iterate(next)
+ }
+ iterate(firstGuess)
+ }
+ def sqrt(x: Double) = fixedPoint(y => (y + x / y) / 2)(1.0)
+
+ Console.println("sqrt(2) = " + sqrt(2))
+ Console.println
+}
+
+//############################################################################
+
+object MB {
+ val tolerance = 0.0001;
+ def abs(x: Double) = if (x < 0) -x else x;
+ def isCloseEnough(x: Double, y: Double) = abs((x - y) / x) < tolerance;
+ def fixedPoint(f: Double => Double)(firstGuess: Double) = {
+ def iterate(guess: Double): Double = {
+ val next = f(guess);
+ Console.println(next);
+ if (isCloseEnough(guess, next)) next
+ else iterate(next)
+ }
+ iterate(firstGuess)
+ }
+ def averageDamp(f: Double => Double)(x: Double) = (x + f(x)) / 2;
+ def sqrt(x: Double) = fixedPoint(averageDamp(y => x/y))(1.0);
+
+ Console.println("sqrt(2) = " + sqrt(2))
+ Console.println
+}
+
+//############################################################################
+
+object MC {
+ def sum(f: Int => Double)(a: Int, b: Int): Double = {
+ def iter(a: Int, result: Double): Double = {
+ if (a > b) result
+ else iter(a + 1, result + f(a))
+ }
+ iter(a, 0)
+ }
+
+ def product(f: Int => Double)(a: Int, b: Int): Double = {
+ def iter(a: Int, result: Double): Double = {
+ if (a > b) result
+ else iter(a + 1, result * f(a))
+ }
+ iter(a, 1)
+ }
+
+ def factorial(n: Int) = product(x => x)(1 , n)
+
+ Console.println(
+ "1 + 2 + .. + 5 = " + sum(x => x)(1, 5));
+ Console.println(
+ "1 * 2 * .. * 5 = " + product(x => x)(1, 5));
+ Console.println;
+
+ Console.println(
+ "1^2 + 2^2 + .. + 5^2 = " + sum(x => x*x)(1, 5));
+ Console.println(
+ "1^2 * 2^2 * .. * 5^2 = " + product(x => x*x)(1, 5));
+ Console.println;
+
+ Console.println(
+ "factorial(0) = " + factorial(0))
+ Console.println(
+ "factorial(1) = " + factorial(1))
+ Console.println(
+ "factorial(2) = " + factorial(2))
+ Console.println(
+ "factorial(3) = " + factorial(3))
+ Console.println(
+ "factorial(4) = " + factorial(4))
+ Console.println(
+ "factorial(5) = " + factorial(5))
+ Console.println
+}
+
+//############################################################################
+
+object MD {
+ def reduce(op: (Double,Double) => Double, zero:Double)(f: Int => Double)(a: Int,b: Int): Double = {
+ def iter(a: Int, result: Double): Double = {
+ if (a > b) result
+ else iter(a + 1, op(result, f(a)))
+ }
+ iter(a, zero)
+ }
+
+ def plus (x:Double,y:Double) = x+y;
+ val sum: (Int => Double) => (Int, Int) => Double = reduce(plus , 0);
+ def times(x:Double,y:Double) = x*y;
+ val product: (Int => Double) => (Int, Int) => Double = reduce(times, 1);
+
+ def factorial(n: Int) = product(x => x)(1 , n)
+
+ Console.println(
+ "1 + 2 + .. + 5 = " + sum(x => x)(1, 5))
+ Console.println(
+ "1 * 2 * .. * 5 = " + product(x => x)(1, 5))
+ Console.println;
+
+ Console.println(
+ "1^2 + 2^2 + .. + 5^2 = " + sum(x => x*x)(1, 5))
+ Console.println(
+ "1^2 * 2^2 * .. * 5^2 = " + product(x => x*x)(1, 5))
+ Console.println;
+
+ Console.println(
+ "factorial(0) = " + factorial(0))
+ Console.println(
+ "factorial(1) = " + factorial(1))
+ Console.println(
+ "factorial(2) = " + factorial(2))
+ Console.println(
+ "factorial(3) = " + factorial(3))
+ Console.println(
+ "factorial(4) = " + factorial(4))
+ Console.println(
+ "factorial(5) = " + factorial(5))
+ Console.println
+}
+
+//############################################################################
+
+object ME {
+ def reduce(op: (Double,Double) => Double, zero:Double)(f: Int => Double)(a: Int,b: Int): Double = {
+ def iter(a: Int, result: Double): Double = {
+ if (a > b) result
+ else iter(a + 1, op(result, f(a)))
+ }
+ iter(a, zero)
+ }
+
+ def sum: (Int => Double) => (Int, Int) => Double = reduce((x,y) => x + y, 0);
+ def product: (Int => Double) => (Int, Int) => Double = reduce((x,y) => x * y, 1);
+
+ def factorial(n: Int) = product(x => x)(1 , n)
+
+ Console.println(
+ "1 + 2 + .. + 5 = " + sum(x => x)(1, 5))
+ Console.println(
+ "1 * 2 * .. * 5 = " + product(x => x)(1, 5))
+ Console.println;
+
+ Console.println(
+ "1^2 + 2^2 + .. + 5^2 = " + sum(x => x*x)(1, 5))
+ Console.println(
+ "1^2 * 2^2 * .. * 5^2 = " + product(x => x*x)(1, 5))
+ Console.println;
+
+ Console.println(
+ "factorial(0) = " + factorial(0))
+ Console.println(
+ "factorial(1) = " + factorial(1))
+ Console.println(
+ "factorial(2) = " + factorial(2))
+ Console.println(
+ "factorial(3) = " + factorial(3))
+ Console.println(
+ "factorial(4) = " + factorial(4))
+ Console.println(
+ "factorial(5) = " + factorial(5))
+ Console.println
+}
+
+//############################################################################
+
+object MF {
+ def fib(x: Int): Int =
+ if (x <= 1) x
+ else fib(x - 2) + fib(x - 1)
+
+ Console.println("fib(0) = " + fib(0))
+ Console.println("fib(1) = " + fib(1))
+ Console.println("fib(2) = " + fib(2))
+ Console.println("fib(3) = " + fib(3))
+ Console.println("fib(4) = " + fib(4))
+ Console.println("fib(5) = " + fib(5))
+ Console.println("fib(6) = " + fib(6))
+ Console.println("fib(7) = " + fib(7))
+ Console.println("fib(8) = " + fib(8))
+ Console.println("fib(9) = " + fib(9))
+}
+
+//############################################################################
+
+object MG {
+ def fib(x: Int) = {
+ def loop(n: Int, prev: Int, fibn: Int): Int =
+ if (n == x) fibn
+ else loop(n + 1, fibn, fibn + prev)
+ if (x == 0) 0 else loop(1, 0, 1)
+ }
+
+ Console.println("fib(0) = " + fib(0))
+ Console.println("fib(1) = " + fib(1))
+ Console.println("fib(2) = " + fib(2))
+ Console.println("fib(3) = " + fib(3))
+ Console.println("fib(4) = " + fib(4))
+ Console.println("fib(5) = " + fib(5))
+ Console.println("fib(6) = " + fib(6))
+ Console.println("fib(7) = " + fib(7))
+ Console.println("fib(8) = " + fib(8))
+ Console.println("fib(9) = " + fib(9))
+}
+
+//############################################################################
+
+object MH {
+ def power(x: Double, y: Int): Double =
+ if (y <= 0) 1
+ else if (y % 2 == 0) power(x * x, y / 2)
+ else x * power(x, y - 1);
+
+
+ Console.println("power(0,0) = " + power(0,0))
+ Console.println("power(0,1) = " + power(0,1))
+ Console.println("power(0,2) = " + power(0,2))
+ Console.println("power(0,3) = " + power(0,3))
+ Console.println("power(0,4) = " + power(0,4))
+ Console.println("power(0,5) = " + power(0,5))
+ Console.println("power(0,6) = " + power(0,6))
+ Console.println("power(0,7) = " + power(0,7))
+ Console.println("power(0,8) = " + power(0,8))
+ Console.println
+
+ Console.println("power(1,0) = " + power(1,0))
+ Console.println("power(1,1) = " + power(1,1))
+ Console.println("power(1,2) = " + power(1,2))
+ Console.println("power(1,3) = " + power(1,3))
+ Console.println("power(1,4) = " + power(1,4))
+ Console.println("power(1,5) = " + power(1,5))
+ Console.println("power(1,6) = " + power(1,6))
+ Console.println("power(1,7) = " + power(1,7))
+ Console.println("power(1,8) = " + power(1,8))
+ Console.println
+
+ Console.println("power(2,0) = " + power(2,0))
+ Console.println("power(2,1) = " + power(2,1))
+ Console.println("power(2,2) = " + power(2,2))
+ Console.println("power(2,3) = " + power(2,3))
+ Console.println("power(2,4) = " + power(2,4))
+ Console.println("power(2,5) = " + power(2,5))
+ Console.println("power(2,6) = " + power(2,6))
+ Console.println("power(2,7) = " + power(2,7))
+ Console.println("power(2,8) = " + power(2,8))
+ Console.println
+
+ Console.println("power(3,0) = " + power(3,0))
+ Console.println("power(3,1) = " + power(3,1))
+ Console.println("power(3,2) = " + power(3,2))
+ Console.println("power(3,3) = " + power(3,3))
+ Console.println("power(3,4) = " + power(3,4))
+ Console.println("power(3,5) = " + power(3,5))
+ Console.println("power(3,6) = " + power(3,6))
+ Console.println("power(3,7) = " + power(3,7))
+ Console.println("power(3,8) = " + power(3,8))
+ Console.println
+
+ Console.println("power(4,0) = " + power(4,0))
+ Console.println("power(4,1) = " + power(4,1))
+ Console.println("power(4,2) = " + power(4,2))
+ Console.println("power(4,3) = " + power(4,3))
+ Console.println("power(4,4) = " + power(4,4))
+ Console.println("power(4,5) = " + power(4,5))
+ Console.println("power(4,6) = " + power(4,6))
+ Console.println("power(4,7) = " + power(4,7))
+ Console.println("power(4,8) = " + power(4,8))
+ Console.println
+
+ Console.println("power(5,0) = " + power(5,0))
+ Console.println("power(5,1) = " + power(5,1))
+ Console.println("power(5,2) = " + power(5,2))
+ Console.println("power(5,3) = " + power(5,3))
+ Console.println("power(5,4) = " + power(5,4))
+ Console.println("power(5,5) = " + power(5,5))
+ Console.println("power(5,6) = " + power(5,6))
+ Console.println("power(5,7) = " + power(5,7))
+ Console.println("power(5,8) = " + power(5,8))
+ Console.println
+}
+
+//############################################################################
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ M0
+ M1
+ M2
+ M3
+ M4
+ M5
+ M6
+ M7
+ M8
+ M9
+ MA
+ MB
+ MC
+ MD
+ ME
+ MF
+ MG
+ MH
+ ()
+ }
+}
+
+//############################################################################
diff --git a/tests/run/Course-2002-07.check b/tests/run/Course-2002-07.check
new file mode 100644
index 000000000..75e956f31
--- /dev/null
+++ b/tests/run/Course-2002-07.check
@@ -0,0 +1,137 @@
+ 0 = 0
+ 1 = 1
+ 0 + 1 = 1
+ 1 + 2 = 3
+2 + 3 + 4 = 9
+
+ 0 = 0
+ 1 = 1
+ 0 + 1 = 1
+ 1 + 2 = 3
+2 + 3 + 4 = 9
+
+ 0 = 0
+ 1 = 1
+ 0 + 1 = 1
+ 1 + 2 = 3
+2 + 3 + 4 = 9
+
+ 0 = 0
+ 1 = 1
+ 0 + 1 = 1
+ 1 + 2 = 3
+2 + 3 + 4 = 9
+
+List() = concat(List())
+List() = concat(List(List()))
+List() = concat(List(List(), List()))
+List() = concat(List(List(), List(), List()))
+List(1, 2, 3, 4, 5, 6) = concat(List(List(1, 2, 3, 4, 5, 6)))
+List(1, 2, 3, 4, 5, 6) = concat(List(List(1, 2, 3, 4, 5, 6), List()))
+List(1, 2, 3, 4, 5, 6) = concat(List(List(1, 2, 3), List(4, 5, 6)))
+List(1, 2, 3, 4, 5, 6) = concat(List(List(), List(1, 2, 3, 4, 5, 6)))
+List(1, 2, 3, 4, 5, 6) = concat(List(List(1, 2, 3, 4, 5, 6), List(), List()))
+List(1, 2, 3, 4, 5, 6) = concat(List(List(1, 2, 3, 4, 5), List(6), List()))
+List(1, 2, 3, 4, 5, 6) = concat(List(List(1, 2, 3), List(4, 5, 6), List()))
+List(1, 2, 3, 4, 5, 6) = concat(List(List(1), List(2, 3, 4, 5, 6), List()))
+List(1, 2, 3, 4, 5, 6) = concat(List(List(), List(1, 2, 3, 4, 5, 6), List()))
+List(1, 2, 3, 4, 5, 6) = concat(List(List(), List(1, 2, 3, 4, 5), List(6)))
+List(1, 2, 3, 4, 5, 6) = concat(List(List(), List(1, 2, 3), List(4, 5, 6)))
+List(1, 2, 3, 4, 5, 6) = concat(List(List(), List(1), List(2, 3, 4, 5, 6)))
+List(1, 2, 3, 4, 5, 6) = concat(List(List(), List(), List(1, 2, 3, 4, 5, 6)))
+List(1, 2, 3, 4, 5, 6) = concat(List(List(1, 2), List(3, 4), List(5, 6)))
+
+List() = zipFun(List(),List())
+List() = zipFun(List(),List(a, b, c))
+List() = zipFun(List(1, 2, 3),List())
+List((1,a)) = zipFun(List(1),List(a))
+List((1,a)) = zipFun(List(1),List(a, b, c))
+List((1,a)) = zipFun(List(1, 2, 3),List(a))
+List((1,a), (2,b)) = zipFun(List(1, 2),List(a, b))
+List((1,a), (2,b)) = zipFun(List(1, 2),List(a, b, c))
+List((1,a), (2,b)) = zipFun(List(1, 2, 3),List(a, b))
+List((1,a), (2,b), (3,c)) = zipFun(List(1, 2, 3),List(a, b, c))
+
+List() = heads(List())
+List() = heads(List(List()))
+List() = heads(List(List(), List()))
+List() = heads(List(List(), List(), List()))
+List(1) = heads(List(List(1, 2, 3, 4, 5, 6)))
+List(1) = heads(List(List(1, 2, 3, 4, 5, 6), List()))
+List(1) = heads(List(List(), List(1, 2, 3, 4, 5, 6)))
+List(1) = heads(List(List(1, 2, 3, 4, 5, 6), List(), List()))
+List(1) = heads(List(List(), List(1, 2, 3, 4, 5, 6), List()))
+List(1) = heads(List(List(), List(), List(1, 2, 3, 4, 5, 6)))
+List(1, 2) = heads(List(List(1), List(2, 3, 4, 5, 6), List()))
+List(1, 2) = heads(List(List(), List(1), List(2, 3, 4, 5, 6)))
+List(1, 4) = heads(List(List(1, 2, 3), List(4, 5, 6)))
+List(1, 4) = heads(List(List(1, 2, 3), List(4, 5, 6), List()))
+List(1, 4) = heads(List(List(), List(1, 2, 3), List(4, 5, 6)))
+List(1, 6) = heads(List(List(1, 2, 3, 4, 5), List(6), List()))
+List(1, 6) = heads(List(List(), List(1, 2, 3, 4, 5), List(6)))
+List(1, 3, 5) = heads(List(List(1, 2), List(3, 4), List(5, 6)))
+
+List() = heads(List())
+List() = heads(List(List()))
+List() = heads(List(List(), List()))
+List() = heads(List(List(), List(), List()))
+List(1) = heads(List(List(1, 2, 3, 4, 5, 6)))
+List(1) = heads(List(List(1, 2, 3, 4, 5, 6), List()))
+List(1) = heads(List(List(), List(1, 2, 3, 4, 5, 6)))
+List(1) = heads(List(List(1, 2, 3, 4, 5, 6), List(), List()))
+List(1) = heads(List(List(), List(1, 2, 3, 4, 5, 6), List()))
+List(1) = heads(List(List(), List(), List(1, 2, 3, 4, 5, 6)))
+List(1, 2) = heads(List(List(1), List(2, 3, 4, 5, 6), List()))
+List(1, 2) = heads(List(List(), List(1), List(2, 3, 4, 5, 6)))
+List(1, 4) = heads(List(List(1, 2, 3), List(4, 5, 6)))
+List(1, 4) = heads(List(List(1, 2, 3), List(4, 5, 6), List()))
+List(1, 4) = heads(List(List(), List(1, 2, 3), List(4, 5, 6)))
+List(1, 6) = heads(List(List(1, 2, 3, 4, 5), List(6), List()))
+List(1, 6) = heads(List(List(), List(1, 2, 3, 4, 5), List(6)))
+List(1, 3, 5) = heads(List(List(1, 2), List(3, 4), List(5, 6)))
+
+f (x) = Prod(Var(x), Var(x))
+f'(x) = Sum(Prod(Var(x), Number(1)), Prod(Var(x), Number(1)))
+
+f (x) = x * x
+f'(x) = x * 1 + x * 1
+g (x) = 2 * x * x + 3 * x
+g'(x) = 2 * x * 1 + x * (2 * 1 + x * 0) + 3 * 1 + x * 0
+g (3) = 27
+g'(3) = 15
+
+ta(x) = x + 3
+tb(x) = x + 3
+tc(x) = x + 3
+td(x) = x + 3
+te(x) = 2 * x + 3
+tf(x) = 2 * x + 3
+tg(x) = 6 * x
+th(x) = x^6
+
+f4(x) = x^4 + 7 * x^3 + 20 * x^2 + 23 * x + 5
+f3(x) = 4 * x^3 + 21 * x^2 + 40 * x + 23
+f2(x) = 12 * x^2 + 42 * x + 40
+f1(x) = 24 * x + 42
+f0(x) = 24
+
+f4(0) = 5 ok
+f4(1) = 56 ok
+f4(2) = 203 ok
+f4(3) = 524 ok
+f4(4) = 1121 ok
+
+f3(0) = 23 ok
+f3(1) = 88 ok
+f3(2) = 219 ok
+f3(3) = 440 ok
+
+f2(0) = 40 ok
+f2(1) = 94 ok
+f2(2) = 172 ok
+
+f1(0) = 42 ok
+f1(1) = 66 ok
+
+f0(0) = 24 ok
+
diff --git a/tests/run/Course-2002-07.scala b/tests/run/Course-2002-07.scala
new file mode 100644
index 000000000..b26eda1e0
--- /dev/null
+++ b/tests/run/Course-2002-07.scala
@@ -0,0 +1,722 @@
+//############################################################################
+// Programmation IV - 2002 - Week 07
+//############################################################################
+
+object M0 {
+
+ trait Expr {
+ def isNumber: Boolean;
+ def isSum: Boolean;
+ def numValue: Int;
+ def leftOp: Expr;
+ def rightOp: Expr;
+ }
+
+ class Number(n: Int) extends Expr {
+ def isNumber: Boolean = true;
+ def isSum: Boolean = false;
+ def numValue: Int = n;
+ def leftOp: Expr = sys.error("Number.leftOp");
+ def rightOp: Expr = sys.error("Number.rightOp");
+ }
+ class Sum(e1: Expr, e2: Expr) extends Expr {
+ def isNumber: Boolean = false;
+ def isSum: Boolean = true;
+ def numValue: Int = sys.error("Sum.numValue");
+ def leftOp: Expr = e1;
+ def rightOp: Expr = e2;
+ }
+
+ class Prod(e1: Expr, e2: Expr) extends Expr {
+ def isNumber: Boolean = false;
+ def isSum: Boolean = false;
+ def numValue: Int = sys.error("Prod.numValue");
+ def leftOp: Expr = e1;
+ def rightOp: Expr = e2;
+ }
+
+ class Var(x: String) extends Expr {
+ def isNumber: Boolean = false;
+ def isSum: Boolean = false;
+ def numValue: Int = sys.error("Var.numValue");
+ def leftOp: Expr = sys.error("Var.leftOp");
+ def rightOp: Expr = sys.error("Var.rightOp");
+ }
+
+ def eval(e: Expr): Int = {
+ if (e.isNumber) e.numValue
+ else if (e.isSum) eval(e.leftOp) + eval(e.rightOp)
+ else sys.error("unknown expression")
+ }
+
+ def test = {
+ Console.println(" 0 = " + eval(new Number(0)));
+ Console.println(" 1 = " + eval(new Number(1)));
+ Console.println(" 0 + 1 = " +
+ eval(new Sum(new Number(0),new Number(1))));
+ Console.println(" 1 + 2 = " +
+ eval(new Sum(new Number(1),new Number(2))));
+ Console.println("2 + 3 + 4 = " +
+ eval(new Sum(new Sum(new Number(2),new Number(3)),new Number(4))));
+ Console.println;
+ }
+
+}
+
+//############################################################################
+
+object M1 {
+
+ trait Expr {
+ def eval: Int;
+ }
+ class Number(n: Int) extends Expr {
+ def eval: Int = n;
+ }
+ class Sum(e1: Expr, e2: Expr) extends Expr {
+ def eval: Int = e1.eval + e2.eval;
+ }
+
+ def test = {
+ Console.println(" 0 = " + new Number(0).eval);
+ Console.println(" 1 = " + new Number(1).eval);
+ Console.println(" 0 + 1 = " +
+ new Sum(new Number(0),new Number(1)).eval);
+ Console.println(" 1 + 2 = " +
+ new Sum(new Number(1),new Number(2)).eval);
+ Console.println("2 + 3 + 4 = " +
+ new Sum(new Sum(new Number(2),new Number(3)),new Number(4)).eval);
+ Console.println;
+ }
+}
+
+//############################################################################
+
+object M2 {
+
+ trait Expr;
+ case class Number(n: Int) extends Expr;
+ case class Sum(e1: Expr, e2: Expr) extends Expr;
+
+ def eval(e: Expr): Int = e match {
+ case Number(n) => n
+ case Sum(e1, e2) => eval(e1) + eval(e2)
+ }
+
+ def test = {
+ Console.println(" 0 = " + eval(Number(0)));
+ Console.println(" 1 = " + eval(Number(1)));
+ Console.println(" 0 + 1 = " + eval(Sum(Number(0),Number(1))));
+ Console.println(" 1 + 2 = " + eval(Sum(Number(1),Number(2))));
+ Console.println("2 + 3 + 4 = " + eval(Sum(Sum(Number(2),Number(3)),
+ Number(4))));
+ Console.println;
+ }
+}
+
+//############################################################################
+
+object M3 {
+
+ trait Expr {
+ def eval: Int = this match {
+ case Number(n) => n
+ case Sum(e1, e2) => e1.eval + e2.eval
+ }
+ }
+ case class Number(n: Int) extends Expr;
+ case class Sum(e1: Expr, e2: Expr) extends Expr;
+
+ def test = {
+ Console.println(" 0 = " + Number(0).eval);
+ Console.println(" 1 = " + Number(1).eval);
+ Console.println(" 0 + 1 = " + Sum(Number(0),Number(1)).eval);
+ Console.println(" 1 + 2 = " + Sum(Number(1),Number(2)).eval);
+ Console.println("2 + 3 + 4 = " + Sum(Sum(Number(2),Number(3)),
+ Number(4)).eval);
+ Console.println;
+ }
+
+}
+
+//############################################################################
+
+object M4 {
+
+ def concat[a](xss: List[List[a]]): List[a] = xss match {
+ case List() => List()
+ case xs :: xss1 => xs ::: concat(xss1)
+ }
+
+ def test_concat[a](xss: List[List[a]]) = {
+ Console.println(concat(xss).toString + " = concat(" + xss + ")"); // !!! .toString
+ }
+
+ def test = {
+ test_concat(List());
+ test_concat(List(List()));
+ test_concat(List(List(),List()));
+ test_concat(List(List(),List(),List()));
+
+ test_concat(List(List(1,2,3,4,5,6)));
+ test_concat(List(List(1,2,3,4,5,6),List[Int]())); // !!! [int]
+ test_concat(List(List(1,2,3),List(4,5,6)));
+ test_concat(List(List[Int](),List(1,2,3,4,5,6))); // !!! [int]
+ test_concat(List(List(1,2,3,4,5,6),List[Int](),List[Int]())); // !!! [int]
+ test_concat(List(List(1,2,3,4,5),List(6),List[Int]())); // !!! [int]
+ test_concat(List(List(1,2,3),List(4,5,6),List[Int]())); // !!! [int]
+ test_concat(List(List(1),List(2,3,4,5,6),List[Int]())); // !!! [int]
+ test_concat(List(List[Int](),List(1,2,3,4,5,6),List[Int]())); // !!! [int]
+ test_concat(List(List[Int](),List(1,2,3,4,5),List(6))); // !!! [int]
+ test_concat(List(List[Int](),List(1,2,3),List(4,5,6))); // !!! [int]
+ test_concat(List(List[Int](),List(1),List(2,3,4,5,6))); // !!! [int]
+ test_concat(List(List[Int](),List[Int](),List(1,2,3,4,5,6))); // !!! [int]
+ test_concat(List(List(1,2),List(3,4),List(5,6)));
+ Console.println;
+ }
+
+}
+
+//############################################################################
+
+object M5 {
+
+ def zipFun[a,b](xs:List[a], ys:List[b]):List[Tuple2[a,b]] = (xs,ys) match {
+ case (List(), _) => List()
+ case (_, List()) => List()
+ case (x :: xs1, y :: ys1) => (x, y) :: zipFun(xs1, ys1)
+ }
+
+ def test_zipFun[a,b](xs: List[a], ys: List[b]) = {
+ Console.println(zipFun(xs,ys).toString + " = zipFun(" + xs + "," + ys + ")"); // !!! .toString
+ }
+
+ def test = {
+ test_zipFun(List(),List());
+ test_zipFun(List(),List('a','b','c'));
+ test_zipFun(List(1,2,3),List());
+
+ test_zipFun(List(1),List('a'));
+ test_zipFun(List(1),List('a','b','c'));
+ test_zipFun(List(1,2,3),List('a'));
+
+ test_zipFun(List(1,2),List('a','b'));
+ test_zipFun(List(1,2),List('a','b','c'));
+ test_zipFun(List(1,2,3),List('a','b'));
+
+ test_zipFun(List(1,2,3),List('a','b','c'));
+
+ Console.println;
+ }
+
+}
+
+
+//############################################################################
+
+object M6 {
+
+ def zipFun[a,b](xs:List[a], ys:List[b]):List[Tuple2[a,b]] = ((xs,ys): @unchecked) match {
+ // !!! case (List(), _), (_, List()) => List()
+ case (x :: xs1, y :: ys1) => (x, y) :: zipFun(xs1, ys1)
+ }
+
+ def test_zipFun[a,b](xs: List[a], ys: List[b]) = {
+ Console.println(zipFun(xs,ys).toString + " = zipFun(" + xs + "," + ys + ")"); // !!! .toString
+ }
+
+ def test = {
+ test_zipFun(List(),List());
+ test_zipFun(List(),List('a','b','c'));
+ test_zipFun(List(1,2,3),List());
+
+ test_zipFun(List(1),List('a'));
+ test_zipFun(List(1),List('a','b','c'));
+ test_zipFun(List(1,2,3),List('a'));
+
+ test_zipFun(List(1,2),List('a','b'));
+ test_zipFun(List(1,2),List('a','b','c'));
+ test_zipFun(List(1,2,3),List('a','b'));
+
+ test_zipFun(List(1,2,3),List('a','b','c'));
+
+ Console.println;
+ }
+
+}
+
+//############################################################################
+
+object M7 {
+
+ def heads[a](xss: List[List[a]]): List[a] = xss flatMap {
+ case x :: xs => List(x)
+ case List() => List()
+ }
+
+ def test_heads[a](xss: List[List[a]]) = {
+ Console.println(heads(xss).toString + " = heads(" + xss + ")"); // !!! .toString
+ }
+
+ def test = {
+ test_heads(List());
+ test_heads(List(List()));
+ test_heads(List(List(),List()));
+ test_heads(List(List(),List(),List()));
+
+ test_heads(List(List(1,2,3,4,5,6)));
+ test_heads(List(List(1,2,3,4,5,6),List[Int]())); // !!! [int]
+ test_heads(List(List[Int](),List(1,2,3,4,5,6))); // !!! [int]
+ test_heads(List(List(1,2,3,4,5,6),List[Int](),List[Int]())); // !!! [int]
+ test_heads(List(List[Int](),List(1,2,3,4,5,6),List[Int]())); // !!! [int]
+ test_heads(List(List[Int](),List[Int](),List(1,2,3,4,5,6))); // !!! [int]
+
+ test_heads(List(List(1),List(2,3,4,5,6),List[Int]())); // !!! [int]
+ test_heads(List(List[Int](),List(1),List(2,3,4,5,6))); // !!! [int]
+
+ test_heads(List(List(1,2,3),List(4,5,6)));
+ test_heads(List(List(1,2,3),List(4,5,6),List[Int]())); // !!! [int]
+ test_heads(List(List[Int](),List(1,2,3),List(4,5,6))); // !!! [int]
+
+ test_heads(List(List(1,2,3,4,5),List(6),List[Int]())); // !!! [int]
+ test_heads(List(List[Int](),List(1,2,3,4,5),List(6))); // !!! [int]
+
+ test_heads(List(List(1,2),List(3,4),List(5,6)));
+
+ Console.println;
+ }
+
+}
+
+//############################################################################
+
+object M8 {
+
+ def heads[a](xss: List[List[a]]): List[a] = xss.flatMap {
+ y => y match {
+ case x :: xs => List(x)
+ case List() => List()
+ }
+ }
+
+ def test_heads[a](xss: List[List[a]]) = {
+ Console.println(heads(xss).toString + " = heads(" + xss + ")"); // !!! .toString
+ }
+
+
+ def test = {
+ test_heads(List());
+ test_heads(List(List()));
+ test_heads(List(List(),List()));
+ test_heads(List(List(),List(),List()));
+
+ test_heads(List(List(1,2,3,4,5,6)));
+ test_heads(List(List(1,2,3,4,5,6),List[Int]())); // !!! [int]
+ test_heads(List(List[Int](),List(1,2,3,4,5,6))); // !!! [int]
+ test_heads(List(List(1,2,3,4,5,6),List[Int](),List[Int]())); // !!! [int]
+ test_heads(List(List[Int](),List(1,2,3,4,5,6),List[Int]())); // !!! [int]
+ test_heads(List(List[Int](),List[Int](),List(1,2,3,4,5,6))); // !!! [int]
+
+ test_heads(List(List(1),List(2,3,4,5,6),List[Int]())); // !!! [int]
+ test_heads(List(List[Int](),List(1),List(2,3,4,5,6))); // !!! [int]
+
+ test_heads(List(List(1,2,3),List(4,5,6)));
+ test_heads(List(List(1,2,3),List(4,5,6),List[Int]())); // !!! [int]
+ test_heads(List(List[Int](),List(1,2,3),List(4,5,6))); // !!!
+
+ test_heads(List(List(1,2,3,4,5),List(6),List[Int]())); // !!! [int]
+ test_heads(List(List[Int](),List(1,2,3,4,5),List(6))); // !!! [int]
+
+ test_heads(List(List(1,2),List(3,4),List(5,6)));
+
+ Console.println;
+ }
+
+}
+
+//############################################################################
+
+object M9 {
+
+ trait Expr {
+ def derive(v: Var): Expr = this match {
+ case Number(_) => Number(0)
+ case Var(name) => if (name == v.name) Number(1) else Number(0)
+ case Sum(e1, e2) => Sum(e1 derive v, e2 derive v)
+ case Prod(e1, e2) => Sum(Prod(e1, e2 derive v), Prod(e2, e1 derive v))
+ }
+ }
+ case class Number(x: Int) extends Expr {
+ override def toString = "Number(" + x + ")"; // !!! remove !
+ }
+ case class Var(name: String) extends Expr {
+ override def toString = "Var(" + name + ")"; // !!! remove !
+ }
+ case class Sum(e1: Expr, e2: Expr) extends Expr {
+ override def toString = "Sum(" + e1 + ", " + e2 + ")"; // !!! remove !
+ }
+ case class Prod(e1: Expr, e2: Expr) extends Expr {
+ override def toString = "Prod(" + e1 + ", " + e2 + ")"; // !!! remove !
+ }
+
+ def test = {
+ val x = Var("x");
+ val f0 = Prod(x, x);
+ val f1 = f0 derive x;
+ Console.println("f (x) = " + f0);
+ Console.println("f'(x) = " + f1);
+ Console.println;
+ }
+
+}
+
+//############################################################################
+
+object MA {
+
+ def lookup[k,v](xs: List[Tuple2[k,v]], k: k): v = xs match {
+ case List() => sys.error("no value for " + k)
+ case (k1,v1) :: xs1 => if (k1 == k) v1 else lookup(xs1, k)
+ }
+
+ trait Expr {
+ def + (that: Expr) = Sum(this, that);
+ def * (that: Expr) = Prod(this, that);
+ def derive(v: Var): Expr = this match {
+ case Number(_) => Number(0)
+ case Var(name) => if (name == v.name) Number(1) else Number(0)
+ case Sum(e1, e2) => (e1 derive v) + (e2 derive v)
+ case Prod(e1, e2) => e1 * (e2 derive v) + e2 * (e1 derive v)
+ }
+ }
+ case class Number(x: Int) extends Expr {
+ override def toString = x.toString
+ }
+ case class Var(name: String) extends Expr {
+ override def toString = name;
+ }
+ case class Sum(e1: Expr, e2: Expr) extends Expr {
+ override def toString = e1.toString + " + " + e2.toString;
+ }
+ case class Prod(e1: Expr, e2: Expr) extends Expr {
+ override def toString = {
+ def factorToString(e: Expr) = e match {
+ case Sum(_, _) => "(" + e.toString + ")"
+ case _ => e.toString
+ }
+ factorToString(e1) + " * " + factorToString(e2);
+ }
+ }
+
+ def eval(e: Expr): Int = e match {
+ case Number(n) => n
+ case Var(_) => sys.error("cannot evaluate variable")
+ case Sum(e1, e2) => eval(e1) + eval(e2)
+ case Prod(e1, e2) => eval(e1) * eval(e2)
+ }
+
+ def evalvars(xs: List[(String,Int)]): Expr => Int = {
+ def loop(e: Expr): Int = e match {
+ case Number(n) => n
+ case Var(name) => lookup(xs,name)
+ case Sum(e1, e2) => loop(e1) + loop(e2)
+ case Prod(e1, e2) => loop(e1) * loop(e2)
+ }
+ loop
+ }
+
+ def test = {
+ val x = Var("x");
+
+ val f0 = x * x;
+ val f1 = f0 derive x;
+ Console.println("f (x) = " + f0);
+ Console.println("f'(x) = " + f1);
+
+ val g0 = Number(2) * x * x + Number(3) * x;
+ val g1 = g0 derive x;
+ Console.println("g (x) = " + g0);
+ Console.println("g'(x) = " + g1);
+ Console.println("g (3) = " + evalvars(List(("x",3)))(g0));
+ Console.println("g'(3) = " + evalvars(List(("x",3)))(g1));
+
+ Console.println;
+ }
+
+}
+
+//############################################################################
+
+object Utils {
+
+ private def power0(x: Int, y: Int): Int =
+ if (y == 1) x else if (y % 2 == 0) power0(x*x,y/2) else x*power0(x, y-1);
+
+ def power(x: Int, y: Int): Int = (x,y) match {
+ case (0,0) => sys.error("power(0,0)")
+ case (0,_) => 0
+ case (1,_) => 1
+ case (_,0) => 1
+ case (_,1) => x
+ case (_,2) => x*x
+ case (_,_) => if (y < 0) 1/power0(x,y) else power0(x,y)
+ }
+
+ def lookup(entries: List[(String,Int)], key: String): Int = entries match {
+ case List() => sys.error("no value for " + key)
+ case (k,v) :: _ if (k == key) => v
+ case _ :: rest => lookup(rest, key)
+ }
+
+ def compare(xs: List[String], ys: List[String]): Int = (xs, ys) match {
+ case (List(), List()) => 0
+ case (List(), _ ) => -1
+ case (_ , List()) => +1
+ case (x::xs , y::ys ) => {
+ val diff = x.compareTo(y);
+ if (diff != 0) diff else compare(xs,ys)
+ }
+ }
+
+}
+
+object MB {
+
+ import Utils._;
+
+
+ trait Expr {
+
+ private def count: Int = this match {
+ case Lit(n) => n
+ case Mul(Lit(n),_) => n
+ case _ => 1
+ }
+
+ private def term: Expr = this match {
+ case Lit(_) => Lit(1)
+ case Mul(Lit(_),r) => r
+ case _ => this
+ }
+
+ private def vars: List[String] = this match {
+ case Var(n) => List(n)
+ case Mul(l,r) => l.vars ::: r.vars
+ case Pow(l,n) => { val vs = l.vars; List.range(0,n).flatMap(i => vs) }
+ case _ => List()
+ }
+
+ private def +< (that: Expr): Boolean = (this +<? that) < 0;
+ private def +<= (that: Expr): Boolean = (this +<? that) <= 0;
+ private def +<? (that: Expr): Int = (this,that) match {
+ case (Add(_,_), _ ) => 0
+ case (_ , Add(_,_)) => 0
+ case (_ , _ ) => compare(this.vars,that.vars)
+ }
+
+ def + (that: Expr): Expr = if (that +<= this) (this,that) match {
+ case (_ , Lit(0) ) => this
+ case (Lit(l) , Lit(r) ) => Lit(l + r)
+ case (_ , Add(rl,rr)) => (this + rl) + rr
+ case (Add(ll,lr), _ ) if (lr +<= that) => ll + (that + lr)
+ case (_ , _ ) => {
+ val l = this.term;
+ val r = that.term;
+ if (l equ r) Lit(this.count + that.count) * r else Add(this, that)
+ }
+ } else that + this;
+
+ private def *< (that: Expr): Boolean = (this *<? that) < 0;
+ private def *<= (that: Expr): Boolean = (this *<? that) <= 0;
+ private def *<? (that: Expr): Int = (this,that) match {
+ case (Mul(_,_), _ ) => 0
+ case (_ , Mul(_,_)) => 0
+ case (Add(_,_), Add(_,_)) => 0
+ case (Add(_,_), _ ) => -1
+ case (_ , Add(_,_)) => +1
+ case (Lit(_) , Lit(_) ) => 0
+ case (Lit(_) , _ ) => -1
+ case (_ , Lit(_) ) => +1
+ case (Var(l) , Var(r) ) => l.compareTo(r)
+ case (Var(_) , Pow(r,_)) => if (this *<= r) -1 else +1
+ case (Pow(l,_), Var(_) ) => if (l *< that) -1 else +1
+ case (Pow(l,_), Pow(r,_)) => l *<? r
+ }
+
+ def * (that: Expr): Expr = if (this *<= that) (this,that) match {
+ case (Lit(0) , _ ) => this
+ case (Lit(1) , _ ) => that
+ case (Mul(ll,lr), r ) => ll * (lr * r)
+ case (Add(ll,lr), r ) => ll * r + lr * r
+ case (Lit(l) , Lit(r) ) => Lit(l * r)
+ case (Var(_) , Var(_) ) if (this equ that) => Pow(this,2)
+ case (Var(_) , Pow(r,n) ) if (this equ r) => Pow(this,n + 1)
+ case (Pow(ll,lr), Pow(rl,rr)) if (ll equ rl) => Pow(ll,lr + rr)
+ case (l , Mul(rl,rr)) if (rl *<= l) => (rl * l) * rr
+ case (_ , _ ) => Mul(this,that)
+ } else that * this;
+
+ def ^ (that: Int): Expr = (this,that) match {
+ case (_ ,1) => this
+ case (Lit(i) ,n) => Lit(power(i,n))
+ case (Var(_) ,n) => Pow(this,n)
+ case (Add(_,_),n) => this * (this ^ (n - 1))
+ case (Mul(l,r),n) => (l ^ n) * (r ^ n)
+ case (Pow(e,m),n) => Pow(e,m + n)
+ }
+
+ def derive(v: Var): Expr = this match {
+ case Lit(_) => Lit(0)
+ case Var(name) => if (name == v.name) Lit(1) else Lit(0)
+ case Add(e1, e2) => (e1 derive v) + (e2 derive v)
+ case Mul(e1, e2) => e1 * (e2 derive v) + e2 * (e1 derive v)
+ case Pow(e1, i2) => Lit(i2) * (e1 derive v) * (e1 ^ (i2 - 1))
+ }
+
+ def evaluate(vars: List[(String,Int)]): Int = this match {
+ case Lit(cst) => cst
+ case Var (name) => lookup(vars, name)
+ case Add (l, r) => l.evaluate(vars) + r.evaluate(vars)
+ case Mul (l, r) => l.evaluate(vars) * r.evaluate(vars)
+ case Pow(l, r) => power(l.evaluate(vars), r)
+ }
+
+ def equ(that: Expr): Boolean = (this,that) match {
+ case (Lit(l) ,Lit(r)) => l == r
+ case (Var(l) ,Var(r)) => l == r
+ case (Add(ll,lr),Add(rl,rr)) => (ll equ rl) && (lr equ rr)
+ case (Mul(ll,lr),Mul(rl,rr)) => (ll equ rl) && (lr equ rr)
+ case (Pow(ll,lr),Pow(rl,rr)) => (ll equ rl) && (lr == rr)
+ case _ => false
+ }
+
+ }
+
+ case class Lit(x: Int) extends Expr {
+ override def toString = x.toString
+ }
+
+ case class Var(name: String) extends Expr {
+ override def toString = name;
+ }
+
+ case class Add(e1: Expr, e2: Expr) extends Expr {
+ override def toString = e1.toString + " + " + e2.toString; // !!! .toString
+ }
+
+ case class Mul(e1: Expr, e2: Expr) extends Expr {
+ override def toString = {
+ def factorToString(e: Expr) = e match {
+ case Add(_, _) => "(" + e.toString + ")"
+ case _ => e.toString
+ }
+ factorToString(e1) + " * " + factorToString(e2);
+ }
+ }
+
+ case class Pow(e1: Expr, i2: Int) extends Expr {
+ override def toString = {
+ def factorToString(e: Expr) = e match {
+ case Add(_, _) => "(" + e.toString + ")"
+ case Mul(_, _) => "(" + e.toString + ")"
+ case _ => e.toString
+ }
+ factorToString(e1) + "^" + i2;
+ }
+ }
+
+ def test = {
+ val _1 = Lit(1);
+ val _2 = Lit(2);
+ val _3 = Lit(3);
+ val _4 = Lit(4);
+ val _5 = Lit(5);
+
+ val x = Var("x");
+
+ val ta = (_1 + (_2 + x));
+ val tb = (_1 + (x + _2));
+ val tc = ((_1 + x) + _2);
+ val td = ((x + _1) + _2);
+ val te = ((x + _1) + (x + _2));
+ val tf = ((_1 + x) + (_2 + x));
+ val tg = x + x + (x * _2) + x + x;
+ val th = x * x * (x ^ 2) * x * x;
+
+ Console.println("ta(x) = " + ta);
+ Console.println("tb(x) = " + tb);
+ Console.println("tc(x) = " + tc);
+ Console.println("td(x) = " + td);
+ Console.println("te(x) = " + te);
+ Console.println("tf(x) = " + tf);
+ Console.println("tg(x) = " + tg);
+ Console.println("th(x) = " + th);
+ Console.println;
+
+ val f4 = (x+ _3)*(_2+x)*x*(x+ _1) + (x+ _5)*(x*(x+ _2)+x+ _1) + (x^2) + x;
+ val f3 = f4.derive(x);
+ val f2 = f3.derive(x);
+ val f1 = f2.derive(x);
+ val f0 = f1.derive(x);
+
+ Console.println("f4(x) = " + f4);
+ Console.println("f3(x) = " + f3);
+ Console.println("f2(x) = " + f2);
+ Console.println("f1(x) = " + f1);
+ Console.println("f0(x) = " + f0);
+ Console.println;
+
+ def check(n: String, f: Expr, x: Int, e: Int): Unit = {
+ val a: Int = f.evaluate(List(("x",x)));
+ val s: String = if (a == e) "ok" else "KO(" + e + ")";
+ Console.println(n + "(" + x + ") = " + a + " " + s);
+ }
+
+ check("f4", f4, 0, 5);
+ check("f4", f4, 1, 56);
+ check("f4", f4, 2, 203);
+ check("f4", f4, 3, 524);
+ check("f4", f4, 4, 1121);
+ Console.println;
+
+ check("f3", f3, 0, 23);
+ check("f3", f3, 1, 88);
+ check("f3", f3, 2, 219);
+ check("f3", f3, 3, 440);
+ Console.println;
+
+ check("f2", f2, 0, 40);
+ check("f2", f2, 1, 94);
+ check("f2", f2, 2, 172);
+ Console.println;
+
+ check("f1", f1, 0, 42);
+ check("f1", f1, 1, 66);
+ Console.println;
+
+ check("f0", f0, 0, 24);
+ Console.println;
+ }
+}
+
+//############################################################################
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ M0.test;
+ M1.test;
+ M2.test;
+ M3.test;
+ M4.test;
+ M5.test;
+ // !!! M6.test;
+ M7.test;
+ M8.test;
+ M9.test;
+ MA.test;
+ MB.test;
+ ()
+ }
+}
+
+//############################################################################
diff --git a/tests/run/Course-2002-13.check b/tests/run/Course-2002-13.check
new file mode 100644
index 000000000..7664f7057
--- /dev/null
+++ b/tests/run/Course-2002-13.check
@@ -0,0 +1,14 @@
+List(S = jean, V = mange, A = le, D = grand, N = table)
+List(S = jean, V = mange, A = le, D = grand, N = cheval)
+
+List(S = jean, V = mange, A = le, D = grand, N = cheval)
+List(S = jean, V = mange, A = la, D = belle, N = table)
+
+List(S = jean, V = mange, A = le, D = nil, N = cheval)
+List(S = jean, V = mange, A = le, D = cons(grand,nil), N = cheval)
+List(S = jean, V = mange, A = le, D = cons(grand,cons(grand,nil)), N = cheval)
+List(S = jean, V = mange, A = la, D = nil, N = table)
+yes
+yes
+no
+
diff --git a/tests/run/Course-2002-13.scala b/tests/run/Course-2002-13.scala
new file mode 100644
index 000000000..a596a3387
--- /dev/null
+++ b/tests/run/Course-2002-13.scala
@@ -0,0 +1,322 @@
+//############################################################################
+// Programmation IV - 2002 - Week 13
+//############################################################################
+
+class Tokenizer(s: String, delimiters: String) extends Iterator[String] {
+
+ private var i = 0;
+
+ def isDelimiter(ch: Char) = {
+ var i = 0;
+ while (i < delimiters.length() && delimiters.charAt(i) != ch) { i = i + 1 }
+ i < delimiters.length()
+ }
+
+ def hasNext: Boolean = {
+ while (i < s.length() && s.charAt(i) <= ' ') { i = i + 1 }
+ i < s.length()
+ }
+
+ def next: String =
+ if (hasNext) {
+ val start = i;
+ var ch = s.charAt(i); i = i + 1;
+ if (isDelimiter(ch)) ch.toString()
+ else {
+ while (i < s.length() &&
+ s.charAt(i) > ' ' &&
+ !isDelimiter(s.charAt(i))){ i = i + 1 }
+ s.substring(start, i)
+ }
+ } else "";
+
+}
+
+object Terms {
+
+ val debug = false;
+
+ trait Term {
+ def map(s: Subst): Term;
+ def tyvars: List[String];
+ }
+
+ case class Binding(name: String, term: Term) {
+ term match { case Var(n) if (name == n) => sys.error("bad binding") case _ => () }
+ override def toString() = name + " = " + term;
+ }
+
+ type Subst = List[Binding];
+
+ def lookup(s: Subst, name: String): Option[Term] = s match {
+ case List() => None
+ case b :: s1 => if (name == b.name) Some(b.term) else lookup(s1, name)
+ }
+
+ case class Var(a: String) extends Term {
+ override def toString() = a;
+ def map(s: Subst): Term = lookup(s, a) match {
+ case Some(b) => b map s
+ case None => this;
+ }
+ def tyvars = List(a);
+ }
+
+ case class Con(a: String, ts: List[Term]) extends Term {
+ override def toString() =
+ a + (if (ts.isEmpty) "" else ts.mkString("(", ",", ")"));
+ def map(s: Subst): Term = Con(a, ts map (t => t map s));
+ def tyvars = (ts flatMap (t => t.tyvars)).distinct;
+ }
+
+ private var count = 0;
+ def newVar(prefix: String) = { count = count + 1; Var(prefix + count) }
+
+ val NoTerm = Con("<none>", List());
+
+ def unify1(x: Term, y: Term, s: Subst): Option[Subst] = (x, y) match {
+ case (Var(a), Var(b)) if (a == b) =>
+ Some(s)
+ case (Var(a), _) => lookup(s, a) match {
+ case Some(x1) => unify(x1, y, s)
+ case None => if (y.tyvars contains a) None else Some(Binding(a, y) :: s)
+ }
+ case (_, Var(b)) => lookup(s, b) match {
+ case Some(y1) => unify(x, y1, s)
+ case None => if (x.tyvars contains b) None else Some(Binding(b, x) :: s)
+ }
+ case (Con(a, xs), Con(b, ys)) if (a == b) =>
+ unify(xs, ys, s)
+ case _ => None
+ }
+
+ def unify(x: Term, y: Term, s: Subst): Option[Subst] = {
+ val ss = unify1(x, y, s);
+ if (debug) Console.println("unify " + x + " with " + y + " = " + ss);
+ ss
+ }
+
+ def unify(xs: List[Term], ys: List[Term], s: Subst): Option[Subst] = (xs, ys) match {
+ case (List(), List()) => Some(s)
+ case (x :: xs1, y :: ys1) =>
+ unify(x, y, s) match {
+ case Some(s1) => unify(xs1, ys1, s1)
+ case None => None
+ }
+ case _ => None
+ }
+}
+
+import Terms._;
+
+object Programs {
+
+ case class Clause(lhs: Term, rhs: List[Term]) {
+ def tyvars =
+ (lhs.tyvars ::: (rhs flatMap (t => t.tyvars))).distinct;
+ def newInstance = {
+ var s: Subst = List();
+ for (a <- tyvars) { s = Binding(a, newVar(a)) :: s }
+ Clause(lhs map s, rhs map (t => t map s))
+ }
+ override def toString() =
+ lhs.toString() + " :- " + rhs.mkString("", ",", "") + ".";
+ }
+
+ def list2stream[a](xs: List[a]): Stream[a] = xs match {
+ case List() => Stream.empty
+ case x :: xs1 => Stream.cons(x, list2stream(xs1))
+ }
+ def option2stream[a](xo: Option[a]): Stream[a] = xo match {
+ case None => Stream.empty
+ case Some(x) => Stream.cons(x, Stream.empty)
+ }
+
+ def solve(query: List[Term], clauses: List[Clause]): Stream[Subst] = {
+
+ def solve2(query: List[Term], s: Subst): Stream[Subst] = query match {
+ case List() =>
+ Stream.cons(s, Stream.empty)
+ case Con("not", qs) :: query1 =>
+ if (solve1(qs, s).isEmpty) Stream.cons(s, Stream.empty)
+ else Stream.empty
+ case q :: query1 =>
+ for (clause <- list2stream(clauses);
+ s1 <- tryClause(clause.newInstance, q, s);
+ s2 <- solve1(query1, s1)) yield s2
+ }
+
+ def solve1(query: List[Term], s: Subst): Stream[Subst] = {
+ val ss = solve2(query, s);
+ if (debug) Console.println("solved " + query + " = " + ss);
+ ss
+ }
+
+ def tryClause(c: Clause, q: Term, s: Subst): Stream[Subst] = {
+ if (debug) Console.println("trying " + c);
+ for (s1 <- option2stream(unify(q, c.lhs, s)); s2 <- solve1(c.rhs, s1)) yield s2;
+ }
+
+ solve1(query, List())
+ }
+}
+
+import Programs._;
+
+class Parser(s: String) {
+ val it = new Tokenizer(s, "(),.?");
+
+ var token: String = it.next;
+
+ def syntaxError(msg: String): Unit = sys.error(msg + ", but " + token + " found");
+
+ def rep[a](p: => a): List[a] = {
+ val t = p;
+ if (token == ",") { token = it.next; t :: rep(p) } else List(t)
+ }
+
+ def constructor: Term = {
+ val a = token;
+ token = it.next;
+ Con(a,
+ if (token equals "(") {
+ token = it.next;
+ val ts: List[Term] = if (token equals ")") List() else rep(term);
+ if (token equals ")") token = it.next else syntaxError("`)' expected");
+ ts
+ } else List())
+ }
+
+ def term: Term = {
+ val ch = token.charAt(0);
+ if ('A' <= ch && ch <= 'Z') { val a = token; token = it.next; Var(a) }
+ else if (it.isDelimiter(ch)) { syntaxError("term expected"); null }
+ else constructor
+ }
+
+ def line: Clause = {
+ val result =
+ if (token equals "?") {
+ token = it.next;
+ Clause(NoTerm, rep(constructor));
+ } else {
+ Clause(
+ constructor,
+ if (token equals ":-") { token = it.next; rep(constructor) } else List())
+ }
+ if (token equals ".") token = it.next else syntaxError("`.' expected");
+ result
+ }
+
+ def all: List[Clause] = if (token equals "") List() else line :: all;
+}
+
+object Prolog {
+
+ def processor: String => Unit = {
+ var program: List[Clause] = List();
+ var solutions: Stream[Subst] = Stream.empty;
+ var tvs: List[String] = List();
+ { input =>
+ new Parser(input).all foreach { c =>
+ if (c.lhs == NoTerm) {
+ c.rhs match {
+ case List(Con("more", List())) =>
+ solutions = solutions.tail;
+ case _ =>
+ solutions = solve(c.rhs, program);
+ tvs = c.tyvars;
+ }
+ if (solutions.isEmpty) {
+ Console.println("no")
+ } else {
+ val s: Subst = solutions.head
+ .filter(b => tvs contains b.name)
+ .map(b => Binding(b.name, b.term map solutions.head))
+ .reverse;
+ if (s.isEmpty) Console.println("yes")
+ else Console.println(s);
+ }
+ } else {
+ program = program ::: List(c);
+ }
+ }
+ }
+ }
+
+ def process(code: String) = processor(code);
+}
+
+//############################################################################
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ Prolog.process(
+ "sujet(jean).\n" +
+ "sujet(marie).\n" +
+ "verbe(mange).\n" +
+ "verbe(dort).\n" +
+ "article(le).\n" +
+ "article(la).\n" +
+ "adjectif(grand).\n" +
+ "adjectif(belle).\n" +
+ "nom(table).\n" +
+ "nom(cheval).\n" +
+
+ "complement(A,D,N) :- article(A), adjectif(D), nom(N).\n" +
+ "phrase(S,V,A,D,N) :- sujet(S), verbe(V), complement(A,D,N).\n" +
+
+ "?phrase(S,V,A,D,N).\n" + "?more.\n"
+ );
+ Console.println;
+
+ Prolog.process(
+ "sujet(jean).\n" +
+ "sujet(marie).\n" +
+ "verbe(mange).\n" +
+ "verbe(dort).\n" +
+ "article(le,m).\n" +
+ "article(la,f).\n" +
+ "adjectif(grand,m).\n" +
+ "adjectif(belle,f).\n" +
+ "nom(table,f).\n" +
+ "nom(cheval,m).\n" +
+
+ "complement(A,D,N) :- article(A,G), adjectif(D,G), nom(N,G).\n" +
+ "phrase(S,V,A,D,N) :- sujet(S), verbe(V), complement(A,D,N).\n" +
+
+ "?phrase(S,V,A,D,N).\n" + "?more.\n"
+ );
+ Console.println;
+
+ Prolog.process(
+ "sujet(jean).\n" +
+ "sujet(marie).\n" +
+ "verbe(mange).\n" +
+ "verbe(dort).\n" +
+ "article(le,m).\n" +
+ "article(la,f).\n" +
+ "adjectif(grand,m).\n" +
+ "adjectif(belle,f).\n" +
+ "nom(table,f).\n" +
+ "nom(cheval,m).\n" +
+
+ "adjectifs(nil,G).\n" +
+ "adjectifs(cons(A1,nil),G) :- adjectif(A1,G).\n" +
+ "adjectifs(cons(A1,cons(A2,nil)),G) :- adjectif(A1,G),adjectif(A2,G).\n"+
+ "complement(A,D,N) :- article(A,G), adjectifs(D,G), nom(N,G).\n" +
+ "phrase(S,V,A,D,N) :- sujet(S), verbe(V), complement(A,D,N).\n" +
+
+ "?phrase(S,V,A,D,N).\n" + "?more.\n" + "?more.\n" + "?more.\n" +
+
+ "?phrase(jean,mange,le,nil,cheval).\n" +
+ "?phrase(jean,mange,le,cons(grand,nil),cheval).\n" +
+ "?phrase(jean,mange,le,cons(grand,nil),table).\n"
+ );
+ Console.println;
+
+ ()
+ }
+}
+
+//############################################################################
diff --git a/tests/run/WeakHashSetTest.scala b/tests/run/WeakHashSetTest.scala
new file mode 100644
index 000000000..8bcb95091
--- /dev/null
+++ b/tests/run/WeakHashSetTest.scala
@@ -0,0 +1,174 @@
+object Test {
+ def main(args: Array[String]): Unit = {
+ val test = scala.reflect.internal.util.WeakHashSetTest
+ test.checkEmpty
+ test.checkPlusEquals
+ test.checkPlusEqualsCollisions
+ test.checkRehashing
+ test.checkRehashCollisions
+ test.checkFindOrUpdate
+ test.checkMinusEquals
+ test.checkMinusEqualsCollisions
+ test.checkClear
+ test.checkIterator
+ test.checkIteratorCollisions
+
+ // This test is commented out because it relies on gc behavior which isn't reliable enough in an automated environment
+ // test.checkRemoveUnreferencedObjects
+ }
+}
+
+// put the main test object in the same package as WeakHashSet because
+// it uses the package private "diagnostics" method
+package scala.reflect.internal.util {
+
+ object WeakHashSetTest {
+ // a class guaranteed to provide hash collisions
+ case class Collider(x : String) extends Comparable[Collider] with Serializable {
+ override def hashCode = 0
+ def compareTo(y : Collider) = this.x compareTo y.x
+ }
+
+ // basic emptiness check
+ def checkEmpty: Unit = {
+ val hs = new WeakHashSet[String]()
+ assert(hs.size == 0)
+ hs.diagnostics.fullyValidate
+ }
+
+ // make sure += works
+ def checkPlusEquals: Unit = {
+ val hs = new WeakHashSet[String]()
+ val elements = List("hello", "goodbye")
+ elements foreach (hs += _)
+ assert(hs.size == 2)
+ assert(hs contains "hello")
+ assert(hs contains "goodbye")
+ hs.diagnostics.fullyValidate
+ }
+
+ // make sure += works when there are collisions
+ def checkPlusEqualsCollisions: Unit = {
+ val hs = new WeakHashSet[Collider]()
+ val elements = List("hello", "goodbye") map Collider
+ elements foreach (hs += _)
+ assert(hs.size == 2)
+ assert(hs contains Collider("hello"))
+ assert(hs contains Collider("goodbye"))
+ hs.diagnostics.fullyValidate
+ }
+
+ // add a large number of elements to force rehashing and then validate
+ def checkRehashing: Unit = {
+ val size = 200
+ val hs = new WeakHashSet[String]()
+ val elements = (0 until size).toList map ("a" + _)
+ elements foreach (hs += _)
+ elements foreach {i => assert(hs contains i)}
+ hs.diagnostics.fullyValidate
+ }
+
+ // make sure rehashing works properly when the set is rehashed
+ def checkRehashCollisions: Unit = {
+ val size = 200
+ val hs = new WeakHashSet[Collider]()
+ val elements = (0 until size).toList map {x => Collider("a" + x)}
+ elements foreach (hs += _)
+ elements foreach {i => assert(hs contains i)}
+ hs.diagnostics.fullyValidate
+ }
+
+ // test that unreferenced objects are removed
+ // not run in an automated environment because gc behavior can't be relied on
+ def checkRemoveUnreferencedObjects: Unit = {
+ val size = 200
+ val hs = new WeakHashSet[Collider]()
+ val elements = (0 until size).toList map {x => Collider("a" + x)}
+ elements foreach (hs += _)
+ // don't throw the following into a retained collection so gc
+ // can remove them
+ for (i <- 0 until size) {
+ hs += Collider("b" + i)
+ }
+ System.gc()
+ Thread.sleep(1000)
+ assert(hs.size == 200)
+ elements foreach {i => assert(hs contains i)}
+ for (i <- 0 until size) {
+ assert(!(hs contains Collider("b" + i)))
+ }
+ hs.diagnostics.fullyValidate
+ }
+
+ // make sure findOrUpdate returns the originally entered element
+ def checkFindOrUpdate: Unit = {
+ val size = 200
+ val hs = new WeakHashSet[Collider]()
+ val elements = (0 until size).toList map {x => Collider("a" + x)}
+ elements foreach {x => assert(hs findEntryOrUpdate x eq x)}
+ for (i <- 0 until size) {
+ // when we do a lookup the result should be the same reference we
+ // original put in
+ assert(hs findEntryOrUpdate(Collider("a" + i)) eq elements(i))
+ }
+ hs.diagnostics.fullyValidate
+ }
+
+ // check -= functionality
+ def checkMinusEquals: Unit = {
+ val hs = new WeakHashSet[String]()
+ val elements = List("hello", "goodbye")
+ elements foreach (hs += _)
+ hs -= "goodbye"
+ assert(hs.size == 1)
+ assert(hs contains "hello")
+ assert(!(hs contains "goodbye"))
+ hs.diagnostics.fullyValidate
+ }
+
+ // check -= when there are collisions
+ def checkMinusEqualsCollisions: Unit = {
+ val hs = new WeakHashSet[Collider]
+ val elements = List(Collider("hello"), Collider("goodbye"))
+ elements foreach (hs += _)
+ hs -= Collider("goodbye")
+ assert(hs.size == 1)
+ assert(hs contains Collider("hello"))
+ assert(!(hs contains Collider("goodbye")))
+ hs -= Collider("hello")
+ assert(hs.size == 0)
+ assert(!(hs contains Collider("hello")))
+ hs.diagnostics.fullyValidate
+ }
+
+ // check that the clear method actually cleans everything
+ def checkClear: Unit = {
+ val size = 200
+ val hs = new WeakHashSet[String]()
+ val elements = (0 until size).toList map ("a" + _)
+ elements foreach (hs += _)
+ hs.clear()
+ assert(hs.size == 0)
+ elements foreach {i => assert(!(hs contains i))}
+ hs.diagnostics.fullyValidate
+ }
+
+ // check that the iterator covers all the contents
+ def checkIterator: Unit = {
+ val hs = new WeakHashSet[String]()
+ val elements = (0 until 20).toList map ("a" + _)
+ elements foreach (hs += _)
+ assert(elements.iterator.toList.sorted == elements.sorted)
+ hs.diagnostics.fullyValidate
+ }
+
+ // check that the iterator covers all the contents even when there is a collision
+ def checkIteratorCollisions: Unit = {
+ val hs = new WeakHashSet[Collider]
+ val elements = (0 until 20).toList map {x => Collider("a" + x)}
+ elements foreach (hs += _)
+ assert(elements.iterator.toList.sorted == elements.sorted)
+ hs.diagnostics.fullyValidate
+ }
+ }
+}
diff --git a/tests/run/bytecodecs.scala b/tests/run/bytecodecs.scala
new file mode 100644
index 000000000..454958dfa
--- /dev/null
+++ b/tests/run/bytecodecs.scala
@@ -0,0 +1,39 @@
+import scala.reflect.internal.pickling.ByteCodecs._
+
+object Test {
+
+ def test8to7(xs: Array[Byte]): Unit = {
+ val ys = encode8to7(xs)
+ decode7to8(ys, ys.length)
+ assert(ys.take(xs.length).deep == xs.deep,
+ "test8to7("+xs.deep+") failed, result = "+ys.take(xs.length).deep)
+ }
+
+ def testAll(xs: Array[Byte]): Unit = {
+ val ys = encode(xs)
+ decode(ys)
+ assert(ys.take(xs.length).deep == xs.deep,
+ "testAll("+xs.deep+") failed, result = "+ys.take(xs.length).deep)
+ }
+
+ def test(inputs: Array[Byte]*): Unit = {
+ for (input <- inputs) {
+ test8to7(input)
+ testAll(input)
+ }
+ }
+
+ def main(args: Array[String]): Unit = {
+ test(
+ Array(1, 2, 3),
+ Array(1, 2, 3, 4, 5, 6, 7),
+ Array(1, -2, 0, -3, -5, -6, -7),
+ Array(1, 3, -1, -128, 0, 0, -128, 1, 2, 3))
+ val rand = new scala.util.Random()
+ for (i <- 1 until 5000) {
+ var xs = new Array[Byte](i)
+ rand.nextBytes(xs)
+ test(xs)
+ }
+ }
+}
diff --git a/tests/run/caseclasses.check b/tests/run/caseclasses.check
new file mode 100644
index 000000000..7eb54ea63
--- /dev/null
+++ b/tests/run/caseclasses.check
@@ -0,0 +1,3 @@
+OK
+creating C(hi)
+OK
diff --git a/tests/run/caseclasses.scala b/tests/run/caseclasses.scala
new file mode 100644
index 000000000..f94bcab95
--- /dev/null
+++ b/tests/run/caseclasses.scala
@@ -0,0 +1,51 @@
+case class Foo(x: Int)(y: Int)
+
+case class Bar()
+
+abstract class Base
+abstract case class Abs(x: Int) extends Base
+
+object M {
+ abstract case class C(x: String) {}
+ object C extends (String => C) {
+ def apply(x: String): C = {
+ println("creating C("+x+")")
+ new C(x) {}
+ }
+ }
+}
+
+object Test extends dotty.runtime.LegacyApp {
+
+ def Abs(x: Int) = new Abs(x * 2){}
+ Abs(2) match {
+ case Abs(4) => ;
+ }
+
+ def fn[a,b](x: a => b) = x;
+ val f = fn(Foo(1))
+ (f(2): AnyRef) match {
+ case Foo(1) => Console.println("OK")
+ case Bar() => Console.println("NO")
+ }
+ try {
+ Bar() productElement 3
+ throw new NullPointerException("duh")
+ } catch {
+ case x:IndexOutOfBoundsException =>
+ }
+
+ M.C("hi") match {
+ case M.C("hi") => println("OK")
+ case _ => println("NO")
+ }
+
+ try {
+ f(2) productElement 3
+ throw new NullPointerException("duh")
+ } catch {
+ case x:IndexOutOfBoundsException =>
+ }
+
+}
+
diff --git a/tests/run/dead-code-elimination.flags b/tests/run/dead-code-elimination.flags
new file mode 100644
index 000000000..49d036a88
--- /dev/null
+++ b/tests/run/dead-code-elimination.flags
@@ -0,0 +1 @@
+-optimize
diff --git a/tests/run/dead-code-elimination.scala b/tests/run/dead-code-elimination.scala
new file mode 100644
index 000000000..fd3f2a996
--- /dev/null
+++ b/tests/run/dead-code-elimination.scala
@@ -0,0 +1,33 @@
+
+// This testcase is a snippet that did not compile correctly under
+// pre-release 2.10.x. The relevant discussion around it can be
+// found at:
+// https://groups.google.com/forum/?fromgroups#!topic/scala-internals/qcyTjk8euUI[1-25]
+//
+// The reason it did not compile is related to the fact that ICode
+// ops did not correctly define the stack entries they consumed and
+// the dead code elimination phase was unable to correctly reconstruct
+// the stack after code elimination.
+//
+// Originally, this did not compile, but I included it in the run
+// tests because this was ASM-dependand and did not happen for GenJVM.
+//
+// Thus, we run the code and force the loading of class B -- if the
+// bytecode is incorrect, it will fail the test.
+
+final class A {
+ def f1 = true
+ def f2 = true
+ @inline def f3 = f1 || f2
+ class B {
+ def f() = 1 to 10 foreach (_ => f3)
+ }
+ def f = (new B).f()
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ // force the loading of B
+ (new A).f
+ }
+}
diff --git a/tests/run/exceptions-2.check b/tests/run/exceptions-2.check
new file mode 100644
index 000000000..4f8244800
--- /dev/null
+++ b/tests/run/exceptions-2.check
@@ -0,0 +1,59 @@
+exceptions-2.scala:267: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+ try { 1 } catch { case e: java.io.IOException => () }
+ ^
+nested1:
+Innermost finally
+Outermost finally
+nested2:
+Innermost finally
+Outermost finally
+mixed:
+10
+Finally!
+withValue1:
+Oh, oh
+10
+withValue2:
+droped a null
+null
+method2:
+10
+Exception occurred
+method3:
+Caught an NPE
+tryFinallyTry:
+Silently ignore exception in finally
+valInFinally:
+Abc
+tryAndValInFinally
+Abc
+=================
+NoExcep.method2:
+Hello, world
+NoExcep.method3:
+method3
+NoExcep.method4:
+..
+Return inside body:
+Normal execution...
+inner finally
+Outer finally
+Return inside synchronized body:
+Synchronized normal execution...
+inner finally
+Outer finally
+Return inside body and return in finally:
+Normal execution...
+inner finally
+Outer finally
+Return inside body and return in finally inside finally:
+Normal execution...
+inner finally
+finally inside finally
+Outer finally
+Throw in catch and finally:
+ABC
+Return with finally clause that cleans the stack
+Normal execution...
+inner finally
+Outer finally
diff --git a/tests/run/exceptions-2.scala b/tests/run/exceptions-2.scala
new file mode 100644
index 000000000..8d755c380
--- /dev/null
+++ b/tests/run/exceptions-2.scala
@@ -0,0 +1,349 @@
+/*
+ * Try exception handling and finally blocks.
+ */
+
+trait Tree extends Exception;
+
+case class Node(a: Tree, b: Tree) extends Tree;
+case class Leaf(x: Int) extends Tree;
+
+
+object NoExcep {
+ def a = true;
+ def b = false;
+ def c = true;
+
+ def method1(t: Tree) = try {
+ Console.println(t);
+ } catch {
+ case Node(Leaf(_), Leaf(_)) => a;
+ case Leaf(_) => b;
+ }
+
+ def method2 = try {
+ Console.println("Hello, world");
+ } catch {
+ case _: Error => Console.println("File error");
+ case t: Throwable => Console.println("Unknown error");
+ }
+
+ def method3 = try {
+ try {
+ Console.println("method3");
+ } catch {
+ case Node(Leaf(_), Leaf(_)) => Console.println("First one");
+ case Leaf(_) => Console.println("Second one");
+ }
+ } catch {
+ case _: Error => Console.println("File error");
+ case t: Exception => Console.println("Unknown error");
+ }
+
+ def method4 = try {
+ Console.println("..");
+ } catch {
+ case _: Throwable => sys.error("..");
+ }
+}
+
+object Test {
+ def nested1: Unit = try {
+ try {
+ sys.error("nnnnoooo");
+ } finally {
+ Console.println("Innermost finally");
+ }
+ } finally {
+ Console.println("Outermost finally");
+ }
+
+ def nested2 = try {
+ try {
+ sys.error("nnnnoooo");
+ } finally {
+ Console.println("Innermost finally");
+ }
+ Console.println("Intermediary step");
+ } finally {
+ Console.println("Outermost finally");
+ }
+
+ def mixed =
+ try {
+ if (10 > 0)
+ throw Leaf(10);
+ Console.println("nooo oneeee can priiiint meee");
+ } catch {
+ case Leaf(a) => Console.println(a);
+ case _: Exception => Console.println("Exception occurred");
+ } finally {
+ Console.println("Finally!");
+ }
+
+ def method2: Unit = {
+ try {
+ if (10 > 0)
+ throw Leaf(10);
+ Console.println("nooo oneeee can priiiint meee");
+ } catch {
+ case Leaf(a) => Console.println(a);
+ case _: Exception => Console.println("Exception occurred");
+ }
+
+ try {
+ val a: Leaf = null;
+ println(a.x);
+ } catch {
+ case Leaf(a) => Console.println(a);
+ case _: NullPointerException => Console.println("Exception occurred");
+ }
+ }
+
+ def method3: Unit = try {
+ try {
+ val a: Leaf = null;
+ println(a.x);
+ } catch {
+ case Leaf(a) => Console.println(a);
+ }
+ } catch {
+ case npe: NullPointerException =>
+ Console.println("Caught an NPE");
+ }
+
+ def withValue1: Unit = {
+ val x = try {
+ 10
+ } finally {
+ Console.println("Oh, oh");
+ };
+ Console.println(x);
+ }
+
+ def withValue2: Unit = {
+ val x = try {
+ null
+ } finally {
+ Console.println("droped a null");
+ };
+ Console.println(x);
+ }
+
+ def tryFinallyTry: Unit = {
+ try {
+ ()
+ } finally {
+ try {
+ sys.error("a");
+ } catch {
+ case _: Throwable => Console.println("Silently ignore exception in finally");
+ }
+ }
+ }
+
+ def valInFinally: Unit =
+ try {
+ } finally {
+ val fin = "Abc";
+ Console.println(fin);
+ }
+
+ def tryAndValInFinally: Unit =
+ try {
+ } finally {
+ val fin = "Abc";
+ try {
+ Console.println(fin);
+ } catch { case _: Throwable => () }
+ }
+
+ def returnInBody: Unit = try {
+ try {
+ Console.println("Normal execution...");
+ return
+ Console.println("non reachable code");
+ } finally {
+ Console.println("inner finally");
+ }
+ } finally {
+ Console.println("Outer finally");
+ }
+
+ def returnInBodySynch: Unit = try {
+ synchronized {
+ try {
+ Console.println("Synchronized normal execution...");
+ return
+ Console.println("non reachable code");
+ } finally {
+ Console.println("inner finally");
+ }
+ }
+ } finally {
+ Console.println("Outer finally");
+ }
+
+
+ def returnInBodyAndInFinally: Unit = try {
+ try {
+ Console.println("Normal execution...");
+ return
+ Console.println("non reachable code");
+ } finally {
+ Console.println("inner finally");
+ return
+ }
+ } finally {
+ Console.println("Outer finally");
+ return
+ }
+
+ def returnInBodyAndInFinally2: Unit = try {
+ try {
+ Console.println("Normal execution...");
+ return
+ Console.println("non reachable code");
+ } finally {
+ try {
+ Console.println("inner finally");
+ return
+ } finally {
+ Console.println("finally inside finally");
+ }
+ }
+ } finally {
+ Console.println("Outer finally");
+ return
+ }
+
+ /** bug #1020, no crash at compile time */
+ def tryCatchInFinally: Unit = {
+ try {
+ Console.println("Try")
+ } catch {
+ case e:java.io.IOException =>
+ throw e
+ } finally {
+ val x = 10
+ // Always make sure result sets and statements are closed,
+ // and the connection is returned to the pool
+ if (x != 10) {
+ try { Console.println("Fin"); } catch { case e:java.io.IOException => ; }
+ }
+ }
+ }
+
+ def tryThrowFinally: Unit = {
+ try {
+ print("A")
+ throw new Exception
+ } catch {
+ case e : Exception =>
+ print("B")
+ throw e
+ } finally {
+ println("C")
+ }
+ }
+
+ def execute(f: => Unit) = try {
+ f;
+ } catch {
+ case _: Throwable => ()
+ }
+
+
+ def returnWithFinallyClean: Int = try {
+ try {
+ Console.println("Normal execution...");
+ return 10
+ Console.println("non reachable code");
+ 11
+ } finally {
+ Console.println("inner finally");
+ }
+ } finally {
+ Console.println("Outer finally");
+ try { 1 } catch { case e: java.io.IOException => () }
+ }
+
+ /** Test that empty finally clauses containing while are correctly emitted.
+ */
+ class Issue {
+ var b = 0
+ try {
+ // println("abc")
+ } finally {
+ while (b == -1) {b = 0}
+ }
+ }
+
+ /* Tests that class Issue passes verification. */
+ def whileInFinally = {
+ new Issue
+ }
+
+
+
+ def main(args: Array[String]): Unit = {
+ Console.println("nested1: ");
+ execute(nested1);
+
+ Console.println("nested2: ");
+ execute(nested2);
+
+ Console.println("mixed: ");
+ execute(mixed);
+
+ Console.println("withValue1:");
+ execute(withValue1);
+
+ Console.println("withValue2:");
+ execute(withValue2);
+
+ Console.println("method2:");
+ execute(method2);
+
+ Console.println("method3:");
+ execute(method3);
+
+ Console.println("tryFinallyTry:");
+ execute(tryFinallyTry);
+
+ Console.println("valInFinally:");
+ execute(valInFinally);
+ Console.println("tryAndValInFinally");
+ execute(tryAndValInFinally);
+
+ Console.println("=================");
+
+ Console.println("NoExcep.method2:");
+ execute(NoExcep.method2);
+
+ Console.println("NoExcep.method3:");
+ execute(NoExcep.method3);
+
+ Console.println("NoExcep.method4:");
+ execute(NoExcep.method4);
+
+ Console.println("Return inside body:");
+ execute(returnInBody);
+
+ Console.println("Return inside synchronized body:");
+ execute(returnInBodySynch);
+
+ Console.println("Return inside body and return in finally:");
+ execute(returnInBodyAndInFinally);
+
+ Console.println("Return inside body and return in finally inside finally:");
+ execute(returnInBodyAndInFinally2);
+
+ Console.println("Throw in catch and finally:");
+ execute(tryThrowFinally);
+
+ Console.println("Return with finally clause that cleans the stack")
+ returnWithFinallyClean
+
+ whileInFinally
+ }
+}
diff --git a/tests/run/exceptions.check b/tests/run/exceptions.check
new file mode 100644
index 000000000..b959df29e
--- /dev/null
+++ b/tests/run/exceptions.check
@@ -0,0 +1 @@
+ok: lookup(2000) = KO
diff --git a/tests/run/exceptions.scala b/tests/run/exceptions.scala
new file mode 100644
index 000000000..f0fe76946
--- /dev/null
+++ b/tests/run/exceptions.scala
@@ -0,0 +1,52 @@
+//############################################################################
+// Exceptions
+//############################################################################
+
+//############################################################################
+
+abstract class IntMap[A] {
+ def lookup(key: Int): A = this match {
+ case Empty() => sys.error("KO")
+ case _ => sys.error("ok")
+ }
+}
+
+case class Empty[A]() extends IntMap[A];
+
+object exceptions {
+
+ def check(what: String, actual: Any, expected: Any): Unit = {
+ val success: Boolean = actual == expected;
+ Console.print(if (success) "ok" else "KO");
+ var value: String = if (actual == null) "null" else actual.toString();
+ if (value == "\u0000") value = "\\u0000";
+ Console.print(": " + what + " = " + value);
+ if (!success) Console.print(" != " + expected);
+ Console.println;
+ Console.flush;
+ }
+
+ def test: Unit = {
+ val key = 2000;
+ val map: IntMap[String] = new Empty[String];
+ val value = try {
+ map.lookup(key)
+ } catch {
+ case e: Throwable => e.getMessage()
+ }
+ check("lookup(" + key + ")", value, "KO");
+ }
+
+}
+
+//############################################################################
+
+object Test {
+
+ def main(args: Array[String]): Unit = {
+ exceptions.test;
+ }
+
+}
+
+//############################################################################
diff --git a/tests/run/hashCodeDistribution.scala b/tests/run/hashCodeDistribution.scala
new file mode 100644
index 000000000..284f3d977
--- /dev/null
+++ b/tests/run/hashCodeDistribution.scala
@@ -0,0 +1,17 @@
+// See ticket #2537.
+object Test {
+ case class C(x: Int, y: Int) { }
+ val COUNT = 300
+ val totalCodes = COUNT * COUNT
+
+ def main (args: Array[String]) = {
+ val hashCodes =
+ for (x <- 0 until COUNT; y <- 0 until COUNT) yield C(x,y).hashCode
+
+ val uniques = hashCodes.distinct
+ val collisionRate = (totalCodes - uniques.size) * 1000 / totalCodes
+
+ assert(collisionRate < 5, "Collision rate too high: %d / 1000".format(collisionRate))
+ // println("collisionRate = %d / 1000".format(collisionRate))
+ }
+}
diff --git a/tests/run/matcharraytail.check b/tests/run/matcharraytail.check
new file mode 100644
index 000000000..f2844d41a
--- /dev/null
+++ b/tests/run/matcharraytail.check
@@ -0,0 +1,2 @@
+Array(foo, bar, baz)
+Vector(bar, baz)
diff --git a/tests/run/matcharraytail.scala b/tests/run/matcharraytail.scala
new file mode 100644
index 000000000..3120769f4
--- /dev/null
+++ b/tests/run/matcharraytail.scala
@@ -0,0 +1,7 @@
+object Test extends dotty.runtime.LegacyApp{
+ Array("foo", "bar", "baz") match {
+ case x@Array("foo", bar :_*) => println(x.deep.toString); println(bar.toString);
+ case Array(x, y, z) => println("shouldn't have fallen through");
+ case _ => println("default case?!");
+ }
+}
diff --git a/tests/run/matchonstream.check b/tests/run/matchonstream.check
new file mode 100644
index 000000000..3dc3aa516
--- /dev/null
+++ b/tests/run/matchonstream.check
@@ -0,0 +1 @@
+It worked!
diff --git a/tests/run/matchonstream.scala b/tests/run/matchonstream.scala
new file mode 100644
index 000000000..6e5556519
--- /dev/null
+++ b/tests/run/matchonstream.scala
@@ -0,0 +1,3 @@
+object Test extends dotty.runtime.LegacyApp{
+ Stream.from(1) match { case Stream(1, 2, x :_*) => println("It worked!") }
+}
diff --git a/tests/run/mixin-bridge-methods.scala b/tests/run/mixin-bridge-methods.scala
new file mode 100644
index 000000000..e0340ebb1
--- /dev/null
+++ b/tests/run/mixin-bridge-methods.scala
@@ -0,0 +1,14 @@
+trait Foo {
+ def getFoo() = "foo"
+}
+
+class Sub extends Foo {
+ def getBar() = "bar"
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val ms = classOf[Sub].getDeclaredMethods
+ assert(ms forall (x => !x.isBridge), ms mkString " ")
+ }
+}
diff --git a/tests/run/null-and-intersect.check b/tests/run/null-and-intersect.check
new file mode 100644
index 000000000..81890cfef
--- /dev/null
+++ b/tests/run/null-and-intersect.check
@@ -0,0 +1,9 @@
+1
+2
+3
+4
+1
+2
+1
+2
+2
diff --git a/tests/run/null-and-intersect.scala b/tests/run/null-and-intersect.scala
new file mode 100644
index 000000000..7266dabe6
--- /dev/null
+++ b/tests/run/null-and-intersect.scala
@@ -0,0 +1,34 @@
+object Test {
+ trait Immortal
+ class Bippy extends Immutable with Immortal
+ class Boppy extends Immutable
+
+ def f[T](x: Traversable[T]) = x match {
+ case _: Map[_, _] => 3
+ case _: Seq[_] => 2
+ case _: Iterable[_] => 1
+ case _ => 4
+ }
+ def g(x: Bippy) = x match {
+ case _: Immutable with Immortal => 1
+ case _ => 2
+ }
+ def h(x: Immutable) = x match {
+ case _: Immortal => 1
+ case _ => 2
+ }
+
+ def main(args: Array[String]): Unit = {
+ println(f(Set(1)))
+ println(f(Seq(1)))
+ println(f(Map(1 -> 2)))
+ println(f(null))
+
+ println(g(new Bippy))
+ println(g(null))
+
+ println(h(new Bippy))
+ println(h(new Boppy))
+ println(h(null))
+ }
+}
diff --git a/tests/run/option-fold.check b/tests/run/option-fold.check
new file mode 100644
index 000000000..4e3fe99f9
--- /dev/null
+++ b/tests/run/option-fold.check
@@ -0,0 +1,5 @@
+List()
+List(5)
+-1
+0
+1
diff --git a/tests/run/option-fold.scala b/tests/run/option-fold.scala
new file mode 100644
index 000000000..84e346ec7
--- /dev/null
+++ b/tests/run/option-fold.scala
@@ -0,0 +1,20 @@
+object Test {
+ sealed class A
+ case object B extends A
+ case class C(x: Int) extends A
+
+ def f[T](x: Option[T]) = x.fold(List.empty[T])(List(_))
+ def g(x: Option[A]) = x.fold(-1) {
+ case B => 0
+ case C(x) => x
+ case _ => ???
+ }
+
+ def main(args: Array[String]): Unit = {
+ println(f(None)) //List()
+ println(f(Some(5))) //List(5)
+ println(g(None)) //-1
+ println(g(Some(B))) //0
+ println(g(Some(C(1)))) //1
+ }
+}
diff --git a/tests/run/proxy.check b/tests/run/proxy.check
new file mode 100644
index 000000000..c40b3db7c
--- /dev/null
+++ b/tests/run/proxy.check
@@ -0,0 +1,6 @@
+false
+true
+false
+false
+true
+true
diff --git a/tests/run/proxy.scala b/tests/run/proxy.scala
new file mode 100644
index 000000000..8449b7329
--- /dev/null
+++ b/tests/run/proxy.scala
@@ -0,0 +1,17 @@
+object Test extends dotty.runtime.LegacyApp {
+ val p = new Proxy {
+ def self = 2
+ }
+ println(p equals 1)
+ println(p equals 2)
+ println(p equals 3)
+ println(p equals null)
+
+ case class Bippy(a: String) extends Proxy {
+ def self = a
+ }
+
+ val label = Bippy("bippy!")
+ println(label == label)
+ println(label == "bippy!")
+}
diff --git a/tests/run/range.scala b/tests/run/range.scala
new file mode 100644
index 000000000..ee934f627
--- /dev/null
+++ b/tests/run/range.scala
@@ -0,0 +1,83 @@
+import scala.collection.immutable.{ Range, NumericRange }
+
+object Test {
+ def rangeForeach(range : Range) = {
+ val buffer = new scala.collection.mutable.ListBuffer[Int];
+ range.foreach(buffer += _);
+ assert(buffer.toList == range.iterator.toList, buffer.toList+"/"+range.iterator.toList)
+ }
+
+ def boundaryTests() = {
+ // #4321
+ assert((Int.MinValue to Int.MaxValue by Int.MaxValue).size == 3)
+ // #4308
+ val caught = (
+ try { (Long.MinValue to Long.MaxValue).sum ; false }
+ catch { case _: IllegalArgumentException => true }
+ )
+ assert(caught)
+ // #7432
+ val noElemAtMin = (
+ try { (10 until 10).min ; false }
+ catch { case _: NoSuchElementException => true }
+ )
+ assert(noElemAtMin)
+ val noElemAtMax = (
+ try { (10 until 10).max ; false }
+ catch { case _: NoSuchElementException => true }
+ )
+ assert(noElemAtMax)
+ }
+
+ case class GR[T](val x: T)(implicit val num: Integral[T]) {
+ import num._
+
+ def negated = GR[T](-x)
+
+ def gr1 = NumericRange(x, x, x)
+ def gr2 = NumericRange.inclusive(x, x, x)
+ def gr3 = NumericRange(x, x * fromInt(10), x)
+ def gr4 = NumericRange.inclusive(x, x * fromInt(10), x)
+ def gr5 = gr3.toList ::: negated.gr3.toList
+
+ def check = {
+ assert(gr1.isEmpty && !gr2.isEmpty)
+ assert(gr3.size == 9 && gr4.size == 10)
+ assert(gr5.sum == num.zero, gr5.toString)
+ assert(!(gr3 contains (x * fromInt(10))))
+ assert((gr4 contains (x * fromInt(10))))
+ }
+ }
+
+ def main(args: Array[String]): Unit = {
+ implicit val imp1: Numeric.BigDecimalAsIfIntegral.type = Numeric.BigDecimalAsIfIntegral
+ implicit val imp2: Numeric.DoubleAsIfIntegral.type = Numeric.DoubleAsIfIntegral
+
+ val _grs = List[GR[_]](
+ GR(BigDecimal(5.0)),
+ GR(BigInt(5)),
+ GR(5L),
+ GR(5.0d),
+ GR(2.toByte)
+ )
+ val grs = _grs ::: (_grs map (_.negated))
+ grs foreach (_.check)
+
+ assert(NumericRange(1, 10, 1) sameElements (1 until 10))
+ assert(NumericRange.inclusive(1, 10, 1) sameElements (1 to 10))
+ assert(NumericRange.inclusive(1, 100, 3) sameElements (1 to 100 by 3))
+
+ // #2518
+ assert((3L to 7 by 2) sameElements List(3L, 5L, 7L))
+
+ rangeForeach(1 to 10);
+ rangeForeach(1 until 10);
+ rangeForeach(10 to 1 by -1);
+ rangeForeach(10 until 1 by -1);
+ rangeForeach(10 to 1 by -3);
+ rangeForeach(10 until 1 by -3);
+
+ // living on the edges
+ boundaryTests()
+ }
+}
diff --git a/tests/run/t0325.check b/tests/run/t0325.check
new file mode 100644
index 000000000..85fe91dac
--- /dev/null
+++ b/tests/run/t0325.check
@@ -0,0 +1,35 @@
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
+List(a, b)
diff --git a/tests/run/t0325.scala b/tests/run/t0325.scala
new file mode 100644
index 000000000..ea6180306
--- /dev/null
+++ b/tests/run/t0325.scala
@@ -0,0 +1,53 @@
+case class RS(self: String) {
+
+ // NB. "\\Q" + '\\' + "\\E" works on Java 1.5 and newer, but not on Java 1.4
+ private def escape(ch: Char): String = ch match {
+ case '\\' => "\\\\"
+ case _ => "\\Q"+ch+"\\E"
+ }
+
+ def split(separator: Char): Array[String] = self.split(escape(separator))
+
+ def split(separators: Array[Char]): Array[String] = {
+ val re = separators.foldLeft("[")(_+escape(_)) + "]"
+ self.split(re)
+ }
+}
+
+object Test {
+ def expect = List("a","b")
+ def test(f: => Array[String], which: String): Unit = {
+ try {
+ val ret = f.toList
+ if (ret != expect)
+ println(which + " returned " + ret + " when expecting " + expect)
+ else
+ println(ret)
+ } catch {
+ case e: Throwable => println(which + " failed with " + e.getClass)
+ }
+ }
+
+ def main(args: Array[String]): Unit = {
+ val badChars = "?*{+([\\^.$"
+
+ for (c <- badChars)
+ test(("a"+c+"b").split(c),"RichString split('"+ c + "')")
+ println
+
+ for (c <- badChars)
+ test(RS("a"+c+"b").split(c),"RS split('"+ c + "')")
+ println
+
+ val badCases = List(
+ ']' -> "x]", '&' -> "&&",'\\' -> "\\x", '[' -> "[x",
+ '^' -> "^x", '-' -> "x-z"
+ )
+ for ((c,str) <- badCases)
+ test(("a"+c+"b").split(str.toArray),"RichString split(\""+ str + "\")")
+ println
+
+ for ((c,str) <- badCases)
+ test(RS("a"+c+"b").split(str.toArray),"RS split(\""+ str + "\")")
+ }
+}
diff --git a/tests/run/t0631.check b/tests/run/t0631.check
new file mode 100644
index 000000000..0a7d5e499
--- /dev/null
+++ b/tests/run/t0631.check
@@ -0,0 +1,3 @@
+Foo.equals called
+false
+true
diff --git a/tests/run/t0631.scala b/tests/run/t0631.scala
new file mode 100644
index 000000000..2767b4bf0
--- /dev/null
+++ b/tests/run/t0631.scala
@@ -0,0 +1,16 @@
+object Test extends dotty.runtime.LegacyApp {
+ class Foo {
+ override def equals(that: Any) = {
+ println("Foo.equals called")
+ super.equals(that)
+ }
+ }
+
+ println(new Foo == new Foo)
+
+ case class Bar(x: Foo)
+ val b = new Bar(new Foo)
+
+ // this should not call Foo.equals, but simply compare object identiy of b
+ println(b == b)
+}
diff --git a/tests/run/t1333.check b/tests/run/t1333.check
new file mode 100644
index 000000000..6303af7f1
--- /dev/null
+++ b/tests/run/t1333.check
@@ -0,0 +1,3 @@
+10
+-10
+-1
diff --git a/tests/run/t1333.scala b/tests/run/t1333.scala
new file mode 100644
index 000000000..1696629cb
--- /dev/null
+++ b/tests/run/t1333.scala
@@ -0,0 +1,14 @@
+object Test {
+ case class A(x: Int)(y: Int)(z: String)
+
+ def f(x: Any) = x match {
+ case A(x) => x
+ case _ => -1
+ }
+
+ def main(args: Array[String]): Unit = {
+ println(f(A(10)(20)("abc")))
+ println(f(A(-10)(20)("abc")))
+ println(f(List(1)))
+ }
+}
diff --git a/tests/run/t1697.scala b/tests/run/t1697.scala
new file mode 100644
index 000000000..39dcdd732
--- /dev/null
+++ b/tests/run/t1697.scala
@@ -0,0 +1,19 @@
+class Term
+case class Num(n: Int) extends Term
+case class Add(x: Term, y: Term) extends Term
+
+object Value {
+ def unapply(term: Any): Boolean = true
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val term = Add(Num(1), Add(Num(2), Num(3)))
+ val res = term match {
+ case Add(Num(x), Num(y)) => "Add(Num, Num)"
+ case Add(Value(), y) => "Add(Value, ?)"
+ case _ => "?"
+ }
+ assert(res == "Add(Value, ?)")
+ }
+}
diff --git a/tests/run/t1909b.scala b/tests/run/t1909b.scala
new file mode 100644
index 000000000..b4bb9a1e0
--- /dev/null
+++ b/tests/run/t1909b.scala
@@ -0,0 +1,9 @@
+class Ticket1909 (x: Int) {
+ def this() = this({
+ def bar() = 5
+ bar
+ })
+}
+object Test extends dotty.runtime.LegacyApp {
+ new Ticket1909()
+}
diff --git a/tests/run/t2074_2.check b/tests/run/t2074_2.check
new file mode 100644
index 000000000..0876ef7d0
--- /dev/null
+++ b/tests/run/t2074_2.check
@@ -0,0 +1,3 @@
+SeqView(...)
+SeqView(...)
+SeqViewZ(...)
diff --git a/tests/run/t2074_2.scala b/tests/run/t2074_2.scala
new file mode 100644
index 000000000..4624170f8
--- /dev/null
+++ b/tests/run/t2074_2.scala
@@ -0,0 +1,22 @@
+// replaced all occurrences of 'Vector' with 'IndexedSeq'
+import scala.collection.immutable.IndexedSeq
+import scala.collection.SeqView
+
+object Test {
+ val funWithCCE = List.range(1,11).view.patch(5, List(100,101), 2)
+
+ val v = new SeqView[Int, IndexedSeq[Int]] {
+ def underlying = IndexedSeq(1,2,3)
+ def apply(idx: Int) = underlying(idx)
+ def length = underlying.length
+ def iterator = underlying.iterator
+ }
+ val w = IndexedSeq(1, 2, 3).view
+
+ def main(args: Array[String]): Unit = {
+ println(v)
+ println(w)
+ println(go)
+ }
+ def go = v zip v
+}
diff --git a/tests/run/t2175.scala b/tests/run/t2175.scala
new file mode 100644
index 000000000..7885882d3
--- /dev/null
+++ b/tests/run/t2175.scala
@@ -0,0 +1,20 @@
+case class Property[T](private var t: T) {
+ var beforeChanges: List[(T, T) => Unit] = Nil
+ var afterChanges: List[T => Unit] = Nil
+ def apply = t
+ def update(t2: T) = {
+ beforeChanges foreach (_(t, t2))
+ t = t2
+ afterChanges foreach (_(t2))
+ }
+}
+
+object Test
+{
+ def main(args: Array[String]): Unit = {
+ val x = Property(10)
+ x update 25
+ assert(x.apply == 25)
+ }
+}
+
diff --git a/tests/run/t2316_run.scala b/tests/run/t2316_run.scala
new file mode 100644
index 000000000..a2adad415
--- /dev/null
+++ b/tests/run/t2316_run.scala
@@ -0,0 +1,32 @@
+case class T1(source: String)
+
+object T1 {
+ implicit def T1FromT2(implicit t2: T2): T1 = new T1(t2.source)
+}
+
+case class T2(source: String)
+
+object A {
+ def requireT1(implicit t1: T1) = t1
+
+ object B1 {
+ implicit val t2_b1: T2 = new T2("from B1")
+ requireT1
+ }
+
+ object B2 {
+ def t1 = {
+ implicit val t2_b2: T2 = new T2("from B2")
+ // Implicits.cacheResult returns T1.T1FromT2(t2_b1) here, which is bogus. Even though T1.T1FromT2 was found
+ // outside of the scope of A.B1, this implicit expression should _not_ be cached, as it includes the bound
+ // variable t2_b1 from this scope.
+ requireT1
+ }
+ }
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ assert(A.B2.t1.source == "from B2")
+ }
+}
diff --git a/tests/run/t2417.check b/tests/run/t2417.check
new file mode 100644
index 000000000..36c954be2
--- /dev/null
+++ b/tests/run/t2417.check
@@ -0,0 +1,12 @@
+testing small Map that doesn't promote to HashMap...
+
+testing single-threaded HashMap use...
+
+testing HashMap.size from multiple threads...
+
+testing small Set that doesn't promote to HashSet...
+
+testing single-threaded HashSet use...
+
+testing HashSet.size from multiple threads...
+
diff --git a/tests/run/t2417.scala b/tests/run/t2417.scala
new file mode 100644
index 000000000..80105f72b
--- /dev/null
+++ b/tests/run/t2417.scala
@@ -0,0 +1,77 @@
+// #2417
+object Test {
+
+ def parallel(numThreads: Int)(block: => Unit): Unit = {
+ var failure: Throwable = null
+ val threads = Array.tabulate(numThreads)(i => new Thread {
+ override def run: Unit = {
+ try {
+ block
+ } catch {
+ case x: Throwable => failure = x
+ }
+ }
+ })
+ for (t <- threads) t.start
+ for (t <- threads) t.join
+ if (failure != null) println("FAILURE: " + failure)
+ }
+
+ def testSet(initialSize: Int, numThreads: Int, passes: Int): Unit = {
+ val orig = Set.empty ++ (1 to initialSize)
+ parallel(numThreads) {
+ for (pass <- 0 until passes) {
+ var s = orig
+ for (e <- (initialSize to 1 by -1)) {
+ s -= e
+ val obs = s.size
+ if (obs != e - 1) {
+ throw new Exception("removed e=" + e + ", size was " + obs + ", s=" + s)
+ }
+ }
+ }
+ }
+ }
+
+ def testMap(initialSize: Int, numThreads: Int, passes: Int): Unit = {
+ val orig = Map.empty ++ ((1 to initialSize) map ((_,"v")))
+ parallel(numThreads) {
+ for (pass <- 0 until passes) {
+ var m = orig
+ for (e <- (initialSize to 1 by -1)) {
+ m -= e
+ val obs = m.size
+ if (obs != e - 1) {
+ throw new Exception("removed e=" + e + ", size was " + obs + ", m=" + m)
+ }
+ }
+ }
+ }
+ }
+
+ def main(args: Array[String]): Unit = {
+ println("testing small Map that doesn't promote to HashMap...")
+ testMap(4, 2, 1000000)
+ println()
+
+ println("testing single-threaded HashMap use...")
+ testMap(5, 1, 1000000)
+ println()
+
+ println("testing HashMap.size from multiple threads...")
+ testMap(5, 2, 1000000)
+ println()
+
+ println("testing small Set that doesn't promote to HashSet...")
+ testSet(4, 2, 1000000)
+ println()
+
+ println("testing single-threaded HashSet use...")
+ testSet(5, 1, 1000000)
+ println()
+
+ println("testing HashSet.size from multiple threads...")
+ testSet(5, 2, 1000000)
+ println()
+ }
+}
diff --git a/tests/run/t2544.check b/tests/run/t2544.check
new file mode 100644
index 000000000..d19538dca
--- /dev/null
+++ b/tests/run/t2544.check
@@ -0,0 +1,10 @@
+2
+2
+3
+3
+-1
+-1
+1
+1
+0
+0
diff --git a/tests/run/t2544.scala b/tests/run/t2544.scala
new file mode 100644
index 000000000..6bee2f108
--- /dev/null
+++ b/tests/run/t2544.scala
@@ -0,0 +1,25 @@
+object Test {
+ object Foo extends Seq[Int] {
+ def apply(i: Int) = i
+ def length = 5
+ def iterator = Iterator(0,1,2,3,4)
+ }
+ def lengthEquiv(result: Int) = println(
+ if (result < 0) -1
+ else if (result == 0) 0
+ else 1
+ )
+
+ def main(args: Array[String]) = {
+ println(Foo indexWhere(_ >= 2,1))
+ println(Foo.toList indexWhere(_ >= 2,1))
+ println(Foo segmentLength(_ <= 3,1))
+ println(Foo.toList segmentLength(_ <= 3,1))
+ lengthEquiv(Foo lengthCompare 7)
+ lengthEquiv(Foo.toList lengthCompare 7)
+ lengthEquiv(Foo lengthCompare 2)
+ lengthEquiv(Foo.toList lengthCompare 2)
+ lengthEquiv(Foo lengthCompare 5)
+ lengthEquiv(Foo.toList lengthCompare 5)
+ }
+}
diff --git a/tests/run/t2788.check b/tests/run/t2788.check
new file mode 100644
index 000000000..684f5f616
--- /dev/null
+++ b/tests/run/t2788.check
@@ -0,0 +1 @@
+List(1, 2) \ No newline at end of file
diff --git a/tests/run/t2788.scala b/tests/run/t2788.scala
new file mode 100644
index 000000000..61344029d
--- /dev/null
+++ b/tests/run/t2788.scala
@@ -0,0 +1,3 @@
+object Test extends dotty.runtime.LegacyApp {
+ println(Array(Some(1), None, Some(2)).flatten.toList)
+}
diff --git a/tests/run/t3038d.flags b/tests/run/t3038d.flags
new file mode 100644
index 000000000..ae0844605
--- /dev/null
+++ b/tests/run/t3038d.flags
@@ -0,0 +1 @@
+-Xcheckinit \ No newline at end of file
diff --git a/tests/run/t3038d.scala b/tests/run/t3038d.scala
new file mode 100644
index 000000000..3dab07675
--- /dev/null
+++ b/tests/run/t3038d.scala
@@ -0,0 +1,58 @@
+trait Foo {
+ @transient protected var load = 1
+ @transient protected var a = 12
+
+ protected def init[B](in: java.io.ObjectInputStream): Unit = {
+ in.defaultReadObject
+ load = in.readInt
+ val sizea = in.readInt
+ a = 12
+ }
+
+ protected def serializeTo(out: java.io.ObjectOutputStream): Unit = {
+ out.defaultWriteObject
+ out.writeInt(load)
+ out.writeInt(a)
+ }
+}
+
+class Bar extends Foo with Serializable {
+ @transient protected var first: Any = null
+ def size = a
+ @transient var second: Any = null
+
+ def checkMember: Unit = { if (first == null) print("") }
+
+ private def writeObject(out: java.io.ObjectOutputStream): Unit = {
+ serializeTo(out)
+ }
+
+ private def readObject(in: java.io.ObjectInputStream): Unit = {
+ first = null
+ init(in)
+ }
+}
+
+object Test {
+ private def toObject[A](bytes: Array[Byte]): A = {
+ val in = new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(bytes))
+ in.readObject.asInstanceOf[A]
+ }
+
+ private def toBytes(o: AnyRef): Array[Byte] = {
+ val bos = new java.io.ByteArrayOutputStream
+ val out = new java.io.ObjectOutputStream(bos)
+ out.writeObject(o)
+ out.close
+ bos.toByteArray
+ }
+
+
+ def main(args: Array[String]): Unit = {
+ val a1 = new Bar()
+ val serialized:Array[Byte] = toBytes(a1)
+ val deserialized: Bar = toObject(serialized)
+ deserialized.size
+ deserialized.checkMember
+ }
+}
diff --git a/tests/run/t3580.scala b/tests/run/t3580.scala
new file mode 100644
index 000000000..f91d5a24f
--- /dev/null
+++ b/tests/run/t3580.scala
@@ -0,0 +1,17 @@
+
+
+
+
+
+object Test {
+
+ class Empty extends Traversable[Nothing] {
+ def foreach[U](f: Nothing => U): Unit = {}
+ }
+
+ def main(args: Array[String]): Unit = {
+ val t = new Empty
+ t.toStream
+ }
+
+}
diff --git a/tests/run/t3613.scala b/tests/run/t3613.scala
new file mode 100644
index 000000000..1293f62c0
--- /dev/null
+++ b/tests/run/t3613.scala
@@ -0,0 +1,22 @@
+class Boopy {
+ private val s = new Schnuck
+ def observer : PartialFunction[ Any, Unit ] = s.observer
+
+ private class Schnuck extends javax.swing.AbstractListModel {
+ model =>
+ val observer : PartialFunction[ Any, Unit ] = {
+ case "Boopy" => fireIntervalAdded( model, 0, 1 )
+ }
+ def getSize = 0
+ def getElementAt( idx: Int ) = ???
+ }
+
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val x = new Boopy
+ val o = x.observer
+ o( "Boopy" ) // --> throws runtime error
+ }
+}
diff --git a/tests/run/t3714.scala b/tests/run/t3714.scala
new file mode 100644
index 000000000..23a1e2e49
--- /dev/null
+++ b/tests/run/t3714.scala
@@ -0,0 +1,33 @@
+trait Break {
+ protected val break: Int;
+}
+
+case class BreakImpl(protected val break: Int) extends Break { }
+
+object Test {
+ // def f1(x: Break) = x match {
+ // case b: BreakImpl => b.break
+ // case b => -1
+ // }
+ def f2(x: Break) = x match {
+ case BreakImpl(x) => x
+ case _ => -1
+ }
+ // def f3(x: Any) = x match {
+ // case b: BreakImpl => b.break
+ // case b => -1
+ // }
+ def f4(x: Any) = x match {
+ case BreakImpl(x) => x
+ case _ => -1
+ }
+
+ def main(args: Array[String]): Unit = {
+ val break = BreakImpl(22)
+ // assert(f1(break) == 22)
+ assert(f2(break) == 22)
+ // assert(f3(break) == 22)
+ assert(f4(break) == 22)
+ }
+}
+
diff --git a/tests/run/t3832.scala b/tests/run/t3832.scala
new file mode 100644
index 000000000..bc84dca22
--- /dev/null
+++ b/tests/run/t3832.scala
@@ -0,0 +1,17 @@
+class t3832 {
+ def this(un: Int) = {
+ this()
+ def bippy = this
+ ()
+ }
+ def this(un: Boolean) = {
+ this()
+ def boppy = () => this
+ ()
+ }
+}
+
+object Test extends dotty.runtime.LegacyApp {
+ new t3832(0)
+ new t3832(true)
+}
diff --git a/tests/run/t3984.scala b/tests/run/t3984.scala
new file mode 100644
index 000000000..15e50b10f
--- /dev/null
+++ b/tests/run/t3984.scala
@@ -0,0 +1,52 @@
+object SetBug {
+ import scala.collection.immutable.{ Set => ImmutSet }
+ import scala.collection.mutable.{ Set => MutSet }
+
+ case class IH (i: Int, h: Int) {
+ override def hashCode: Int = h
+ }
+
+ def run(): Unit = {
+ var is = ImmutSet.empty[IH]
+ var ms = MutSet.empty[IH]
+ for (ih <- List(IH(2,0),IH(0,0),IH(4,4),IH(6,4),IH(-8,1520786080))) {
+ is = is + ih
+ ms = ms + ih
+ }
+ assert(is == ms)
+ val x = IH(6,4)
+ is = is - x
+ ms = ms - x
+ assert(is == ms)
+ }
+}
+
+object MapBug {
+ import scala.collection.immutable.{ Map => ImmutMap }
+ import scala.collection.mutable.{ Map => MutMap }
+
+ case class IH (i: Int, h: Int) {
+ override def hashCode: Int = h
+ }
+
+ def run(): Unit = {
+ var im = ImmutMap.empty[IH,IH]
+ var mm = MutMap.empty[IH,IH]
+ for (ih <- List(IH(2,0),IH(0,0),IH(4,4),IH(6,4),IH(-8,1520786080))) {
+ im = im + ((ih,ih))
+ mm = mm + ((ih,ih))
+ }
+ assert(im == mm)
+ val x = IH(6,4)
+ im = im - x
+ mm = mm - x
+ assert(im == mm)
+ }
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ SetBug.run()
+ MapBug.run()
+ }
+}
diff --git a/tests/run/t4415.scala b/tests/run/t4415.scala
new file mode 100644
index 000000000..33d390869
--- /dev/null
+++ b/tests/run/t4415.scala
@@ -0,0 +1,86 @@
+/**
+ * Demonstration of issue with Extractors. If lines 15/16 are not present, get at runtime:
+ *
+ * Exception in thread "main" java.lang.VerifyError: (class: ExtractorIssue$$, method: convert signature: (LTopProperty;)LMyProp;) Accessing value from uninitialized register 5
+ * at ExtractorIssue.main(ExtractorIssue.scala)
+ * at com.intellij.rt.execution.application.AppMain.main(AppMain.java:115)]
+ *
+ * If lines 15/16 are present, the compiler crashes:
+ *
+ * fatal error (server aborted): not enough arguments for method body%3: (val p: MyProp[java.lang.String])MyProp[_33].
+ * Unspecified value parameter p.
+ */
+object Test {
+
+ def main(args: Array[String]): Unit = {
+ convert(new SubclassProperty)
+ }
+
+ def convert(prop: TopProperty): MyProp[_] = {
+ prop match {
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //case SubclassSecondMatch(p) => p // if these lines are present, the compiler crashes. If commented, unsafe byte
+ //case SecondMatch(p) => p // byte code is generated, which causes a java.lang.VerifyError at runtime
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ case SubclassMatch(p) => p
+ case StandardMatch(p) => p
+ }
+ }
+}
+
+class TopProperty
+
+class StandardProperty extends TopProperty
+class SubclassProperty extends StandardProperty
+
+class SecondProperty extends TopProperty
+class SubclassSecondProperty extends StandardProperty
+
+trait MyProp[T]
+case class MyPropImpl[T]() extends MyProp[T]
+
+object SubclassMatch {
+
+ def unapply(prop: SubclassProperty) : Option[MyProp[String]] = {
+ Some(new MyPropImpl)
+ }
+
+ def apply(prop: MyProp[String]) : SubclassProperty = {
+ new SubclassProperty()
+ }
+}
+
+object StandardMatch {
+
+ def unapply(prop: StandardProperty) : Option[MyProp[String]] = {
+ Some(new MyPropImpl)
+ }
+
+ def apply(prop: MyProp[String]) : StandardProperty = {
+ new StandardProperty()
+ }
+}
+
+object SubclassSecondMatch {
+
+ def unapply(prop: SubclassSecondProperty) : Option[MyProp[BigInt]] = {
+ Some(new MyPropImpl)
+ }
+
+ def apply(prop: MyProp[String]) : SubclassSecondProperty = {
+ new SubclassSecondProperty()
+ }
+}
+
+object SecondMatch {
+
+ def unapply(prop: SecondProperty) : Option[MyProp[BigInt]] = {
+ Some(new MyPropImpl)
+ }
+
+ def apply(prop: MyProp[String]) : SecondProperty = {
+ new SecondProperty()
+ }
+}
diff --git a/tests/run/t4482.check b/tests/run/t4482.check
new file mode 100644
index 000000000..0cfbf0888
--- /dev/null
+++ b/tests/run/t4482.check
@@ -0,0 +1 @@
+2
diff --git a/tests/run/t4482.scala b/tests/run/t4482.scala
new file mode 100644
index 000000000..392861c22
--- /dev/null
+++ b/tests/run/t4482.scala
@@ -0,0 +1,15 @@
+trait Foo { def i: Int }
+trait Bar
+
+case class Spam(i: Int) extends Foo with Bar
+
+object Test {
+ def matchParent(p:Any) = p match {
+ case f:Foo if f.i == 1 => 1
+ case _:Bar => 2
+ case _:Foo => 3
+ }
+ def main(args: Array[String]): Unit = {
+ println(matchParent(Spam(3)))
+ }
+}
diff --git a/tests/run/t4753.check b/tests/run/t4753.check
new file mode 100644
index 000000000..7b19ee8df
--- /dev/null
+++ b/tests/run/t4753.check
@@ -0,0 +1 @@
+boolean
diff --git a/tests/run/t4753.scala b/tests/run/t4753.scala
new file mode 100644
index 000000000..cfb252cbe
--- /dev/null
+++ b/tests/run/t4753.scala
@@ -0,0 +1,12 @@
+trait A {
+ val actualType: Class[_]
+}
+trait B extends A {
+ final val actualType = classOf[Boolean]
+}
+
+object Test extends B {
+ def main(args: Array[String]): Unit = {
+ println(actualType)
+ }
+}
diff --git a/tests/run/t4859.check b/tests/run/t4859.check
new file mode 100644
index 000000000..d329744ca
--- /dev/null
+++ b/tests/run/t4859.check
@@ -0,0 +1,8 @@
+Inner
+Inner.i
+About to reference Inner.i
+Outer
+Inner.i
+About to reference O.N
+About to reference O.N
+About to reference O.N.apply()
diff --git a/tests/run/t4859.scala b/tests/run/t4859.scala
new file mode 100644
index 000000000..8b354ca94
--- /dev/null
+++ b/tests/run/t4859.scala
@@ -0,0 +1,29 @@
+object O {
+ case class N()
+ object P
+}
+
+object Outer {
+ println("Outer")
+ object Inner {
+ println("Inner")
+ def i: Unit = {
+ println("Inner.i")
+ }
+ }
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ Outer.Inner.i // we still don't initialize Outer here (but should we?)
+
+ {println("About to reference Inner.i"); Outer}.Inner.i // Outer will be initialized.
+
+ {println("About to reference O.N" ); O}.N
+
+ {println("About to reference O.N" ); O}.N
+
+ {println("About to reference O.N.apply()"); O}.N.apply()
+ }
+}
+
diff --git a/tests/run/t4871.check b/tests/run/t4871.check
new file mode 100644
index 000000000..a60526a0f
--- /dev/null
+++ b/tests/run/t4871.check
@@ -0,0 +1,2 @@
+class Test$C
+class Test$D
diff --git a/tests/run/t4871.scala b/tests/run/t4871.scala
new file mode 100644
index 000000000..e25d5c138
--- /dev/null
+++ b/tests/run/t4871.scala
@@ -0,0 +1,12 @@
+object Test {
+ class C
+ class D
+
+ def main(args: Array[String]): Unit = {
+ val z: Class[C] = classOf
+ val z2: Class[D] = classOf[D]
+
+ println(z)
+ println(z2)
+ }
+}
diff --git a/tests/run/t5158.check b/tests/run/t5158.check
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/tests/run/t5158.check
@@ -0,0 +1 @@
+0
diff --git a/tests/run/t5158.scala b/tests/run/t5158.scala
new file mode 100644
index 000000000..34c02c306
--- /dev/null
+++ b/tests/run/t5158.scala
@@ -0,0 +1,17 @@
+case class B(var x: Int) {
+ def succ(): Unit = {
+ x = x + 1
+ }
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val b = B(0)
+ b match {
+ case B(x) =>
+ //println(x)
+ b.succ()
+ println(x)
+ }
+ }
+}
diff --git a/tests/run/t5293-map.scala b/tests/run/t5293-map.scala
new file mode 100644
index 000000000..1ef7d97e5
--- /dev/null
+++ b/tests/run/t5293-map.scala
@@ -0,0 +1,88 @@
+
+
+
+import scala.collection.JavaConverters._
+
+
+
+object Test extends dotty.runtime.LegacyApp {
+
+ def bench(label: String)(body: => Unit): Long = {
+ val start = System.nanoTime
+
+ 0.until(10).foreach(_ => body)
+
+ val end = System.nanoTime
+
+ //println("%s: %s ms".format(label, (end - start) / 1000.0 / 1000.0))
+
+ end - start
+ }
+
+ def benchJava(values: java.util.Map[Int, Int]) = {
+ bench("Java Map") {
+ val m = new java.util.HashMap[Int, Int]
+
+ m.putAll(values)
+ }
+ }
+
+ def benchScala(values: Iterable[(Int, Int)]) = {
+ bench("Scala Map") {
+ val m = new scala.collection.mutable.HashMap[Int, Int]
+
+ m ++= values
+ }
+ }
+
+ def benchScalaSorted(values: Iterable[(Int, Int)]) = {
+ bench("Scala Map sorted") {
+ val m = new scala.collection.mutable.HashMap[Int, Int]
+
+ m ++= values.toArray.sorted
+ }
+ }
+
+ def benchScalaPar(values: Iterable[(Int, Int)]) = {
+ bench("Scala ParMap") {
+ val m = new scala.collection.parallel.mutable.ParHashMap[Int, Int] map { x => x }
+
+ m ++= values
+ }
+ }
+
+ val total = 50000
+ val values = (0 until total) zip (0 until total)
+ val map = scala.collection.mutable.HashMap.empty[Int, Int]
+
+ map ++= values
+
+ // warmup
+ for (x <- 0 until 5) {
+ benchJava(map.asJava)
+ benchScala(map)
+ benchScalaPar(map)
+ benchJava(map.asJava)
+ benchScala(map)
+ benchScalaPar(map)
+ }
+
+ val javamap = benchJava(map.asJava)
+ val scalamap = benchScala(map)
+ val scalaparmap = benchScalaPar(map)
+
+ // println(javamap)
+ // println(scalamap)
+ // println(scalaparmap)
+
+ assert(scalamap < (javamap * 10), "scalamap: " + scalamap + " vs. javamap: " + javamap)
+ assert(scalaparmap < (javamap * 10), "scalaparmap: " + scalaparmap + " vs. javamap: " + javamap)
+}
+
+
+
+
+
+
+
+
diff --git a/tests/run/t5293.scala b/tests/run/t5293.scala
new file mode 100644
index 000000000..8a99989c5
--- /dev/null
+++ b/tests/run/t5293.scala
@@ -0,0 +1,83 @@
+
+
+
+import scala.collection.JavaConverters._
+
+
+
+object Test extends dotty.runtime.LegacyApp {
+
+ def bench(label: String)(body: => Unit): Long = {
+ val start = System.nanoTime
+
+ 0.until(10).foreach(_ => body)
+
+ val end = System.nanoTime
+
+ //println("%s: %s ms".format(label, (end - start) / 1000.0 / 1000.0))
+
+ end - start
+ }
+
+ def benchJava(values: java.util.Collection[Int]) = {
+ bench("Java Set") {
+ val set = new java.util.HashSet[Int]
+
+ set.addAll(values)
+ }
+ }
+
+ def benchScala(values: Iterable[Int]) = {
+ bench("Scala Set") {
+ val set = new scala.collection.mutable.HashSet[Int]
+
+ set ++= values
+ }
+ }
+
+ def benchScalaSorted(values: Iterable[Int]) = {
+ bench("Scala Set sorted") {
+ val set = new scala.collection.mutable.HashSet[Int]
+
+ set ++= values.toArray.sorted
+ }
+ }
+
+ def benchScalaPar(values: Iterable[Int]) = {
+ bench("Scala ParSet") {
+ val set = new scala.collection.parallel.mutable.ParHashSet[Int] map { x => x }
+
+ set ++= values
+ }
+ }
+
+ val values = 0 until 50000
+ val set = scala.collection.mutable.HashSet.empty[Int]
+
+ set ++= values
+
+ // warmup
+ for (x <- 0 until 5) {
+ benchJava(set.asJava)
+ benchScala(set)
+ benchScalaPar(set)
+ benchJava(set.asJava)
+ benchScala(set)
+ benchScalaPar(set)
+ }
+
+ val javaset = benchJava(set.asJava)
+ val scalaset = benchScala(set)
+ val scalaparset = benchScalaPar(set)
+
+ assert(scalaset < (javaset * 8), "scalaset: " + scalaset + " vs. javaset: " + javaset)
+ assert(scalaparset < (javaset * 8), "scalaparset: " + scalaparset + " vs. javaset: " + javaset)
+}
+
+
+
+
+
+
+
+
diff --git a/tests/run/t5407.check b/tests/run/t5407.check
new file mode 100644
index 000000000..51993f072
--- /dev/null
+++ b/tests/run/t5407.check
@@ -0,0 +1,2 @@
+2
+2
diff --git a/tests/run/t5407.scala b/tests/run/t5407.scala
new file mode 100644
index 000000000..cc761e5c0
--- /dev/null
+++ b/tests/run/t5407.scala
@@ -0,0 +1,17 @@
+case class Foo(private val x: Int, y: Option[Int], z: Boolean)
+
+object Test extends dotty.runtime.LegacyApp {
+ def foo(x: Foo) = x match {
+ case Foo(x, Some(y), z) => y
+ case Foo(x, y, z) => 0
+ }
+ val x = Foo(1, Some(2), false)
+ println(foo(x))
+
+
+ def bar(x: Foo) = x match {
+ case Foo(x, Some(y), z) => y
+ case Foo(x, None, z) => 0
+ }
+ println(bar(x))
+}
diff --git a/tests/run/t6070.check b/tests/run/t6070.check
new file mode 100644
index 000000000..00750edc0
--- /dev/null
+++ b/tests/run/t6070.check
@@ -0,0 +1 @@
+3
diff --git a/tests/run/t6070.scala b/tests/run/t6070.scala
new file mode 100644
index 000000000..828386d13
--- /dev/null
+++ b/tests/run/t6070.scala
@@ -0,0 +1,36 @@
+abstract class Bomb {
+ type T
+ val x: T
+
+ def size(that: T): Int
+}
+
+class StringBomb extends Bomb {
+ type T = String
+ val x = "abc"
+ def size(that: String): Int = that.length
+}
+
+class IntBomb extends Bomb {
+ type T = Int
+ val x = 10
+
+ def size(that: Int) = x + that
+}
+
+case class Mean(var bomb: Bomb)
+
+object Test extends dotty.runtime.LegacyApp {
+ def foo(x: Mean) = x match {
+ case Mean(b) =>
+ // BUG: b is assumed to be a stable identifier, but it can actually be mutated
+ println(b.size({ mutate(); b.x }))
+ }
+
+ def mutate(): Unit = {
+ m.bomb = new IntBomb
+ }
+
+ val m = Mean(new StringBomb)
+ foo(m) // should print 3
+}
diff --git a/tests/run/t6198.scala b/tests/run/t6198.scala
new file mode 100644
index 000000000..d893b9568
--- /dev/null
+++ b/tests/run/t6198.scala
@@ -0,0 +1,24 @@
+import scala.collection.immutable._
+
+object Test extends dotty.runtime.LegacyApp {
+ // test that ListSet.tail does not use a builder
+ // we can't test for O(1) behavior, so the best we can do is to
+ // check that ls.tail always returns the same instance
+ val ls = ListSet.empty[Int] + 1 + 2
+
+ if(ls.tail ne ls.tail)
+ println("ListSet.tail should not use a builder!")
+
+ // class that always causes hash collisions
+ case class Collision(value:Int) { override def hashCode = 0 }
+
+ // create a set that should have a collison
+ val x = HashSet.empty + Collision(0) + Collision(1)
+ if(x.getClass.getSimpleName != "HashSetCollision1")
+ println("HashSet of size >1 with collisions should use HashSetCollision")
+
+ // remove the collision again by removing all but one element
+ val y = x - Collision(0)
+ if(y.getClass.getSimpleName != "HashSet1")
+ println("HashSet of size 1 should use HashSet1" + y.getClass)
+}
diff --git a/tests/run/t6206.check b/tests/run/t6206.check
new file mode 100644
index 000000000..806457366
--- /dev/null
+++ b/tests/run/t6206.check
@@ -0,0 +1,4 @@
+outer
+outer
+inner
+inner
diff --git a/tests/run/t6206.scala b/tests/run/t6206.scala
new file mode 100644
index 000000000..668ade7f5
--- /dev/null
+++ b/tests/run/t6206.scala
@@ -0,0 +1,37 @@
+class Outer {
+ def apply( position : Inner ): Unit = {}
+ class Inner
+
+ this.apply(new Inner)
+ this (new Inner) // error,
+}
+
+
+class Outer1 {
+
+ self =>
+
+ def apply( position : Inner ) : String = "outer"
+
+ class Inner( ) {
+
+ def apply(arg: Inner): String = "inner"
+
+ def testMe = {
+ List(
+ self.apply( this ), // a) this works
+ self( this ), // b) this does not work!
+ this apply this,
+ this(this)
+ ) foreach println
+ }
+ }
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val o = new Outer1
+ val i = new o.Inner
+ i.testMe
+ }
+}
diff --git a/tests/run/t6253a.scala b/tests/run/t6253a.scala
new file mode 100644
index 000000000..c2db1f5af
--- /dev/null
+++ b/tests/run/t6253a.scala
@@ -0,0 +1,64 @@
+import scala.collection.immutable.HashSet
+
+object Test extends dotty.runtime.LegacyApp {
+
+ var hashCount = 0
+
+ /**
+ * A key that produces lots of hash collisions, to exercise the part of the code that deals with those
+ */
+ case class Collision(value: Int) {
+
+ override def hashCode = {
+ // we do not check hash counts for Collision keys because ListSet.++ uses a mutable hashset internally,
+ // so when we have hash collisions, union will call key.hashCode.
+ // hashCount += 1
+ value / 5
+ }
+ }
+
+ /**
+ * A key that is identical to int other than that it counts hashCode invocations
+ */
+ case class HashCounter(value: Int) {
+
+ override def hashCode = {
+ hashCount += 1
+ value
+ }
+ }
+
+ def testUnion[T](sizes: Seq[Int], offsets: Seq[Double], keyType: String, mkKey: Int => T): Unit = {
+ for {
+ i <- sizes
+ o <- offsets
+ } {
+ val e = HashSet.empty[T]
+ val j = (i * o).toInt
+ // create two sets of size i with overlap o
+ val a = e ++ (0 until i).map(mkKey)
+ require(a.size == i, s"Building HashSet of size $i failed. Key type $keyType.")
+ val b = e ++ (j until (i + j)).map(mkKey)
+ require(b.size == i, s"Building HashSet of size $i failed. Key type $keyType.")
+ val as = e ++ (0 until j).map(mkKey)
+ require(as.size == j, s"Building HashSet of size $j failed. Key type $keyType.")
+ val hashCount0 = hashCount
+ val u = a union b
+ require(hashCount == hashCount0, s"key.hashCode should not be called, but has been called ${hashCount - hashCount0} times. Key type $keyType.")
+ require(u == (a union scala.collection.mutable.HashSet(b.toSeq: _*)), s"Operation must still work for other sets!")
+ require(u.size == i + j, s"Expected size ${i+j}. Real size ${u.size}. Key type $keyType.")
+ for (x <- 0 until i + j)
+ require(u.contains(mkKey(x)), s"Key type $keyType. Set (0 until ${i + j}) should contain $x but does not.")
+ val a_as = a union as
+ val as_a = as union a
+ require((a_as eq a) || (a_as eq as), s"No structural sharing in a union as. Key type $keyType, a=(0 until $i) as=(0 until $j)")
+ require((as_a eq a) || (as_a eq as), s"No structural sharing in as union a. Key type $keyType, a=(0 until $i) as=(0 until $j)")
+ }
+ }
+
+ val sizes = Seq(1, 10, 100, 1000, 10000, 100000)
+ val offsets = Seq(0.0, 0.25, 0.5, 0.75, 1.0)
+ testUnion(sizes, offsets, "int", identity[Int])
+ testUnion(sizes, offsets, "hashcounter", HashCounter.apply)
+ testUnion(sizes, offsets, "collision", Collision.apply)
+}
diff --git a/tests/run/t6253b.scala b/tests/run/t6253b.scala
new file mode 100644
index 000000000..c049aea7f
--- /dev/null
+++ b/tests/run/t6253b.scala
@@ -0,0 +1,62 @@
+import scala.collection.immutable.HashSet
+
+object Test extends dotty.runtime.LegacyApp {
+
+ var hashCount = 0
+
+ /**
+ * A key that produces lots of hash collisions, to exercise the part of the code that deals with those
+ */
+ case class Collision(value: Int) {
+
+ override def hashCode = {
+ hashCount += 1
+ value / 5
+ }
+ }
+
+ /**
+ * A key that is identical to int other than that it counts hashCode invocations
+ */
+ case class HashCounter(value: Int) {
+
+ override def hashCode = {
+ hashCount += 1
+ value
+ }
+ }
+
+ def testIntersect[T](sizes: Seq[Int], offsets: Seq[Double], keyType: String, mkKey: Int => T): Unit = {
+ for {
+ i <- sizes
+ o <- offsets
+ } {
+ val e = HashSet.empty[T]
+ val j = (i * o).toInt
+ // create two sets of size i with overlap o
+ val a = e ++ (0 until i).map(mkKey)
+ require(a.size == i, s"Building HashSet of size $i failed. Key type $keyType.")
+ val b = e ++ (j until (i + j)).map(mkKey)
+ require(b.size == i, s"Building HashSet of size $i failed. Key type $keyType.")
+ val as = e ++ (0 until j).map(mkKey)
+ require(as.size == j, s"Building HashSet of size $j failed. Key type $keyType.")
+ val hashCount0 = hashCount
+ val u = a intersect b
+ require(hashCount == hashCount0, s"key.hashCode should not be called, but has been called ${hashCount - hashCount0} times. Key type $keyType.")
+ require(u == (a intersect scala.collection.mutable.HashSet(b.toSeq: _*)), s"Operation must still work for other sets!")
+ require(u.size == i - j, s"Expected size ${i + j}. Real size ${u.size}. Key type $keyType.")
+ for (x <- j until i)
+ require(u.contains(mkKey(x)), s"Key type $keyType. Set (0 until ${i + j}) should contain $x but does not.")
+ val a_as = a intersect as
+ val as_a = as intersect a
+ require((a_as eq as) || (a_as eq a), s"No structural sharing in a intersect as. Key type $keyType, a=(0 until $i) as=(0 until $j)")
+ require((as_a eq as) || (as_a eq a), s"No structural sharing in as intersect a. Key type $keyType, a=(0 until $i) as=(0 until $j)")
+ }
+ }
+
+ val sizes = Seq(1, 10, 100, 1000, 10000, 100000)
+ val offsets = Seq(0.0, 0.25, 0.5, 0.75, 1.0)
+ testIntersect(sizes, offsets, "int", identity[Int])
+ testIntersect(sizes, offsets, "hashcounter", HashCounter.apply)
+ testIntersect(sizes, offsets, "collision", Collision.apply)
+}
diff --git a/tests/run/t6253c.scala b/tests/run/t6253c.scala
new file mode 100644
index 000000000..39c3a5b17
--- /dev/null
+++ b/tests/run/t6253c.scala
@@ -0,0 +1,63 @@
+import scala.collection.immutable.HashSet
+
+object Test extends dotty.runtime.LegacyApp {
+
+ var hashCount = 0
+
+ /**
+ * A key that produces lots of hash collisions, to exercise the part of the code that deals with those
+ */
+ case class Collision(value: Int) {
+
+ override def hashCode = {
+ hashCount += 1
+ value / 5
+ }
+ }
+
+ /**
+ * A key that is identical to int other than that it counts hashCode invocations
+ */
+ case class HashCounter(value: Int) {
+
+ override def hashCode = {
+ hashCount += 1
+ value
+ }
+ }
+
+ def testDiff[T](sizes: Seq[Int], offsets: Seq[Double], keyType: String, mkKey: Int => T): Unit = {
+ for {
+ i <- sizes
+ o <- offsets
+ } {
+ val e = HashSet.empty[T]
+ val j = (i * o).toInt
+ // create two sets of size i with overlap o
+ val a = e ++ (0 until i).map(mkKey)
+ require(a.size == i, s"Building HashSet of size $i failed. Key type $keyType.")
+ val b = e ++ (j until (i + j)).map(mkKey)
+ require(b.size == i, s"Building HashSet of size $i failed. Key type $keyType.")
+ val as = e ++ (0 until j).map(mkKey)
+ require(as.size == j, s"Building HashSet of size $j failed. Key type $keyType.")
+ val hashCount0 = hashCount
+ val u = a diff b
+ require(hashCount == hashCount0, s"key.hashCode should not be called, but has been called ${hashCount - hashCount0} times. Key type $keyType.")
+ require(u == (a diff scala.collection.mutable.HashSet(b.toSeq: _*)), s"Operation must still work for other sets!")
+ require(u.size == j, s"Expected size $j. Real size ${u.size}. Key type $keyType.")
+ for (x <- 0 until j)
+ require(u.contains(mkKey(x)), s"Key type $keyType. Set (0 until ${i + j}) should contain $x but does not.")
+ require((as intersect b).isEmpty)
+ val b_as = b diff as
+ val as_b = as diff b
+ require((b_as eq b) || (b_as eq as), s"No structural sharing in b diff as. Key type $keyType, b=($j until ${i + j}) as=(0 until $j)")
+ require((as_b eq b) || (as_b eq as), s"No structural sharing in as diff b. Key type $keyType, b=($j until ${i + j}) as=(0 until $j)")
+ }
+ }
+
+ val sizes = Seq(1, 10, 100, 1000, 10000, 100000)
+ val offsets = Seq(0.0, 0.25, 0.5, 0.75, 1.0)
+ testDiff(sizes, offsets, "int", identity[Int])
+ testDiff(sizes, offsets, "hashCounter", HashCounter.apply)
+ testDiff(sizes, offsets, "collision", Collision.apply)
+}
diff --git a/tests/run/t6337a.scala b/tests/run/t6337a.scala
new file mode 100644
index 000000000..0a78cd0b8
--- /dev/null
+++ b/tests/run/t6337a.scala
@@ -0,0 +1,16 @@
+object Test {
+ def main(args: Array[String]): Unit = {
+ val x = X(XX(3))
+ assert(x.q.x.x + 9 == 13)
+ }
+}
+trait Q extends Any {
+ def x: Int
+ def inc: XX
+}
+case class X(val x: Q) extends AnyVal {
+ def q = X(x.inc)
+}
+case class XX(val x: Int) extends AnyVal with Q {
+ def inc = XX(x + 1)
+}
diff --git a/tests/run/t6385.scala b/tests/run/t6385.scala
new file mode 100644
index 000000000..f86fe8c14
--- /dev/null
+++ b/tests/run/t6385.scala
@@ -0,0 +1,13 @@
+object Test {
+ def main(args: Array[String]): Unit = {
+ val y: AA[Int] = C(2)
+ val c: Int = y.x.y
+ assert(c == 2)
+ }
+}
+trait AA[T] extends Any {
+ def x: C[T]
+}
+case class C[T](val y: T) extends AnyVal with AA[T] {
+ def x = this
+}
diff --git a/tests/run/t6628.check b/tests/run/t6628.check
new file mode 100644
index 000000000..bb101b641
--- /dev/null
+++ b/tests/run/t6628.check
@@ -0,0 +1,2 @@
+true
+true
diff --git a/tests/run/t6628.scala b/tests/run/t6628.scala
new file mode 100644
index 000000000..bc87c1250
--- /dev/null
+++ b/tests/run/t6628.scala
@@ -0,0 +1,11 @@
+object Test {
+ def coll = new Traversable[String] {
+ override def foreach[U](f:String=>U): Unit = { f("1") }
+ }
+ val dropped = coll.view drop 1
+
+ def main(args: Array[String]): Unit = {
+ println(dropped.isEmpty)
+ println(dropped.force.isEmpty)
+ }
+}
diff --git a/tests/run/t6793.scala b/tests/run/t6793.scala
new file mode 100644
index 000000000..3d8492c10
--- /dev/null
+++ b/tests/run/t6793.scala
@@ -0,0 +1,9 @@
+package a { class C1(private[a] val v0: String) }
+package b { class C2(v1: String) extends a.C1(v1) { def foo = v1 } }
+
+object Test extends dotty.runtime.LegacyApp {
+ new b.C2("x")
+
+ val c2Fields = classOf[b.C2].getDeclaredFields
+ assert(c2Fields.size == 1, c2Fields.map(_.getName).toList)
+}
diff --git a/tests/run/t7200.scala b/tests/run/t7200.scala
new file mode 100644
index 000000000..8f33d016f
--- /dev/null
+++ b/tests/run/t7200.scala
@@ -0,0 +1,34 @@
+import language.higherKinds
+
+object Test extends dotty.runtime.LegacyApp {
+
+ // Slice of comonad is where this came up
+ trait Foo[F[_]] {
+ def coflatMap[A, B](f: F[A] => B): F[A] => F[B]
+ }
+
+ // A non-empty list
+ case class Nel[A](head: A, tail: List[A])
+
+ object NelFoo extends Foo[Nel] {
+
+ // It appears that the return type for recursive calls is not inferred
+ // properly, yet no warning is issued. Providing a return type or
+ // type arguments for the recursive call fixes the problem.
+
+ def coflatMap[A, B](f: Nel[A] => B) = // ok w/ return type
+ l => Nel(f(l), l.tail match {
+ case Nil => Nil
+ case h :: t => {
+ val r = coflatMap(f)(Nel(h, t)) // ok w/ type args
+ r.head :: r.tail
+ }
+ })
+ }
+
+ // Without a recursive call all is well, but with recursion we get a
+ // ClassCastException from Integer to Nothing
+ NelFoo.coflatMap[Int, Int](_.head + 1)(Nel(1, Nil)) // Ok
+ NelFoo.coflatMap[Int, Int](_.head + 1)(Nel(1, List(2))) // CCE
+
+}
diff --git a/tests/run/t7214.scala b/tests/run/t7214.scala
new file mode 100644
index 000000000..d73fe6dd5
--- /dev/null
+++ b/tests/run/t7214.scala
@@ -0,0 +1,57 @@
+// pattern matcher crashes here trying to synthesize an uneeded outer test.
+// no-symbol does not have an owner
+// at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:49)
+// at scala.tools.nsc.Global.abort(Global.scala:253)
+// at scala.reflect.internal.Symbols$NoSymbol.owner(Symbols.scala:3248)
+// at scala.reflect.internal.Symbols$Symbol.effectiveOwner(Symbols.scala:678)
+// at scala.reflect.internal.Symbols$Symbol.isDefinedInPackage(Symbols.scala:664)
+// at scala.reflect.internal.TreeGen.mkAttributedSelect(TreeGen.scala:188)
+// at scala.reflect.internal.TreeGen.mkAttributedRef(TreeGen.scala:124)
+// at scala.tools.nsc.ast.TreeDSL$CODE$.REF(TreeDSL.scala:308)
+// at scala.tools.nsc.typechecker.PatternMatching$TreeMakers$TypeTestTreeMaker$treeCondStrategy$.outerTest(PatternMatching.scala:1209)
+class Crash {
+ type Alias = C#T
+
+ val c = new C
+ val t = new c.T
+
+ // Crash via a Typed Pattern...
+ (t: Any) match {
+ case e: Alias =>
+ }
+
+ // ... or via a Typed Extractor Pattern.
+ object Extractor {
+ def unapply(a: Alias): Option[Any] = None
+ }
+ (t: Any) match {
+ case Extractor(_) =>
+ case _ =>
+ }
+
+ // checking that correct outer tests are applied when
+ // aliases for path dependent types are involved.
+ val c2 = new C
+ type CdotT = c.T
+ type C2dotT = c2.T
+
+ val outerField = t.getClass.getDeclaredFields.find(_.getName contains ("outer")).get
+ outerField.setAccessible(true)
+
+ (t: Any) match {
+ case _: C2dotT =>
+ println(s"!!! wrong match. t.outer=${outerField.get(t)} / c2 = $c2") // this matches on 2.10.0
+ case _: CdotT =>
+ case _ =>
+ println(s"!!! wrong match. t.outer=${outerField.get(t)} / c = $c")
+ }
+}
+
+class C {
+ class T
+}
+
+object Test extends dotty.runtime.LegacyApp {
+ new Crash
+}
+
diff --git a/tests/run/t7571.scala b/tests/run/t7571.scala
new file mode 100644
index 000000000..fd4babee3
--- /dev/null
+++ b/tests/run/t7571.scala
@@ -0,0 +1,12 @@
+class Foo(val a: Int) extends AnyVal {
+ def foo = { {case x => x + a}: PartialFunction[Int, Int]}
+
+ def bar = (new {}).toString
+}
+
+object Test extends dotty.runtime.LegacyApp {
+ val x = new Foo(1).foo.apply(2)
+ assert(x == 3, x)
+ val s = new Foo(1).bar
+ assert(s.nonEmpty, s)
+}
diff --git a/tests/run/t8177f.scala b/tests/run/t8177f.scala
new file mode 100644
index 000000000..6f9a68c11
--- /dev/null
+++ b/tests/run/t8177f.scala
@@ -0,0 +1,20 @@
+trait Thing { type A; var p: A = _ }
+class A[T](final val x: Thing { type A = T }) {
+ type Q = T
+
+ def x1: T = x.p
+ def x2: Q = x.p
+ def x3: x.A = x.p
+}
+// all result types should be inferred as Int
+class B extends A[Int](null) {
+ def y1 = x1
+ def y2 = x2
+ val y3 = x3 // before SI-8177, this lead to a signature that erased to java.lang.Object
+}
+
+
+object Test extends dotty.runtime.LegacyApp {
+ val methods = classOf[B].getDeclaredMethods.sortBy(_.getName)
+ assert(methods.forall(_.toGenericString.startsWith("public int")))
+}
diff --git a/tests/run/t8197.scala b/tests/run/t8197.scala
new file mode 100644
index 000000000..b510f96f1
--- /dev/null
+++ b/tests/run/t8197.scala
@@ -0,0 +1,16 @@
+// SI-8197, see also SI-4592 and SI-4728
+class A
+class B
+
+class Foo(val x: A = null) {
+ def this(bla: B*) = {
+ this(new A)
+ }
+}
+
+object Test extends dotty.runtime.LegacyApp {
+ // both constructors of `Foo` are applicable. Overloading resolution
+ // will eliminate the alternative that uses a default argument, therefore
+ // the vararg constructor is chosen.
+ assert((new Foo).x != null)
+}
diff --git a/tests/run/try-catch-unify.check b/tests/run/try-catch-unify.check
new file mode 100644
index 000000000..67a8c64a3
--- /dev/null
+++ b/tests/run/try-catch-unify.check
@@ -0,0 +1,4 @@
+Failure(java.lang.NumberFormatException: For input string: "Hi")
+Success(5.0)
+O NOES
+Failure(java.lang.NumberFormatException: For input string: "Hi")
diff --git a/tests/run/try-catch-unify.scala b/tests/run/try-catch-unify.scala
new file mode 100644
index 000000000..151e549e5
--- /dev/null
+++ b/tests/run/try-catch-unify.scala
@@ -0,0 +1,16 @@
+import util._
+
+import control.Exception._
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ println(catching(classOf[NumberFormatException]) withTry ("Hi".toDouble))
+ println(catching(classOf[NumberFormatException]) withTry ("5".toDouble))
+ try {
+ catching(classOf[NumberFormatException]) withTry (sys.error("O NOES"))
+ } catch {
+ case t: Throwable => println(t.getMessage)
+ }
+ println(nonFatalCatch withTry ("Hi".toDouble))
+ }
+}
diff --git a/tests/run/unapplyArray.scala b/tests/run/unapplyArray.scala
new file mode 100644
index 000000000..a29ef124b
--- /dev/null
+++ b/tests/run/unapplyArray.scala
@@ -0,0 +1,31 @@
+object Test {
+ def main(args:Array[String]): Unit = {
+ val z = Array(1,2,3,4)
+ val zs: Seq[Int] = z
+ val za: Any = z
+
+/*
+ Console.println("z is arr[int]"+z.isInstanceOf[Array[int]])
+ Console.println("zs is arr[int]"+zs.isInstanceOf[Array[int]])
+ Console.println("za is arr[int]"+ za.isInstanceOf[Array[int]])
+
+ Console.println("z is seq[int]"+z.isInstanceOf[Seq[int]])
+ Console.println("zs is seq[int]"+zs.isInstanceOf[Seq[int]])
+ Console.println("za is seq[int]"+ za.isInstanceOf[Seq[int]])
+
+ Console.println("z is anyref"+z.isInstanceOf[AnyRef])
+
+ Console.println("z useq "+ Seq.unapplySeq(z))
+ Console.println("zs useq "+ Seq.unapplySeq(zs))
+ Console.println("za useq "+ Seq.unapplySeq(za))
+
+ Console.println("z aseq "+ Seq.unapplySeq(z))
+ Console.println("zs aseq "+ Seq.unapplySeq(zs))
+ Console.println("za aseq "+ Seq.unapplySeq(za))
+*/
+ val zl = zs match {
+ case Seq(xs:_*) => xs.length
+ }
+ assert(zl == 4)
+ }
+}
diff --git a/tests/run/verify-ctor.check b/tests/run/verify-ctor.check
new file mode 100644
index 000000000..8baef1b4a
--- /dev/null
+++ b/tests/run/verify-ctor.check
@@ -0,0 +1 @@
+abc
diff --git a/tests/run/verify-ctor.scala b/tests/run/verify-ctor.scala
new file mode 100644
index 000000000..528d038a8
--- /dev/null
+++ b/tests/run/verify-ctor.scala
@@ -0,0 +1,13 @@
+class Foo(val str: String) {
+ def this(arr: Array[Char]) = this({
+ if (arr.length == 0) sys.exit(1)
+ new String(arr)
+ })
+}
+
+object Test {
+ def main(args: Array[String]) = {
+ val t = new Foo(Array('a', 'b', 'c'))
+ println(t.str)
+ }
+}
diff --git a/tests/run/virtpatmat_try.check b/tests/run/virtpatmat_try.check
new file mode 100644
index 000000000..80ebbf494
--- /dev/null
+++ b/tests/run/virtpatmat_try.check
@@ -0,0 +1,2 @@
+meh
+B
diff --git a/tests/run/virtpatmat_try.flags b/tests/run/virtpatmat_try.flags
new file mode 100644
index 000000000..3f5a3100e
--- /dev/null
+++ b/tests/run/virtpatmat_try.flags
@@ -0,0 +1 @@
+ -Xexperimental
diff --git a/tests/run/virtpatmat_try.scala b/tests/run/virtpatmat_try.scala
new file mode 100644
index 000000000..2cd05b799
--- /dev/null
+++ b/tests/run/virtpatmat_try.scala
@@ -0,0 +1,47 @@
+object Test extends dotty.runtime.LegacyApp {
+ case class A(val x: String) extends Throwable
+ class B extends Exception { override def toString = "B" }
+ def bla = 0
+
+ try {
+ throw new A("meh")
+ } catch { // this should emit a "catch-switch"
+ case y: A => println(y.x)
+ case (_ : A | _ : B) => println("B")
+ case _: Throwable => println("other")
+ }
+
+ try {
+ throw new B()
+ } catch { // case classes and alternative flattening aren't supported yet, but could be in principle
+ // case A(x) => println(x)
+ case y: A => println(y.x)
+ case x@((_ : A) | (_ : B)) => println(x)
+ case _: Throwable => println("other")
+ }
+
+ def simpleTry: Unit = {
+ try {
+ bla
+ } catch {
+ case x: Exception if x.getMessage == "test" => println("first case " + x)
+ case x: Exception => println("second case " + x)
+ }
+ }
+
+ def typedWildcardTry: Unit = {
+ try { bla } catch { case _: ClassCastException => bla }
+ }
+
+ def wildcardTry: Unit = {
+ try { bla } catch { case _: Throwable => bla }
+ }
+
+ def tryPlusFinally: Unit = {
+ try { bla } finally { println("finally") }
+ }
+
+ def catchAndPassToLambda: Unit = {
+ try { bla } catch { case ex: Exception => val f = () => ex }
+ }
+}