I found that the following macro which generates forward declaration and actual declaration of a proc with static arg cannot be compiled with message "Error: cannot instantiate: 'static_arg:type'". I compiled by Nim 1.4.8.
It can be compiled by older version of Nim like 1.0.6. It also can be compiled without macro (comment out part). What is happening?
import macros
macro testMacro():untyped =
result = newStmtList()
var params:seq[NimNode]
params.add(ident("string"))
var mainParams = params
var identDefs = newNimNode(nnkIdentDefs).add(ident"static_arg").add(newNimNode(nnkBracketExpr).add(ident"static").add(ident"bool")).add(newEmptyNode())
mainParams.add(identDefs)
var mainProcDef = newNimNode(nnkProcDef).add(ident"solve").add(newEmptyNode()).add(newEmptyNode()).add(newNimNode(nnkFormalParams).add(mainParams)).add(newEmptyNode()).add(newEmptyNode()).add(newEmptyNode())
result.add mainProcDef
var mainBody = newStmtList().add(newNimNode(nnkDiscardStmt).add(newEmptyNode()))
result.add newProc(name = ident"solve", params = mainParams, body = mainBody, pragmas = newEmptyNode())
echo result.repr
#### this outputs the following
# proc solve(static_arg: static[bool]): string {.discardable.}
# proc solve(static_arg: static[bool]): string {.discardable.} =
# discard
testMacro()
discard solve(true)
You didn't copy your main params. The exact same nimNodes are being used for both formal params which is causing some problems with binding. Try this
proc copy(a : seq[NimNode]) : seq[NimNode] =
result.setLen(len(a))
for i in 0..<len(a):
result[i] = a[i].copy()
#mainParams.copy()
result.add newProc(name = ident"solve", params = mainParams.copy(), body = mainBody, pragmas = newEmptyNode())
Thanks! I understand the issue!
By the way, I didn't know quote. It looks good to make macros readble.