Currently compile time proc s the build up NimNode s are usually called in template or macro, eg:
import macros
proc helloNode():NimNode {.compileTime.} =
newLit("hello")
macro hello():untyped =
helloNode()
echo hello()
I would like to directly "splice" a valid NimNode at some arbitrary point but haven't been able to get it work so far, eg:
macro splice(n:static[NimNode]):untyped = n
echo splice(helloNode())
which gives the error:
macro splice(n: static[NimNode]): untyped
first type mismatch at position: 1
required type for n: static[NimNode]
but expression 'helloNode()' is of type: NimNode
These are some variations I tried:
macro splice(n:static[NimNode]):untyped =
let n : NimNode = n
result = n
macro splice(n:static[NimNode]):untyped =
genAst(n):
`n`
i do not fully understand what you try to archive, but this compiles for me:
import macros
proc helloNode(): NimNode {.compileTime.} =
newLit("hello")
macro hello():untyped =
helloNode()
static:
echo hello()
macro splice(n: NimNode): untyped = n
static:
echo splice(helloNode())
I would like
echo splice(helloNode())
to not be in a static context, I'd like it to be the same as if I just typed:
echo "hello"
does a typed/untyped parameter do what you want to do?
macro x(val: untyped): untyped =
val
echo x("hallo") # generates the ast echo "hallo"
Note that while the type of the parameter is written as untyped/typed it's actually of type NimNode.
The difference between untyped and typed parameters is the same as for templates.
Worst case, you can do this:
import macros
template useNode(n: NimNode): untyped {.dirty.} =
macro temp(): untyped {.gensym.} =
result = n
temp()
echo useNode(newLit("hello"))
Don't know if dirty and gensym help but I included them anyway
I think this is what you want https://play.nim-lang.org/#ix=3EIM
import macros
proc helloNode():NimNode {.compileTime.} =
newLit("hello")
macro hello(x: static proc(): NimNode):untyped =
let node = x()
result = quote do:
`node`
echo hello(helloNode)