I scrounged together a half-working implementation of macroexpand-all. It recursively macroexpands all the subforms within a form until there are absolutely no macros left in the _expression_. This is a temporary solution for whoever needs it, as I think Felix probably already has this implemented somewhere in the Chicken scheme system (because the compiler needs it I think) and just haven't exposed it for public use yet.
(1) It does not work if you call it with fundamental macros ALREADY shadowed by existing local bindings.
This will STILL try to expand the "let" inside the form, because macroexpand-all does not know about the "let" binding introduced before the call to macroexpand-all.
(2) It does not work if the given form contains local macro definitions, or subforms that expand to local macro definitions. I imagine this will take some work and I just haven't gotten around to doing this yet.
;;--------------------------------------------------------------------------------
;;---------------------------- MACRO EXPAND ------------------------------------
;;Helper Function for macroexpanding an _expression_ with a list of known bound symbols.
;;Symbols are assumed to be NOT bound to macros. So this implementation does not work
;;with local macros.
(define (-macroexpand-all bound-symbols _expression_)
(define (recurse-macroexpand-all bound-symbols _expression_)
(cons (-macroexpand-all bound-symbols (car _expression_))
(-macroexpand-all bound-symbols (cdr _expression_))))
(define (get-symbols binding)
(cond ((null? binding) '())
((pair? binding) (append (get-symbols (car binding)) (get-symbols (cdr binding))))
(else (list binding))))
(if (pair? _expression_)
(let ((head (car _expression_))
(tail (cdr _expression_)))
(cond
;;((...) ...)
((pair? head) (recurse-macroexpand-all bound-symbols _expression_))
;;Bound Symbol
((memq head bound-symbols) (recurse-macroexpand-all bound-symbols _expression_))
;;Quoted _expression_
((eq? head '##core#quote)
_expression_)
;;Lambda _expression_
((eq? head '##core#lambda)
(let* ((bindings (cadr _expression_))
(body (cddr _expression_))
(new-symbols (append (get-symbols bindings) bound-symbols)))
(cons head
(cons bindings
(recurse-macroexpand-all new-symbols body)))))
;;Let Form
((eq? head '##core#let)
(let* ((bindings (cadr _expression_))
(body (cddr _expression_))
(new-symbols (append (map car bindings) bound-symbols))
(expanded-bindings (map (lambda (b)
(list (car b) (-macroexpand-all bound-symbols (cadr b))))
bindings)))
(cons head (cons expanded-bindings (recurse-macroexpand-all new-symbols body)))))
;;Normal Form just expand it
(else (recurse-macroexpand-all bound-symbols (expand _expression_)))))
_expression_))
;;Macroexpand-All
(define (macroexpand-all _expression_)
(-macroexpand-all '() _expression_))