繁体   English   中英

将复杂参数传递给Nimrod宏

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM