[英]Passing complex parameters to a Nimrod macro
我想将配置参数传递给宏。 我已经有一个程序可以根据这些参数(序列元组)生成一串Nimrod代码。 我知道我可以传递一个字符串并用strVal对其进行转换 (如答案https://stackoverflow.com/a/19956317/334703所示)。 我可以对更复杂的数据进行同样的处理吗?
或者,我可以在编译时过程中使用此字符串的Nimrod代码,并调用诸如parseStmt之类的过程吗?
编辑:Nimrod代码的生成对测试我的想法很有用,我同意我应该直接生成AST。
这是我正在考虑的结构的示例。
type
Tconfig = tuple
letters: seq[string]
numbers:seq[int]
var
data = (@("aa", "bb"), @(11, 22))
macro mymacro(data: Tconfig): stmt =
...
如果您的宏需要处理传递给它的实际常量数据,建议的方法是使用静态参数:
type
TConfig = tuple
letters: seq[string]
numbers:seq[int]
const data = (@["aa", "bb"], @[11, 22])
macro mymacro(cfg: static[TConfig]): stmt =
echo "letters"
for s in cfg.letters:
echo s
echo "numbers"
for n in cfg.numbers:
echo n
mymacro(data)
这种方法有很多好处:
1)输入参数cfg
不会获取原始AST,而是在宏主体内部具有TConfig
类型,因此您可以更轻松地访问其成员,如示例所示。
2)当将它们与宏一起使用时,编译器将自动评估产生TConfig
值的复杂表达式(例如, mymacro(mergeConfigs(userConfig, systemConfig))
,假设mergeConfigs
是可以在编译时评估的proc)。
有关静态参数的更多信息,请参考手册:
http://nim-lang.org/manual.html#static-t
我不确定100%的意思,但是从上下文来看,您似乎需要的功能是macros.toStrLit
的功能,该功能从AST生成字符串文字节点。 例:
import macros, strutils
macro showExpr(x: expr): stmt =
parseStmt("echo(" & x.toStrLit.strVal.escape & ")")
showExpr("x" & "y")
不过,请考虑直接转换AST,因为将代码生成和重新解析为字符串会导致引号(请注意上面的.escape
),缩进等意外。
如果您需要或想要遍历宏中数据的结构,则首先需要将变量设为const
。 var
用于运行时,因此宏将仅获得一个nnkSym
节点。 将其设为const
您将获得与在此处手动键入值相同的输入。 我将使用treeRepr
宏和大量的echo
来向您展示您所获得的AST类型以及如何运行:
import macros
type
Tconfig = tuple
letters: seq[string]
numbers:seq[int]
const data: Tconfig = (@["aa", "bb"], @[11, 22])
macro mymacro(data: Tconfig): stmt =
echo "AST being passed in:\n", treeRepr(data)
echo "root type is ", data.kind
echo "number of children ", len(data)
let n1 = data[0]
echo "first child is ", n1.kind
echo "first child children ", len(n1)
let e2 = n1[1]
echo "second exp child is ", e2.kind
echo "second exp child children ", len(e2)
let v1 = e2[0]
echo "first seq value is ", v1.kind
echo "first seq value children ", len(v1)
echo "Final literal is ", v1.strVal
when isMainModule:
mymacro(data)
当我编译该示例时,我得到以下输出:
AST being passed in:
Par
ExprColonExpr
Sym "letters"
Bracket
StrLit aa
StrLit bb
ExprColonExpr
Sym "numbers"
Bracket
IntLit 11
IntLit 22
root type is nnkPar
number of children 2
first child is nnkExprColonExpr
first child children 2
second exp child is nnkBracket
second exp child children 2
first seq value is nnkStrLit
first seq value children 0
Final literal is aa
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.