Now we use async libraries from standard must add runForever() in the last of the file. If there's a way to defer code excuting to the end of current module, we can hide this tail into macros. For example:
defer:
echo "world"
echo "hello"
# outputs:
# hello
# world
These codes would not compile in current nim version.
Yes it does not compile, for some reason defer at global scope does not work, but there is something that does work pretty nicely, calling the c function atexit from the standard library.
EDIT: I read your question again, but more precisely. You say at the end of module, this solution calls the procedures at the end of the program. Im am afraid, I don't know a solution for calling something at the end of a module.
proc atexit(fun: pointer): void {. cdecl, importc: "atexit" .}
proc foo1() {. cdecl .} =
echo "foo1"
atexit(foo1)
proc foo2() {. cdecl .} =
echo "foo2"
atexit(foo2)
# outputs:
# hello world!
Note, I think the nim library could just compile to something like this for top level defer.
EDIT: I wrote a little macro that does the job like a defer statement:
import macros
proc atexit(fun: pointer): void {. cdecl, importc: "atexit" .}
macro topLevelDefer(blk: untyped): stmt =
let sym = genSym(nskProc, "proc_exit")
result = quote do:
proc `sym`() {. cdecl .} =
`blk`
atexit(`sym`)
topLevelDefer:
stdout.write "!"
topLevelDefer:
stdout.write " world"
stdout.write "hello"