summary refs log tree commit diff stats
path: root/tests/macros/tclosuremacro.nim
blob: 2a7847b9ec09c910fd23223e441b5eaad6f2ca09 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
discard """
  output: '''
noReturn
calling mystuff
yes
calling mystuff
yes
calling sugarWithPragma
sugarWithPragma called
'''
"""

import sugar, macros

proc twoParams(x: (int, int) -> int): int =
  result = x(5, 5)

proc oneParam(x: int -> int): int =
  x(5)

proc noParams(x: () -> int): int =
  result = x()

proc noReturn(x: () -> void) =
  x()

proc doWithOneAndTwo(f: (int, int) -> int): int =
  f(1,2)

doAssert twoParams(proc (a, b: auto): auto = a + b) == 10
doAssert twoParams((x, y) => x + y) == 10
doAssert oneParam(x => x+5) == 10
doAssert noParams(() => 3) == 3
doAssert doWithOneAndTwo((x, y) => x + y) == 3

noReturn((() -> void) => echo("noReturn"))

proc pass2(f: (int, int) -> int): (int) -> int =
  ((x: int) -> int) => f(2, x)

doAssert pass2((x, y) => x + y)(4) == 6

fun(x, y: int) {.noSideEffect.} => x + y

doAssert typeof(fun) is (proc (x, y: int): int {.nimcall.})
doAssert fun(3, 4) == 7

proc register(name: string; x: proc()) =
  echo "calling ", name
  x()

register("mystuff", proc () =
  echo "yes"
)

proc helper(x: NimNode): NimNode =
  if x.kind == nnkProcDef:
    result = copyNimTree(x)
    result[0] = newEmptyNode()
    result = newCall("register", newLit($x[0]), result)
  else:
    result = copyNimNode(x)
    for i in 0..<x.len:
      result.add helper(x[i])

macro m(x: untyped): untyped =
  result = helper(x)

m:
  proc mystuff() =
    echo "yes"

sugarWithPragma() {.m.} => echo "sugarWithPragma called"

typedParamAndPragma(x, y: int) {.used.} -> int => x + y
doAssert typedParamAndPragma(1, 2) == 3

type
  Bot = object
    call: proc (): string {.noSideEffect.}

var myBot = Bot()
myBot.call = () {.noSideEffect.} => "I'm a bot."
doAssert myBot.call() == "I'm a bot."