diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/async/tlambda.nim | 55 | ||||
-rw-r--r-- | tests/async/tnimcall_to_closure.nim | 17 | ||||
-rw-r--r-- | tests/ccgbugs/tgeneric_closure.nim | 28 | ||||
-rw-r--r-- | tests/closure/tclosure0.nim | 87 | ||||
-rw-r--r-- | tests/closure/tclosure2.nim | 2 | ||||
-rw-r--r-- | tests/closure/tclosure3.nim | 5 | ||||
-rw-r--r-- | tests/closure/tclosurebug2.nim | 6 | ||||
-rw-r--r-- | tests/closure/tinvalidclosure.nim | 4 | ||||
-rw-r--r-- | tests/closure/tjester.nim | 2 | ||||
-rw-r--r-- | tests/closure/tnestedclosure.nim | 4 | ||||
-rw-r--r-- | tests/closure/tnoclosure.nim | 25 | ||||
-rw-r--r-- | tests/destructor/tdestructor3.nim | 3 | ||||
-rw-r--r-- | tests/generics/tspecialized_procvar.nim | 17 | ||||
-rw-r--r-- | tests/iter/tclosureiters.nim | 73 | ||||
-rw-r--r-- | tests/iter/timplicit_auto.nim | 2 | ||||
-rw-r--r-- | tests/iter/titer10.nim | 51 | ||||
-rw-r--r-- | tests/iter/titer7.nim | 14 | ||||
-rw-r--r-- | tests/iter/tkeep_state_between_yield.nim | 36 | ||||
-rw-r--r-- | tests/iter/tnested_closure_iter.nim | 16 | ||||
-rw-r--r-- | tests/iter/tpermutations.nim | 58 | ||||
-rw-r--r-- | tests/iter/twrap_walkdir.nim | 16 | ||||
-rw-r--r-- | tests/metatype/ttypedesc3.nim | 2 |
22 files changed, 500 insertions, 23 deletions
diff --git a/tests/async/tlambda.nim b/tests/async/tlambda.nim new file mode 100644 index 000000000..e0ff1f483 --- /dev/null +++ b/tests/async/tlambda.nim @@ -0,0 +1,55 @@ + +# bug 2007 + +import asyncdispatch, asyncnet, logging, json, uri, strutils, future + +type + Builder = ref object + client: Client + build: Build + + ProgressCB* = proc (message: string): Future[void] {.closure, gcsafe.} + + Build* = ref object + onProgress*: ProgressCB + + Client = ref ClientObj + ClientObj = object + onMessage: proc (client: Client, msg: JsonNode): Future[void] + +proc newClient*(name: string, + onMessage: (Client, JsonNode) -> Future[void]): Client = + new result + result.onMessage = onMessage + +proc newBuild*(onProgress: ProgressCB): Build = + new result + result.onProgress = onProgress + +proc start(build: Build, repo, hash: string) {.async.} = + let path = repo.parseUri().path.toLower() + +proc onProgress(builder: Builder, message: string) {.async.} = + debug($message) + +proc onMessage(builder: Builder, message: JsonNode) {.async.} = + debug("onMessage") + +proc newBuilder(): Builder = + var cres: Builder + new cres + + cres.client = newClient("builder", (client, msg) => (onMessage(cres, msg))) + cres.build = newBuild( + proc (msg: string): Future[void] {.closure, gcsafe.} = onProgress(cres, msg)) + return cres + +proc main() = + # Set up logging. + var console = newConsoleLogger(fmtStr = verboseFmtStr) + addHandler(console) + + var builder = newBuilder() + + +main() diff --git a/tests/async/tnimcall_to_closure.nim b/tests/async/tnimcall_to_closure.nim new file mode 100644 index 000000000..748b67cb1 --- /dev/null +++ b/tests/async/tnimcall_to_closure.nim @@ -0,0 +1,17 @@ + +import asyncdispatch + +proc defaultOnProgressChanged() = discard + +proc ask(x: proc()) = x() + +proc retrFile*(onProgressChanged: proc() {.nimcall.}): Future[void] = + var retFuture = newFuture[void]("retrFile") + iterator retrFileIter(): FutureBase {.closure.} = + ask(onProgressChanged) + complete(retFuture) + + var nameIterVar = retrFileIter + return retFuture + +discard retrFile(defaultOnProgressChanged) diff --git a/tests/ccgbugs/tgeneric_closure.nim b/tests/ccgbugs/tgeneric_closure.nim new file mode 100644 index 000000000..f9d5e7910 --- /dev/null +++ b/tests/ccgbugs/tgeneric_closure.nim @@ -0,0 +1,28 @@ + + +# bug 2659 + +type + GenProcType[T,U] = proc(x:T, y:var U) + IntProcType = proc(x:int, y:var int) + +proc mult(x:int, y:var int) = + y = 2 * x + +when isMainModule: + + var input = 1 + var output = 0 + + var someIntProc:IntProcType = mult + var someGenProc:GenProcType[int,int] = mult + + mult(input, output) + echo output + + someIntProc(input, output) + echo output + + # Uncommenting causes an error in the C compiler. + someGenProc(input, output) + echo output diff --git a/tests/closure/tclosure0.nim b/tests/closure/tclosure0.nim new file mode 100644 index 000000000..9952268d5 --- /dev/null +++ b/tests/closure/tclosure0.nim @@ -0,0 +1,87 @@ +discard """ + output: '''foo88 +23 24foo 88 +18 +18 +99 +99 +99 +99 99 +99 99 +12 99 99 +12 99 99''' +""" + +when true: + # test simple closure within dummy 'main': + proc dummy = + proc main2(param: int) = + var fooB = 23 + proc outer(outerParam: string) = + var outerVar = 88 + echo outerParam, outerVar + proc inner() = + block Test: + echo fooB, " ", param, outerParam, " ", outerVar + inner() + outer("foo") + main2(24) + + dummy() + +when true: + proc outer2(x:int) : proc(y:int):int = # curry-ed application + return proc(y:int):int = x*y + + var fn = outer2(6) # the closure + echo fn(3) # it works + + var rawP = fn.rawProc() + var rawE = fn.rawEnv() + + # A type to cast the function pointer into a nimcall + type + TimesClosure = proc(a: int, x: pointer): int {.nimcall.} + + # Call the function with its closure + echo cast[TimesClosure](rawP)(3, rawE) + +when true: + proc outer = + var x, y: int = 99 + proc innerA = echo x + proc innerB = + echo y + innerA() + + innerA() + innerB() + + outer() + +when true: + proc indirectDep = + var x, y: int = 99 + proc innerA = echo x, " ", y + proc innerB = + innerA() + + innerA() + innerB() + + indirectDep() + +when true: + proc needlessIndirection = + var x, y: int = 99 + proc indirection = + var z = 12 + proc innerA = echo z, " ", x, " ", y + proc innerB = + innerA() + + innerA() + innerB() + indirection() + + needlessIndirection() diff --git a/tests/closure/tclosure2.nim b/tests/closure/tclosure2.nim index d331388cf..9c5ee1426 100644 --- a/tests/closure/tclosure2.nim +++ b/tests/closure/tclosure2.nim @@ -87,7 +87,7 @@ when true: proc py() {.closure.} = echo "py" - const + let mapping = { "abc": px, "xyz": py diff --git a/tests/closure/tclosure3.nim b/tests/closure/tclosure3.nim index 8f6f4a70f..d5ffb5ab2 100644 --- a/tests/closure/tclosure3.nim +++ b/tests/closure/tclosure3.nim @@ -8,8 +8,9 @@ proc main = for iterations in 0..50_000: var s: seq[proc(): string {.closure.}] = @[] for i in 0 .. n-1: - let ii = i - s.add(proc(): string = return $(ii*ii)) + (proc () = + let ii = i + s.add(proc(): string = return $(ii*ii)))() for i in 0 .. n-1: let val = s[i]() if val != $(i*i): echo "bug ", val diff --git a/tests/closure/tclosurebug2.nim b/tests/closure/tclosurebug2.nim index 581b735bf..f131406a3 100644 --- a/tests/closure/tclosurebug2.nim +++ b/tests/closure/tclosurebug2.nim @@ -19,11 +19,11 @@ proc mustRehash(length, counter: int): bool {.inline.} = assert(length > counter) result = (length * 2 < counter * 3) or (length - counter < 4) -proc nextTry(h, maxHash: THash): THash {.inline.} = +proc nextTry(h, maxHash: Hash): Hash {.inline.} = result = ((5 * h) + 1) and maxHash template rawGetImpl() {.dirty.} = - var h: THash = hash(key) and high(t.data) # start with real hash value + var h: Hash = hash(key) and high(t.data) # start with real hash value while t.data[h].slot != seEmpty: if t.data[h].key == key and t.data[h].slot == seFilled: return h @@ -31,7 +31,7 @@ template rawGetImpl() {.dirty.} = result = -1 template rawInsertImpl() {.dirty.} = - var h: THash = hash(key) and high(data) + var h: Hash = hash(key) and high(data) while data[h].slot == seFilled: h = nextTry(h, high(data)) data[h].key = key diff --git a/tests/closure/tinvalidclosure.nim b/tests/closure/tinvalidclosure.nim index c9136a736..d3f38cde5 100644 --- a/tests/closure/tinvalidclosure.nim +++ b/tests/closure/tinvalidclosure.nim @@ -1,9 +1,9 @@ discard """ line: 12 - errormsg: "type mismatch: got (proc (x: int){.closure, gcsafe, locks: 0.})" + errormsg: "type mismatch: got (proc (x: int){.gcsafe, locks: 0.})" """ -proc ugh[T](x: T) {.closure.} = +proc ugh[T](x: T) {.nimcall.} = echo "ugha" diff --git a/tests/closure/tjester.nim b/tests/closure/tjester.nim index 3bd10120a..84e0fcb71 100644 --- a/tests/closure/tjester.nim +++ b/tests/closure/tjester.nim @@ -7,7 +7,7 @@ type data: T callback: proc () {.closure.} -proc cbOuter(response: string) {.closure, discardable.} = +proc cbOuter(response: string) {.discardable.} = iterator cbIter(): Future[int] {.closure.} = for i in 0..7: proc foo(): int = diff --git a/tests/closure/tnestedclosure.nim b/tests/closure/tnestedclosure.nim index 67e196f66..0628a6977 100644 --- a/tests/closure/tnestedclosure.nim +++ b/tests/closure/tnestedclosure.nim @@ -21,13 +21,13 @@ proc main(param: int) = # test simple closure within dummy 'main': proc dummy = proc main2(param: int) = - var foo = 23 + var fooB = 23 proc outer(outerParam: string) = var outerVar = 88 echo outerParam, outerVar proc inner() = block Test: - echo foo, " ", param, outerParam, " ", outerVar + echo fooB, " ", param, outerParam, " ", outerVar inner() outer("foo") main2(24) diff --git a/tests/closure/tnoclosure.nim b/tests/closure/tnoclosure.nim new file mode 100644 index 000000000..25cce0040 --- /dev/null +++ b/tests/closure/tnoclosure.nim @@ -0,0 +1,25 @@ +discard """ + output: '''@[1] +@[1, 1] +@[1, 2, 1] +@[1, 3, 3, 1] +@[1, 4, 6, 4, 1] +@[1, 5, 10, 10, 5, 1] +@[1, 6, 15, 20, 15, 6, 1] +@[1, 7, 21, 35, 35, 21, 7, 1] +@[1, 8, 28, 56, 70, 56, 28, 8, 1] +@[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]''' +""" + +import sequtils + +proc pascal(n: int) = + var row = @[1] + for r in 1..n: + echo row + row = zip(row & @[0], @[0] & row).mapIt(it[0] + it[1]) + +pascal(10) + +# bug #3499 last snippet fixed +# bug 705 last snippet fixed diff --git a/tests/destructor/tdestructor3.nim b/tests/destructor/tdestructor3.nim index 0968f1fd7..d0c53c7bd 100644 --- a/tests/destructor/tdestructor3.nim +++ b/tests/destructor/tdestructor3.nim @@ -19,10 +19,11 @@ proc `=`(lhs: var T, rhs: T) = proc `=destroy`(v: var T) = echo "destroy" -block: +proc usedToBeBlock = var v1 : T var v2 : T = v1 +usedToBeBlock() # bug #1632 diff --git a/tests/generics/tspecialized_procvar.nim b/tests/generics/tspecialized_procvar.nim new file mode 100644 index 000000000..4bdc94a66 --- /dev/null +++ b/tests/generics/tspecialized_procvar.nim @@ -0,0 +1,17 @@ +discard """ + output: '''concrete 88''' +""" + +# Another regression triggered by changed closure computations: + +proc foo[T](x: proc(): T) = + echo "generic ", x() + +proc foo(x: proc(): int) = + echo "concrete ", x() + +# note the following 'proc' is not .closure! +foo(proc (): auto {.nimcall.} = 88) + +# bug #3499 last snippet fixed +# bug 705 last snippet fixed diff --git a/tests/iter/tclosureiters.nim b/tests/iter/tclosureiters.nim new file mode 100644 index 000000000..0eb624a8c --- /dev/null +++ b/tests/iter/tclosureiters.nim @@ -0,0 +1,73 @@ +discard """ + output: '''0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +5 5 +7 7 +9 9 +0 +0 +0 +0 +1 +2''' +""" + +when true: + proc main() = + let + lo=0 + hi=10 + + iterator itA(): int = + for x in lo..hi: + yield x + + for x in itA(): + echo x + + var y: int + + iterator itB(): int = + while y <= hi: + yield y + inc y + + y = 5 + for x in itB(): + echo x, " ", y + inc y + + main() + + +iterator infinite(): int {.closure.} = + var i = 0 + while true: + yield i + inc i + +iterator take[T](it: iterator (): T, numToTake: int): T {.closure.} = + var i = 0 + for x in it(): + if i >= numToTake: + break + yield x + inc i + +# gives wrong reasult (3 times 0) +for x in infinite.take(3): + echo x + +# does what we want +let inf = infinite +for x in inf.take(3): + echo x diff --git a/tests/iter/timplicit_auto.nim b/tests/iter/timplicit_auto.nim index ccb279fe0..d5cb95eb8 100644 --- a/tests/iter/timplicit_auto.nim +++ b/tests/iter/timplicit_auto.nim @@ -9,7 +9,7 @@ proc univ(x, y: int): State = Tree var w, h = 30 -iterator fields(a = (0,0), b = (h-1,w-1)) = +iterator fields(a = (0,0), b = (h-1,w-1)): auto = for y in max(a[0], 0) .. min(b[0], h-1): for x in max(a[1], 0) .. min(b[1], w-1): yield (y,x) diff --git a/tests/iter/titer10.nim b/tests/iter/titer10.nim new file mode 100644 index 000000000..6a6afc780 --- /dev/null +++ b/tests/iter/titer10.nim @@ -0,0 +1,51 @@ +discard """ + output: '''3 +2 +5 +1 +@[@[0, 0], @[0, 1]] +@[@[0, 0], @[0, 1]] +@[@[2, 2], @[2, 3]] +@[@[2, 2], @[2, 3]]''' +""" + +when true: + # bug #2604 + + import algorithm + + iterator byDistance*[int]( ints: openArray[int], base: int ): int = + var sortable = @ints + + sortable.sort do (a, b: int) -> int: + result = cmp( abs(base - a), abs(base - b) ) + + for val in sortable: + yield val + + when isMainModule: + proc main = + for val in byDistance([2, 3, 5, 1], 3): + echo val + main() + +when true: + # bug #1527 + + import sequtils + + let thread = @[@[0, 0], + @[0, 1], + @[2, 2], + @[2, 3]] + + iterator threadUniqs(seq1: seq[seq[int]]): seq[seq[int]] = + for i in 0 .. <seq1.len: + block: + let i = i + yield seq1.filter do (x: seq[int]) -> bool: x[0] == seq1[i][0] + proc main2 = + for uniqs in thread.threadUniqs: + echo uniqs + + main2() diff --git a/tests/iter/titer7.nim b/tests/iter/titer7.nim index d0337b7bd..c2bd9b9cb 100644 --- a/tests/iter/titer7.nim +++ b/tests/iter/titer7.nim @@ -14,11 +14,7 @@ discard """ 49 64 81 ---- squares of evens, only -4 -16 -36 -64''' +''' """ iterator `/`[T](sequence: seq[T], @@ -40,10 +36,10 @@ iterator `/>>`[I,O](sequence: seq[I], if (filtermap.f(element)): yield filtermap.m(element) -proc isEven(x:int): bool {.closure.} = result = +proc isEven(x:int): bool = (x and 1) == 0 -proc square(x:int): int {.closure.} = result = +proc square(x:int): int = x * x let list = @[1,2,3,4,5,6,7,8,9] @@ -52,6 +48,6 @@ echo ("--- evens") for item in list / isEven : echo(item) echo ("--- squares") for item in list >> square : echo(item) -echo ("--- squares of evens, only") +#echo ("--- squares of evens, only") # next line doesn't compile. Generic types are not inferred -for item in list />> (isEven, square) : echo(item) +#for item in list />> (isEven, square) : echo(item) diff --git a/tests/iter/tkeep_state_between_yield.nim b/tests/iter/tkeep_state_between_yield.nim new file mode 100644 index 000000000..f4f0ee363 --- /dev/null +++ b/tests/iter/tkeep_state_between_yield.nim @@ -0,0 +1,36 @@ +discard """ + output: '''@[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 18, 20, 21, 24, 27, 30, 36, 40, 42] +1002''' +""" + +import strutils + +proc slice[T](iter: iterator(): T {.closure.}, sl: auto): seq[T] = + var res: seq[int64] = @[] + var i = 0 + for n in iter(): + if i > sl.b: + break + if i >= sl.a: + res.add(n) + inc i + res + +iterator harshad(): int64 {.closure.} = + for n in 1 .. < int64.high: + var sum = 0 + for ch in string($n): + sum += parseInt("" & ch) + if n mod sum == 0: + yield n + +echo harshad.slice 0 .. <20 + +for n in harshad(): + if n > 1000: + echo n + break + + +# bug #3499 last snippet fixed +# bug 705 last snippet fixed diff --git a/tests/iter/tnested_closure_iter.nim b/tests/iter/tnested_closure_iter.nim new file mode 100644 index 000000000..ec2253cf1 --- /dev/null +++ b/tests/iter/tnested_closure_iter.nim @@ -0,0 +1,16 @@ +discard """ + output: '''0 +1 +2''' +""" +# bug #1725 +iterator factory(): int {.closure.} = + iterator bar(): int {.closure.} = + yield 0 + yield 1 + yield 2 + + for x in bar(): yield x + +for x in factory(): + echo x diff --git a/tests/iter/tpermutations.nim b/tests/iter/tpermutations.nim new file mode 100644 index 000000000..a3b383323 --- /dev/null +++ b/tests/iter/tpermutations.nim @@ -0,0 +1,58 @@ + +import sequtils, future + +iterator permutations*[T](ys: openarray[T]): tuple[perm: seq[T], sign: int] = + var + d = 1 + c = newSeq[int](ys.len) + xs = newSeq[T](ys.len) + sign = 1 + + for i, y in ys: xs[i] = y + yield (xs, sign) + + block outter: + while true: + while d > 1: + dec d + c[d] = 0 + while c[d] >= d: + inc d + if d >= ys.len: break outter + + let i = if (d and 1) == 1: c[d] else: 0 + swap xs[i], xs[d] + sign *= -1 + yield (xs, sign) + inc c[d] + +proc det(a: seq[seq[float]]): float = + let n = toSeq 0..a.high + for sigma, sign in n.permutations: + result += sign.float * n.map((i: int) => a[i][sigma[i]]).foldl(a * b) + +proc perm(a: seq[seq[float]]): float = + let n = toSeq 0..a.high + for sigma, sign in n.permutations: + result += n.map((i: int) => a[i][sigma[i]]).foldl(a * b) + +for a in [ + @[ @[1.0, 2.0] + , @[3.0, 4.0] + ], + @[ @[ 1.0, 2, 3, 4] + , @[ 4.0, 5, 6, 7] + , @[ 7.0, 8, 9, 10] + , @[10.0, 11, 12, 13] + ], + @[ @[ 0.0, 1, 2, 3, 4] + , @[ 5.0, 6, 7, 8, 9] + , @[10.0, 11, 12, 13, 14] + , @[15.0, 16, 17, 18, 19] + , @[20.0, 21, 22, 23, 24] + ] ]: + echo a + echo "perm: ", a.perm, " det: ", a.det + +# bug #3499 last snippet fixed +# bug 705 last snippet fixed diff --git a/tests/iter/twrap_walkdir.nim b/tests/iter/twrap_walkdir.nim new file mode 100644 index 000000000..4ac487d8e --- /dev/null +++ b/tests/iter/twrap_walkdir.nim @@ -0,0 +1,16 @@ + + + +import os + +# bug #3636 + +proc fooIt(foo: string): iterator(): (string) = + iterator temp(): (string) = + for f in walkDirRec(foo): # No problem with walkFiles + yield f + return temp + +let it = fooIt(".") +for x in it(): + echo x diff --git a/tests/metatype/ttypedesc3.nim b/tests/metatype/ttypedesc3.nim index 3d40b25b2..9f19bd6e3 100644 --- a/tests/metatype/ttypedesc3.nim +++ b/tests/metatype/ttypedesc3.nim @@ -6,7 +6,7 @@ type proc pr(T: typedesc[Base]) = echo "proc " & T.name method me(T: typedesc[Base]) = echo "method " & T.name -iterator it(T: typedesc[Base]) = yield "yield " & T.name +iterator it(T: typedesc[Base]): auto = yield "yield " & T.name Base.pr Child.pr |