Proc with a "NimNode" input are automatically compile-time, otherwise you can
tag them with {.compiletime.} pragma.
Regarding implementing your own AST with an Expr AST -> Nim AST, you might also
be interested into my step-by-step experiments into writing a compiler in Nim
macros:
[https://github.com/mratsim/compute-graph-optim](https://github.com/mratsim/compute-graph-optim)
which now lives as a PoC tensor/matrix operation compiler:
[https://github.com/numforge/laser/tree/master/laser/lux_compiler](https://github.com/numforge/laser/tree/master/laser/lux_compiler).
The AST implementation is described here:
[https://github.com/numforge/laser/blob/master/laser/lux_compiler/core/low_level_design_considerations.md](https://github.com/numforge/laser/blob/master/laser/lux_compiler/core/low_level_design_considerations.md)
It's still unfinished so there is only about 1000 lines so should be pretty
easy to follow.