`((@ ,fn apply) this ,arglist)))
(defun destructuring-wrap (arr n bindings body &key setf?)
- (cond ((null bindings)
- body)
- ((atom bindings)
- ;; dotted destructuring list
- `(let ((,bindings (when (> (length ,arr) ,n)
- ((@ ,arr slice) ,n))))
- ,body))
- (t (let ((var (car bindings))
- (inner-body (destructuring-wrap arr (1+ n) (cdr bindings) body :setf? setf?)))
- (cond ((null var) inner-body)
- ((atom var) (if setf?
- `(progn (setf ,var (aref ,arr ,n))
- ,inner-body)
- `(let ((,var (aref ,arr ,n)))
- ,inner-body)))
- (t `(,(if setf? 'dset 'destructuring-bind)
- ,var (aref ,arr ,n)
- ,inner-body)))))))
+ (flet ((bind-rest (sym)
+ `(let ((,sym (when (> (length ,arr) ,n)
+ ((@ ,arr slice) ,n))))
+ ,body)))
+ (cond ((null bindings)
+ body)
+ ((atom bindings) ;; dotted destructuring list
+ (bind-rest bindings))
+ ((eq (car bindings) '&rest)
+ (if (and (= (length bindings) 2)
+ (atom (second bindings)))
+ (bind-rest (second bindings))
+ (error "~a is invalid in destructuring list." bindings)))
+ (t (let ((var (car bindings))
+ (inner-body (destructuring-wrap arr (1+ n) (cdr bindings) body :setf? setf?)))
+ (cond ((null var) inner-body)
+ ((atom var) (if setf?
+ `(progn (setf ,var (aref ,arr ,n))
+ ,inner-body)
+ `(let ((,var (aref ,arr ,n)))
+ ,inner-body)))
+ (t `(,(if setf? 'dset 'destructuring-bind)
+ ,var (aref ,arr ,n)
+ ,inner-body))))))))
(defpsmacro dset (bindings expr &body body)
(let ((arr (if (complex-js-expr? expr) (ps-gensym) expr)))