While I'm not sure what kind of features the times -> j syntax should allow (or
if times and -> are fixed), the simplest implementation for the second usage I
can come up with:
import macros, strutils, os
macro theMagicWord(statments: untyped): untyped =
result = statments
for st in statments:
for node in st:
if node.kind == nnkStrLit:
node.strVal = node.strVal & ", Please."
proc parseArgs(cmd: NimNode): (NimNode, NimNode) =
doAssert cmd.len == 2
expectKind(cmd[1], nnkInfix)
expectKind(cmd[1][0], nnkIdent)
expectKind(cmd[1][1], nnkIdent)
expectKind(cmd[1][2], nnkIdent)
doAssert cmd[1][0].strVal == "->"
doAssert cmd[1][1].strVal == "times"
result = (cmd[0], # leave cmd[0] as is, has to be valid integer expr
cmd[1][2]) # identifier to use for loop
macro rpt(cmd: untyped, stmts: untyped): untyped =
expectKind(cmd, nnkCommand)
expectKind(stmts, nnkStmtList)
let (toIdx, iterVar) = parseArgs(cmd)
result = quote do:
for `iterVar` in 1..`toIdx`:
`stmts`
echo result.repr
# old macro
#rpt j, paramStr(1).parseInt :
# theMagicWord:
# echo j, "- Give me some bear"
# echo "Now"
rpt paramStr(1).parseInt times -> j:
theMagicWord:
echo j, "- Give me some bear"
echo "Now"
Run