[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

portable code walkers



We did code walking in a simple way for our flavors implementation
in Franz using their macroexpand function.  The Franz macroexpand
expands more than just the top level form; it finds all subforms
that will be evaluated and expands any macros found there as well
-- basically, it does a code walk.  We had to fix it (since it
didn't know about all the special forms in Franz).  We then modified
it so it takes an optional argument that is a function.  That
function is applied to every subform that will be eval'd after it
has been completely macroexpanded.  The value returned by that
function is used in place of the form.  I would like to propose
something similar here:

---------------
CODE-WALK form &optional function		[ function ]

For the form given, this expands all the macros at the top level,
determines which subforms will be eval'd and calls itself recursively
on those subforms consing up the equivalent form from the values
given.  If the optional function is given, after all the subforms
are expanded (in each recursive call), the function is called and
passed the new form and substitutes the value returned for that
form.

For example, given:

	(defun hack-ivar-refs (form)
	  (cond ((ivarp form) `(get-ivar ,form self))
		((and (listp form)
		      (eq (car form) 'setq)
		      (ivarp (cadr form)))
		 ;; being lazy -- assuming only 2 args to setq
		 `(set-ivar ,(cadr form) self ,(caddr form)))
		(t form)))

a call like (code-walk form #'hack-ivar-refs) will find all the
references to the instance variables that need to be found and
replaced by the appropriate calls to get and set their values.
-----

This took care of what we needed to do for our flavors implementation
quite nicely.  I'm not sure if there are code walking situations
that would require greater functionality...  It is possible that
someone would like to have hooks to look at the forms before they
are macroexpanded or perhaps even after each macro is expanded;
both of those two things could be handled easily.

Comments?

				-Liz