簡體   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