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