diff options
Diffstat (limited to 'tests/closure')
-rw-r--r-- | tests/closure/t11042.nim | 55 | ||||
-rw-r--r-- | tests/closure/t15594.nim | 10 | ||||
-rw-r--r-- | tests/closure/t19095.nim | 35 | ||||
-rw-r--r-- | tests/closure/t20152.nim | 20 | ||||
-rw-r--r-- | tests/closure/t8550.nim | 1 | ||||
-rw-r--r-- | tests/closure/t9334.nim | 19 | ||||
-rw-r--r-- | tests/closure/tcapture.nim | 26 | ||||
-rw-r--r-- | tests/closure/tclosure.nim | 247 | ||||
-rw-r--r-- | tests/closure/tclosure_issues.nim | 6 | ||||
-rw-r--r-- | tests/closure/tinvalidclosure.nim | 2 | ||||
-rw-r--r-- | tests/closure/tinvalidclosure4.nim | 9 | ||||
-rw-r--r-- | tests/closure/tinvalidclosure5.nim | 10 | ||||
-rw-r--r-- | tests/closure/tnested.nim | 36 | ||||
-rw-r--r-- | tests/closure/tstmtlist.nim | 9 | ||||
-rw-r--r-- | tests/closure/ttimeinfo.nim | 8 |
15 files changed, 258 insertions, 235 deletions
diff --git a/tests/closure/t11042.nim b/tests/closure/t11042.nim new file mode 100644 index 000000000..6a3928316 --- /dev/null +++ b/tests/closure/t11042.nim @@ -0,0 +1,55 @@ +discard """ + output:''' +foo: 1 +foo: 2 +bar: 1 +bar: 2 +foo: 1 +foo: 2 +bar: 1 +bar: 2 +bar: 3 +bar: 4 +bar: 5 +bar: 6 +bar: 7 +bar: 8 +bar: 9 +''' +""" + +# bug #11042 +block: + iterator foo: int = + for x in 1..2: + echo "foo: ", x + for y in 1..2: + discard + + for x in foo(): discard + + let bar = iterator: int = + for x in 1..2: + echo "bar: ", x + for y in 1..2: + discard + + for x in bar(): discard + + +block: + iterator foo: int = + for x in 1..2: + echo "foo: ", x + for y in 1..2: + discard + + for x in foo(): discard + + let bar = iterator: int = + for x in 1..9: + echo "bar: ", x + for y in 1..2: + discard + + for x in bar(): discard \ No newline at end of file diff --git a/tests/closure/t15594.nim b/tests/closure/t15594.nim new file mode 100644 index 000000000..aacd9ed84 --- /dev/null +++ b/tests/closure/t15594.nim @@ -0,0 +1,10 @@ +discard """ + errormsg: "The variable name cannot be `result`!" +""" + +import sugar + +proc begin(): int = + capture result: + echo 1+1 + result diff --git a/tests/closure/t19095.nim b/tests/closure/t19095.nim new file mode 100644 index 000000000..880456e02 --- /dev/null +++ b/tests/closure/t19095.nim @@ -0,0 +1,35 @@ +discard """ + action: compile +""" + +block: + func inCheck() = + discard + + iterator iter(): int = + yield 0 + yield 0 + + func search() = + let inCheck = 0 + + for i in iter(): + + proc hello() = + inCheck() + + search() +block: + iterator iter(): int = + yield 0 + yield 0 + + func search() = + let lmrMoveCounter = 0 + + for i in iter(): + + proc hello() = + discard lmrMoveCounter + + search() diff --git a/tests/closure/t20152.nim b/tests/closure/t20152.nim new file mode 100644 index 000000000..484ea0741 --- /dev/null +++ b/tests/closure/t20152.nim @@ -0,0 +1,20 @@ +discard """ + action: compile +""" + +proc foo() = + iterator it():int {.closure.} = + yield 1 + proc useIter() {.nimcall.} = + var iii = it # <-- illegal capture + doAssert iii() == 1 + useIter() +foo() + +proc foo2() = + proc bar() = # Local function, but not a closure, because no captures + echo "hi" + proc baz() {.nimcall.} = # Calls local function + bar() + baz() +foo2() diff --git a/tests/closure/t8550.nim b/tests/closure/t8550.nim index 153246f08..a07f45cdc 100644 --- a/tests/closure/t8550.nim +++ b/tests/closure/t8550.nim @@ -1,4 +1,5 @@ discard """ + targets: "c js" output: "@[\"42\"]" """ diff --git a/tests/closure/t9334.nim b/tests/closure/t9334.nim new file mode 100644 index 000000000..36a9a7d77 --- /dev/null +++ b/tests/closure/t9334.nim @@ -0,0 +1,19 @@ +discard """ + cmd: "nim $target --hints:off $options -r $file" + nimout: '''@[1] +@[1, 1] +''' + nimoutFull: true +""" +proc p(s: var seq[int]): auto = + let sptr = addr s + return proc() = sptr[].add 1 + +proc f = + var data = @[1] + p(data)() + echo repr data + +static: + f() # prints [1] +f() # prints [1, 1] diff --git a/tests/closure/tcapture.nim b/tests/closure/tcapture.nim index 304a76285..dafc44739 100644 --- a/tests/closure/tcapture.nim +++ b/tests/closure/tcapture.nim @@ -1,6 +1,11 @@ discard """ output: ''' -to be, or not to be''' +to be, or not to be +(v: 1) +(w: -1) +(v: 1) +(w: -1) +''' joinable: false """ @@ -9,4 +14,21 @@ import sequtils, sugar let m = @[proc (s: string): string = "to " & s, proc (s: string): string = "not to " & s] var l = m.mapIt(capture([it], proc (s: string): string = it(s))) let r = l.mapIt(it("be")) -echo r[0] & ", or " & r[1] \ No newline at end of file +echo r[0] & ", or " & r[1] + +type + O = object + v: int + U = object + w: int +var o = O(v: 1) +var u = U(w: -1) +var execute: proc() +capture o, u: + execute = proc() = + echo o + echo u +execute() +o.v = -1 +u.w = 1 +execute() diff --git a/tests/closure/tclosure.nim b/tests/closure/tclosure.nim index cfef4193a..401a71d40 100644 --- a/tests/closure/tclosure.nim +++ b/tests/closure/tclosure.nim @@ -1,5 +1,5 @@ discard """ - target: "c" + targets: "c" output: ''' 1 3 6 11 20 foo foo88 @@ -38,14 +38,10 @@ joinable: false block tclosure: - proc map(n: var openarray[int], fn: proc (x: int): int {.closure}) = + proc map(n: var openArray[int], fn: proc (x: int): int {.closure}) = for i in 0..n.len-1: n[i] = fn(n[i]) - proc foldr(n: openarray[int], fn: proc (x, y: int): int {.closure}): int = - for i in 0..n.len-1: - result = fn(result, n[i]) - - proc each(n: openarray[int], fn: proc(x: int) {.closure.}) = + proc each(n: openArray[int], fn: proc(x: int) {.closure.}) = for i in 0..n.len-1: fn(n[i]) @@ -67,21 +63,9 @@ block tclosure: #OUT 2 4 6 8 10 - type - ITest = tuple[ - setter: proc(v: int), - getter: proc(): int] - - proc getInterf(): ITest = - var shared: int - - return (setter: proc (x: int) = shared = x, - getter: proc (): int = return shared) - - # bug #5015 - type Mutator = proc(matched: string): string {.noSideEffect, gcsafe, locks: 0.} + type Mutator = proc(matched: string): string {.noSideEffect, gcsafe.} proc putMutated( MutatorCount: static[int], @@ -180,7 +164,7 @@ block tclosure0: block tclosure3: proc main = const n = 30 - for iterations in 0..50_000: + for iterations in 0..10_000: var s: seq[proc(): string {.closure.}] = @[] for i in 0 .. n-1: (proc () = @@ -203,210 +187,12 @@ block tclosure4: let json_elems = json_params["files"].elems # These fail compilation. var files = map(json_elems, proc (x: JsonNode): string = x.str) - #var files = json_elems.map do (x: JsonNode) -> string: x.str let text = """{"files": ["a", "b", "c"]}""" run((text.parseJson).fields) -import hashes, math -block tclosurebug2: - type - TSlotEnum = enum seEmpty, seFilled, seDeleted - TKeyValuePair[A, B] = tuple[slot: TSlotEnum, key: A, val: B] - TKeyValuePairSeq[A, B] = seq[TKeyValuePair[A, B]] - - TOrderedKeyValuePair[A, B] = tuple[ - slot: TSlotEnum, next: int, key: A, val: B] - TOrderedKeyValuePairSeq[A, B] = seq[TOrderedKeyValuePair[A, B]] - OrderedTable[A, B] = object ## table that remembers insertion order - data: TOrderedKeyValuePairSeq[A, B] - counter, first, last: int - - const - growthFactor = 2 - - proc mustRehash(length, counter: int): bool {.inline.} = - assert(length > counter) - result = (length * 2 < counter * 3) or (length - counter < 4) - - proc nextTry(h, maxHash: Hash): Hash {.inline.} = - result = ((5 * h) + 1) and maxHash - - template rawGetImpl() {.dirty.} = - 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 - h = nextTry(h, high(t.data)) - result = -1 - - template rawInsertImpl() {.dirty.} = - var h: Hash = hash(key) and high(data) - while data[h].slot == seFilled: - h = nextTry(h, high(data)) - data[h].key = key - data[h].val = val - data[h].slot = seFilled - - template addImpl() {.dirty.} = - if mustRehash(len(t.data), t.counter): enlarge(t) - rawInsert(t, t.data, key, val) - inc(t.counter) - - template putImpl() {.dirty.} = - var index = rawGet(t, key) - if index >= 0: - t.data[index].val = val - else: - addImpl() - - proc len[A, B](t: OrderedTable[A, B]): int {.inline.} = - ## returns the number of keys in `t`. - result = t.counter - - template forAllOrderedPairs(yieldStmt: untyped) {.dirty.} = - var h = t.first - while h >= 0: - var nxt = t.data[h].next - if t.data[h].slot == seFilled: yieldStmt - h = nxt - - iterator pairs[A, B](t: OrderedTable[A, B]): tuple[key: A, val: B] = - ## iterates over any (key, value) pair in the table `t` in insertion - ## order. - forAllOrderedPairs: - yield (t.data[h].key, t.data[h].val) - - iterator mpairs[A, B](t: var OrderedTable[A, B]): tuple[key: A, val: var B] = - ## iterates over any (key, value) pair in the table `t` in insertion - ## order. The values can be modified. - forAllOrderedPairs: - yield (t.data[h].key, t.data[h].val) - - iterator keys[A, B](t: OrderedTable[A, B]): A = - ## iterates over any key in the table `t` in insertion order. - forAllOrderedPairs: - yield t.data[h].key - - iterator values[A, B](t: OrderedTable[A, B]): B = - ## iterates over any value in the table `t` in insertion order. - forAllOrderedPairs: - yield t.data[h].val - - iterator mvalues[A, B](t: var OrderedTable[A, B]): var B = - ## iterates over any value in the table `t` in insertion order. The values - ## can be modified. - forAllOrderedPairs: - yield t.data[h].val - - proc rawGet[A, B](t: OrderedTable[A, B], key: A): int = - rawGetImpl() - - proc `[]`[A, B](t: OrderedTable[A, B], key: A): B = - ## retrieves the value at ``t[key]``. If `key` is not in `t`, - ## default empty value for the type `B` is returned - ## and no exception is raised. One can check with ``hasKey`` whether the key - ## exists. - var index = rawGet(t, key) - if index >= 0: result = t.data[index].val - - proc mget[A, B](t: var OrderedTable[A, B], key: A): var B = - ## retrieves the value at ``t[key]``. The value can be modified. - ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. - var index = rawGet(t, key) - if index >= 0: result = t.data[index].val - else: raise newException(KeyError, "key not found: " & $key) - - proc hasKey[A, B](t: OrderedTable[A, B], key: A): bool = - ## returns true iff `key` is in the table `t`. - result = rawGet(t, key) >= 0 - - proc rawInsert[A, B](t: var OrderedTable[A, B], - data: var TOrderedKeyValuePairSeq[A, B], - key: A, val: B) = - rawInsertImpl() - data[h].next = -1 - if t.first < 0: t.first = h - if t.last >= 0: data[t.last].next = h - t.last = h - - proc enlarge[A, B](t: var OrderedTable[A, B]) = - var n: TOrderedKeyValuePairSeq[A, B] - newSeq(n, len(t.data) * growthFactor) - var h = t.first - t.first = -1 - t.last = -1 - while h >= 0: - var nxt = t.data[h].next - if t.data[h].slot == seFilled: - rawInsert(t, n, t.data[h].key, t.data[h].val) - h = nxt - swap(t.data, n) - - proc `[]=`[A, B](t: var OrderedTable[A, B], key: A, val: B) = - ## puts a (key, value)-pair into `t`. - putImpl() - - proc add[A, B](t: var OrderedTable[A, B], key: A, val: B) = - ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. - addImpl() - - proc iniOrderedTable[A, B](initialSize=64): OrderedTable[A, B] = - ## creates a new ordered hash table that is empty. `initialSize` needs to be - ## a power of two. - assert isPowerOfTwo(initialSize) - result.counter = 0 - result.first = -1 - result.last = -1 - newSeq(result.data, initialSize) - - proc toOrderedTable[A, B](pairs: openarray[tuple[key: A, - val: B]]): OrderedTable[A, B] = - ## creates a new ordered hash table that contains the given `pairs`. - result = iniOrderedTable[A, B](nextPowerOfTwo(pairs.len+10)) - for key, val in items(pairs): result[key] = val - - proc sort[A, B](t: var OrderedTable[A,B], - cmp: proc (x, y: tuple[key: A, val: B]): int {.closure.}) = - ## sorts the ordered table so that the entry with the highest counter comes - ## first. This is destructive (with the advantage of being efficient)! - ## You must not modify `t` afterwards! - ## You can use the iterators `pairs`, `keys`, and `values` to iterate over - ## `t` in the sorted order. - - # we use shellsort here; fast enough and simple - var h = 1 - while true: - h = 3 * h + 1 - if h >= high(t.data): break - while true: - h = h div 3 - for i in countup(h, high(t.data)): - var j = i - #echo(t.data.len, " ", j, " - ", h) - #echo(repr(t.data[j-h])) - proc rawCmp(x, y: TOrderedKeyValuePair[A, B]): int = - if x.slot in {seEmpty, seDeleted} and y.slot in {seEmpty, seDeleted}: - return 0 - elif x.slot in {seEmpty, seDeleted}: - return -1 - elif y.slot in {seEmpty, seDeleted}: - return 1 - else: - let item1 = (x.key, x.val) - let item2 = (y.key, y.val) - return cmp(item1, item2) - - while rawCmp(t.data[j-h], t.data[j]) <= 0: - swap(t.data[j], t.data[j-h]) - j = j-h - if j < h: break - if h == 1: break - - - import sugar block inference3304: type @@ -453,19 +239,19 @@ block doNotation: b.onClick do (e: Event): echo "click at ", e.x, ",", e.y - b.onFocusLost: + b.onFocusLost do (): echo "lost focus 1" - b.onFocusLost do: + b.onFocusLost do (): echo "lost focus 2" - b.onUserEvent("UserEvent 1") do: + b.onUserEvent("UserEvent 1") do (): discard - b.onUserEvent "UserEvent 2": + onUserEvent(b, "UserEvent 2") do (): discard - b.onUserEvent("UserEvent 3"): + b.onUserEvent("UserEvent 3") do (): discard b.onUserEvent("UserEvent 4", () => echo "event 4") @@ -513,7 +299,7 @@ block tflatmap: let g: A -> Rand[B] = (a: A) => ((rng: RNG) => (f(a), rng)) flatMap(s, g) - let f = nextInt.map(i => i - i mod 2) + discard nextInt.map(i => i - i mod 2) @@ -705,3 +491,14 @@ block tnoclosure: row = zip(row & @[0], @[0] & row).mapIt(it[0] + it[1]) echo row pascal(10) + +block: # bug #22297 + iterator f: int {.closure.} = + try: + yield 12 + finally: + return 14 + + let s = f + doAssert s() == 12 + doAssert s() == 14 diff --git a/tests/closure/tclosure_issues.nim b/tests/closure/tclosure_issues.nim index 4688834de..b1a2d7c6b 100644 --- a/tests/closure/tclosure_issues.nim +++ b/tests/closure/tclosure_issues.nim @@ -71,12 +71,12 @@ block tissue7104: proc sp(cb: proc())= cb() - sp: + sp do (): var i = 0 echo "ok ", i - sp(): + sp do (): inc i echo "ok ", i - sp do: + sp do (): inc i echo "ok ", i diff --git a/tests/closure/tinvalidclosure.nim b/tests/closure/tinvalidclosure.nim index b2d8bd28d..37d0f68a2 100644 --- a/tests/closure/tinvalidclosure.nim +++ b/tests/closure/tinvalidclosure.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "type mismatch: got <proc (x: int){.gcsafe, locks: 0.}>" + errormsg: "type mismatch: got <proc (x: int){.nimcall, gcsafe.}>" line: 12 """ diff --git a/tests/closure/tinvalidclosure4.nim b/tests/closure/tinvalidclosure4.nim new file mode 100644 index 000000000..7985a2488 --- /dev/null +++ b/tests/closure/tinvalidclosure4.nim @@ -0,0 +1,9 @@ +discard """ + errormsg: "illegal capture 'v'" + line: 7 +""" + +proc outer(v: int) = + proc b {.nimcall.} = echo v + b() +outer(5) diff --git a/tests/closure/tinvalidclosure5.nim b/tests/closure/tinvalidclosure5.nim new file mode 100644 index 000000000..3b5f46a40 --- /dev/null +++ b/tests/closure/tinvalidclosure5.nim @@ -0,0 +1,10 @@ +discard """ + errormsg: "type mismatch: got <proc (){.closure, gcsafe.}> but expected 'A = proc (){.nimcall.}'" + line: 9 +""" + +type A = proc() {.nimcall.} +proc main = + let b = 1 + let a: A = proc() = echo b + diff --git a/tests/closure/tnested.nim b/tests/closure/tnested.nim index dbbe9ba58..ec5af9b13 100644 --- a/tests/closure/tnested.nim +++ b/tests/closure/tnested.nim @@ -1,4 +1,5 @@ discard """ +targets: "c js" output: ''' foo88 23 24foo 88 @@ -33,6 +34,7 @@ py py px 6 +proc (){.closure, noSideEffect, gcsafe.} ''' """ @@ -177,3 +179,37 @@ block tclosure2: outer2() + +# bug #5688 + +import typetraits + +block: + proc myDiscard[T](a: T) = discard + + proc foo() = + let a = 5 + let f = (proc() = + myDiscard (proc() = echo a) + ) + echo name(typeof(f)) + + foo() + + +block: + iterator foo: int {.closure.} = + yield 1 + yield 2 + yield 3 + + proc pork = + let call = foo + for i in call(): + discard i + + let call2 = foo + while not finished(call2): + discard call2() + + pork() diff --git a/tests/closure/tstmtlist.nim b/tests/closure/tstmtlist.nim new file mode 100644 index 000000000..6a1390617 --- /dev/null +++ b/tests/closure/tstmtlist.nim @@ -0,0 +1,9 @@ +discard """ + action: compile +""" + +proc foo(x: proc()) = x() +foo: echo "a" #[tt.Warning + ^ statement list expression assumed to be anonymous proc; this is deprecated, use `do (): ...` or `proc () = ...` instead [StmtListLambda]]# +foo do: echo "b" #[tt.Warning + ^ statement list expression assumed to be anonymous proc; this is deprecated, use `do (): ...` or `proc () = ...` instead [StmtListLambda]]# diff --git a/tests/closure/ttimeinfo.nim b/tests/closure/ttimeinfo.nim index 7416c0d31..24d535cbf 100644 --- a/tests/closure/ttimeinfo.nim +++ b/tests/closure/ttimeinfo.nim @@ -1,7 +1,7 @@ discard """ output: ''' -@[2000-01-01T00:00:00+00:00, 2001-01-01T00:00:00+00:00, 2002-01-01T00:00:00+00:00, 2003-01-01T00:00:00+00:00, 2004-01-01T00:00:00+00:00, 2005-01-01T00:00:00+00:00, 2006-01-01T00:00:00+00:00, 2007-01-01T00:00:00+00:00, 2008-01-01T00:00:00+00:00, 2009-01-01T00:00:00+00:00, 2010-01-01T00:00:00+00:00, 2011-01-01T00:00:00+00:00, 2012-01-01T00:00:00+00:00, 2013-01-01T00:00:00+00:00, 2014-01-01T00:00:00+00:00, 2015-01-01T00:00:00+00:00] -@[2000-01-01T00:00:00+00:00, 2001-01-01T00:00:00+00:00, 2002-01-01T00:00:00+00:00, 2003-01-01T00:00:00+00:00, 2004-01-01T00:00:00+00:00, 2005-01-01T00:00:00+00:00, 2006-01-01T00:00:00+00:00, 2007-01-01T00:00:00+00:00, 2008-01-01T00:00:00+00:00, 2009-01-01T00:00:00+00:00, 2010-01-01T00:00:00+00:00, 2011-01-01T00:00:00+00:00, 2012-01-01T00:00:00+00:00, 2013-01-01T00:00:00+00:00, 2014-01-01T00:00:00+00:00, 2015-01-01T00:00:00+00:00] +@[2000-01-01T00:00:00Z, 2001-01-01T00:00:00Z, 2002-01-01T00:00:00Z, 2003-01-01T00:00:00Z, 2004-01-01T00:00:00Z, 2005-01-01T00:00:00Z, 2006-01-01T00:00:00Z, 2007-01-01T00:00:00Z, 2008-01-01T00:00:00Z, 2009-01-01T00:00:00Z, 2010-01-01T00:00:00Z, 2011-01-01T00:00:00Z, 2012-01-01T00:00:00Z, 2013-01-01T00:00:00Z, 2014-01-01T00:00:00Z, 2015-01-01T00:00:00Z] +@[2000-01-01T00:00:00Z, 2001-01-01T00:00:00Z, 2002-01-01T00:00:00Z, 2003-01-01T00:00:00Z, 2004-01-01T00:00:00Z, 2005-01-01T00:00:00Z, 2006-01-01T00:00:00Z, 2007-01-01T00:00:00Z, 2008-01-01T00:00:00Z, 2009-01-01T00:00:00Z, 2010-01-01T00:00:00Z, 2011-01-01T00:00:00Z, 2012-01-01T00:00:00Z, 2013-01-01T00:00:00Z, 2014-01-01T00:00:00Z, 2015-01-01T00:00:00Z] ''' """ @@ -12,11 +12,11 @@ import times # 1 proc f(n: int): DateTime = - DateTime(year: n, month: mJan, monthday: 1) + initDateTime(1, mJan, n, 0, 0, 0, utc()) echo toSeq(2000 || 2015).map(f) # 2 echo toSeq(2000 || 2015).map(proc (n: int): DateTime = - DateTime(year: n, month: mJan, monthday: 1) + initDateTime(1, mJan, n, 0, 0, 0, utc()) ) |