There may be two question:
1. How to implement a custom Pragma macro? For example: {. Emit.}, {. link.}. 2.How to use macros to implement decorators similar to Java and Python, such as @Authentication(userId).
I think this is what you're looking for:
import std/macros
macro decorator(procedure: untyped): untyped =
expectKind(procedure, nnkProcDef) # 1. ensure macro accepts only procedures
procedure[^1].add( # 2. modify the procedure body in some way
quote do:
echo "decorated stuff in procedure body"
)
return procedure # 3. return the modified procedure at compile-time (decorated)
proc test() {.decorator.} =
echo "normal stuff in procedure body"
test()
# normal stuff in procedure body
# decorated stuff in procedure body
From my understanding, decorators modify a function in some way. What you want to do is create a macro that accepts a procedure definition, and modify then return that procedure. You use the macro's name as the procedure's pragma to pass the procedure into the macro. During compile-time the macro is expanded, applies the transformations, and returns the newly modified procedure.
For adding something like @Authentication(userId) might look like this as a proof-of-concept:
# modified example above
import std/macros
macro decorator(id, procedure: untyped): untyped =
expectKind(id, nnkIdent)
expectKind(procedure, nnkProcDef)
let idStr = id.repr
procedure[^1].add(
quote do:
echo "printing identifier: ", `idStr`
)
return procedure
proc test() {.decorator(identifierThing).} =
echo "normal stuff in procedure body"
test()
# normal stuff in procedure body
# printing identifier: identifierThing
Check out these for learning how macros work: https://nim-lang.org/docs/macros.html (the module itself) https://nim-lang.org/docs/tut3.html https://nim-by-example.github.io/macros/ https://dev.to/beef331/demystification-of-macros-in-nim-13n8 (this one's really good and simple)