[cmucl-imp] define-compiler-macro and funcall forms.
Mark Cox
markcox80 at gmail.com
Sun Mar 15 04:26:09 UTC 2015
G'day,
The compiler macro functions created by CMUCL using
define-compiler-macro do not correctly handle funcall forms in cases
where the compiler macro function returns the input form. This is
demonstrated with the following example:
(defun square (x)
(expt x 2))
(define-compiler-macro square (&whole form arg)
(declare (ignore arg))
form)
(funcall (compiler-macro-function 'square) '(square x) nil)
=> (SQUARE X)
(funcall (compiler-macro-function 'square) '(funcall #'square x) nil)
=> (#'SQUARE X)
The cause of this error is due to a bug in the body argument returned
by lisp::parse-defmacro.
(nth-value 0 (lisp::parse-defmacro '(&whole form arg) 'my-form '(form)
'square 'define-compiler-macro))
=> (let* ((my-form (if (progn
(not (and (listp my-form)
(eq 'funcall (car my-form)))))
my-form
(progn
(setf my-form (cdr my-form))))))
(unless (lisp::list-length-bounded-p (the list (cdr my-form)) 1 1)
(lisp::do-arg-count-error 'define-compiler-macro
'square
(cdr my-form)
'(&whole form arg)
1
1))
(let* ((form my-form) (arg (car (cdr my-form))))
form))
The body above is evaluated in a lexical environment where MY-FORM is
bound to '(funcall #'square x). A new binding of MY-FORM is introduced
by the first LET* in the body above such that MY-FORM is (cdr '(#'square x)).
This value is then bound to the &WHOLE symbol FORM specified in the input
lambda list to PARSE-DEFMACRO.
Thanks
Mark
[1]. http://www.lispworks.com/documentation/HyperSpec/Body/m_define.htm
More information about the cmucl-imp
mailing list