macro `//`*(l, r: untyped): untyped =
result = newStrLitNode($l.toStrLit & "/" & $r.toStrLit)
echo first // second // third
This resolves, with nim 1.2.4 as "first // second/third". Is there a way such that first // second gets resolved before {} // third?
Use parenthesis or prefix your operator with a character with higher precedence:
https://nim-lang.org/docs/manual.html#syntax-precedence
The only characters with higher precedence than // would be $// or ^//.
What you are already getting, so probably not what you want.
The second you can get by choosing a right-associative operator - one that starts with a caret , such as ^//: (see https://nim-lang.org/docs/manual.html#syntax-associativity )
macro `^//`*(l, r: untyped): untyped =
result = newStrLitNode($l.toStrLit & "/" & $r.toStrLit)
echo first ^// second ^// third
# outputs first/second ^// third ; see https://play.nim-lang.org/#ix=2xTW
This will work regardless of associativity in this case (doesn't matter what you join first), but you're converting to a string literal so the first-evaluated operator will already have converted everything to strings (which is why you see // in the output). In this case you will have to not generate a string literal but something else that makes sense.
Also of note: https://nim-lang.github.io/Nim/manual_experimental.html#pattern-operators-the-star-operator (and it's friend the star-star operator described below it); however, these are term rewriting macros; they should not change the meaning of the underlying operators, there is a depth limit (though the documentation doesn't say what it is) after which rewriting will stop.
@nucleic, not sure if this is what you ultimately want (it's not that efficient), but here it is:
import system, macros
proc processLeftRight(l, r: NimNode): string =
echo l.treeRepr
echo r.treeRepr
if l.kind == nnkInfix:
result = processLeftRight(l[1], l[2]) & "/" & result
else:
result = $l.toStrLit() & "/" & result
if r.kind == nnkInfix:
result = result & processLeftRight(r[1], r[2])
else:
result = result & $r.toStrLit()
macro `//`*(l, r: untyped): untyped =
result = newStrLitNode(processLeftRight(l, r))
echo first // second // third // fourth
# Outputs:
# first/second/third/fourth