tclosuremacro.nim 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. discard """
  2. output: '''
  3. noReturn
  4. calling mystuff
  5. yes
  6. calling mystuff
  7. yes
  8. calling sugarWithPragma
  9. sugarWithPragma called
  10. '''
  11. """
  12. import sugar, macros
  13. proc twoParams(x: (int, int) -> int): int =
  14. result = x(5, 5)
  15. proc oneParam(x: int -> int): int =
  16. x(5)
  17. proc noParams(x: () -> int): int =
  18. result = x()
  19. proc noReturn(x: () -> void) =
  20. x()
  21. proc doWithOneAndTwo(f: (int, int) -> int): int =
  22. f(1,2)
  23. doAssert twoParams(proc (a, b: auto): auto = a + b) == 10
  24. doAssert twoParams((x, y) => x + y) == 10
  25. doAssert oneParam(x => x+5) == 10
  26. doAssert noParams(() => 3) == 3
  27. doAssert doWithOneAndTwo((x, y) => x + y) == 3
  28. noReturn((() -> void) => echo("noReturn"))
  29. proc pass2(f: (int, int) -> int): (int) -> int =
  30. ((x: int) -> int) => f(2, x)
  31. doAssert pass2((x, y) => x + y)(4) == 6
  32. fun(x, y: int) {.noSideEffect.} => x + y
  33. doAssert typeof(fun) is (proc (x, y: int): int {.nimcall.})
  34. doAssert fun(3, 4) == 7
  35. proc register(name: string; x: proc()) =
  36. echo "calling ", name
  37. x()
  38. register("mystuff", proc () =
  39. echo "yes"
  40. )
  41. proc helper(x: NimNode): NimNode =
  42. if x.kind == nnkProcDef:
  43. result = copyNimTree(x)
  44. result[0] = newEmptyNode()
  45. result = newCall("register", newLit($x[0]), result)
  46. else:
  47. result = copyNimNode(x)
  48. for i in 0..<x.len:
  49. result.add helper(x[i])
  50. macro m(x: untyped): untyped =
  51. result = helper(x)
  52. m:
  53. proc mystuff() =
  54. echo "yes"
  55. sugarWithPragma() {.m.} => echo "sugarWithPragma called"
  56. typedParamAndPragma(x, y: int) {.used.} -> int => x + y
  57. doAssert typedParamAndPragma(1, 2) == 3
  58. type
  59. Bot = object
  60. call: proc (): string {.noSideEffect.}
  61. var myBot = Bot()
  62. myBot.call = () {.noSideEffect.} => "I'm a bot."
  63. doAssert myBot.call() == "I'm a bot."