define-compiler-macro and funcall forms.

Mark Cox <[email protected]> Sun, 15 Mar 2015 14:26:09 +1000
Newsgroups gmane.lisp.cmucl.devel
Message-ID <[email protected]>
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

_______________________________________________
cmucl-imp mailing list
[email protected]
http://lists.zs64.net/mailman/listinfo/cmucl-imp