* optimization: [N]BUTLAST perform a single pass over the list. (lp#1245697)
* optimization: EQUALP on structures with raw slots (double-float/complex)
no longer conses and is faster.
+ * optimization: RESTART-CASE expands to more compact code.
+ Thanks to Jan Moringen. (lp#1249055)
* enhancement: Top-level defmethod without defgeneric no longer causes
undefined-function warnings in subsequent forms. (lp#503095)
* bug fix: EQUALP now compares correctly structures with raw slots larger
(return (values result form))))
result)))))
(parse-clause (clause)
- (unless (and (listp clause ) (>= (length clause) 2)
+ (unless (and (listp clause) (>= (length clause) 2)
(listp (second clause)))
(error "ill-formed ~S clause, no lambda-list:~% ~S"
'restart-case clause))
(parse-keywords-and-body body)
(list name (sb!xc:gensym "TAG") keywords lambda-list body))))
(make-binding (clause-data)
- (destructuring-bind (name tag keywords &rest rest) clause-data
- (declare (ignore rest))
- `(,name #'(lambda (&rest temp)
- (setq ,temp-var temp)
- (locally (declare (optimize (safety 0)))
- (go ,tag)))
- ,@keywords)))
+ (destructuring-bind (name tag keywords lambda-list body) clause-data
+ (declare (ignore body))
+ `(,name
+ (lambda ,(cond ((null lambda-list)
+ ())
+ ((and (null (cdr lambda-list))
+ (not (member (car lambda-list)
+ '(&optional &key &aux))))
+ '(temp))
+ (t
+ '(&rest temp)))
+ ,@(when lambda-list `((setq ,temp-var temp)))
+ (locally (declare (optimize (safety 0)))
+ (go ,tag)))
+ ,@keywords)))
(make-apply-and-return (clause-data)
(destructuring-bind (name tag keywords lambda-list body) clause-data
(declare (ignore name keywords))
`(,tag (return-from ,block-tag
- (apply (lambda ,lambda-list ,@body) ,temp-var))))))
+ ,(cond ((null lambda-list)
+ `(progn ,@body))
+ ((and (null (cdr lambda-list))
+ (not (member (car lambda-list)
+ '(&optional &key &aux))))
+ `(funcall (lambda ,lambda-list ,@body) ,temp-var))
+ (t
+ `(apply (lambda ,lambda-list ,@body) ,temp-var))))))))
(let ((clauses-data (mapcar #'parse-clause clauses)))
`(block ,block-tag
(let ((,temp-var nil))