Hi,
I’m trying to write a macro that takes a proc and extracts its type signature - used to create another proc with a modified signature. Simplified version of my attempt so far:
proc parseStmts*(stmts: NimNode): NimNode =
return stmts[0][2]
macro getTheType*(stmts: untyped) =
echo stmts.parseStmts().getType().treeRepr()
Which is meant to be called like this:
proc f(x: string): int = 2
getTheType:
"my proc" -> f
This fails with the error node has no type. I wonder whether this is because the ident for the proc is unbound within the macro. If that’s the case, how can I bind it?
You cannot inspect the type signature of an untyped node. And yes concretely that is because the ident is not bound.
Fix:
import macros
macro getTheType*(stmts: typed) =
echo stmts.treerepr
echo stmts[0][0].getType().repr
proc f(x: string): int = 2
getTheType:
proc myProc(s: string): int =
discard
will return proc[int, string] (the first type is the one of the return value or an empty node).
If you need to work with proc types in a typed context, you will have to deal with symbol overloads (nnkClosedSymChoice). In that case this might help: https://github.com/numforge/laser/blob/d1e6ae61/laser/lux_compiler/frontend/lux_sigmatch.nim
This allows matching type-erased types with a concrete one in my linear-algebra-compiler-as-macro project, for instance: https://github.com/numforge/laser/blob/d1e6ae61/laser/lux_compiler/lux_dsl.nim#L43-L58
proc foobar(a, b, c: Fn): Fn =
# Iteration Domain
var i, j: Iter
# Avoid in-place update of implicit result ref address
# https://github.com/nim-lang/Nim/issues/11637
var bar: Fn
bar[i, j] = a[i, j] + b[i, j] + c[i, j]
# Update result
result = bar
with Fn being concretized into Tensor[float32]
generate foobar:
proc foobar(a: Tensor[float32], b, c: Tensor[float32]): Tensor[float32]