Given a string with the results of an astGenRepr in it, how do I convert it back to a NimNode that matches the original?
Consider this:
import macros
macro astFor*(s:untyped):untyped =
result = newLit(s.astGenRepr)
macro start(): untyped =
var x = astFor:
proc foo() =
echo "hi"
echo "x: ", x
var parsed = x.parseStmt()
echo "parsed: ", parsed.astGenRepr
# why is parsed.astGenRepr not the same as x?
start
I'm looking for something like parseStmt that would make parsed.astGenRepr and x be the same. Instead, it produces this:
x: nnkStmtList.newTree(
nnkProcDef.newTree(
newIdentNode("foo"),
newEmptyNode(),
newEmptyNode(),
nnkFormalParams.newTree(
newEmptyNode()
),
newEmptyNode(),
newEmptyNode(),
nnkStmtList.newTree(
nnkCommand.newTree(
newIdentNode("echo"),
newLit("hi")
)
)
)
)
parsed: nnkStmtList.newTree(
nnkCall.newTree(
nnkDotExpr.newTree(
newIdentNode("nnkStmtList"),
newIdentNode("newTree")
),
nnkCall.newTree(
nnkDotExpr.newTree(
newIdentNode("nnkProcDef"),
newIdentNode("newTree")
),
nnkCall.newTree(
newIdentNode("newIdentNode"),
newLit("foo")
),
nnkCall.newTree(
newIdentNode("newEmptyNode")
),
nnkCall.newTree(
newIdentNode("newEmptyNode")
),
nnkCall.newTree(
nnkDotExpr.newTree(
newIdentNode("nnkFormalParams"),
newIdentNode("newTree")
),
nnkCall.newTree(
newIdentNode("newEmptyNode")
)
),
nnkCall.newTree(
newIdentNode("newEmptyNode")
),
nnkCall.newTree(
newIdentNode("newEmptyNode")
),
nnkCall.newTree(
nnkDotExpr.newTree(
newIdentNode("nnkStmtList"),
newIdentNode("newTree")
),
nnkCall.newTree(
nnkDotExpr.newTree(
newIdentNode("nnkCommand"),
newIdentNode("newTree")
),
nnkCall.newTree(
newIdentNode("newIdentNode"),
newLit("echo")
),
nnkCall.newTree(
newIdentNode("newLit"),
newLit("hi")
)
)
)
)
)
)
I should explain exactly what I'm trying to do:
I'm trying to make macros. In my macros, I'd like to start with a base AST, then modify it according to passed-in arguments. I'm having trouble making that base AST.
There's dumpAstGen which makes it easy to print out the AST-generating code. For example:
dumpAstGen:
echo something
# produces:
# nnkStmtList.newTree(
# nnkCommand.newTree(
# newIdentNode("echo"),
# newIdentNode("something")
# )
# )
I've had success copying and pasting that output back into my source. But it's cumbersome to copy and paste a bunch of trees.
So I tried using quote. But quote produces newSymNode in places where dumpAstGen produces newIdentNode:
macro usingQuote(): untyped =
var x = quote do:
echo something
echo x.astGenRepr()
usingQuote
# produces:
# nnkCommand.newTree(
# newSymNode("echo"),
# newIdentNode("something")
# )
Unfortunately, newSymNode breaks where newIdentNode didn't. (I haven't yet been able to make a small, reproducible example for this breakage).
And that's why I tried making my own kind of quote substitute in that first post. But I can't figure out how to evaluate a string as produced by astGenRepr