Hi,
I would like to have a macro which generates a variable within a template:
template foo(): expr =
var id {.gensym.} = 10
id + 10
echo foo() # echos 20
echo foo() # echos 20
import macros
macro letsCreateVar(): stmt =
result = parseExpr("var id {.gensym.} = 10")
template foo2(): expr =
letsCreateVar()
id + 10
echo foo2() # echos 20
echo foo2() # error: redefination of 'id'
It might seem like this has no real usage, the actual example is complicated (I'm happy to share if someone is interested). Is there a way to make this compile?
Do you really need the variable?
var tmp{.compiletime.} = 10
proc foo(): int {.compiletime} =
tmp = tmp + 10
tmp
echo foo() # echos 20
echo foo() # echos 30
import macros
var defd {.compiletime.} = false
macro letsCreateVar(): stmt =
result =
if defd: parseExpr("discard")
else: parseExpr("var id {.gensym.} = 10")
defd = true
Hi! Thank you all the answers. I still couldn't generate the variable the way I wanted. Let me show the code: https://github.com/petermora/nimMapBenchmarks/blob/master/test12.nim
In this example the templateF id is heavily overused: it is either a template if myMap12 is called with a lambda expression (for example proc (x: int): int = x+1). Also templateF can be a pointer to a proc (therefore a normal variable) if myMap12 is called with an already existing function.
The code currently compiles. The problem is that if I call myMap12(someSeq, alreadyExistingFunction) twice, then the two templateF variables conflict.
The motivation behind this strange code is that we could truly inline the given function if that is lambda.
@Araq: To my excuse, I use parseExpr only here in the forum because I believe that it is more readable. I tried using macros.gensym, but I couldn't make it work.
Peter