Just think of them as defining functions that take s expressions in and spit s expressions out before “normal” runtime evaluation and which hence only see built in symbols.
"This paper describes a modified form of Kohlbecker’s algo-
rithm for reliably hygienic (capture-free) macro expansion
in block-structured languages, where macros are source-to-
source transformations specified using a high-level pattern
language."
But then there are things like hygiene, performance and some tricky edge-cases.
And I couldn't find any standard (and simple) algorithm to implement macros (preferably written in something other than Scheme itself).
Still trying to wrap my head around.