the way macros are expanded, the code is searched for references of the macro. If a referenence is found, the macro is executed and the code altered with the results of the macro.
The macroexpander will then "stupidly" rerun against the code, over and over again, until there are no more macros to expand.
This crude behavior allows you to have recursive macros, but it's not actually doing anything all that "smart"- I think you're reading more into the complexities of recursive macros than is probably there.
This is what I originally had in mind. As far as I can tell, this doesn't work for bytecode-compiled Lisp, correct? (Since it would compile it as a function call, although it's a macro...) So does that mean every implementation of Lisp has to have a single-pass interpreter in it?
Well, every implementation of Lisp does indeed contain an interpreter: eval!
But the way Lisp compilers deal with recursive macros is to not allow them. From the Common Lisp spec:
"All macro and symbol macro calls appearing in the source code being compiled are expanded at compile time in such a way that they will not be expanded again at run time."
That rules out recursive macros. I think they're allowed when Lisp is being interpreted, but you should probably just not use them.