I'm familiar with the pitfalls of quote do: and excited about the new genAst which "can be used as a replacement"
I thought I'd try it out on the last macro i wrote:
import macros
macro applyThem(x,y: tuple; op: untyped): untyped =
result = nnkTupleConstr.newNimNode
for i in 0 ..< x.getTypeImpl.len:
result.add quote do:
block:
var
a{.inject.} = `x`[`i`]
b{.inject.} = `y`[`i`]
`op`
assert applyThem( (x: 3, y: 4), (u: 4,v: 5), a+b ) == (7,9)
assert applyThem( (1, 2.0), (3, 4.5), a*b) == (3, 9.0)
but i couldn't figure out how to get it to work in this context.
Can anyone help me out?
Assign the result of genAst to a variable and add it to result.
I've used it like this:
macro tm_add_or_remove_impl(reg: ptr tm_api_registry_api, load: bool, impls: varargs[typed]): untyped =
doAssert(impls.len > 0, "Missing impls")
result = newNimNode(nnkStmtList)
for impl in impls:
let typeName = repr(getTypeInst(impl))
let typeVersion = ident(typeName & "version")
let implType = getTypeImpl(impl)
var p = case implType.kind
of nnkObjectTy:
newCall(ident("unsafeAddr"), impl)
of nnkProcTy:
impl
else:
doAssert false, repr(impl) & " must be an object or proc type."
nil
let ast = genAst(reg, load, typeName, typeVersion, p):
if load:
reg[].add_implementation(typeName, typeVersion, p)
else:
reg[].remove_implementation(typeName, typeVersion, p)
result.add ast
import macros
import std/genasts
macro applyThem(x,y: tuple; op: untyped): untyped =
result = nnkTupleConstr.newNimNode
for i in 0 ..< x.getTypeImpl.len:
let ast = genAst(i, x, y, op):
block:
var
a{.inject.} = x[i]
b{.inject.} = y[i]
op
result.add ast
assert applyThem( (x: 3, y: 4), (u: 4,v: 5), a+b ) == (7,9)
assert applyThem( (1, 2.0), (3, 4.5), a*b) == (3, 9.0)
Actually, I forgot you can use do: too.
result.add genAst(i, x, y, op) do:
aha! thanks! i thought i was doing something wrong with the captures or something.
so that means you could surround it in a (block:)
result.add (block:genAst(i, x, y, op):
block:
var
a{.inject.} = x[i]
b{.inject.} = y[i]
op
)