Changeset 3200
- Timestamp:
- 05/28/08 13:26:38 (8 months ago)
- Files:
-
- trunk/thirdparty/alexandria/_darcs/inventory (modified) (1 diff)
- trunk/thirdparty/alexandria/_darcs/pristine/alexandria.asd (modified) (1 diff)
- trunk/thirdparty/alexandria/_darcs/pristine/arrays.lisp (modified) (1 diff)
- trunk/thirdparty/alexandria/_darcs/pristine/conditions.lisp (modified) (1 diff)
- trunk/thirdparty/alexandria/_darcs/pristine/control-flow.lisp (modified) (3 diffs)
- trunk/thirdparty/alexandria/_darcs/pristine/definitions.lisp (modified) (3 diffs)
- trunk/thirdparty/alexandria/_darcs/pristine/doc/alexandria.texinfo (modified) (4 diffs)
- trunk/thirdparty/alexandria/_darcs/pristine/hash-tables.lisp (modified) (2 diffs)
- trunk/thirdparty/alexandria/_darcs/pristine/lists.lisp (modified) (2 diffs)
- trunk/thirdparty/alexandria/_darcs/pristine/macros.lisp (modified) (2 diffs)
- trunk/thirdparty/alexandria/_darcs/pristine/numbers.lisp (modified) (2 diffs)
- trunk/thirdparty/alexandria/_darcs/pristine/package.lisp (modified) (6 diffs)
- trunk/thirdparty/alexandria/_darcs/pristine/sequences.lisp (modified) (8 diffs)
- trunk/thirdparty/alexandria/_darcs/pristine/symbols.lisp (modified) (1 diff)
- trunk/thirdparty/alexandria/_darcs/pristine/tests.lisp (modified) (17 diffs)
- trunk/thirdparty/alexandria/_darcs/pristine/types.lisp (modified) (2 diffs)
- trunk/thirdparty/alexandria/alexandria.asd (modified) (1 diff)
- trunk/thirdparty/alexandria/arrays.lisp (modified) (1 diff)
- trunk/thirdparty/alexandria/conditions.lisp (modified) (1 diff)
- trunk/thirdparty/alexandria/control-flow.lisp (modified) (3 diffs)
- trunk/thirdparty/alexandria/definitions.lisp (modified) (3 diffs)
- trunk/thirdparty/alexandria/doc/alexandria.texinfo (modified) (4 diffs)
- trunk/thirdparty/alexandria/hash-tables.lisp (modified) (2 diffs)
- trunk/thirdparty/alexandria/lists.lisp (modified) (2 diffs)
- trunk/thirdparty/alexandria/macros.lisp (modified) (2 diffs)
- trunk/thirdparty/alexandria/numbers.lisp (modified) (2 diffs)
- trunk/thirdparty/alexandria/package.lisp (modified) (6 diffs)
- trunk/thirdparty/alexandria/sequences.lisp (modified) (8 diffs)
- trunk/thirdparty/alexandria/symbols.lisp (modified) (1 diff)
- trunk/thirdparty/alexandria/tests.lisp (modified) (17 diffs)
- trunk/thirdparty/alexandria/types.lisp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/thirdparty/alexandria/_darcs/inventory
r2190 r3200 99 99 ] 100 100 [Small fix to REQUIRED-ARGUMENT's control string. 101 Luis Oliveira <loliveira@common-lisp.net>**20070823040500] 101 Luis Oliveira <loliveira@common-lisp.net>**20070823040500] [New macro: COERCEF 102 Luis Oliveira <loliveira@common-lisp.net>**20070720003607 103 104 Added respective documentation to the manual. 105 ] 106 [New function: FEATUREP 107 Luis Oliveira <loliveira@common-lisp.net>**20070720003420 108 109 Added respective documentation in manual as well. 110 ] 111 [New macro: NCONCF 112 Luis Oliveira <loliveira@common-lisp.net>**20070720003523 113 114 - Added respective documentation to the manual. 115 - New test: NCONCF.1 116 ] 117 [New macro: IGNORE-SOME-CONDITIONS 118 Luis Oliveira <loliveira@common-lisp.net>**20070726171110] 119 [Simplify IGNORE-SOME-CONDITIONS's docstring. 120 Luis Oliveira <loliveira@common-lisp.net>**20070823040556] 121 [Merge conflicts around the conditions 122 attila.lendvai@gmail.com**20071001122707] 123 [fix: darcs merge conflict was recorded into package.lisp 124 attila.lendvai@gmail.com**20071031173831] 125 [Fix map-permutations typo. 126 levente.meszaros@gmail.com**20071102163851] 127 [Switch the argument order of STARTS/ENDS-WITH-SUBSEQ to that it matches STARTS/ENDS-WITH. 128 attila.lendvai@gmail.com**20071126135259] 129 [fixed and robustified tests 130 Nikodemus Siivola <nikodemus@random-state.net>**20071219125512] 131 [ENSURE-GETHASH 132 Nikodemus Siivola <nikodemus@random-state.net>**20071219125800 133 134 * new function: like GETHASH, but saves the default value in table if 135 key is not found.* 136 137 ] 138 [better SHUFFLE 139 Nikodemus Siivola <nikodemus@random-state.net>**20071219125911 140 141 * Thanks to Sean Ross: implement the Fisher/Yates/Knuth algorithm 142 correctly. 143 144 * As penance, specialize for lists as well: travel along the list, 145 swapping towards the end -- marginally more efficient then swapping 146 along the whole length. 147 148 ] 149 [fix MAKE-GENSYM-LIST when called without the second argument 150 Nikodemus Siivola <nikodemus@random-state.net>**20071219130559 151 152 * plus a test-case 153 154 ] 155 [fix SANS -> REMOVE-FROM-PLIST in tests 156 Nikodemus Siivola <nikodemus@random-state.net>**20071219130641 157 158 * So SANS is now REMOVE-FROM-PLIST. 159 160 ...I have to say that I'm still not sure I like this: 161 162 (remove-from-plist x y) ; which is the plist? 163 164 The common usage in REMOVE &co is to put the element designators 165 first. This is confusing. 166 167 Maybe we really want both: 168 169 function SANS plist &rest keys 170 function REMOVE-FROM-PLIST keys plist 171 172 ] 173 [NTH-VALUE-OR 174 Nikodemus Siivola <nikodemus@random-state.net>**20071219132132 175 176 * Thanks to Andreas Fuchs -- I only took the liberty of changing the name from 177 MULTIPLE-VALUE-OR to NTH-VALUE-OR. 178 179 ] 180 [fix dependency: macros.lisp is using MAKE-GENSYM-LIST from symbols.lisp 181 attila.lendvai@gmail.com**20071221100634] 182 [Extract the function name of KEY too, not just TEST in GENERATE-SWITCH-BODY. 183 attila.lendvai@gmail.com**20080209201446 184 Patch by Stelian Ionescu. 185 ] 186 [fix tests: DELETEF.1 modified constant data 187 Nikodemus Siivola <nikodemus@random-state.net>**20080217070803 188 189 * ...so that running tests multiple times caused unrelated tests to fail 190 due to coalesced constants being frobbed. Gah. 191 192 ] 193 [new macro: DOPLIST 194 Nikodemus Siivola <nikodemus@random-state.net>**20080217071024 195 196 * Like DOLIST, but iterates over plists. 197 198 ] 199 [extended ONCE-ONLY 200 Nikodemus Siivola <nikodemus@random-state.net>**20080217071829 201 202 * Support (once-only ((nx x)) ...) style also. 203 204 ] 205 [fix WHICHEVER 206 Nikodemus Siivola <nikodemus@random-state.net>**20080217071955 207 208 * More efficient with constant arguments. 209 210 * Respect lexical environment with non-constant arguments. 211 212 ] 213 [fix removef and deletef not to use an inline lambda 214 nikodemus@random-state.net**20080223171025 215 216 CLHS says the third argument to DEFINE-MODIFY-MACRO must be a symbol. 217 Reported by Chun Tian. 218 219 ] 220 [Added an almost full implementation of CDR5 221 attila.lendvai@gmail.com**20080301100637] 222 [Fix file dependencies in the .asd 223 attila.lendvai@gmail.com**20080301105628] 224 [FEATUREP accept any compound test specifier, not just the keywords :AND, :OR and :NOT. 225 attila.lendvai@gmail.com**20080301105651 226 Patch by Stelian Ionescu. 227 ] 228 [Fix autodoc argument list of remove-from-plistf and delete-from-plistf. 229 attila.lendvai@gmail.com**20080301111034 230 Patch by Michael Weber. 231 ] 232 [Extract the body of define-constant macro into a function to avoid some warnings. 233 attila.lendvai@gmail.com**20080310134214 234 (Based on patch by Tobias C. Rittweiler) 235 ] 236 [Fix define-constant thinko, thanks for Tobias C. Rittweiler for pointing it out. 237 attila.lendvai@gmail.com**20080310141844] 238 [fix docstring typos in numbers.lisp (patch by Tobias C. Rittweiler) 239 attila.lendvai@gmail.com**20080310180012] 240 [Optimize sequence-of-length-p, make it inlinable 241 attila.lendvai@gmail.com**20080310181353] 242 [alexandria-define-constant-testcase.diff 243 Tobias C. Rittweiler <tcr@freebits.de>**20080311151906 244 245 * tests.lisp (define-constant.1): Adapted to latest changes; 246 argument to :KEY is now evaluated. 247 ] 248 [More elegant implementation for remove-from-plist by Michael Weber. 249 attila.lendvai@gmail.com**20080312091456] 250 [alexandria-copy-hashtable.diff 251 Tobias C. Rittweiler <tcr@freebits.de>**20080311143832 252 253 * hash-tables.lisp (copy-hash-table): Added new &key arg :KEY; 254 it's run on each element before it's stored in the new HT. 255 Additionally, make all &key args get their default even when 256 NIL was passed for them. 257 258 * tests.lisp (copy-hash-table.2): New test case. 259 260 ] 261 [alexandria-parse-body.diff 262 Tobias C. Rittweiler <tcr@freebits.de>**20080311093924 263 264 * macros.lisp (parse-body): Don't use ALEXANDRIA:STARTS-WITH. 265 266 The reason is that this way PARSE-BODY is a completely 267 standalone definition, and can hence be used in consequent 268 macro definitions within the Alexandria project without 269 having to worrying if `sequences.lisp' has already been 270 loaded (where STARTS-WITH is defined.) 271 272 ] 273 [One level less quote in the implementation of the CDR5 types macro 274 attila.lendvai@gmail.com**20080313160255] 275 [alexandria-cdr5-types.diff 276 Tobias C. Rittweiler <tcr@freebits.de>**20080313203602 277 278 * types.lisp: Fix quoting problem introduced by Attila's last 279 patch; additionally add automatically generated docstrings to all 280 the types defined. 281 282 * tests.lisp (cdr5.*): New test cases. 283 ] 284 [Fix dependency: previous patch to CDR5 in types.lisp uses ensure-car from lists.lisp 285 attila.lendvai@gmail.com**20080314115151] 286 [alexandria-unwind-protect-case.diff 287 Tobias C. Rittweiler <tcr@freebits.de>**20080311154836 288 289 * conditions.lisp (unwind-protect-case): New macro. Similiar to 290 CL:UNWIND-PROTECT except that it's possible to explicitly specify 291 under which circumstances cleanup operations are run. 292 293 * tests.lisp (unwind-protect-case.1-5): New test cases. 294 ] 295 [alexandria-export-unwind-protect-case.diff 296 Tobias C. Rittweiler <tcr@freebits.de>**20080311195448 297 298 * package.lisp: Export UNWIND-PROTECT-CASE. 299 ] 300 [Added simple-reader-error 301 attila.lendvai@gmail.com**20080327192821] 302 [Fix some glitches with simple-reader-error and add comment why there's no :report for it. 303 attila.lendvai@gmail.com**20080401110518] 304 [Added length= 305 attila.lendvai@gmail.com**20080410172801] 306 [added simple-parse-error 307 attila.lendvai@gmail.com**20080427205301] trunk/thirdparty/alexandria/_darcs/pristine/alexandria.asd
r2190 r3200 10 10 (:file "conditions" :depends-on ("package")) 11 11 (:file "hash-tables" :depends-on ("package")) 12 (:file "macros" :depends-on ("package" "strings" ))13 (:file "control-flow" :depends-on ("package" " macros"))12 (:file "macros" :depends-on ("package" "strings" "symbols")) 13 (:file "control-flow" :depends-on ("package" "definitions" "macros")) 14 14 (:file "symbols" :depends-on ("package")) 15 (:file "arrays" :depends-on ("package" ))16 (:file "types" :depends-on ("package" ))15 (:file "arrays" :depends-on ("package" "types")) 16 (:file "types" :depends-on ("package" "symbols" "lists")) 17 17 (:file "binding" :depends-on ("package")) 18 18 (:file "functions" :depends-on ("package" "symbols" "macros")) 19 19 (:file "lists" :depends-on ("package" "functions")) 20 20 (:file "sequences" :depends-on ("package" "lists")) 21 (:file "numbers" :depends-on ("package" "sequences")))) 21 (:file "numbers" :depends-on ("package" "sequences")) 22 (:file "features" :depends-on ("package" "control-flow")))) trunk/thirdparty/alexandria/_darcs/pristine/arrays.lisp
r2190 r3200 1 1 (in-package :alexandria) 2 3 (deftype array-index (&optional (length array-dimension-limit))4 "Type designator for an index into array of LENGTH: an integer between5 0 (inclusive) and LENGTH (exclusive). LENGTH defaults to6 ARRAY-DIMENSION-LIMIT."7 `(integer 0 (,length)))8 9 (deftype array-length (&optional (length array-dimension-limit))10 "Type designator for a dimension of an array of LENGTH: an integer between11 0 (inclusive) and LENGTH (inclusive). LENGTH defaults to12 ARRAY-DIMENSION-LIMIT."13 `(integer 0 ,length))14 2 15 3 (defun copy-array (array &key trunk/thirdparty/alexandria/_darcs/pristine/conditions.lisp
r2190 r3200 13 13 (warn 'simple-style-warning :format-control message :format-arguments args)) 14 14 15 ;; We don't specify a :report for simple-reader-error to let the underlying 16 ;; implementation report the line and column position for us. Unfortunately 17 ;; this way the message from simple-error is not displayed, but it's still 18 ;; inspectable from the debugger. 19 (define-condition simple-reader-error (reader-error simple-error) 20 ()) 21 22 (defun simple-reader-error (stream message &rest args) 23 (error 'simple-reader-error 24 :stream stream 25 :format-control message 26 :format-arguments args)) 27 28 (define-condition simple-parse-error (simple-error parse-error) 29 ()) 30 31 (defun simple-parse-error (message &rest args) 32 (error 'simple-parse-error 33 :format-control message 34 :format-arguments args)) 35 36 (defmacro ignore-some-conditions ((&rest conditions) &body body) 37 "Similar to CL:IGNORE-ERRORS but the (unevaluated) CONDITIONS 38 list determines which specific conditions are to be ignored." 39 `(handler-case 40 (progn ,@body) 41 ,@(loop for condition in conditions collect 42 `(,condition (c) (values nil c))))) 43 44 (defmacro unwind-protect-case ((&optional abort-flag) protected-form &body clauses) 45 "Like CL:UNWIND-PROTECT, but you can specify the circumstances that 46 the cleanup CLAUSES are run. 47 48 ABORT-FLAG is the name of a variable that will be bound to T in 49 CLAUSES if the PROTECTED-FORM aborted preemptively, and to NIL 50 otherwise. 51 52 Examples: 53 54 (unwind-protect-case () 55 (protected-form) 56 (:normal (format t \"This is only evaluated if PROTECTED-FORM executed normally.~%\")) 57 (:abort (format t \"This is only evaluated if PROTECTED-FORM aborted preemptively.~%\")) 58 (:always (format t \"This is evaluated in either case.~%\"))) 59 60 (unwind-protect-case (aborted-p) 61 (protected-form) 62 (:always (perform-cleanup-if aborted-p))) 63 " 64 (check-type abort-flag (or null symbol)) 65 (let ((gflag (gensym "FLAG+"))) 66 `(let ((,gflag t)) 67 (unwind-protect (multiple-value-prog1 ,protected-form (setf ,gflag nil)) 68 (let ,(and abort-flag `((,abort-flag ,gflag))) 69 ,@(loop for (cleanup-kind . forms) in clauses 70 collect (ecase cleanup-kind 71 (:normal `(when (not ,gflag) ,@forms)) 72 (:abort `(when ,gflag ,@forms)) 73 (:always `(progn ,@forms))))))))) trunk/thirdparty/alexandria/_darcs/pristine/control-flow.lisp
r2190 r3200 4 4 (with-gensyms (value) 5 5 (setf test (extract-function-name test)) 6 (setf key (extract-function-name key)) 6 7 (when (and (consp default) 7 8 (member (first default) '(error cerror))) … … 39 40 (generate-switch-body whole object clauses test key '(cerror "Return NIL from CSWITCH."))) 40 41 41 (defmacro whichever (&rest possibilities )42 (defmacro whichever (&rest possibilities &environment env) 42 43 "Evaluates exactly one of POSSIBILITIES, chosen at random." 43 `(funcall (the function 44 (svref (load-time-value 45 (vector ,@(mapcar (lambda (possibility) 46 `(lambda () ,possibility)) 47 possibilities)) 48 t) 49 (random ,(length possibilities)))))) 44 (setf possibilities (mapcar (lambda (p) (macroexpand p env)) possibilities)) 45 (if (every (lambda (p) (constantp p)) possibilities) 46 `(svref (load-time-value (vector ,@possibilities)) (random ,(length possibilities))) 47 (with-gensyms (function) 48 `(let ((,function (lambda () ,(pop possibilities)))) 49 (declare (function ,function)) 50 ,@(let ((p 1)) 51 (mapcar (lambda (possibility) 52 `(when (zerop (random ,(incf p))) 53 (setf ,function (lambda () ,possibility)))) 54 possibilities)) 55 (funcall ,function))))) 50 56 51 57 (defmacro xor (&rest datums) … … 67 73 datums) 68 74 (return-from ,xor (values ,true t)))))) 75 76 (defmacro nth-value-or (nth-value &body forms) 77 "Evaluates FORM arguments one at a time, until the NTH-VALUE returned by one 78 of the forms is non-NIL. It then returns all the values returned by evaluating 79 that form. If none of the forms return a non-nil nth value, this form returns 80 NIL." 81 (once-only (nth-value) 82 (with-gensyms (values) 83 `(let ((,values (multiple-value-list ,(first forms)))) 84 (if (nth ,nth-value ,values) 85 (values-list ,values) 86 ,(if (rest forms) 87 `(nth-value-or ,nth-value ,@(rest forms)) 88 nil)))))) trunk/thirdparty/alexandria/_darcs/pristine/definitions.lisp
r2190 r3200 2 2 3 3 (defun extract-function-name (spec) 4 "Useful for macros that want to emulatethe functional interface for functions4 "Useful for macros that want to mimic the functional interface for functions 5 5 like #'eq and 'eq." 6 6 (if (and (consp spec) … … 9 9 spec)) 10 10 11 (defmacro define-constant (name initial-value &key (test 'eql) documentation) 12 "Ensures that the global variable named by NAME is a constant with a value 13 that is equal under TEST to the result of evaluating INITIAL-VALUE. TEST 14 defaults to EQL, and if given it must be a symbol naming a function. If 15 DOCUMENTATION is given, it becomes the documentation string of the constant. 11 (defun %reevaluate-constant (name value &key (test 'eql)) 12 (if (not (boundp name)) 13 value 14 (let ((old (symbol-value name)) 15 (new value)) 16 (if (not (constantp name)) 17 (prog1 new 18 (cerror "Try to redefine the variable as a constant." 19 "~@<~S is an already bound non-constant variable ~ 20 whose value is ~S.~:@>" name old)) 21 (if (funcall test old new) 22 old 23 (prog1 new 24 (cerror "Try to redefine the constant." 25 "~@<~S is an already defined constant whose value ~ 26 ~S is not equal to the provided initial value ~S ~ 27 under ~S.~:@>" name old new test))))))) 28 29 (defmacro define-constant (name initial-value &key (test ''eql) documentation) 30 "Ensures that the global variable named by NAME is a constant with a 31 value that is equal under TEST to the result of evaluating 32 INITIAL-VALUE. TEST is a /function designator/ that defaults to 33 EQL. If DOCUMENTATION is given, it becomes the documentation string of 34 the constant. 16 35 17 36 Signals an error if NAME is already a bound non-constant variable. … … 19 38 Signals an error if NAME is already a constant variable whose value is not 20 39 equal under TEST to result of evaluating INITIAL-VALUE." 21 (setf test (extract-function-name test)) 22 `(defconstant ,name 23 (let ((new ,initial-value)) 24 (if (boundp ',name) 25 (let ((old (symbol-value ',name))) 26 (cond 27 ((constantp ',name) 28 (cond 29 ((,test old new) 30 old) 31 (t 32 (cerror "Try to redefine the constant." 33 "~@<~S is an already defined constant whose value ~ 34 ~S is not equal to the provided initial value ~S ~ 35 under ~S.~:@>" ',name old new ',test) 36 new))) 37 (t 38 (cerror "Try to redefine the variable as a constant." 39 "~@<~S is an already bound non-constant variable ~ 40 whose value is ~S.~:@>" ',name old) 41 new))) 42 new)) 40 `(defconstant ,name (%reevaluate-constant ',name 41 ,initial-value 42 :test ,test) 43 43 ,@(when documentation `(,documentation)))) trunk/thirdparty/alexandria/_darcs/pristine/doc/alexandria.texinfo
r2190 r3200 81 81 * Type Designator Manipulation:: 82 82 * Mathematical Utilities:: 83 * Features:: 83 84 @end menu 84 85 … … 126 127 @include include/type-alexandria-circular-list.texinfo 127 128 @include include/macro-alexandria-appendf.texinfo 129 @include include/macro-alexandria-nconcf.texinfo 128 130 @include include/fun-alexandria-circular-list.texinfo 129 131 @include include/fun-alexandria-circular-list-p.texinfo … … 192 194 @include include/fun-alexandria-of-type.texinfo 193 195 @include include/fun-alexandria-type-equal.texinfo 196 @include include/macro-alexandria-coercef.texinfo 194 197 195 198 @node Mathematical Utilities … … 209 212 @include include/fun-alexandria-standard-deviation.texinfo 210 213 214 @c FIXME: get a better section name 215 @node Features 216 @comment node-name, next, previous, up 217 @section Features 218 219 @include include/fun-alexandria-featurep.texinfo 220 211 221 @bye trunk/thirdparty/alexandria/_darcs/pristine/hash-tables.lisp
r2190 r3200 1 1 (in-package :alexandria) 2 2 3 (defun copy-hash-table (table &key 4 (test (hash-table-test table)) 5 (size (hash-table-size table)) 6 (rehash-size (hash-table-size table)) 7 (rehash-threshold (hash-table-rehash-threshold table))) 8 "Returns a shallow copy of hash table TABLE, with the same keys and values 3 (defun copy-hash-table (table &key key test size 4 rehash-size rehash-threshold) 5 "Returns a copy of hash table TABLE, with the same keys and values 9 6 as the TABLE. The copy has the same properties as the original, unless 10 overridden by the keyword arguments." 7 overridden by the keyword arguments. 8 9 Before each of the original values is set into the new hash-table, KEY 10 is invoked on the value. As KEY defaults to CL:IDENTITY, a shallow 11 copy is returned by default." 12 (setf key (or key 'identity)) 13 (setf test (or test (hash-table-test table))) 14 (setf size (or size (hash-table-size table))) 15 (setf rehash-size (or rehash-size (hash-table-size table))) 16 (setf rehash-threshold (or rehash-threshold (hash-table-rehash-threshold table))) 11 17 (let ((copy (make-hash-table :test test :size size 12 18 :rehash-size rehash-size 13 19 :rehash-threshold rehash-threshold))) 14 20 (maphash (lambda (k v) 15 (setf (gethash k copy) v))21 (setf (gethash k copy) (funcall key v))) 16 22 table) 17 23 copy)) … … 84 90 table)) 85 91 92 (defun ensure-gethash (key hash-table &optional default) 93 "Like GETHASH, but if KEY is not found in the HASH-TABLE saves the DEFAULT 94 under key before returning it. Secondary return value is true if key was 95 already in the table." 96 (multiple-value-bind (value ok) (gethash key hash-table) 97 (if ok 98 (values value ok) 99 (values (setf (gethash key hash-table) default) nil)))) trunk/thirdparty/alexandria/_darcs/pristine/lists.lisp
r2190 r3200 18 18 (push (cons (car tail) (cadr tail)) alist)))) 19 19 20 (defun malformed-plist (plist) 21 (error "Malformed plist: ~S" plist)) 22 23 (defmacro doplist ((key val plist &optional values) &body body) 24 "Iterates over elements of PLIST. BODY can be preceded by 25 declarations, and is like a TAGBODY. RETURN may be used to terminate 26 the iteration early. If RETURN is not used, returns VALUES." 27 (multiple-value-bind (forms declarations) (parse-body body) 28 (with-gensyms (tail loop results) 29 `(block nil 30 (flet ((,results () 31 (let (,key ,val) 32 (declare (ignorable ,key ,val)) 33 (return ,values)))) 34 (let* ((,tail ,plist) 35 (,key (if ,tail 36 (pop ,tail) 37 (,results))) 38 (,val (if ,tail 39 (pop ,tail) 40 (malformed-plist ',plist)))) 41 (declare (ignorable ,key ,val)) 42 ,@declarations 43 (tagbody 44 ,loop 45 ,@forms 46 (setf ,key (if ,tail 47 (pop ,tail) 48 (,results)) 49 ,val (if ,tail 50 (pop ,tail) 51 (malformed-plist ',plist))) 52 (go ,loop)))))))) 53 20 54 (define-modify-macro appendf (&rest lists) append 21 55 "Modify-macro for APPEND. Appends LISTS to the place designated by the first 56 argument.") 57 58 (define-modify-macro nconcf (&rest lists) nconc 59 "Modify-macro for NCONC. Concatenates LISTS to place designated by the first 22 60 argument.") 23 61 … … 152 190 not destructively modified. Keys are compared using EQ." 153 191 (declare (optimize (speed 3))) 154 ;; FIXME: unoptimal: (sans '(:a 1 :b 2) :a) has no need to copy the 155 ;; tail. 156 (loop for cell = plist :then (cddr cell) 157 for key = (car cell) 158 while cell 192 ;; FIXME: possible optimization: (remove-from-plist '(:x 0 :a 1 :b 2) :a) 193 ;; could return the tail without consing up a new list. 194 (loop for (key . rest) on plist by #'cddr 195 do (assert rest () "Expected a proper plist, got ~S" plist) 159 196 unless (member key keys :test #'eq) 160 collect key 161 and do (assert (cdr cell) () "Not a proper plist") 162 and collect (cadr cell))) 197 collect key and collect (first rest))) 163 198 164 199 (defun delete-from-plist (plist &rest keys) 165 200 "Just like REMOVE-FROM-PLIST, but this version may destructively modify the 166 201 provided plist." 167 ;; FIXME unoptimal202 ;; FIXME: should not cons 168 203 (apply 'remove-from-plist plist keys)) 169 204 170 (define-modify-macro remove-from-plistf ( plist&rest keys) remove-from-plist)171 (define-modify-macro delete-from-plistf ( plist&rest keys) delete-from-plist)205 (define-modify-macro remove-from-plistf (&rest keys) remove-from-plist) 206 (define-modify-macro delete-from-plistf (&rest keys) delete-from-plist) 172 207 173 208 (declaim (inline sans)) trunk/thirdparty/alexandria/_darcs/pristine/macros.lisp
r2190 r3200 18 18 `(with-gensyms ,names ,@forms)) 19 19 20 (defmacro once-only (names &body forms) 21 "Evaluates FORMS with NAMES rebound to temporary variables, 22 ensuring that each is evaluated only once. 20 (defmacro once-only (specs &body forms) 21 "Each SPEC must be either a NAME, or a (NAME INITFORM), with plain 22 NAME using the named variable as initform. 23 24 Evaluates FORMS with names rebound to temporary variables, ensuring 25 that each is evaluated only once. 23 26 24 27 Example: 25 28 (defmacro cons1 (x) (once-only (x) `(cons ,x ,x))) 26 29 (let ((y 0)) (cons1 (incf y))) => (1 . 1)" 27 (let ((gensyms (make-gensym-list (length names) "ONCE-ONLY"))) 30 (let ((gensyms (make-gensym-list (length specs) "ONCE-ONLY")) 31 (names-and-forms (mapcar (lambda (spec) 32 (etypecase spec 33 (list 34 (destructuring-bind (name form) spec 35 (cons name form))) 36 (symbol 37 (cons spec spec)))) 38 specs))) 28 39 ;; bind in user-macro 29 `(let ,(mapcar (lambda (g n) (list g `(gensym ,(string n))))30 gensyms names )40 `(let ,(mapcar (lambda (g n) (list g `(gensym ,(string (car n))))) 41 gensyms names-and-forms) 31 42 ;; bind in final expansion 32 `(let (,,@(mapcar (lambda (g n) ``(,,g ,,n)) gensyms names)) 43 `(let (,,@(mapcar (lambda (g n) 44 ``(,,g ,,(cdr n))) 45 gensyms names-and-forms)) 33 46 ;; bind in user-macro 34 ,(let ,(mapcar #'list names gensyms) 47 ,(let ,(mapcar (lambda (n g) (list (car n) g)) 48 names-and-forms gensyms) 35 49 ,@forms))))) 36 50 … … 51 65 (setf doc (pop body))) 52 66 (go :declarations)) 53 (when ( starts-with 'declare current)67 (when (and (listp current) (eql (first current) 'declare)) 54 68 (push (pop body) decls) 55 69 (go :declarations))) trunk/thirdparty/alexandria/_darcs/pristine/numbers.lisp
r2190 r3200 45 45 "Return a list of n numbers, starting from START (with numeric contagion 46 46 from STEP applied), each consequtive number being the sum of the previous one 47 and STEP. START defaults to 0 and STEP to 0.47 and STEP. START defaults to 0 and STEP to 1. 48 48 49 49 Examples: … … 63 63 "Calls FUNCTION with N numbers, starting from START (with numeric contagion 64 64 from STEP applied), each consequtive number being the sum of the previous one 65 and STEP. START defaults to 0 and STEP to 0. Returns N.65 and STEP. START defaults to 0 and STEP to 1. Returns N. 66 66 67 67 Examples: 68 68 69 (iota 4) => (0 1 2 3 4) 70 (iota 3 :start 1 :step 1.0) => (1.0 2.0 3.0) 71 (iota 3 :start -1 :step -1/2) => (-1 -3/2 -2) 69 (map-iota #'print 3 :start 1 :step 1.0) => 3 70 ;;; 1.0 71 ;;; 2.0 72 ;;; 3.0 72 73 " 73 74 (declare (type (integer 0) n) (number start step)) trunk/thirdparty/alexandria/_darcs/pristine/package.lisp
r2190 r3200 13 13 #:cswitch 14 14 #:eswitch 15 #:nth-value-or 15 16 #:switch 16 17 #:whichever … … 19 20 #:alist-hash-table 20 21 #:copy-hash-table 22 #:ensure-gethash 21 23 #:hash-table-alist 22 24 #:hash-table-keys … … 38 40 #:alist-plist 39 41 #:appendf 42 #:nconcf 40 43 #:circular-list 41 44 #:circular-list-p 42 45 #:circular-tree-p 46 #:doplist 43 47 #:ensure-car 44 48 #:ensure-cons … … 90 94 #:map-combinations 91 95 #:map-derangements 92 #:map-permu ations96 #:map-permutations 93 97 #:proper-sequence 94 98 #:random-elt … … 96 100 #:rotate 97 101 #:sequence-of-length-p 102 #:length= 98 103 #:shuffle 99 104 #:starts-with … … 114 119 #:of-type 115 120 #:type= 116 ;; Errors 121 #:coercef 122 ;; Conditions 117 123 #:required-argument 124 #:ignore-some-conditions 118 125 #:simple-style-warning 126 #:simple-reader-error 127 #:simple-parse-error 128 #:unwind-protect-case 129 ;; Features 130 #:featurep 119 131 )) trunk/thirdparty/alexandria/_darcs/pristine/sequences.lisp
r2190 r3200 1 1 (in-package :alexandria) 2 3 ;; Make these inlinable by declaiming them INLINE here and some of them 4 ;; NOTINLINE at the end of the file. Exclude functions that have a compiler 5 ;; macro, because inlining seems to cancel compiler macros (at least on SBCL). 6 (declaim (inline copy-sequence sequence-of-length-p)) 2 7 3 8 (defun rotate-tail-to-head (sequence n) … … 52 57 (defun shuffle (sequence &key (start 0) end) 53 58 "Returns a random permutation of SEQUENCE bounded by START and END. 54 Permuted sequence may share storage with the original one. Signals 55 anerror if SEQUENCE is not a proper sequence."59 Permuted sequence may share storage with the original one. Signals an 60 error if SEQUENCE is not a proper sequence." 56 61 (declare (fixnum start) (type (or fixnum null) end)) 57 (let ((end (or end (if (listp sequence) (list-length sequence) (length sequence))))) 58 (loop for i from start below end 59 do (rotatef (elt sequence i) (elt sequence (random end))))) 62 (typecase sequence 63 (list 64 (let* ((end (or end (list-length sequence))) 65 (n (- end start))) 66 (do ((tail (nthcdr start sequence) (cdr tail))) 67 ((zerop n)) 68 (rotatef (car tail) (car (nthcdr (random n) tail))) 69 (decf n)))) 70 (vector 71 (let ((end (or end (length sequence)))) 72 (loop for i from (- end 1) downto start 73 do (rotatef (aref sequence i) (aref sequence (random (+ i 1))))))) 74 (sequence 75 (let ((end (or end (length sequence)))) 76 (loop for i from (- end 1) downto start 77 do (rotatef (elt sequence i) (elt sequence (random (+ i 1)))))))) 60 78 sequence) 61 79 … … 70 88 (elt sequence i))) 71 89 90 (declaim (inline remove/swapped-arguments)) 91 (defun remove/swapped-arguments (sequence item &rest keyword-arguments) 92 (apply #'remove item sequence keyword-arguments)) 93 72 94 (define-modify-macro removef (item &rest remove-keywords) 73 (lambda (seq item &rest keyword-arguments) 74 (apply #'remove item seq keyword-arguments)) 95 remove/swapped-arguments 75 96 "Modify-macro for REMOVE. Sets place designated by the first argument to 76 97 the result of calling REMOVE with ITEM, place, and the REMOVE-KEYWORDS.") 77 98 99 (declaim (inline delete/swapped-arguments)) 100 (defun delete/swapped-arguments (sequence item &rest keyword-arguments) 101 (apply #'delete item sequence keyword-arguments)) 102 78 103 (define-modify-macro deletef (item &rest remove-keywords) 79 (lambda (seq item &rest keyword-arguments) 80 (apply #'delete item seq keyword-arguments)) 104 delete/swapped-arguments 81 105 "Modify-macro for DELETE. Sets place designated by the first argument to 82 106 the result of calling DELETE with ITEM, place, and the REMOVE-KEYWORDS.") … … 95 119 (sequence (zerop (length sequence))))) 96 120 121 (defun length= (&rest sequences) 122 "Takes any number of sequences or integers in any order. Returns true iff 123 the length of all the sequences and the integers are equal. Hint: there's a 124 compiler macro that expands into more efficient code if the first argument 125 is a literal integer." 126 (declare (dynamic-extent sequences) 127 (inline sequence-of-length-p) 128 (optimize speed)) 129 (unless (cdr sequences) 130 (error "You must call LENGTH= with at least two arguments")) 131 ;; There's room for optimization here: multiple list arguments could be 132 ;; traversed in parallel. 133 (let* ((first (pop sequences)) 134 (current (if (integerp first) 135 first 136 (length first)))) 137 (declare (type array-index current)) 138 (dolist (el sequences) 139 (if (integerp el) 140 (unless (= el current) 141 (return-from length= nil)) 142 (unless (sequence-of-length-p el current) 143 (return-from length= nil))))) 144 t) 145 146 (define-compiler-macro length= (&whole form length &rest sequences) 147 (cond 148 ((zerop (length sequences)) 149 form) 150 (t 151 (let ((optimizedp (integerp length))) 152 (with-unique-names (tmp current) 153 (declare (ignorable current)) 154 `(locally 155 (declare (inline sequence-of-length-p)) 156 (let ((,tmp) 157 ,@(unless optimizedp 158 `((,current ,length)))) 159 ,@(unless optimizedp 160 `((unless (integerp ,current) 161 (setf ,current (length ,current))))) 162 (and 163 ,@(loop 164 :for sequence :in sequences 165 :collect `(progn 166 (setf ,tmp ,sequence) 167 (if (integerp ,tmp) 168 (= ,tmp ,(if optimizedp 169 length 170 current)) 171 (sequence-of-length-p ,tmp ,(if optimizedp 172 length 173 current))))))))))))) 174 97 175 (defun sequence-of-length-p (sequence length) 98 176 "Return true if SEQUENCE is a sequence of length LENGTH. Signals an error if 99 177 SEQUENCE is not a sequence. Returns FALSE for circular lists." 178 (declare (type array-index length) 179 (inline length) 180 (optimize speed)) 100 181 (etypecase sequence 101 182 (null … … 105 186 (unless (minusp n) 106 187 (let ((tail (nthcdr n sequence))) 107 (and tail (null (cdr tail))))))) 188 (and tail 189 (null (cdr tail))))))) 190 (vector 191 (= length (length sequence))) 108 192 (sequence 109 193 (= length (length sequence))))) 110 194 111 (declaim (inline copy-sequence))112 195 (defun copy-sequence (type sequence) 113 196 "Returns a fresh sequence of TYPE, which has the same elements as … … 174 257 :expected-type '(and proper-sequence (not (satisfies emptyp)))))))) 175 258 176 (defun starts-with-subseq ( sequence prefix&rest args &key (return-suffix nil) &allow-other-keys)259 (defun starts-with-subseq (prefix sequence &rest args &key (return-suffix nil) &allow-other-keys) 177 260 "Test whether the first elements of SEQUENCE are the same (as per TEST) as the elements of PREFIX. 178 261 … …
