After reading the macro chapter in "Software Tools" I rewrote the macro processor. The main problem with my approach was the idea of 'new code' or what code should be expanding at this moment. This was solved by using recursion but it is confusing and in no way elegant.
In the first version the input stream would be scaned for 'let' and 'define' and a symbol table would be created. Any code that was not part of a 'let' or 'define' would get stored as new code. After this first pass was complete, the new code was scanned for symbols. If a symbol was found, a recursive call would be made to the scanner using the macros code as new code and any parameters as the symbol table.
The idea that made the macro processor in "Software Tools" more elegant was the way they treated the input stream. I was considering the input stream as one character at a time coming in. Once you have a token you have to stick it in some data structure if you want to scan it later. In the book they think of the input stream as a stack. They allow for whole tokens to be pushed back on the input. Altering the stream in this way is easy to implement and keeps the recursion in the data structure which allows me to write iterative code.
You can get the code here