I have this type defined
type
Handler = proc(x: int)
Based on that, I wanted to implement the handlers
proc handlerThis(x: int) = discard
proc handlerThat(x: int) = discard
proc handlerThus(x: int) = discard
I thought of writing macros that to simplify it e.g.
import macros
macro function(head, body: untyped): untyped =
let (funcname, handlertype) =
if head.kind == nnkinfix and head.len == 3: (head[1], head[2])
else: (nil, nil)
if funcname == nil or handlertype == nil:
{.fatal: """function only support "name of type" format""".}
...
function handlerThis of Handler:
discard
# which expanded to
proc handlerThis(x: int) = discard # x will be injected from macro transformation
How to expand that Handler type to be used in macro?
After some exploring around, I somehow implemented it like this
import macros
type
Handler = proc(x: int): int
macro function(head: untyped, thetype: typed, body: untyped): untyped =
var impl = thetype.symbol().getImpl()
var params = newSeq[NimNode]()
for node in impl[2][0]:
params.add node
result = newProc(name = head,
params = params,
body = body)
function handleThis, Handler:
x * 10
echo handleThis(5)
But I can't implement like function handleThis of Handler: ... , any idea?
Something like this?
import macros
type
Handler = proc(x: int): int
macro function_impl(head: untyped, thetype: typed, body: untyped): untyped =
var impl = thetype.symbol().getImpl()
var params = newSeq[NimNode]()
for node in impl[2][0]:
params.add node
result = newProc(name = head,
params = params,
body = body)
macro function(head_thetype: untyped, body: untyped): untyped =
head_thetype.expectKind nnkInfix
assert eqIdent(head_thetype[0], "of")
let head = head_thetype[1]
let thetype = head_thetype[2]
result = quote do: function_impl(`head`, `thetype`, `body`)
function handleThis of Handler:
x * 10
echo handleThis(5)