我尝试在宏中使用 nnkDotExpr 并收到错误。具体来说,我正在尝试编写一个宏,它将编写一个返回特定字段的过程。我尝试了三种方法,但似乎都失败了,我不知道为什么。
这是我的代码。
import macros
type
Test_Type = object of RootObj
Name_HIDDEN: string
macro Name_MacroA*(vType: untyped): untyped =
var tName = nnkDotExpr(ident("self"), ident("Name_HIDDEN"))
quote do:
proc Name*(self: var `vType`): string =
return `tName`
macro Name_MacroB*(vType: untyped): untyped =
var tName = newNimNode(nnkDotExpr)
tName.add(ident("self"))
tName.add(ident("Name_HIDDEN"))
quote do:
proc Name*(self: var `vType`): string =
return `tName`
macro Name_MacroC*(vType: untyped): untyped =
var tName = nnkDotExpr.newTree(ident("self"), ident("Name_HIDDEN"))
quote do:
proc Name*(self: var `vType`): string =
return `tName`
Name_MacroB(Test_Type)
var tTest: Test_Type
tTest.Name_HIDDEN = "Hello"
echo tTest.Name
当我使用 Name_MacroA 时,出现错误:
Error: attempting to call routine: 'nnkDotExpr'
found 'nnkDotExpr' [enumField declared in /usr/local/Cellar/nim/2.0.0_1/nim/lib/core/macros.nim(45, 5)]
Name_MacroA 尝试匹配 nnkDotExpr 引用中的代码 尼姆宏。
当我使用 Name_MacroB 或 Name_MacroC 时,出现错误:
template/generic instantiation of `Name_MacroB` from here test4.nim(17, 20) Error: undeclared identifier: 'self'
candidates (edit distance, scope distance); see '--spellSuggest':
(2, 4): 'del'
(2, 4): 'ref'
(2, 4): 'send'
Name_MacroB 是尝试匹配来自 Nim Macros
的代码Name_MacroC 尝试匹配来自 Nim Macros
的代码第一个问题是,当它是一个枚举时,您试图调用
nnkDotExpr
。对于 NimNodeKind 就像 nnkDotExpr
,你需要使用 newTree。
第二个问题是
quote do
正在为 self
参数生成一个唯一的符号,因此您需要让它像这样使用您自己的身份
# Create your own ident
let selfIdent = ident"self"
# Can use genSym if you think there might be conflicts
# let selfIdent = genSym(nskParam, "self")
tName.add(selfIdent)
tName.add(ident("Name_HIDDEN"))
quote do:
# Now it uses your symbol here instead of making a new one
proc Name*(`selfIdent`: var `vType`): string =
return `tName`
还有 newDotExpr 使创建点表达式变得更简单