[slime-devel] suggested macroexpansion feature (and volunteer)
Chris Capel
pdf23ds at gmail.com
Wed Apr 13 03:25:53 UTC 2005
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).
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.)
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? 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?).
Chris Capel
(defmacro expand (form &environment e)
(list 'quote (macroexpand-1 form e)))
(defun get-list-to-expand (list list-indexes)
(flet ((recurse ()
(get-list-to-expand (nth (car list-indexes) list)
(cdr list-indexes))))
(if (null list-indexes)
(list 'expand list)
(let ((sym (find (car list) '(macrolet symbol-macrolet))))
(if sym
(list sym (cadr list) (recurse))
(recurse))))))
(get-list-to-expand '(symbol-macrolet ((s a)) s) '(2))
(defun nsubst-list (source substitution list-indexes)
(if (null list-indexes)
substitution
(progn
(setf (nth (car list-indexes) source)
(nsubst-list (nth (car list-indexes) source)
substitution
(cdr list-indexes)))
source)))
(nsubst-list '(a b (c d)) '(e f) '(2 1))
(defun subst-all-tree (tree obj-a obj-b &key (test #'equal))
(mapcar (lambda (i)
(if (consp i)
(subst-all-tree i obj-a obj-b :test test)
(if (funcall test obj-a i)
obj-b
i)))
tree))
(subst-all-tree '(a b (c d)) 'd 'e)
(defun expand-part (list &rest list-indexes)
(nsubst-list list
(eval (get-list-to-expand list list-indexes))
list-indexes))
(expand-part
'(macrolet ((x (m) `(y ,m)))
(x z))
2)
(expand-part
'(let ((x 50))
(destructuring-bind (x y z) f
(dolist (q y)
x)))
2) ;; or "2 3)" for the dolist
More information about the slime-devel
mailing list