Another possible use case for term rewriting macros is user-defined warnings -
for example when converting from older API to a new one. Implicitly rewriting
everything is a bad idea, but making it easier to migrate old code, or prevent
accidental misuses is still useful. Paired with pattern matching it might be
possible to get something like this working quite easily:
macro optNot*{not a}(a: bool{nkCall}): untyped =
if a.matches(Call[
Sym(strVal: "[]"),
Sym(getTypeInst: Sym(strVal: "Lex")),
.._
]):
warning("Deprecated use of `not lex[]`, convert to `lex.not []`", a)
result = nnkPragmaBlock.newTree(
nnkPRagma.newTree(ident "noRewrite"),
newCall("not", a)
)
Run
The only issue is that `{.noRewrite.}` pragma seems to be broken again (I'm not
100% sure if I'm using it correctly here, but considering example from the
manual also gives repeated macro expansions ...).
template pwnEcho{echo(x)}(x: typed) =
{.noRewrite.}: echo("pwned!")
echo "ab"
Run
Creates
/usercode/in.nim(4, 6) Hint: pwnEcho(["ab"]) --> ' {.noRewrite.}:
echo(["pwned!"])' [Pattern]
/usercode/in.nim(2, 22) Hint: pwnEcho(["pwned!"]) --> ' {.noRewrite.}:
echo(["pwned!"])' [Pattern]
/usercode/in.nim(2, 22) Hint: pwnEcho(["pwned!"]) --> ' {.noRewrite.}:
echo(["pwned!"])' [Pattern]
/usercode/in.nim(2, 22) Hint: pwnEcho(["pwned!"]) --> ' {.noRewrite.}:
echo(["pwned!"])' [Pattern]
/usercode/in.nim(2, 22) Hint: pwnEcho(["pwned!"]) --> ' {.noRewrite.}:
echo(["pwned!"])' [Pattern]
/usercode/in.nim(2, 22) Hint: pwnEcho(["pwned!"]) --> ' {.noRewrite.}:
echo(["pwned!"])' [Pattern]
/usercode/in.nim(2, 22) Hint: pwnEcho(["pwned!"]) --> ' {.noRewrite.}:
echo(["pwned!"])' [Pattern]
/usercode/in.nim(2, 22) Hint: pwnEcho(["pwned!"]) --> ' {.noRewrite.}:
echo(["pwned!"])' [Pattern]
... N lines omitted
Run