DEFMACRO supports extended macro lambda lists
[jscl.git] / src / lambda-list.lisp
index e217333..a0df680 100644 (file)
       (unless (consp tail)
         (error "Odd number of keyword arguments.")))))
 
-(defmacro !destructuring-bind (lambda-list expression &body body)
+(defun !destructuring-bind-macro-function (lambda-list expression &rest body)
   (multiple-value-bind (d-ll)
       (parse-destructuring-lambda-list lambda-list)
     (let ((bindings '()))
-      (labels (;; Return a chain of the form (CAR (CDR (CDR ... (CDR X))),
+      (labels ( ;; Return a chain of the form (CAR (CDR (CDR ... (CDR X))),
                ;; such that there are N calls to CDR.
                (nth-chain (x n &optional tail)
                  (if tail
                ,@body)))))))
 
 
+;;; Because DEFMACRO uses destructuring-bind to parse the arguments of
+;;; the macro-function, we can't define DESTRUCTURING-BIND with
+;;; defmacro to avoid a circularity. So just define the macro function
+;;; explicitly.
+
+#+common-lisp
+(defmacro !destructuring-bind (lambda-list expression &body body)
+  (apply #'!destructuring-bind-macro-function lambda-list expression body))
+
 #+jscl
-(defmacro destructuring-bind (lambda-list expression &body body)
-  `(!destructuring-bind ,lambda-list ,expression ,@body))
+(eval-when-compile
+  (let ((macroexpander
+         '#'(lambda (form &optional environment)
+              (declare (ignore environment))
+              (apply #'!destructuring-bind-macro-function form))))
+    (%compile-defmacro '!destructuring-bind macroexpander)
+    (%compile-defmacro  'destructuring-bind macroexpander)))