walker.lisp
42 lines
| 1.2 KiB
| text/x-common-lisp
|
CommonLispLexer
/ src / walker.lisp
r36 | ||||
(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))) | ||||
r37 | (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*))) | ||||
r36 | (defun walk (transformer-name form) | |||
r37 | (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))) | ||||