英文:
How can I see the contents of a NimNode?
问题
我正在使用Nim编程语言,并进行一些元编程。
我想要编写一种DSL,以便生成procs。为此,我想要将一些Nim代码传递给宏(例如,一个proc定义),最终从中生成proc。
现在,我知道您可以使用以下语法在宏内捕获Nim代码:
macro generateMapper(body: untyped): untyped =
echo body.repr
generateMapper():
proc useThisToGenerateAProc(source: A, target: B)
这会将proc useThisToGenerateAProc(source: A, target: B)
放入body,但是echo body.repr不显示任何内容。
我如何查看实际位于body或其他NimNodes中的NimNodes是什么?
英文:
I'm using the nim programming language and am doing some metaprogramming.
I want to write a DSL of some sorts that enables generating procs. For that I want to pass some nim-code into a macro (e.g. a proc definition) and eventually generate the proc from that.
Now I know you can capture nim-code inside of a macro with syntax such as this:
macro generateMapper(body: untyped): untyped =
echo body.repr
generateMapper():
proc useThisToGenerateAProc(source: A, target: B)
Which puts proc useThisToGenerateAProc(source: A, target: B)
into body, but echo'ing body.repr doesn't show anything.
How can I see what NimNodes are actually inside body or other NimNodes in general etc.?
答案1
得分: 2
这些将在编译时为您打印出NimNode及其包含的所有内容的表示。
astGenRepr
的示例:
macro generateMapper(body: untyped): untyped =
echo body.astGenRepr
generateMapper():
proc myMapProc(source: A, target: B): string
这会打印(带有我的注释):
nnkStmtList.newTree( # 表示整行代码的一般“盒子”
nnkProcDef.newTree( # 表示整个过程定义的一般“盒子”
newIdentNode("myMapProc"), # 过程的名称
newEmptyNode(),
newEmptyNode(),
nnkFormalParams.newTree( # 表示此过程所有参数的一般“盒子”
newIdentNode("string"), # 返回类型,在这种情况下是string。如果没有返回类型,则可以使用newEmptyNode()
nnkIdentDefs.newTree( # 表示第一个参数的一般“盒子”
newIdentNode("source"),# 第一个参数的名称
newIdentNode("A"), # 第一个参数的类型
newEmptyNode()
),
nnkIdentDefs.newTree( # 表示第二个参数的一般“盒子”
newIdentNode("target"),# 第二个参数的名称
newIdentNode("B"), # 第二个参数的类型
newEmptyNode()
)
),
newEmptyNode(),
newEmptyNode(),
newEmptyNode()
)
)
与此相比,更紧凑的treeRepr
:
StmtList
ProcDef
Ident "myMapProc"
Empty
Empty
FormalParams
Ident "string"
IdentDefs
Ident "source"
Ident "A"
Empty
IdentDefs
Ident "target"
Ident "B"
Empty
Empty
Empty
Empty
还有更紧凑的lisprepr
:
(StmtList (ProcDef (Ident "myMapProc") (Empty) (Empty) (FormalParams (Ident "string") (IdentDefs (Ident "source") (Ident "A") (Empty)) (IdentDefs (Ident "target") (Ident "B") (Empty))) (Empty) (Empty) (Empty)))
英文:
You'll want to use these procs from std/macros
(in order of most verbose representation to least):
These will print you a representation at compile-time of the NimNode and everything it contains.
AstGenRepr of those 3 is the one that is closest to the code you'd actually write inside a macro where you deal with the Nodes yourself.
An example with astGenRepr
:
macro generateMapper(body: untyped): untyped =
echo body.astGenRepr
generateMapper():
proc myMapProc(source: A, target: B): string
This prints (With comments from myself):
nnkStmtList.newTree( # The general "box" representing the entire line of code
nnkProcDef.newTree( # The general "box" representing the entire proc definition
newIdentNode("myMapProc"), # The name of the proc
newEmptyNode(),
newEmptyNode(),
nnkFormalParams.newTree( # The general "box" representing all parameters of this proc
newIdentNode("string"), # The return type, in this case string. Can be newEmptyNode() in case of no return type
nnkIdentDefs.newTree( # The general "box" representing the first parameter
newIdentNode("source"),# Name of the first parameter
newIdentNode("A"), # Type of the first parameter
newEmptyNode()
),
nnkIdentDefs.newTree( # The general "box" representing the second parameter
newIdentNode("target"),# Name of the second parameter
newIdentNode("B"), # Type of the second parameter
newEmptyNode()
)
),
newEmptyNode(),
newEmptyNode(),
newEmptyNode()
)
)
Compared to that the more compact treeRepr
:
StmtList
ProcDef
Ident "myMapProc"
Empty
Empty
FormalParams
Ident "string"
IdentDefs
Ident "source"
Ident "A"
Empty
IdentDefs
Ident "target"
Ident "B"
Empty
Empty
Empty
Empty
And the even more compact lisprepr
:
(StmtList (ProcDef (Ident "myMapProc") (Empty) (Empty) (FormalParams (Ident "string") (IdentDefs (Ident "source") (Ident "A") (Empty)) (IdentDefs (Ident "target") (Ident "B") (Empty))) (Empty) (Empty) (Empty)))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论