diff options
Diffstat (limited to 'tests/closure')
45 files changed, 1218 insertions, 916 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/t1641.nim b/tests/closure/t1641.nim new file mode 100644 index 000000000..a3e4da367 --- /dev/null +++ b/tests/closure/t1641.nim @@ -0,0 +1,20 @@ +discard """ + output: '''foo 0 +bar 0 +baz''' +""" + +# bug #1641 +proc baz() = + echo "baz" + +proc bar(x: int, p: proc()) = + echo "bar ", x + p() + +proc foo(x: int, p: proc(x: int)) = + echo "foo ", x + p(x) + +let x = 0 +x.foo do(x: int): x.bar do(): baz() 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 new file mode 100644 index 000000000..a07f45cdc --- /dev/null +++ b/tests/closure/t8550.nim @@ -0,0 +1,13 @@ +discard """ + targets: "c js" + output: "@[\"42\"]" +""" + +proc chk_fail(): seq[string] = + iterator x(): int {.closure.} = yield 42 + proc f(cl: iterator(): int {.closure.}): seq[string] = + result = @[] + for i in cl(): result.add($i) + result = f(x) + +echo(chk_fail()) 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/tboehmdeepcopy.nim b/tests/closure/tboehmdeepcopy.nim new file mode 100644 index 000000000..7c937ca10 --- /dev/null +++ b/tests/closure/tboehmdeepcopy.nim @@ -0,0 +1,18 @@ +discard """ + cmd: "nim c --gc:boehm $options $file" + output: '''meep''' + disabled: "windows" +""" + +proc callit(it: proc ()) = + it() + +proc main = + var outer = "meep" + proc x = + echo outer + var y: proc() + deepCopy(y, x) + callit(y) + +main() diff --git a/tests/closure/tcapture.nim b/tests/closure/tcapture.nim new file mode 100644 index 000000000..dafc44739 --- /dev/null +++ b/tests/closure/tcapture.nim @@ -0,0 +1,34 @@ +discard """ + output: ''' +to be, or not to be +(v: 1) +(w: -1) +(v: 1) +(w: -1) +''' + joinable: false +""" + +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] + +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 09d48436e..401a71d40 100644 --- a/tests/closure/tclosure.nim +++ b/tests/closure/tclosure.nim @@ -1,47 +1,504 @@ discard """ - file: "tclosure.nim" - output: "1 3 6 11 20" + targets: "c" + output: ''' +1 3 6 11 20 foo +foo88 +23 24foo 88 +18 +18 +99 +99 +99 +99 99 +99 99 +12 99 99 +12 99 99 +success +@[1, 2, 5] +click at 10,20 +lost focus 1 +lost focus 2 +registered handler for UserEvent 1 +registered handler for UserEvent 2 +registered handler for UserEvent 3 +registered handler for UserEvent 4 +asdas +processClient end +false +baro0 +foo88 +23 24foo 88 +foo88 +23 24foo 88 +11 +@[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1] +''' +joinable: false """ -# Test the closure implementation -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]) +block tclosure: + 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 each(n: openarray[int], fn: proc(x: int) {.closure.}) = - for i in 0..n.len-1: - fn(n[i]) + proc each(n: openArray[int], fn: proc(x: int) {.closure.}) = + for i in 0..n.len-1: + fn(n[i]) -var - myData: array[0..4, int] = [0, 1, 2, 3, 4] + var myData: array[0..4, int] = [0, 1, 2, 3, 4] -proc testA() = - var p = 0 - map(myData, proc (x: int): int = - result = x + 1 shl (proc (y: int): int = - return y + p - )(0) - inc(p)) + proc testA() = + var p = 0 + map(myData, proc (x: int): int = + result = x + 1 shl (proc (y: int): int = + return y + p + )(0) + inc(p)) -testA() + testA() -myData.each do (x: int): - write(stdout, x) - write(stdout, " ") + myData.each do (x: int): + write(stdout, x) + write(stdout, " ") -#OUT 2 4 6 8 10 + #OUT 2 4 6 8 10 -type - ITest = tuple[ - setter: proc(v: int), - getter: proc(): int] + # bug #5015 -proc getInterf(): ITest = - var shared: int + type Mutator = proc(matched: string): string {.noSideEffect, gcsafe.} - return (setter: proc (x: int) = shared = x, - getter: proc (): int = return shared) + proc putMutated( + MutatorCount: static[int], + mTable: static[array[MutatorCount, Mutator]], input: string) = + for i in 0..<MutatorCount: echo mTable[i](input) + proc mutator0(matched: string): string = + "foo" + + const + mTable = [Mutator(mutator0)] + + putMutated(1, mTable, "foo") + + + +block tclosure0: + 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() + + + + + + +block tclosure3: + proc main = + const n = 30 + for iterations in 0..10_000: + var s: seq[proc(): string {.closure.}] = @[] + for i in 0 .. n-1: + (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 + + if getOccupiedMem() > 5000_000: quit("still a leak!") + echo "success" + + main() + + + +import json, tables, sequtils +block tclosure4: + proc run(json_params: OrderedTable) = + let json_elems = json_params["files"].elems + # These fail compilation. + var files = map(json_elems, proc (x: JsonNode): string = x.str) + + let text = """{"files": ["a", "b", "c"]}""" + run((text.parseJson).fields) + + + +import sugar +block inference3304: + type + List[T] = ref object + val: T + + proc foo[T](l: List[T]): seq[int] = + @[1,2,3,5].filter(x => x != l.val) + + echo(foo(List[int](val: 3))) + + + +block tcodegenerr1923: + type + Foo[M] = proc() : M + + proc bar[M](f : Foo[M]) = + discard f() + + proc baz() : int = 42 + + bar(baz) + + + +block doNotation: + type + Button = object + Event = object + x, y: int + + proc onClick(x: Button, handler: proc(x: Event)) = + handler(Event(x: 10, y: 20)) + + proc onFocusLost(x: Button, handler: proc()) = + handler() + + proc onUserEvent(x: Button, eventName: string, handler: proc) = + echo "registered handler for ", eventName + + var b = Button() + + b.onClick do (e: Event): + echo "click at ", e.x, ",", e.y + + b.onFocusLost do (): + echo "lost focus 1" + + b.onFocusLost do (): + echo "lost focus 2" + + b.onUserEvent("UserEvent 1") do (): + discard + + onUserEvent(b, "UserEvent 2") do (): + discard + + b.onUserEvent("UserEvent 3") do (): + discard + + b.onUserEvent("UserEvent 4", () => echo "event 4") + + + +import tables +block fib50: + proc memoize(f: proc (a: int64): int64): proc (a: int64): int64 = + var previous = initTable[int64, int64]() + return proc(i: int64): int64 = + if not previous.hasKey i: + previous[i] = f(i) + return previous[i] + + var fib: proc(a: int64): int64 + + fib = memoize(proc (i: int64): int64 = + if i == 0 or i == 1: + return 1 + return fib(i-1) + fib(i-2) + ) + + doAssert fib(50) == 20365011074 + + + +block tflatmap: + # bug #3995 + type + RNG = tuple[] + Rand[A] = (RNG) -> (A, RNG) + + proc nextInt(r: RNG): (int, RNG) = + (1, ()) + + proc flatMap[A,B](f: Rand[A], g: A -> Rand[B]): Rand[B] = + (rng: RNG) => ( + let (a, rng2) = f(rng); + let g1 = g(a); + g1(rng2) + ) + + proc map[A,B](s: Rand[A], f: A -> B): Rand[B] = + let g: A -> Rand[B] = (a: A) => ((rng: RNG) => (f(a), rng)) + flatMap(s, g) + + discard nextInt.map(i => i - i mod 2) + + + +block tforum: + type + PAsyncHttpServer = ref object + value: string + PFutureBase = ref object + callback: proc () {.closure.} + value: string + failed: bool + + proc accept(server: PAsyncHttpServer): PFutureBase = + new(result) + result.callback = proc () = + discard + server.value = "hahaha" + + proc processClient(): PFutureBase = + new(result) + + proc serve(server: PAsyncHttpServer): PFutureBase = + iterator serveIter(): PFutureBase {.closure.} = + echo server.value + while true: + var acceptAddrFut = server.accept() + yield acceptAddrFut + var fut = acceptAddrFut.value + + var f = processClient() + f.callback = + proc () = + echo("processClient end") + echo(f.failed) + yield f + var x = serveIter + for i in 0 .. 1: + result = x() + result.callback() + + discard serve(PAsyncHttpServer(value: "asdas")) + + + +block futclosure2138: + proc any[T](list: varargs[T], pred: (T) -> bool): bool = + for item in list: + if pred(item): + result = true + break + + proc contains(s: string, words: varargs[string]): bool = + any(words, (word) => s.contains(word)) + + + +block tinterf: + type + ITest = tuple[ + setter: proc(v: int) {.closure.}, + getter1: proc(): int {.closure.}, + getter2: proc(): int {.closure.}] + + proc getInterf(): ITest = + var shared1, shared2: int + + return (setter: proc (x: int) = + shared1 = x + shared2 = x + 10, + getter1: proc (): int = result = shared1, + getter2: proc (): int = return shared2) + + var i = getInterf() + i.setter(56) + + doAssert i.getter1() == 56 + doAssert i.getter2() == 66 + + + +block tjester: + type + Future[T] = ref object + data: T + callback: proc () {.closure.} + + proc cbOuter(response: string) {.discardable.} = + iterator cbIter(): Future[int] {.closure.} = + for i in 0..7: + proc foo(): int = + iterator fooIter(): Future[int] {.closure.} = + echo response, i + yield Future[int](data: 17) + var iterVar = fooIter + iterVar().data + yield Future[int](data: foo()) + + var iterVar2 = cbIter + proc cb2() {.closure.} = + try: + if not finished(iterVar2): + let next = iterVar2() + if next != nil: + next.callback = cb2 + except: + echo "WTF" + cb2() + + cbOuter "baro" + + + +block tnamedparamanonproc: + type + PButton = ref object + TButtonClicked = proc(button: PButton) {.nimcall.} + + proc newButton(onClick: TButtonClicked) = + discard + + proc main() = + newButton(onClick = proc(b: PButton) = + var requestomat = 12 + ) + + main() + + + +block tnestedclosure: + proc main(param: int) = + var foo = 23 + proc outer(outerParam: string) = + var outerVar = 88 + echo outerParam, outerVar + proc inner() = + block Test: + echo foo, " ", param, outerParam, " ", outerVar + inner() + outer("foo") + + # 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() + + main(24) + + # Jester + async triggered this bug: + proc cbOuter() = + var response = "hohoho" + block: + proc cbIter() = + block: + proc fooIter() = + doAssert response == "hohoho" + fooIter() + cbIter() + cbOuter() + + + +block tnestedproc: + proc p(x, y: int): int = + result = x + y + + echo p((proc (): int = + var x = 7 + return x)(), + (proc (): int = return 4)()) + + + +block tnoclosure: + proc pascal(n: int) = + var row = @[1] + for r in 1..n: + 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/tclosure0.nim b/tests/closure/tclosure0.nim deleted file mode 100644 index 9952268d5..000000000 --- a/tests/closure/tclosure0.nim +++ /dev/null @@ -1,87 +0,0 @@ -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 deleted file mode 100644 index 9c5ee1426..000000000 --- a/tests/closure/tclosure2.nim +++ /dev/null @@ -1,101 +0,0 @@ -discard """ - output: '''0 -11 -1 -11 -2 -11 -3 -11 -4 -11 -5 -11 -6 -11 -7 -11 -8 -11 -9 -11 -11 -py -py -py -py -px -6''' -""" - -when true: - proc ax = - for xxxx in 0..9: - var i = 0 - proc bx = - if i > 10: - echo xxxx - return - i += 1 - #for j in 0 .. 0: echo i - bx() - - bx() - echo i - - ax() - -when true: - proc accumulator(start: int): (proc(): int {.closure.}) = - var x = start-1 - #let dummy = proc = - # discard start - - result = proc (): int = - #var x = 9 - for i in 0 .. 0: x = x + 1 - - return x - - var a = accumulator(3) - let b = accumulator(4) - echo a() + b() + a() - - - proc outer = - - proc py() = - # no closure here: - for i in 0..3: echo "py" - - py() - - outer() - - -when true: - proc outer2 = - var errorValue = 3 - proc fac[T](n: T): T = - if n < 0: result = errorValue - elif n <= 1: result = 1 - else: result = n * fac(n-1) - - proc px() {.closure.} = - echo "px" - - proc py() {.closure.} = - echo "py" - - let - mapping = { - "abc": px, - "xyz": py - } - mapping[0][1]() - - echo fac(3) - - - outer2() - diff --git a/tests/closure/tclosure3.nim b/tests/closure/tclosure3.nim deleted file mode 100644 index d5ffb5ab2..000000000 --- a/tests/closure/tclosure3.nim +++ /dev/null @@ -1,21 +0,0 @@ -discard """ - file: "tclosure3.nim" - output: "success" -""" - -proc main = - const n = 30 - for iterations in 0..50_000: - var s: seq[proc(): string {.closure.}] = @[] - for i in 0 .. n-1: - (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 - - if getOccupiedMem() > 3000_000: quit("still a leak!") - echo "success" - -main() diff --git a/tests/closure/tclosure4.nim b/tests/closure/tclosure4.nim deleted file mode 100644 index 69c076cd5..000000000 --- a/tests/closure/tclosure4.nim +++ /dev/null @@ -1,13 +0,0 @@ - -import json, tables, sequtils - -proc run(json_params: Table) = - 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 - echo "Hey!" - -when isMainModule: - let text = """{"files": ["a", "b", "c"]}""" - run((text.parseJson).fields) diff --git a/tests/closure/tclosure_issues.nim b/tests/closure/tclosure_issues.nim new file mode 100644 index 000000000..b1a2d7c6b --- /dev/null +++ b/tests/closure/tclosure_issues.nim @@ -0,0 +1,82 @@ +discard """ + output: '''true +(999, 0) +ok 0 +ok 1 +ok 2 +''' +""" + + +block tissue600: + for i in 1..1: + var reported = false + proc report() = + reported = true + + + +import sequtils +block tissue1502def: + let xs: seq[tuple[key: string, val: seq[string]]] = @[("foo", @["bar"])] + + let maps = xs.map( + proc(x: auto): tuple[typ: string, maps: seq[string]] = + (x.key, x.val.map(proc(x: string): string = x))) + + + +block tissue1642: + var i = 0 + proc p() = inc(i) + + + +block tissue1846: + type + TBinOp[T] = proc (x,y: T): bool + THeap[T] = object + cmp: TBinOp[T] + + proc less[T](x,y: T): bool = + x < y + + proc initHeap[T](cmp: TBinOp[T]): THeap[T] = + result.cmp = cmp + + var h = initHeap[int](less[int]) + echo h.cmp(2,3) + + + +block tissue1911: + proc foo(x: int) : auto = + + proc helper() : int = x + proc bar() : int = helper() + proc baz() : int = helper() + + return (bar, baz) + +# bug #11523 +proc foo(): proc = + let a = 999 + return proc(): (int, int) = + return (a, 0) + +echo foo()() + + +block tissue7104: + proc sp(cb: proc())= + cb() + + sp do (): + var i = 0 + echo "ok ", i + sp do (): + inc i + echo "ok ", i + sp do (): + inc i + echo "ok ", i diff --git a/tests/closure/tclosurebug2.nim b/tests/closure/tclosurebug2.nim deleted file mode 100644 index f131406a3..000000000 --- a/tests/closure/tclosurebug2.nim +++ /dev/null @@ -1,194 +0,0 @@ -import hashes, math - -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]] - TOrderedTable*[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: TOrderedTable[A, B]): int {.inline.} = - ## returns the number of keys in `t`. - result = t.counter - -template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} = - 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: TOrderedTable[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 TOrderedTable[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: TOrderedTable[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: TOrderedTable[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 TOrderedTable[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: TOrderedTable[A, B], key: A): int = - rawGetImpl() - -proc `[]`*[A, B](t: TOrderedTable[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 TOrderedTable[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: TOrderedTable[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 TOrderedTable[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 TOrderedTable[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 TOrderedTable[A, B], key: A, val: B) = - ## puts a (key, value)-pair into `t`. - putImpl() - -proc add*[A, B](t: var TOrderedTable[A, B], key: A, val: B) = - ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. - addImpl() - -proc initOrderedTable*[A, B](initialSize=64): TOrderedTable[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]]): TOrderedTable[A, B] = - ## creates a new ordered hash table that contains the given `pairs`. - result = initOrderedTable[A, B](nextPowerOfTwo(pairs.len+10)) - for key, val in items(pairs): result[key] = val - -proc sort*[A, B](t: var TOrderedTable[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 diff --git a/tests/closure/tclosureinference3304.nim b/tests/closure/tclosureinference3304.nim deleted file mode 100644 index db4aa1d04..000000000 --- a/tests/closure/tclosureinference3304.nim +++ /dev/null @@ -1,15 +0,0 @@ -discard """ - output: '''@[1, 2, 5]''' -""" - -import future, sequtils - -type - List[T] = ref object - val: T - -proc foo[T](l: List[T]): seq[int] = - @[1,2,3,5].filter(x => x != l.val) - -when isMainModule: - echo(foo(List[int](val: 3))) diff --git a/tests/closure/tcodegenerr1923.nim b/tests/closure/tcodegenerr1923.nim deleted file mode 100644 index ee131ae15..000000000 --- a/tests/closure/tcodegenerr1923.nim +++ /dev/null @@ -1,9 +0,0 @@ -type - Foo[M] = proc() : M - -proc bar[M](f : Foo[M]) = - discard f() - -proc baz() : int = 42 - -bar(baz) \ No newline at end of file diff --git a/tests/closure/tdeeplynested.nim b/tests/closure/tdeeplynested.nim deleted file mode 100644 index ddf4fa6a4..000000000 --- a/tests/closure/tdeeplynested.nim +++ /dev/null @@ -1,20 +0,0 @@ -discard """ - output: '''int: 108''' -""" - -# bug #4070 - -proc id(f: (proc())): auto = - return f - -proc foo(myinteger: int): (iterator(): int) = - return iterator(): int {.closure.} = - proc bar() = - proc kk() = - echo "int: ", myinteger - - kk() - - id(bar)() - -discard foo(108)() diff --git a/tests/closure/texplicit_dummy_closure.nim b/tests/closure/texplicit_dummy_closure.nim index ec608b31a..02b9ac7c7 100644 --- a/tests/closure/texplicit_dummy_closure.nim +++ b/tests/closure/texplicit_dummy_closure.nim @@ -1,3 +1,6 @@ +discard """ + disabled: true +""" # This is a regression of the new lambda lifting; detected by Aporia import asyncio, sockets @@ -5,8 +8,8 @@ import os type Window = object - oneInstSock*: PAsyncSocket - IODispatcher*: PDispatcher + oneInstSock*: AsyncSocket + IODispatcher*: Dispatcher var win: Window @@ -14,9 +17,9 @@ var proc initSocket() = win.oneInstSock = asyncSocket() #win.oneInstSock.handleAccept = - proc test(s: PAsyncSocket) = - var client: PAsyncSocket - proc dummy(c: PAsyncSocket) {.closure.} = + proc test(s: AsyncSocket) = + var client: AsyncSocket + proc dummy(c: AsyncSocket) {.closure.} = discard client.handleRead = dummy test(win.oneInstSock) diff --git a/tests/closure/tfib50.nim b/tests/closure/tfib50.nim deleted file mode 100644 index 719aa3ad5..000000000 --- a/tests/closure/tfib50.nim +++ /dev/null @@ -1,22 +0,0 @@ -discard """ - output: "20365011074" -""" - -import tables - -proc memoize(f: proc (a: int64): int64): proc (a: int64): int64 = - var previous = initTable[int64, int64]() - return proc(i: int64): int64 = - if not previous.hasKey i: - previous[i] = f(i) - return previous[i] - -var fib: proc(a: int64): int64 - -fib = memoize(proc (i: int64): int64 = - if i == 0 or i == 1: - return 1 - return fib(i-1) + fib(i-2) -) - -echo fib(50) diff --git a/tests/closure/tflatmap.nim b/tests/closure/tflatmap.nim deleted file mode 100644 index 240756424..000000000 --- a/tests/closure/tflatmap.nim +++ /dev/null @@ -1,24 +0,0 @@ - -# bug #3995 - -import future - -type - RNG* = tuple[] - Rand*[A] = (RNG) -> (A, RNG) - -proc nextInt*(r: RNG): (int, RNG) = - (1, ()) - -proc flatMap[A,B](f: Rand[A], g: A -> Rand[B]): Rand[B] = - (rng: RNG) => ( - let (a, rng2) = f(rng); - let g1 = g(a); - g1(rng2) - ) - -proc map[A,B](s: Rand[A], f: A -> B): Rand[B] = - let g: A -> Rand[B] = (a: A) => ((rng: RNG) => (f(a), rng)) - flatMap(s, g) - -let f = nextInt.map(i => i - i mod 2) diff --git a/tests/closure/tforum.nim b/tests/closure/tforum.nim deleted file mode 100644 index 4f6a16ff7..000000000 --- a/tests/closure/tforum.nim +++ /dev/null @@ -1,44 +0,0 @@ -discard """ - output: '''asdas -processClient end -false -''' -""" - -type - PAsyncHttpServer = ref object - value: string - PFutureBase = ref object - callback: proc () {.closure.} - value: string - failed: bool - -proc accept(server: PAsyncHttpServer): PFutureBase = - new(result) - result.callback = proc () = - discard - server.value = "hahaha" - -proc processClient(): PFutureBase = - new(result) - -proc serve(server: PAsyncHttpServer): PFutureBase = - iterator serveIter(): PFutureBase {.closure.} = - echo server.value - while true: - var acceptAddrFut = server.accept() - yield acceptAddrFut - var fut = acceptAddrFut.value - - var f = processClient() - f.callback = - proc () = - echo("processClient end") - echo(f.failed) - yield f - var x = serveIter - for i in 0 .. 1: - result = x() - result.callback() - -discard serve(PAsyncHttpServer(value: "asdas")) diff --git a/tests/closure/tfutclosure2138.nim b/tests/closure/tfutclosure2138.nim deleted file mode 100644 index e18834074..000000000 --- a/tests/closure/tfutclosure2138.nim +++ /dev/null @@ -1,10 +0,0 @@ -import future, sequtils - -proc any[T](list: varargs[T], pred: (T) -> bool): bool = - for item in list: - if pred(item): - result = true - break - -proc contains(s: string, words: varargs[string]): bool = - any(words, (word) => s.contains(word)) \ No newline at end of file diff --git a/tests/closure/tinfer_closure_for_nestedproc.nim b/tests/closure/tinfer_closure_for_nestedproc.nim new file mode 100644 index 000000000..6450d1492 --- /dev/null +++ b/tests/closure/tinfer_closure_for_nestedproc.nim @@ -0,0 +1,42 @@ +discard """ + action: compile +""" + +# bug #9441 +import asyncdispatch, asyncfutures, strtabs + +type + Request = object + Context = object + position: int + accept: bool + headers: StringTableRef + Handler = proc (r: ref Request, c: Context): Future[Context] + +proc respond(req: Request): Future[void] = discard + +proc handle*(h: Handler): auto = # (proc (req: Request): Future[void]) = + proc server(req: Request): Future[void] {.async.} = + let emptyCtx = Context( + position: 0, + accept: true, + headers: newStringTable() + ) + var reqHeap = new(Request) + reqHeap[] = req + var + f: Future[Context] + ctx: Context + try: + f = h(reqHeap, emptyCtx) + ctx = await f + except: + discard + if f.failed: + await req.respond() + else: + if not ctx.accept: + await req.respond() + return server + +waitFor handle(nil)(Request()) diff --git a/tests/closure/tinterf.nim b/tests/closure/tinterf.nim deleted file mode 100644 index 1ac6da945..000000000 --- a/tests/closure/tinterf.nim +++ /dev/null @@ -1,24 +0,0 @@ -discard """ - output: '''56 66''' -""" - -type - ITest = tuple[ - setter: proc(v: int) {.closure.}, - getter1: proc(): int {.closure.}, - getter2: proc(): int {.closure.}] - -proc getInterf(): ITest = - var shared1, shared2: int - - return (setter: proc (x: int) = - shared1 = x - shared2 = x + 10, - getter1: proc (): int = result = shared1, - getter2: proc (): int = return shared2) - -var i = getInterf() -i.setter(56) - -echo i.getter1(), " ", i.getter2() - diff --git a/tests/closure/tinvalidclosure.nim b/tests/closure/tinvalidclosure.nim index d3f38cde5..37d0f68a2 100644 --- a/tests/closure/tinvalidclosure.nim +++ b/tests/closure/tinvalidclosure.nim @@ -1,6 +1,6 @@ discard """ + errormsg: "type mismatch: got <proc (x: int){.nimcall, gcsafe.}>" line: 12 - errormsg: "type mismatch: got (proc (x: int){.gcsafe, locks: 0.})" """ proc ugh[T](x: T) {.nimcall.} = diff --git a/tests/closure/tinvalidclosure2.nim b/tests/closure/tinvalidclosure2.nim index 845559309..2d58f0215 100644 --- a/tests/closure/tinvalidclosure2.nim +++ b/tests/closure/tinvalidclosure2.nim @@ -1,6 +1,6 @@ discard """ - line: 10 errormsg: "illegal capture 'A'" + line: 10 """ proc outer() = diff --git a/tests/closure/tinvalidclosure3.nim b/tests/closure/tinvalidclosure3.nim new file mode 100644 index 000000000..0cbdaf39e --- /dev/null +++ b/tests/closure/tinvalidclosure3.nim @@ -0,0 +1,12 @@ +discard """ + errormsg: "illegal capture 'x'" + line: 9 +""" + +proc outer(arg: string) = + var x = 0 + proc inner {.inline.} = + echo "inner", x + inner() + +outer("abc") 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/tissue1502def.nim b/tests/closure/tissue1502def.nim deleted file mode 100644 index 0aa6b16e3..000000000 --- a/tests/closure/tissue1502def.nim +++ /dev/null @@ -1,6 +0,0 @@ -import sequtils -let xs: seq[tuple[key: string, val: seq[string]]] = @[("foo", @["bar"])] - -let maps = xs.map( - proc(x: auto): tuple[typ: string, maps: seq[string]] = - (x.key, x.val.map(proc(x: string): string = x))) \ No newline at end of file diff --git a/tests/closure/tissue1642.nim b/tests/closure/tissue1642.nim deleted file mode 100644 index 5b921fc05..000000000 --- a/tests/closure/tissue1642.nim +++ /dev/null @@ -1,3 +0,0 @@ -block: - var i = 0 - proc p() = inc(i) \ No newline at end of file diff --git a/tests/closure/tissue1846.nim b/tests/closure/tissue1846.nim deleted file mode 100644 index 3fbef169d..000000000 --- a/tests/closure/tissue1846.nim +++ /dev/null @@ -1,16 +0,0 @@ -type - TBinOp*[T] = proc (x,y: T): bool - - THeap*[T] = object - cmp*: TBinOp[T] - -proc less*[T](x,y: T): bool = - x < y - -proc initHeap*[T](cmp: TBinOp[T]): THeap[T] = - result.cmp = cmp - -when isMainModule: - var h = initHeap[int](less[int]) - - echo h.cmp(2,3) \ No newline at end of file diff --git a/tests/closure/tissue1911.nim b/tests/closure/tissue1911.nim deleted file mode 100644 index 311d99134..000000000 --- a/tests/closure/tissue1911.nim +++ /dev/null @@ -1,7 +0,0 @@ -proc foo(x: int) : auto = - - proc helper() : int = x - proc bar() : int = helper() - proc baz() : int = helper() - - return (bar, baz) \ No newline at end of file diff --git a/tests/closure/tissue600.nim b/tests/closure/tissue600.nim deleted file mode 100644 index eacc7a123..000000000 --- a/tests/closure/tissue600.nim +++ /dev/null @@ -1,4 +0,0 @@ -for i in 1..1: - var reported = false - proc report() = - reported = true \ No newline at end of file diff --git a/tests/closure/tjester.nim b/tests/closure/tjester.nim deleted file mode 100644 index 84e0fcb71..000000000 --- a/tests/closure/tjester.nim +++ /dev/null @@ -1,32 +0,0 @@ -discard """ - output: '''baro0''' -""" - -type - Future[T] = ref object - data: T - callback: proc () {.closure.} - -proc cbOuter(response: string) {.discardable.} = - iterator cbIter(): Future[int] {.closure.} = - for i in 0..7: - proc foo(): int = - iterator fooIter(): Future[int] {.closure.} = - echo response, i - yield Future[int](data: 17) - var iterVar = fooIter - iterVar().data - yield Future[int](data: foo()) - - var iterVar2 = cbIter - proc cb2() {.closure.} = - try: - if not finished(iterVar2): - let next = iterVar2() - if next != nil: - next.callback = cb2 - except: - echo "WTF" - cb2() - -cbOuter "baro" diff --git a/tests/closure/tmacrobust1512.nim b/tests/closure/tmacrobust1512.nim index 95681e750..0f44c5e1a 100644 --- a/tests/closure/tmacrobust1512.nim +++ b/tests/closure/tmacrobust1512.nim @@ -1,115 +1,110 @@ +discard """ +output: "" +""" + import macros, strutils # https://github.com/nim-lang/Nim/issues/1512 -proc macrobust0 (raw_input: string) = +proc macrobust0(input: string): string = var output = "" - proc p1 (a:string) = - output.add (a) - - proc p2 (a:string) = p1 (a) - proc p3 (a:string) = p2 (a) - proc p4 (a:string) = p3 (a) - proc p5 (a:string) = p4 (a) - proc p6 (a:string) = p5 (a) - proc p7 (a:string) = p6 (a) - proc p8 (a:string) = p7 (a) - proc p9 (a:string) = p8 (a) - proc p10 (a:string) = p9 (a) - proc p11 (a:string) = p10 (a) - proc p12 (a:string) = p11 (a) - proc p13 (a:string) = p12 (a) - proc p14 (a:string) = p13 (a) - proc p15 (a:string) = p14 (a) - proc p16 (a:string) = p15 (a) - proc p17 (a:string) = p16 (a) - proc p18 (a:string) = p17 (a) - proc p19 (a:string) = p18 (a) - proc p20 (a:string) = p19 (a) - - let input = $raw_input - - for a in input.split (): - p20 (a) - p19 (a) - - - p18 (a) - p17 (a) - p16 (a) - p15 (a) - p14 (a) - p13 (a) - p12 (a) - p11 (a) - p10 (a) - p9 (a) - p8 (a) - p7 (a) - p6 (a) - p5 (a) - p4 (a) - p3 (a) - p2 (a) - p1 (a) - - - echo output - -macro macrobust (raw_input: expr) : stmt = - + proc p1(a:string) = + output.add(a) + + proc p2(a:string) = p1(a) + proc p3(a:string) = p2(a) + proc p4(a:string) = p3(a) + proc p5(a:string) = p4(a) + proc p6(a:string) = p5(a) + proc p7(a:string) = p6(a) + proc p8(a:string) = p7(a) + proc p9(a:string) = p8(a) + proc p10(a:string) = p9(a) + proc p11(a:string) = p10(a) + proc p12(a:string) = p11(a) + proc p13(a:string) = p12(a) + proc p14(a:string) = p13(a) + proc p15(a:string) = p14(a) + proc p16(a:string) = p15(a) + proc p17(a:string) = p16(a) + proc p18(a:string) = p17(a) + proc p19(a:string) = p18(a) + proc p20(a:string) = p19(a) + + for a in input.split(): + p20(a) + p19(a) + p18(a) + p17(a) + p16(a) + p15(a) + p14(a) + p13(a) + p12(a) + p11(a) + p10(a) + p9(a) + p8(a) + p7(a) + p6(a) + p5(a) + p4(a) + p3(a) + p2(a) + p1(a) + + result = output + +macro macrobust(input: static[string]): untyped = var output = "" - proc p1 (a:string) = - output.add (a) - - proc p2 (a:string) = p1 (a) - proc p3 (a:string) = p2 (a) - proc p4 (a:string) = p3 (a) - proc p5 (a:string) = p4 (a) - proc p6 (a:string) = p5 (a) - proc p7 (a:string) = p6 (a) - proc p8 (a:string) = p7 (a) - proc p9 (a:string) = p8 (a) - proc p10 (a:string) = p9 (a) - proc p11 (a:string) = p10 (a) - proc p12 (a:string) = p11 (a) - proc p13 (a:string) = p12 (a) - proc p14 (a:string) = p13 (a) - proc p15 (a:string) = p14 (a) - proc p16 (a:string) = p15 (a) - proc p17 (a:string) = p16 (a) - proc p18 (a:string) = p17 (a) - proc p19 (a:string) = p18 (a) - proc p20 (a:string) = p19 (a) - - let input = $raw_input - - for a in input.split (): - p20 (a) - p19 (a) - - p18 (a) - p17 (a) - p16 (a) - p15 (a) - p14 (a) - p13 (a) - p12 (a) - p11 (a) - p10 (a) - p9 (a) - p8 (a) - p7 (a) - p6 (a) - p5 (a) - p4 (a) - p3 (a) - p2 (a) - - echo output - discard result - -macrobust """ + proc p1(a:string) = + output.add(a) + + proc p2(a:string) = p1(a) + proc p3(a:string) = p2(a) + proc p4(a:string) = p3(a) + proc p5(a:string) = p4(a) + proc p6(a:string) = p5(a) + proc p7(a:string) = p6(a) + proc p8(a:string) = p7(a) + proc p9(a:string) = p8(a) + proc p10(a:string) = p9(a) + proc p11(a:string) = p10(a) + proc p12(a:string) = p11(a) + proc p13(a:string) = p12(a) + proc p14(a:string) = p13(a) + proc p15(a:string) = p14(a) + proc p16(a:string) = p15(a) + proc p17(a:string) = p16(a) + proc p18(a:string) = p17(a) + proc p19(a:string) = p18(a) + proc p20(a:string) = p19(a) + + for a in input.split(): + p20(a) + p19(a) + p18(a) + p17(a) + p16(a) + p15(a) + p14(a) + p13(a) + p12(a) + p11(a) + p10(a) + p9(a) + p8(a) + p7(a) + p6(a) + p5(a) + p4(a) + p3(a) + p2(a) + p1(a) + + result = newLit(output) + +const input = """ fdsasadfsdfa sadfsdafsdaf dsfsdafdsfadsfa fsdaasdfasdf fsdafsadfsad asdfasdfasdf @@ -122,16 +117,7 @@ macrobust """ sdfasdafsadf sdfasdafsdaf sdfasdafsdaf """ +let str1 = macrobust(input) +let str2 = macrobust0(input) -macrobust0 """ - fdsasadfsdfa sadfsdafsdaf - dsfsdafdsfadsfa fsdaasdfasdf - fsdafsadfsad asdfasdfasdf - fdsasdfasdfa sadfsadfsadf - sadfasdfsdaf sadfsdafsdaf dsfasdaf - sadfsdafsadf fdsasdafsadf fdsasadfsdaf - sdfasadfsdafdfsa sadfsadfsdaf - sdafsdaffsda sdfasadfsadf - fsdasdafsdfa sdfasdfafsda - sdfasdafsadf sdfasdafsdaf sdfasdafsdaf -""" \ No newline at end of file +doAssert str1 == str2 diff --git a/tests/closure/tnamedparamanonproc.nim b/tests/closure/tnamedparamanonproc.nim deleted file mode 100644 index 94e32894f..000000000 --- a/tests/closure/tnamedparamanonproc.nim +++ /dev/null @@ -1,14 +0,0 @@ - -type - PButton = ref object - TButtonClicked = proc(button: PButton) {.nimcall.} - -proc newButton*(onClick: TButtonClicked) = - discard - -proc main() = - newButton(onClick = proc(b: PButton) = - var requestomat = 12 - ) - -main() diff --git a/tests/closure/tnested.nim b/tests/closure/tnested.nim new file mode 100644 index 000000000..ec5af9b13 --- /dev/null +++ b/tests/closure/tnested.nim @@ -0,0 +1,215 @@ +discard """ +targets: "c js" +output: ''' +foo88 +23 24foo 88 +foo88 +23 24foo 88 +11 +int: 108 +0 +11 +1 +11 +2 +11 +3 +11 +4 +11 +5 +11 +6 +11 +7 +11 +8 +11 +9 +11 +11 +py +py +py +py +px +6 +proc (){.closure, noSideEffect, gcsafe.} +''' +""" + + +block tnestedclosure: + proc main(param: int) = + var foo = 23 + proc outer(outerParam: string) = + var outerVar = 88 + echo outerParam, outerVar + proc inner() = + block Test: + echo foo, " ", param, outerParam, " ", outerVar + inner() + outer("foo") + + # 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() + + main(24) + + # Jester + async triggered this bug: + proc cbOuter() = + var response = "hohoho" + block: + proc cbIter() = + block: + proc fooIter() = + doAssert response == "hohoho" + fooIter() + cbIter() + cbOuter() + + +block tnestedproc: + proc p(x, y: int): int = + result = x + y + + echo p((proc (): int = + var x = 7 + return x)(), + (proc (): int = return 4)()) + + +block deeplynested: + # bug #4070 + proc id(f: (proc())): auto = + return f + + proc foo(myinteger: int): (iterator(): int) = + return iterator(): int {.closure.} = + proc bar() = + proc kk() = + echo "int: ", myinteger + kk() + id(bar)() + + discard foo(108)() + + +block tclosure2: + when true: + proc ax = + for xxxx in 0..9: + var i = 0 + proc bx = + if i > 10: + echo xxxx + return + i += 1 + #for j in 0 .. 0: echo i + bx() + + bx() + echo i + + ax() + + when true: + proc accumulator(start: int): (proc(): int {.closure.}) = + var x = start-1 + #let dummy = proc = + # discard start + + result = proc (): int = + #var x = 9 + for i in 0 .. 0: x = x + 1 + + return x + + var a = accumulator(3) + let b = accumulator(4) + echo a() + b() + a() + + + proc outer = + + proc py() = + # no closure here: + for i in 0..3: echo "py" + + py() + + outer() + + + when true: + proc outer2 = + var errorValue = 3 + proc fac[T](n: T): T = + if n < 0: result = errorValue + elif n <= 1: result = 1 + else: result = n * fac(n-1) + + proc px() {.closure.} = + echo "px" + + proc py() {.closure.} = + echo "py" + + let + mapping = { + "abc": px, + "xyz": py + } + mapping[0][1]() + + echo fac(3) + + + 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/tnestedclosure.nim b/tests/closure/tnestedclosure.nim deleted file mode 100644 index 0628a6977..000000000 --- a/tests/closure/tnestedclosure.nim +++ /dev/null @@ -1,51 +0,0 @@ -discard """ - output: '''foo88 -23 24foo 88 -foo88 -23 24foo 88 -hohoho''' -""" - -# test nested closure -proc main(param: int) = - var foo = 23 - proc outer(outerParam: string) = - var outerVar = 88 - echo outerParam, outerVar - proc inner() = - block Test: - echo foo, " ", param, outerParam, " ", outerVar - inner() - outer("foo") - -# 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() - -main(24) - -# Jester + async triggered this bug: -proc cbOuter() = - var response = "hohoho" - block: - proc cbIter() = - block: - proc fooIter() = - echo response - fooIter() - - cbIter() - -cbOuter() diff --git a/tests/closure/tnestedproc.nim b/tests/closure/tnestedproc.nim deleted file mode 100644 index 7eeeff198..000000000 --- a/tests/closure/tnestedproc.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - output: "11" -""" - -proc p(x, y: int): int = - result = x + y - -echo p((proc (): int = - var x = 7 - return x)(), - (proc (): int = return 4)()) - diff --git a/tests/closure/tnoclosure.nim b/tests/closure/tnoclosure.nim deleted file mode 100644 index 25cce0040..000000000 --- a/tests/closure/tnoclosure.nim +++ /dev/null @@ -1,25 +0,0 @@ -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/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 3138ae72e..24d535cbf 100644 --- a/tests/closure/ttimeinfo.nim +++ b/tests/closure/ttimeinfo.nim @@ -1,15 +1,22 @@ +discard """ +output: ''' +@[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] +''' +""" + # bug #2073 import sequtils import times # 1 -proc f(n: int): TimeInfo = - TimeInfo(year: n, month: mJan, monthday: 1) +proc f(n: int): DateTime = + initDateTime(1, mJan, n, 0, 0, 0, utc()) echo toSeq(2000 || 2015).map(f) # 2 -echo toSeq(2000 || 2015).map(proc (n: int): TimeInfo = - TimeInfo(year: n, month: mJan, monthday: 1) +echo toSeq(2000 || 2015).map(proc (n: int): DateTime = + initDateTime(1, mJan, n, 0, 0, 0, utc()) ) |