123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406 |
- discard """
- output: '''
- 0
- 1
- 2
- 3
- 0
- 1
- 2
- 3
- wth
- 3
- 2
- 1
- 0
- (total: 6)
- S1
- 5
- abc
- '''
- """
- # bug #1915
- import macros
- # Test that parameters are properly gensym'ed finally:
- template genNodeKind(kind, name: untyped) =
- proc name*(children: varargs[NimNode]): NimNode {.compiletime.}=
- result = newNimNode(kind)
- for c in children:
- result.add(c)
- genNodeKind(nnkNone, None)
- # Test that generics in templates still work (regression to fix #1915)
- # bug #2004
- type Something = object
- proc testA(x: Something) = discard
- template def(name: untyped) =
- proc testB[T](reallyUniqueName: T) =
- `test name`(reallyUniqueName)
- def A
- var x: Something
- testB(x)
- # bug #2215
- # Test that templates in generics still work (regression to fix the
- # regression...)
- template forStatic(index, slice, predicate: untyped) =
- const a = slice.a
- const b = slice.b
- when a <= b:
- template iteration(i: int) =
- block:
- const index = i
- predicate
- template iterateStartingFrom(i: int) =
- when i <= b:
- iteration i
- iterateStartingFrom i + 1
- iterateStartingFrom a
- proc concreteProc(x: int) =
- forStatic i, 0..3:
- echo i
- proc genericProc(x: auto) =
- forStatic i, 0..3:
- echo i
- concreteProc(7) # This works
- genericProc(7) # This doesn't compile
- import tables
- # bug #9476
- proc getTypeInfo*(T: typedesc): pointer =
- var dummy: T
- getTypeInfo(dummy)
- macro implementUnary(op: untyped): untyped =
- result = newStmtList()
- template defineTable(tableSymbol) =
- var tableSymbol = initTable[pointer, pointer]()
- let tableSymbol = genSym(nskVar, "registeredProcs")
- result.add(getAst(defineTable(tableSymbol)))
- template defineRegisterInstantiation(tableSym, regTemplSym, instSym, op) =
- template regTemplSym*(T: typedesc) =
- let ti = getTypeInfo(T)
- proc instSym(xOrig: int): int {.gensym, cdecl.} =
- let x {.inject.} = xOrig
- op
- tableSym[ti] = cast[pointer](instSym)
- let regTemplSymbol = ident("registerInstantiation")
- let instSymbol = ident("instantiation")
- result.add(getAst(defineRegisterInstantiation(
- tableSymbol, regTemplSymbol, instSymbol, op
- )))
- echo result.repr
- implementUnary(): x*x
- registerInstantiation(int)
- registerInstantiation(float)
- # bug #10192
- template nest(body) {.dirty.} =
- template p1(b1: untyped) {.dirty, used.} =
- template implp1: untyped {.dirty.} = b1
- template p2(b2: untyped) {.dirty, used.} =
- template implp2: untyped {.dirty.} = b2
- body
- implp1
- implp2
- template test() =
- nest:
- p1:
- var foo = "bar"
- p2:
- doAssert(foo.len == 3)
- test()
- # regression found in PMunch's parser generator
- proc namedcall(arg: string) =
- discard
- macro m(): untyped =
- result = quote do:
- (proc (arg: string) =
- namedcall(arg = arg)
- echo arg)
- let meh = m()
- meh("wth")
- macro foo(body: untyped): untyped =
- result = body
- template baz(): untyped =
- foo:
- proc bar2(b: int): int =
- echo b
- if b > 0: b + bar2(b = b - 1)
- else: 0
- echo (total: bar2(3))
- baz()
- # bug #12121
- macro state_machine_enum(states: varargs[untyped]) =
- result = nnkTypeSection.newTree(
- nnkTypeDef.newTree(
- nnkPragmaExpr.newTree(ident("State"), nnkPragma.newTree(ident("pure"))),
- newEmptyNode(),
- nnkEnumTy.newTree(newEmptyNode())
- )
- )
- for s in states:
- expectKind(s, nnkIdent)
- result[0][2].add s
- template mystate_machine(body: untyped) =
- state_machine_enum(S1, S2, S3)
- var state_stack: seq[State]
- template state_current(): State {.inject, used.} =
- state_stack[^1]
- template state_push(state_name) {.inject, used.} =
- state_stack.add State.state_name
- template state_pop(n = 1) {.inject, used.} =
- state_stack.setLen(state_stack.len - n)
- body
- mystate_machine:
- state_push(S1)
- echo state_current()
- state_pop()
- # bug #15075
- block: #Doesn't work
- template genGenTempl: untyped =
- proc loop(locals: int)
- proc loop(locals: int) = discard
- genGenTempl()
- let pool = loop
- block: #Doesn't work
- macro genGenMacro: untyped =
- quote do:
- proc loop(locals: int)
- proc loop(locals: int) = discard
- genGenMacro()
- let pool = loop
- block: #This works
- proc loop(locals: int)
- proc loop(locals: int) = discard
- let pool = loop
- #Now somewhat recursive:
- type Cont = ref object of RootObj
- fn*: proc(c: Cont): Cont {.nimcall.}
- block: #Doesn't work
- template genGenTempl(): untyped =
- proc loop(locals: Cont): Cont
- proc loop(locals: Cont): Cont =
- return Cont(fn: loop)
- proc doServer(): Cont =
- return Cont(fn: loop)
- genGenTempl()
- discard doServer()
- block: #Doesn't work
- macro genGenMacro(): untyped =
- quote:
- proc loop(locals: Cont): Cont
- proc loop(locals: Cont): Cont =
- return Cont(fn: loop)
- proc doServer(): Cont =
- return Cont(fn: loop)
- genGenMacro()
- discard doServer()
- block: #This works
- proc loop(locals: Cont): Cont
- proc loop(locals: Cont): Cont =
- return Cont(fn: loop)
- proc doServer(): Cont =
- return Cont(fn: loop)
- discard doServer()
- #And fully recursive:
- block: #Doesn't work
- template genGenTempl: untyped =
- proc loop(locals: int)
- proc loop(locals: int) = loop(locals)
- genGenTempl()
- let pool = loop
- block: #Doesn't work
- macro genGenMacro: untyped =
- quote do:
- proc loop(locals: int)
- proc loop(locals: int) = loop(locals)
- genGenMacro()
- let pool = loop
- block: #This works
- proc loop(locals: int)
- proc loop(locals: int) = loop(locals)
- let pool = loop
- block:
- template genAndCallLoop: untyped =
- proc loop() {.gensym.}
- proc loop() {.gensym.} =
- discard
- loop()
- genAndCallLoop
- block: #Fully recursive and gensymmed:
- template genGenTempl: untyped =
- proc loop(locals: int) {.gensym.}
- proc loop(locals: int) {.gensym.} = loop(locals)
- let pool = loop
- genGenTempl()
- block: #Make sure gensymmed symbol doesn't overwrite the forward decl
- proc loop()
- proc loop() = discard
- template genAndCallLoop: untyped =
- proc loop() {.gensym.} =
- discard
- loop()
- genAndCallLoop()
- template genLoopDecl: untyped =
- proc loop()
- template genLoopDef: untyped =
- proc loop() = discard
- block:
- genLoopDecl
- genLoopDef
- loop()
- block:
- proc loop()
- genLoopDef
- loop()
- block:
- genLoopDecl
- proc loop() = discard
- loop()
- block: #Gensymmed sym sharing forward decl
- macro genGenMacro: untyped =
- let sym = genSym(nskProc, "loop")
- nnkStmtList.newTree(
- newProc(sym, body = newEmptyNode()),
- newCall(sym),
- newProc(sym, body = newStmtList()),
- )
- genGenMacro
- # inject pragma on params
- template test(procname, body: untyped): untyped =
- proc procname(data {.inject.}: var int = 0) =
- body
- test(hello):
- echo data
- data = 3
- var data = 5
- hello(data)
- # bug #5691
- template bar(x: typed) = discard
- macro barry(x: typed) = discard
- var a = 0
- bar:
- var a = 10
- barry:
- var a = 20
- bar:
- var b = 10
- barry:
- var b = 20
- var b = 30
- # template bar(x: static int) = discard
- #You may think that this should work:
- # bar((var c = 1; echo "hey"; c))
- # echo c
- #But it must not! Since this would be incorrect:
- # bar((var b = 3; const c = 1; echo "hey"; c))
- # echo b # <- b wouldn't exist
- discard not (let xx = 1; true)
- discard xx
- template barrel(a: typed): untyped = a
- barrel:
- var aa* = 1
- var bb = 3
- export bb
- # Test declaredInScope within params
- template test1: untyped =
- when not declaredInScope(thing):
- var thing {.inject.}: int
- proc chunkedReadLoop =
- test1
- test1
- template test2: untyped =
- when not not not declaredInScope(thing):
- var thing {.inject.}: int
- proc chunkedReadLoop2 =
- test2
- test2
- test1(); test2()
- block: # bug #22846
- template foo2(x: proc (y: string)) =
- let f = x
- f("abc")
- foo2(proc (y: string) = echo y)
|