diff options
Diffstat (limited to 'tests/run')
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 } + } +} |