I have been trying to figure out how to get this working for the last few days,
but no luck yet. Consider this snippet:
template skel(T: untyped): untyped =
let fn = proc(): T =
echo "I am fn"
fn
proc gen(): NimNode =
result = getAst skel(int)
macro foo(): untyped =
gen()
let f = foo()
Run
This is the bare minimum I can reduce my real life code to. The macro `foo()`
calls proc `gen()` to generate code. `gen()` runs `getAst()` on template
`skel()` which contains the code that should be generated.
The code is organized like this for good reasons: in my real code `gen()`
generates a bit more code which gets injected in the `skel()` template, so I
think I can not easily make big structural changes.
The above works, but I am looking for a way to get the type `T` all the way out
as a parameter the `foo()` macro. Ideally, this is what I would like to do,
although it does not compile:
template skel(T: untyped): untyped =
let fn = proc(): T =
echo "I am fn"
fn
proc gen[T](): NimNode =
result = getAst skel(T) # <-- error: Error: getAst takes a call, but got
getAst
macro foo(T: typedesc): untyped =
gen[T]()
let fn = foo(int)
Run
I do not understand what Nim is trying to say here `getAst takes a call but got
getAst`? So let's pass the type as an argument:
template skel(T: untyped): untyped =
let fn = proc(): T =
echo "I am fn"
fn
proc gen(T: typedesc): NimNode =
result = getAst skel(T)
macro foo(T: typedesc): untyped =
gen(T) # <-- Error: type mismatch: got <NimNode>
let fn = foo(int)
Run
Nope, doesn't work - the `typedesc` argument of the macro gets converted to a
`NimNode` and I can't figure out how to turn it back into a `typedesc`
I've tried numerous permutations resulting in numerous other interesting error
messages, I went through the manual a number of times and I discussed this on
#nim, but I am still lost. How to solve this?
Thanks!