(in-package code-walker) (defvar *transformers* (make-hash-table :test #'equal)) (defmacro deftransform (transformer-name head args &body body) `(progn (setf (gethash (list ',transformer-name ',head) *transformers*) (lambda ,args ,@body)) (list ',transformer-name ',head))) (defmacro deftransform-stop (transformer-name head) `(progn (setf (gethash (list ',transformer-name ',head) *transformers*) (lambda (&rest args) (declare (ignore args)) nil)) (list ',transformer-name ',head))) (defvar *whole*) (defvar *transformer-name*) (defun whole () *whole*) (defun walk-continue (&optional subform) (if subform (walk *transformer-name* subform) (mapcar (lambda (subform) (walk *transformer-name* subform)) *whole*))) (defun walk (transformer-name form) (let ((*transformer-name* transformer-name) (*whole* form)) (if (listp form) (let ((transformer (gethash (list transformer-name (first form)) *transformers* nil))) (if transformer (apply transformer (rest form)) (walk-continue))) form)))