summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/async/tlambda.nim55
-rw-r--r--tests/async/tnimcall_to_closure.nim17
-rw-r--r--tests/ccgbugs/tgeneric_closure.nim28
-rw-r--r--tests/closure/tclosure0.nim87
-rw-r--r--tests/closure/tclosure2.nim2
-rw-r--r--tests/closure/tclosure3.nim5
-rw-r--r--tests/closure/tclosurebug2.nim6
-rw-r--r--tests/closure/tinvalidclosure.nim4
-rw-r--r--tests/closure/tjester.nim2
-rw-r--r--tests/closure/tnestedclosure.nim4
-rw-r--r--tests/closure/tnoclosure.nim25
-rw-r--r--tests/destructor/tdestructor3.nim3
-rw-r--r--tests/generics/tspecialized_procvar.nim17
-rw-r--r--tests/iter/tclosureiters.nim73
-rw-r--r--tests/iter/timplicit_auto.nim2
-rw-r--r--tests/iter/titer10.nim51
-rw-r--r--tests/iter/titer7.nim14
-rw-r--r--tests/iter/tkeep_state_between_yield.nim36
-rw-r--r--tests/iter/tnested_closure_iter.nim16
-rw-r--r--tests/iter/tpermutations.nim58
-rw-r--r--tests/iter/twrap_walkdir.nim16
-rw-r--r--tests/metatype/ttypedesc3.nim2
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