discard """ output: ''' x + y = 30 ''' """ import std/[sugar, algorithm, random, sets, tables, strutils] template main() = block: # `=>` block: let f1 = () => 42 doAssert f1() == 42 let f2 = (x: int) => x + 1 doAssert f2(42) == 43 let f3 = (x, y: int) => x + y doAssert f3(1, 2) == 3 var x = 0 let f4 = () => (x = 12) f4() doAssert x == 12 let f5 = () => (discard) # simplest proc that returns void f5() block: proc call1(f: () -> int): int = f() doAssert call1(() => 12) == 12 proc call2(f: int -> int): int = f(42) doAssert call2(x => x) == 42 doAssert call2((x) => x) == 42 doAssert call2((x: int) => x) == 42 proc call3(f: (int, int) -> int): int = f(1, 2) doAssert call3((x, y) => x + y) == 3 doAssert call3((x, y: int) => x + y) == 3 doAssert call3((x: int, y: int) => x + y) == 3 var a = 0 proc call4(f: int -> void) = f(42) call4((x: int) => (a = x)) doAssert a == 42 proc call5(f: (int {.noSideEffect.} -> int)): int = f(42) doAssert call5(x {.noSideEffect.} => x + 1) == 43 block: # `->` doAssert $(() -> int) == "proc (): int{.closure.}" doAssert $(float -> int) == "proc (i0: float): int{.closure.}" doAssert $((float) -> int) == "proc (i0: float): int{.closure.}" doAssert $((float, bool) -> int) == "proc (i0: float, i1: bool): int{.closure.}" doAssert $(() -> void) == "proc (){.closure.}" doAssert $(float -> void) == "proc (i0: float){.closure.}" doAssert $((float) -> void) == "proc (i0: float){.closure.}" doAssert $((float, bool) -> void) == "proc (i0: float, i1: bool){.closure.}" doAssert $(() {.inline.} -> int) == "proc (): int{.inline.}" doAssert $(float {.inline.} -> int) == "proc (i0: float): int{.inline.}" doAssert $((float) {.inline.} -> int) == "proc (i0: float): int{.inline.}" doAssert $((float, bool) {.inline.} -> int) == "proc (i0: float, i1: bool): int{.inline.}" block: # capture var closure1: () -> int for i in 0 .. 10: if i == 5: capture i: closure1 = () => i doAssert closure1() == 5 var closure2: () -> (int, int) for i in 0 .. 10: for j in 0 .. 10: if i == 5 and j == 3: capture i, j: closure2 = () => (i, j) doAssert closure2() == (5, 3) block: # bug #16967 var s = newSeq[proc (): int](5) {.push exportc.} proc bar() = for i in 0 ..< s.len: let foo = i + 1 capture foo: s[i] = proc(): int = foo {.pop.} bar() for i, p in s.pairs: let foo = i + 1 doAssert p() == foo block: # dup block dup_with_field: type Foo = object col, pos: int name: string proc inc_col(foo: var Foo) = inc(foo.col) proc inc_pos(foo: var Foo) = inc(foo.pos) proc name_append(foo: var Foo, s: string) = foo.name &= s let a = Foo(col: 1, pos: 2, name: "foo") block: let b = a.dup(inc_col, inc_pos): _.pos = 3 name_append("bar") inc_pos doAssert(b == Foo(col: 2, pos: 4, name: "foobar")) block: let b = a.dup(inc_col, pos = 3, name = "bar"): name_append("bar") inc_pos doAssert(b == Foo(col: 2, pos: 4, name: "barbar")) block: var a = @[1, 2, 3, 4, 5, 6, 7, 8, 9] doAssert dup(a, sort(_)) == sorted(a) doAssert a.dup(sort) == sorted(a) # Chaining: var aCopy = a aCopy.insert(10) doAssert a.dup(insert(10)).dup(sort()) == sorted(aCopy) block: when nimvm: discard else: const b = @[0, 1, 2] discard b.dup shuffle() doAssert b[0] == 0 doAssert b[1] == 1 block: # collect let data = @["bird", "word"] # if this gets stuck in your head, its not my fault doAssert collect(newSeq, for (i, d) in data.pairs: (if i mod 2 == 0: d)) == @["bird"] doAssert collect(initTable(2), for (i, d) in data.pairs: {i: d}) == {0: "bird", 1: "word"}.toTable doAssert collect(initHashSet(), for d in data.items: {d}) == data.toHashSet block: let x = collect(newSeqOfCap(4)): for (i, d) in data.pairs: if i mod 2 == 0: d doAssert x == @["bird"] block: # bug #12874 let bug = collect( newSeq, for (i, d) in data.pairs:( block: if i mod 2 == 0: d else: d & d ) ) doAssert bug == @["bird", "wordword"] block: let y = collect(newSeq): for (i, d) in data.pairs: try: parseInt(d) except: 0 doAssert y == @[0, 0] block: let z = collect(newSeq): for (i, d) in data.pairs: case d of "bird": "word" else: d doAssert z == @["word", "word"] block: proc tforum(): seq[int] = collect(newSeq): for y in 0..10: if y mod 5 == 2: for x in 0..y: x doAssert tforum() == @[0, 1, 2, 0, 1, 2, 3, 4, 5, 6, 7] block: let x = collect: for d in data.items: when d is int: "word" else: d doAssert x == @["bird", "word"] block: doAssert collect(for (i, d) in pairs(data): (i, d)) == @[(0, "bird"), (1, "word")] doAssert collect(for d in data.items: (try: parseInt(d) except: 0)) == @[0, 0] doAssert collect(for (i, d) in pairs(data): {i: d}) == {1: "word", 0: "bird"}.toTable doAssert collect(for d in data.items: {d}) == data.toHashSet block: # bug #14332 template foo = discard collect(newSeq, for i in 1..3: i) foo() proc mainProc() = block: # dump # symbols in templates are gensym'd let x = 10 y = 20 dump(x + y) # x + y = 30 block: # dumpToString template square(x): untyped = x * x let x = 10 doAssert dumpToString(square(x)) == "square(x): x * x = 100" let s = dumpToString(doAssert 1+1 == 2) doAssert "failedAssertImpl" in s let s2 = dumpToString: doAssertRaises(AssertionDefect): doAssert false doAssert "except AssertionDefect" in s2 static: main() mainProc() main() mainProc()