Chris Capel pdf23ds@gmail.com writes:
I've been thinking about a neat feature I think could be implemented in a pretty straightforward way to help with the debugging of macros. There would be a new minor mode for a buffer containing some random form. Selecting any given subform of the buffer's form would macroexpand that one form, in place. Of course, it would have to respect macrolet's and symbol-macrolet's (which isn't that hard, really).
Suppose you have:
(defmacro bar (x) `(1+ ,x)) (defmacro foo (&rest body) '()) (defun baz (y) (foo (bar y)))
and now you select (bar y) and let it expand. What's the result?
I already have the code written (included below) to expand such forms (perhaps buggy, perhaps incomplete). (One thing I know it doesn't do is find and respect macrolets that aren't present in the form until after some expansion. I don't know that this is a big deal.)
I suspect that your code doesn't pass down the environment correctly. Every macro can potentially call macroexpand itself and I think you have to expand every macro and pass the proper environemnt. I think in the general case you need a full codewalker. Of course, a lot of useful stuff can be done with something much simpler.
[Isn't it shame that there's no portable codewalker for Common Lisp?]
What's missing is the hooks into slime and Emacs. I don't want to bother with these (because they'd be a lot more effort for me) until I find whether there are any similar features currently available for SLIME. So has anyone done anything like this yet?
Not that I know of. There are only the macroexpand{-1,-all} commands.
If not, I suppose SLIME would need another minor mode with some cool keybindings and code to figure out what to pass as the list-indexes variable based on the position in the buffer (perhaps the hardest part?).
I have the impression that your list-indexes are similar to what CMUCL calls "source-path". You could use the code in SLIME's source-path-parser. Basically you can pass in a string (or stream) and you get the corresponding sexp and a table which maps each (sub)form to the start and the end position in the string. So you could give it the toplevel expression from the buffer as a string, search the interval in the table which matches the buffer position best and you know which subform to expand. If you know the subform (comparable with eq) you can compute the source-path. But you probably don't need that, since you already have the subform.
Hm... sounds like a lot of work. Maybe there's something simpler.
Helmut.