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

Reply via email to