I'm trying to autogenerate implementation for the procedure with macro rcall
proc multiply(a, b: int): int
proc multiply(a, b: int): int =
rcall(multiply)
# => rcall_impl("multiply", a, b, int)
echo multiply(1, 2)
And it almost works, but it refuses to understand int as int.
The working code with int return type set manually playground but if I change that manually set int in rcall_impl(fname, a, b, int) to rtype it won't compiles anymore. Even if the macro also evaluates to int. Why?
import macros
proc rcall_impl*[A, B, R](fn: string, a: A, b: B, _: type[R]): R =
echo (fn, a, b)
macro rcall(fn: typed) =
let impl = get_impl(fn.symbol)
var fname = impl[0].symbol.`$`
var fsignature: seq[NimNode]
for formal_param in impl.find_child(it.kind == nnkFormalParams):
if formal_param.kind != nnkIdentDefs: continue
for param in formal_param:
if param.kind != nnkEmpty:
# fsignature.add(param.symbol.`$`)
fsignature.add(param)
let (args, rtype) = (fsignature[0..^2], fsignature[^1])
if args.len == 1:
let a = args[0]
quote do:
return rcall_impl(`fname`, `a`, int)
elif args.len == 2:
let (a, b) = (args[0], args[1])
quote do:
return rcall_impl(`fname`, `a`, `b`, int) # <= problem here if changed to `return rcall_impl(`fname`, `a`, `b`, `rtype`)`
elif args.len == 3:
let (a, b, c) = (args[0], args[1], args[2])
quote do:
return rcall_impl(`fname`, `a`, `b`, `c`, int)
else:
quote do:
not supported
proc multiply(a, b: int): int
proc multiply(a, b: int): int = rcall(multiply)
echo multiply(1, 2)
Yes, it builds the correct expression return rcall_impl("multiply", a, b, int) but still refuses to compile, please see updated post, I simplified the code a little bit and added more detailed error description.
Considering that is a third question thread you posted
Thanks for taking time answering. I try to not post too many questions... and check out real-time chats.
your rtype is a Sym, when you want it to be an Ident
rcall_impl should be proc rcall_impl[A,B](fn:string,a:A,b:B,R:typedesc):R
you can use newCall(fname, argSeq) instead of the if statements and quote do
but that's all style stuff.
the real fix is: don't have rtype be a sym in the first place. the quick fix is: return rtype_impl('fname','a','b',typedesc['rtype']