0.8.10.13:
[sbcl.git] / src / code / early-extensions.lisp
index e195215..5fb2c0f 100644 (file)
   ;; just define ASSQ explicitly in terms of more primitive
   ;; operations:
   (dolist (pair alist)
-    (when (eq (car pair) item)
+    ;; though it may look more natural to write this as 
+    ;;   (AND PAIR (EQ (CAR PAIR) ITEM))
+    ;; the temptation to do so should be resisted, as pointed out by PFD
+    ;; sbcl-devel 2003-08-16, as NIL elements are rare in association
+    ;; lists.  -- CSR, 2003-08-16
+    (when (and (eq (car pair) item) (not (null pair)))
       (return pair))))
 
 ;;; like (DELETE .. :TEST #'EQ):
 
 ;;; Iterate over the entries in a HASH-TABLE.
 (defmacro dohash ((key-var value-var table &optional result) &body body)
-  (multiple-value-bind (forms decls) (parse-body body nil)
+  (multiple-value-bind (forms decls) (parse-body body :doc-string-allowed nil)
     (let ((gen (gensym))
          (n-more (gensym)))
       `(with-hash-table-iterator (,gen ,table)
@@ -1092,6 +1097,41 @@ which can be found at <http://sbcl.sourceforge.net/>.~:@>"
                (let ((it ,test)) (declare (ignorable it)),@body)
                (acond ,@rest))))))
 
+;;; (binding* ({(names initial-value [flag])}*) body)
+;;; FLAG may be NIL or :EXIT-IF-NULL
+;;;
+;;; This form unites LET*, MULTIPLE-VALUE-BIND and AWHEN.
+(defmacro binding* ((&rest bindings) &body body)
+  (let ((bindings (reverse bindings)))
+    (loop with form = `(progn ,@body)
+          for binding in bindings
+          do (destructuring-bind (names initial-value &optional flag)
+                 binding
+               (multiple-value-bind (names declarations)
+                   (etypecase names
+                     (null
+                      (let ((name (gensym)))
+                        (values (list name) `((declare (ignorable ,name))))))
+                     (symbol
+                      (values (list names) nil))
+                     (list
+                      (collect ((new-names) (ignorable))
+                        (dolist (name names)
+                          (when (eq name nil)
+                            (setq name (gensym))
+                            (ignorable name))
+                          (new-names name))
+                        (values (new-names)
+                                (when (ignorable)
+                                  `((declare (ignorable ,@(ignorable)))))))))
+                 (setq form `(multiple-value-bind ,names
+                                 ,initial-value
+                               ,@declarations
+                               ,(ecase flag
+                                       ((nil) form)
+                                       ((:exit-if-null)
+                                        `(when ,(first names) ,form)))))))
+          finally (return form))))
 \f
 ;;; Delayed evaluation
 (defmacro delay (form)
@@ -1106,3 +1146,31 @@ which can be found at <http://sbcl.sourceforge.net/>.~:@>"
 (defun promise-ready-p (promise)
   (or (not (consp promise))
       (car promise)))
+\f
+;;; toplevel helper
+(defmacro with-rebound-io-syntax (&body body)
+  `(%with-rebound-io-syntax (lambda () ,@body)))
+
+(defun %with-rebound-io-syntax (function)
+  (declare (type function function))
+  (let ((*package* *package*)
+       (*print-array* *print-array*)
+       (*print-base* *print-base*)
+       (*print-case* *print-case*)
+       (*print-circle* *print-circle*)
+       (*print-escape* *print-escape*)
+       (*print-gensym* *print-gensym*)
+       (*print-length* *print-length*)
+       (*print-level* *print-level*)
+       (*print-lines* *print-lines*)
+       (*print-miser-width* *print-miser-width*)
+       (*print-pretty* *print-pretty*)
+       (*print-radix* *print-radix*)
+       (*print-readably* *print-readably*)
+       (*print-right-margin* *print-right-margin*)
+       (*read-base* *read-base*)
+       (*read-default-float-format* *read-default-float-format*)
+       (*read-eval* *read-eval*)
+       (*read-suppress* *read-suppress*)
+       (*readtable* *readtable*))
+    (funcall function)))