tclosures.nim 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. discard """
  2. action: run
  3. """
  4. import random, strutils
  5. const consolePrefix = "jsCallbacks"
  6. asm """
  7. var callback = []
  8. function regCallback (fn) { callback.push (fn); }
  9. function runCallbacks () {
  10. var result = "\n"
  11. var n = 0
  12. for (var fn in callback) {
  13. n += 1
  14. result += "("+String (n)+")"
  15. result += callback [fn] ()
  16. result += "\n"
  17. }
  18. return result
  19. }
  20. function print (text) { console.log (text); }
  21. """
  22. proc consoleprint (str:cstring): void {.importc: "print", noDecl.}
  23. proc print* (a: varargs[string, `$`]) = consoleprint "$1: $2" % [consolePrefix, join(a, " ")]
  24. type CallbackProc {.importc.} = proc () : cstring
  25. proc regCallback (fn:CallbackProc) {.importc.}
  26. proc runCallbacks ():cstring {.importc.}
  27. proc `*` (s:string, n:Natural) : string = s.repeat(n)
  28. proc outer (i:Natural) : (string, int) =
  29. let c = $char(rand(93) + 33)
  30. let n = rand(40)
  31. let s = c * n
  32. proc inner(): cstring = ("[$1]" % $n) & s & " <--"
  33. regCallback(inner)
  34. return (s, n)
  35. var expected = "\n"
  36. for i in 1 .. 10:
  37. let (s, n) = outer(i)
  38. expected &= ("($1)[$2]" % [$i, $n]) & s & " <--"
  39. expected &= "\n"
  40. let results = runCallbacks()
  41. doAssert(expected == $results)
  42. block issue7048:
  43. block:
  44. proc foo(x: seq[int]): auto =
  45. proc bar: int = x[1]
  46. bar
  47. var stuff = @[1, 2]
  48. let f = foo(stuff)
  49. stuff[1] = 321
  50. doAssert f() == 2
  51. block:
  52. proc foo(x: tuple[things: string]; y: array[3, int]): auto =
  53. proc very: auto =
  54. proc deeply: auto =
  55. proc nested: (char, int) = (x.things[0], y[1])
  56. nested
  57. deeply
  58. very()
  59. var
  60. stuff = (things: "NIM")
  61. stuff2 = [32, 64, 96]
  62. let f = foo(stuff, stuff2)
  63. stuff.things = "VIM"
  64. stuff2[1] *= 10
  65. doAssert f()() == ('N', 64)
  66. doAssert (stuff.things[0], stuff2[1]) == ('V', 640)
  67. block:
  68. proc foo(x: ptr string): auto =
  69. proc bar(): int = len(x[])
  70. bar
  71. var
  72. s1 = "xyz"
  73. s2 = "stuff"
  74. p = addr s1
  75. let f = foo(p)
  76. p = addr s2
  77. doAssert len(p[]) == 5
  78. doAssert f() == 3