Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions compiler/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,11 @@ proc recoverContext(c: PContext) =
while c.p != nil and c.p.owner.kind != skModule: c.p = c.p.next

proc semWithPContext*(c: PContext, n: PNode): PNode =
var n = n
if sfMainModule in c.module.flags:
n = newTree(nkStmtList, n,
newTree(nkCall,
newIdentNode(getIdent(c.cache, "nimAtCompileTimeExit"), n.info)))
# no need for an expensive 'try' if we stop after the first error anyway:
if c.config.errorMax <= 1:
result = semStmtAndGenerateGenerics(c, n)
Expand Down
13 changes: 13 additions & 0 deletions lib/core/macros.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1816,3 +1816,16 @@ proc extractDocCommentsAndRunnables*(n: NimNode): NimNode =
result.add ni
else: break
else: break

var compileTimeExitProcs {.compileTime.}: seq[proc(): NimNode]
proc addCompileTimeExitProc*(cb: proc(): NimNode) {.compileTime.} =
## Schedules `cb` to be executed as if it was a macro call
## at the end of main module. Appends result of `cb` at the
## end of main module.
if compileTimeExitProcs.len == 0:
nimSetCompileTimeExit(proc(): NimNode =
result = newNimNode(nnkStmtList)
for cb in compileTimeExitProcs:
result.add(cb()))
compileTimeExitProcs.add(cb)

9 changes: 9 additions & 0 deletions lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3087,3 +3087,12 @@ proc arrayWithDefault*[T](size: static int): array[size, T] {.noinit, nodestroy,
## Creates a new array filled with `default(T)`.
for i in 0..size-1:
result[i] = default(T)

var compileTimeExitProc {.compileTime.}: proc(): NimNode

proc nimSetCompileTimeExit*(cb: proc(): NimNode) {.compileTime.} =
compileTimeExitProc = cb

macro nimAtCompileTimeExit*(): untyped =
if compileTimeExitProc != nil:
result = compileTimeExitProc()
20 changes: 20 additions & 0 deletions tests/macros/tctexit.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
discard """
output: "Hello\nTest passed: 11"
"""
import macros

var foo {.compileTime.} = 0

static:
addCompileTimeExitProc() do() -> NimNode:
let f = ident"foo"
result = quote do:
proc test() =
echo "Test passed: ", static(foo)
test()

static:
foo = 10
inc foo

echo "Hello"
Loading