diff options
| author | Jim Blandy | 1992-11-07 06:11:16 +0000 |
|---|---|---|
| committer | Jim Blandy | 1992-11-07 06:11:16 +0000 |
| commit | 0761aafc4586a806cc7b9d341f52957239c3e235 (patch) | |
| tree | 714e47a7d6e1e3f86f621f691423c8a94772faf0 /lisp | |
| parent | 448933608477ddfb8158097cfc6dca62ad8d7b88 (diff) | |
| download | emacs-0761aafc4586a806cc7b9d341f52957239c3e235.tar.gz emacs-0761aafc4586a806cc7b9d341f52957239c3e235.zip | |
* cl.el: New version - 3.0 - from Cesar Quiroz.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/cl.el | 601 |
1 files changed, 359 insertions, 242 deletions
diff --git a/lisp/cl.el b/lisp/cl.el index 22fda0f4b94..f8de1550561 100644 --- a/lisp/cl.el +++ b/lisp/cl.el | |||
| @@ -1,11 +1,10 @@ | |||
| 1 | ;;; cl.el --- Common-Lisp extensions for GNU Emacs Lisp. | 1 | ;; Common-Lisp extensions for GNU Emacs Lisp. |
| 2 | 2 | ;; Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc. | |
| 3 | ;; Copyright (C) 1987, 1988, 1989 Free Software Foundation, Inc. | ||
| 4 | 3 | ||
| 5 | ;; Author: Cesar Quiroz <quiroz@cs.rochester.edu> | 4 | ;; Author: Cesar Quiroz <quiroz@cs.rochester.edu> |
| 6 | ;; Keywords: extensions | 5 | ;; Keywords: extensions |
| 7 | 6 | ||
| 8 | (defvar cl-version "2.0 beta 29 October 1989") | 7 | (defvar cl-version "3.0 beta 01 November 1992") |
| 9 | 8 | ||
| 10 | ;; This file is part of GNU Emacs. | 9 | ;; This file is part of GNU Emacs. |
| 11 | 10 | ||
| @@ -24,6 +23,29 @@ | |||
| 24 | ;; file named COPYING. Among other things, the copyright notice | 23 | ;; file named COPYING. Among other things, the copyright notice |
| 25 | ;; and this notice must be preserved on all copies. | 24 | ;; and this notice must be preserved on all copies. |
| 26 | 25 | ||
| 26 | ;;; Notes from Rob Austein on his mods | ||
| 27 | ;; yaya:/usr/u/sra/cl/cl.el, 5-May-1991 16:01:34, sra | ||
| 28 | ;; | ||
| 29 | ;; Slightly hacked copy of cl.el 2.0 beta 27. | ||
| 30 | ;; | ||
| 31 | ;; Various minor performance improvements: | ||
| 32 | ;; a) Don't use MAPCAR when we're going to discard its results. | ||
| 33 | ;; b) Make various macros a little more clever about optimizing | ||
| 34 | ;; generated code in common cases. | ||
| 35 | ;; c) Fix DEFSETF to expand to the right code at compile-time. | ||
| 36 | ;; d) Make various macros cleverer about generating reasonable | ||
| 37 | ;; code when compiled, particularly forms like DEFSTRUCT which | ||
| 38 | ;; are usually used at top-level and thus are only compiled if | ||
| 39 | ;; you use Hallvard Furuseth's hacked bytecomp.el. | ||
| 40 | ;; | ||
| 41 | ;; New features: GETF, REMF, and REMPROP. | ||
| 42 | ;; | ||
| 43 | ;; Notes: | ||
| 44 | ;; 1) I'm sceptical about the FBOUNDP checks in SETF. Why should | ||
| 45 | ;; the SETF expansion fail because the SETF method isn't defined | ||
| 46 | ;; at compile time? Lisp is going to check for a binding at run-time | ||
| 47 | ;; anyway, so maybe we should just assume the user's right here. | ||
| 48 | |||
| 27 | ;;; Commentary: | 49 | ;;; Commentary: |
| 28 | 50 | ||
| 29 | ;;;; These are extensions to Emacs Lisp that provide some form of | 51 | ;;;; These are extensions to Emacs Lisp that provide some form of |
| @@ -47,6 +69,9 @@ | |||
| 47 | ;;;; the files are concatenated together one cannot ensure that | 69 | ;;;; the files are concatenated together one cannot ensure that |
| 48 | ;;;; declaration always precedes use. | 70 | ;;;; declaration always precedes use. |
| 49 | ;;;; | 71 | ;;;; |
| 72 | ;;;; Bug reports, suggestions and comments, | ||
| 73 | ;;;; to quiroz@cs.rochester.edu | ||
| 74 | |||
| 50 | 75 | ||
| 51 | ;;;; GLOBAL | 76 | ;;;; GLOBAL |
| 52 | ;;;; This file provides utilities and declarations that are global | 77 | ;;;; This file provides utilities and declarations that are global |
| @@ -64,29 +89,23 @@ | |||
| 64 | 89 | ||
| 65 | ;;; Code: | 90 | ;;; Code: |
| 66 | 91 | ||
| 67 | (defmacro psetq (&rest body) | 92 | ;;; This version is due to Hallvard Furuseth (hallvard@ifi.uio.no, 6 Jul 91) |
| 68 | "(psetq {var value }...) => nil | 93 | (defmacro psetq (&rest args) |
| 69 | Like setq, but all the values are computed before any assignment is made." | 94 | "(psetq {VARIABLE VALUE}...): In parallel, set each VARIABLE to its VALUE. |
| 70 | (let ((length (length body))) | 95 | All the VALUEs are evaluated, and then all the VARIABLEs are set. |
| 71 | (cond ((/= (% length 2) 0) | 96 | Aside from order of evaluation, this is the same as `setq'." |
| 72 | (error "psetq needs an even number of arguments, %d given" | 97 | ;; check there is a reasonable number of forms |
| 73 | length)) | 98 | (if (/= (% (length args) 2) 0) |
| 74 | ((null body) | 99 | (error "Odd number of arguments to `psetq'")) |
| 75 | '()) | 100 | (setq args (copy-sequence args)) ;for safety below |
| 76 | (t | 101 | (prog1 (cons 'setq args) |
| 77 | (list 'prog1 nil | 102 | (while (progn (if (not (symbolp (car args))) |
| 78 | (let ((setqs '()) | 103 | (error "`psetq' expected a symbol, found '%s'." |
| 79 | (bodyforms (reverse body))) | 104 | (prin1-to-string (car args)))) |
| 80 | (while bodyforms | 105 | (cdr (cdr args))) |
| 81 | (let* ((value (car bodyforms)) | 106 | (setcdr args (list (list 'prog1 (nth 1 args) |
| 82 | (place (cadr bodyforms))) | 107 | (cons 'setq |
| 83 | (setq bodyforms (cddr bodyforms)) | 108 | (setq args (cdr (cdr args)))))))))) |
| 84 | (if (null setqs) | ||
| 85 | (setq setqs (list 'setq place value)) | ||
| 86 | (setq setqs (list 'setq place | ||
| 87 | (list 'prog1 value | ||
| 88 | setqs)))))) | ||
| 89 | setqs)))))) | ||
| 90 | 109 | ||
| 91 | ;;; utilities | 110 | ;;; utilities |
| 92 | ;;; | 111 | ;;; |
| @@ -111,8 +130,8 @@ symbols, the pairings list and the newsyms list are returned." | |||
| 111 | (defun zip-lists (evens odds) | 130 | (defun zip-lists (evens odds) |
| 112 | "Merge two lists EVENS and ODDS, taking elts from each list alternatingly. | 131 | "Merge two lists EVENS and ODDS, taking elts from each list alternatingly. |
| 113 | EVENS and ODDS are two lists. ZIP-LISTS constructs a new list, whose | 132 | EVENS and ODDS are two lists. ZIP-LISTS constructs a new list, whose |
| 114 | even numbered elements (0,2,...) come from EVENS and whose odd numbered | 133 | even numbered elements (0,2,...) come from EVENS and whose odd |
| 115 | elements (1,3,...) come from ODDS. | 134 | numbered elements (1,3,...) come from ODDS. |
| 116 | The construction stops when the shorter list is exhausted." | 135 | The construction stops when the shorter list is exhausted." |
| 117 | (do* ((p0 evens (cdr p0)) | 136 | (do* ((p0 evens (cdr p0)) |
| 118 | (p1 odds (cdr p1)) | 137 | (p1 odds (cdr p1)) |
| @@ -164,9 +183,11 @@ shortest list is exhausted." | |||
| 164 | ;;; larger lists. The fourth pass could be eliminated. | 183 | ;;; larger lists. The fourth pass could be eliminated. |
| 165 | ;;; 10 dec 1986. Emacs Lisp has no REMPROP, so I just eliminated the | 184 | ;;; 10 dec 1986. Emacs Lisp has no REMPROP, so I just eliminated the |
| 166 | ;;; 4th pass. | 185 | ;;; 4th pass. |
| 186 | ;;; | ||
| 187 | ;;; [22 April 1991, sra] REMPROP now in library, so restored 4th pass. | ||
| 167 | (defun duplicate-symbols-p (list) | 188 | (defun duplicate-symbols-p (list) |
| 168 | "Find all symbols appearing more than once in LIST. | 189 | "Find all symbols appearing more than once in LIST. |
| 169 | Return a list of all such duplicates; nil if there are no duplicates." | 190 | Return a list of all such duplicates; `nil' if there are no duplicates." |
| 170 | (let ((duplicates '()) ;result built here | 191 | (let ((duplicates '()) ;result built here |
| 171 | (propname (gensym)) ;we use a fresh property | 192 | (propname (gensym)) ;we use a fresh property |
| 172 | ) | 193 | ) |
| @@ -184,8 +205,9 @@ Return a list of all such duplicates; nil if there are no duplicates." | |||
| 184 | (dolist (x list) | 205 | (dolist (x list) |
| 185 | (if (> (get x propname) 1) | 206 | (if (> (get x propname) 1) |
| 186 | (setq duplicates (cons x duplicates)))) | 207 | (setq duplicates (cons x duplicates)))) |
| 187 | ;; pass 4: unmark. eliminated. | 208 | ;; pass 4: unmark. |
| 188 | ;; (dolist (x list) (remprop x propname)) | 209 | (dolist (x list) |
| 210 | (remprop x propname)) | ||
| 189 | ;; return result | 211 | ;; return result |
| 190 | duplicates)) | 212 | duplicates)) |
| 191 | 213 | ||
| @@ -203,14 +225,14 @@ Return a list of all such duplicates; nil if there are no duplicates." | |||
| 203 | 225 | ||
| 204 | (defmacro defkeyword (x &optional docstring) | 226 | (defmacro defkeyword (x &optional docstring) |
| 205 | "Make symbol X a keyword (symbol whose value is itself). | 227 | "Make symbol X a keyword (symbol whose value is itself). |
| 206 | Optional second arg DOCSTRING is a documentation string for it." | 228 | Optional second argument is a documentation string for it." |
| 207 | (cond ((symbolp x) | 229 | (cond ((symbolp x) |
| 208 | (list 'defconst x (list 'quote x) docstring)) | 230 | (list 'defconst x (list 'quote x) docstring)) |
| 209 | (t | 231 | (t |
| 210 | (error "`%s' is not a symbol" (prin1-to-string x))))) | 232 | (error "`%s' is not a symbol" (prin1-to-string x))))) |
| 211 | 233 | ||
| 212 | (defun keywordp (sym) | 234 | (defun keywordp (sym) |
| 213 | "Return t if SYM is a keyword." | 235 | "t if SYM is a keyword." |
| 214 | (if (and (symbolp sym) (char-equal (aref (symbol-name sym) 0) ?\:)) | 236 | (if (and (symbolp sym) (char-equal (aref (symbol-name sym) 0) ?\:)) |
| 215 | ;; looks like one, make sure value is right | 237 | ;; looks like one, make sure value is right |
| 216 | (set sym sym) | 238 | (set sym sym) |
| @@ -232,17 +254,17 @@ Otherwise it is a keyword whose name is `:' followed by SYM's name." | |||
| 232 | ;;; | 254 | ;;; |
| 233 | 255 | ||
| 234 | (defvar *gentemp-index* 0 | 256 | (defvar *gentemp-index* 0 |
| 235 | "Integer used by `gentemp' to produce new names.") | 257 | "Integer used by gentemp to produce new names.") |
| 236 | 258 | ||
| 237 | (defvar *gentemp-prefix* "T$$_" | 259 | (defvar *gentemp-prefix* "T$$_" |
| 238 | "Names generated by `gentemp begin' with this string by default.") | 260 | "Names generated by gentemp begin with this string by default.") |
| 239 | 261 | ||
| 240 | (defun gentemp (&optional prefix oblist) | 262 | (defun gentemp (&optional prefix oblist) |
| 241 | "Generate a fresh interned symbol. | 263 | "Generate a fresh interned symbol. |
| 242 | There are two optional arguments, PREFIX and OBLIST. PREFIX is the string | 264 | There are 2 optional arguments, PREFIX and OBLIST. PREFIX is the |
| 243 | that begins the new name, OBLIST is the obarray used to search for old | 265 | string that begins the new name, OBLIST is the obarray used to search for |
| 244 | names. The defaults are just right, YOU SHOULD NEVER NEED THESE ARGUMENTS | 266 | old names. The defaults are just right, YOU SHOULD NEVER NEED THESE |
| 245 | IN YOUR OWN CODE." | 267 | ARGUMENTS IN YOUR OWN CODE." |
| 246 | (if (null prefix) | 268 | (if (null prefix) |
| 247 | (setq prefix *gentemp-prefix*)) | 269 | (setq prefix *gentemp-prefix*)) |
| 248 | (if (null oblist) | 270 | (if (null oblist) |
| @@ -257,15 +279,16 @@ IN YOUR OWN CODE." | |||
| 257 | newsymbol)) | 279 | newsymbol)) |
| 258 | 280 | ||
| 259 | (defvar *gensym-index* 0 | 281 | (defvar *gensym-index* 0 |
| 260 | "Integer used by `gensym' to produce new names.") | 282 | "Integer used by gensym to produce new names.") |
| 261 | 283 | ||
| 262 | (defvar *gensym-prefix* "G$$_" | 284 | (defvar *gensym-prefix* "G$$_" |
| 263 | "Names generated by `gensym' begin with this string by default.") | 285 | "Names generated by gensym begin with this string by default.") |
| 264 | 286 | ||
| 265 | (defun gensym (&optional prefix) | 287 | (defun gensym (&optional prefix) |
| 266 | "Generate a fresh uninterned symbol. | 288 | "Generate a fresh uninterned symbol. |
| 267 | Optional arg PREFIX is the string that begins the new name. Most people | 289 | There is an optional argument, PREFIX. PREFIX is the |
| 268 | take just the default, except when debugging needs suggest otherwise." | 290 | string that begins the new name. Most people take just the default, |
| 291 | except when debugging needs suggest otherwise." | ||
| 269 | (if (null prefix) | 292 | (if (null prefix) |
| 270 | (setq prefix *gensym-prefix*)) | 293 | (setq prefix *gensym-prefix*)) |
| 271 | (let ((newsymbol nil) | 294 | (let ((newsymbol nil) |
| @@ -289,10 +312,10 @@ take just the default, except when debugging needs suggest otherwise." | |||
| 289 | ;;;; (quiroz@cs.rochester.edu) | 312 | ;;;; (quiroz@cs.rochester.edu) |
| 290 | 313 | ||
| 291 | ;;; indentation info | 314 | ;;; indentation info |
| 292 | (put 'case 'lisp-indent-function 1) | 315 | (put 'case 'lisp-indent-hook 1) |
| 293 | (put 'ecase 'lisp-indent-function 1) | 316 | (put 'ecase 'lisp-indent-hook 1) |
| 294 | (put 'when 'lisp-indent-function 1) | 317 | (put 'when 'lisp-indent-hook 1) |
| 295 | (put 'unless 'lisp-indent-function 1) | 318 | (put 'unless 'lisp-indent-hook 1) |
| 296 | 319 | ||
| 297 | ;;; WHEN and UNLESS | 320 | ;;; WHEN and UNLESS |
| 298 | ;;; These two forms are simplified ifs, with a single branch. | 321 | ;;; These two forms are simplified ifs, with a single branch. |
| @@ -408,29 +431,26 @@ reverse order." | |||
| 408 | ;;;; (quiroz@cs.rochester.edu) | 431 | ;;;; (quiroz@cs.rochester.edu) |
| 409 | 432 | ||
| 410 | ;;; some lisp-indentation information | 433 | ;;; some lisp-indentation information |
| 411 | (put 'do 'lisp-indent-function 2) | 434 | (put 'do 'lisp-indent-hook 2) |
| 412 | (put 'do* 'lisp-indent-function 2) | 435 | (put 'do* 'lisp-indent-hook 2) |
| 413 | (put 'dolist 'lisp-indent-function 1) | 436 | (put 'dolist 'lisp-indent-hook 1) |
| 414 | (put 'dotimes 'lisp-indent-function 1) | 437 | (put 'dotimes 'lisp-indent-hook 1) |
| 415 | (put 'do-symbols 'lisp-indent-function 1) | 438 | (put 'do-symbols 'lisp-indent-hook 1) |
| 416 | (put 'do-all-symbols 'lisp-indent-function 1) | 439 | (put 'do-all-symbols 'lisp-indent-hook 1) |
| 417 | 440 | ||
| 418 | 441 | ||
| 419 | (defmacro do (stepforms endforms &rest body) | 442 | (defmacro do (stepforms endforms &rest body) |
| 420 | "(do STEPFORMS ENDFORMS . BODY): Iterate BODY, stepping some local | 443 | "(do STEPFORMS ENDFORMS . BODY): Iterate BODY, stepping some local variables. |
| 421 | variables. STEPFORMS must be a list of symbols or lists. In the second | 444 | STEPFORMS must be a list of symbols or lists. In the second case, the |
| 422 | case, the lists must start with a symbol and contain up to two more forms. | 445 | lists must start with a symbol and contain up to two more forms. In |
| 423 | In the STEPFORMS, a symbol is the same as a (symbol). The other two forms | 446 | the STEPFORMS, a symbol is the same as a (symbol). The other 2 forms |
| 424 | are the initial value (def. NIL) and the form to step (def. itself). | 447 | are the initial value (def. NIL) and the form to step (def. itself). |
| 425 | |||
| 426 | The values used by initialization and stepping are computed in parallel. | 448 | The values used by initialization and stepping are computed in parallel. |
| 427 | The ENDFORMS are a list (CONDITION . ENDBODY). If the CONDITION evaluates | 449 | The ENDFORMS are a list (CONDITION . ENDBODY). If the CONDITION |
| 428 | to true in any iteration, ENDBODY is evaluated and the last form in it is | 450 | evaluates to true in any iteration, ENDBODY is evaluated and the last |
| 429 | returned. | 451 | form in it is returned. |
| 430 | 452 | The BODY (which may be empty) is evaluated at every iteration, with | |
| 431 | The BODY (which may be empty) is evaluated at every iteration, with the | 453 | the symbols of the STEPFORMS bound to the initial or stepped values." |
| 432 | symbols of the STEPFORMS bound to the initial or stepped values." | ||
| 433 | |||
| 434 | ;; check the syntax of the macro | 454 | ;; check the syntax of the macro |
| 435 | (and (check-do-stepforms stepforms) | 455 | (and (check-do-stepforms stepforms) |
| 436 | (check-do-endforms endforms)) | 456 | (check-do-endforms endforms)) |
| @@ -448,16 +468,13 @@ symbols of the STEPFORMS bound to the initial or stepped values." | |||
| 448 | (defmacro do* (stepforms endforms &rest body) | 468 | (defmacro do* (stepforms endforms &rest body) |
| 449 | "`do*' is to `do' as `let*' is to `let'. | 469 | "`do*' is to `do' as `let*' is to `let'. |
| 450 | STEPFORMS must be a list of symbols or lists. In the second case, the | 470 | STEPFORMS must be a list of symbols or lists. In the second case, the |
| 451 | lists must start with a symbol and contain up to two more forms. In the | 471 | lists must start with a symbol and contain up to two more forms. In |
| 452 | STEPFORMS, a symbol is the same as a (symbol). The other two forms are | 472 | the STEPFORMS, a symbol is the same as a (symbol). The other 2 forms |
| 453 | the initial value (def. NIL) and the form to step (def. itself). | 473 | are the initial value (def. NIL) and the form to step (def. itself). |
| 454 | |||
| 455 | Initializations and steppings are done in the sequence they are written. | 474 | Initializations and steppings are done in the sequence they are written. |
| 456 | 475 | The ENDFORMS are a list (CONDITION . ENDBODY). If the CONDITION | |
| 457 | The ENDFORMS are a list (CONDITION . ENDBODY). If the CONDITION evaluates | 476 | evaluates to true in any iteration, ENDBODY is evaluated and the last |
| 458 | to true in any iteration, ENDBODY is evaluated and the last form in it is | 477 | form in it is returned. |
| 459 | returned. | ||
| 460 | |||
| 461 | The BODY (which may be empty) is evaluated at every iteration, with | 478 | The BODY (which may be empty) is evaluated at every iteration, with |
| 462 | the symbols of the STEPFORMS bound to the initial or stepped values." | 479 | the symbols of the STEPFORMS bound to the initial or stepped values." |
| 463 | ;; check the syntax of the macro | 480 | ;; check the syntax of the macro |
| @@ -501,8 +518,7 @@ the symbols of the STEPFORMS bound to the initial or stepped values." | |||
| 501 | 518 | ||
| 502 | (defun extract-do-inits (forms) | 519 | (defun extract-do-inits (forms) |
| 503 | "Returns a list of the initializations (for do) in FORMS | 520 | "Returns a list of the initializations (for do) in FORMS |
| 504 | (a stepforms, see the do macro). | 521 | --a stepforms, see the do macro--. FORMS is assumed syntactically valid." |
| 505 | FORMS is assumed syntactically valid." | ||
| 506 | (mapcar | 522 | (mapcar |
| 507 | (function | 523 | (function |
| 508 | (lambda (entry) | 524 | (lambda (entry) |
| @@ -516,15 +532,17 @@ FORMS is assumed syntactically valid." | |||
| 516 | ;;; DO*. The writing of PSETQ has made it largely unnecessary. | 532 | ;;; DO*. The writing of PSETQ has made it largely unnecessary. |
| 517 | 533 | ||
| 518 | (defun extract-do-steps (forms) | 534 | (defun extract-do-steps (forms) |
| 519 | "EXTRACT-DO-STEPS FORMS => an s-expr. | 535 | "EXTRACT-DO-STEPS FORMS => an s-expr |
| 520 | FORMS is the stepforms part of a DO macro (q.v.). This function constructs | 536 | FORMS is the stepforms part of a DO macro (q.v.). This function |
| 521 | an s-expression that does the stepping at the end of an iteration." | 537 | constructs an s-expression that does the stepping at the end of an |
| 538 | iteration." | ||
| 522 | (list (cons 'psetq (select-stepping-forms forms)))) | 539 | (list (cons 'psetq (select-stepping-forms forms)))) |
| 523 | 540 | ||
| 524 | (defun extract-do*-steps (forms) | 541 | (defun extract-do*-steps (forms) |
| 525 | "EXTRACT-DO*-STEPS FORMS => an s-expr. | 542 | "EXTRACT-DO*-STEPS FORMS => an s-expr |
| 526 | FORMS is the stepforms part of a DO* macro (q.v.). This function constructs | 543 | FORMS is the stepforms part of a DO* macro (q.v.). This function |
| 527 | an s-expression that does the stepping at the end of an iteration." | 544 | constructs an s-expression that does the stepping at the end of an |
| 545 | iteration." | ||
| 528 | (list (cons 'setq (select-stepping-forms forms)))) | 546 | (list (cons 'setq (select-stepping-forms forms)))) |
| 529 | 547 | ||
| 530 | (defun select-stepping-forms (forms) | 548 | (defun select-stepping-forms (forms) |
| @@ -546,8 +564,8 @@ an s-expression that does the stepping at the end of an iteration." | |||
| 546 | 564 | ||
| 547 | (defmacro dolist (stepform &rest body) | 565 | (defmacro dolist (stepform &rest body) |
| 548 | "(dolist (VAR LIST [RESULTFORM]) . BODY): do BODY for each elt of LIST. | 566 | "(dolist (VAR LIST [RESULTFORM]) . BODY): do BODY for each elt of LIST. |
| 549 | The RESULTFORM defaults to nil. The VAR is bound to successive elements | 567 | The RESULTFORM defaults to nil. The VAR is bound to successive |
| 550 | of the value of LIST and remains bound (to the nil value) when the | 568 | elements of the value of LIST and remains bound (to the nil value) when the |
| 551 | RESULTFORM is evaluated." | 569 | RESULTFORM is evaluated." |
| 552 | ;; check sanity | 570 | ;; check sanity |
| 553 | (cond | 571 | (cond |
| @@ -563,23 +581,27 @@ RESULTFORM is evaluated." | |||
| 563 | ;; generate code | 581 | ;; generate code |
| 564 | (let* ((var (car stepform)) | 582 | (let* ((var (car stepform)) |
| 565 | (listform (cadr stepform)) | 583 | (listform (cadr stepform)) |
| 566 | (resultform (caddr stepform))) | 584 | (resultform (caddr stepform)) |
| 567 | (list 'progn | 585 | (listsym (gentemp))) |
| 568 | (list 'mapcar | 586 | (nconc |
| 569 | (list 'function | 587 | (list 'let (list var (list listsym listform)) |
| 570 | (cons 'lambda (cons (list var) body))) | 588 | (nconc |
| 571 | listform) | 589 | (list 'while listsym |
| 572 | (list 'let | 590 | (list 'setq |
| 573 | (list (list var nil)) | 591 | var (list 'car listsym) |
| 574 | resultform)))) | 592 | listsym (list 'cdr listsym))) |
| 593 | body)) | ||
| 594 | (and resultform | ||
| 595 | (cons (list 'setq var nil) | ||
| 596 | (list resultform)))))) | ||
| 575 | 597 | ||
| 576 | (defmacro dotimes (stepform &rest body) | 598 | (defmacro dotimes (stepform &rest body) |
| 577 | "(dotimes (VAR COUNTFORM [RESULTFORM]) . BODY): Repeat BODY, counting in VAR. | 599 | "(dotimes (VAR COUNTFORM [RESULTFORM]) . BODY): Repeat BODY, counting in VAR. |
| 578 | The COUNTFORM should return a positive integer. The VAR is bound to | 600 | The COUNTFORM should return a positive integer. The VAR is bound to |
| 579 | successive integers from 0 to COUNTFORM - 1 and the BODY is repeated for | 601 | successive integers from 0 to COUNTFORM-1 and the BODY is repeated for |
| 580 | each of them. At the end, the RESULTFORM is evaluated and its value | 602 | each of them. At the end, the RESULTFORM is evaluated and its value |
| 581 | returned. During this last evaluation, the VAR is still bound, and its | 603 | returned. During this last evaluation, the VAR is still bound, and its |
| 582 | value is the number of times the iteration occurred. An omitted RESULTFORM | 604 | value is the number of times the iteration occurred. An omitted RESULTFORM |
| 583 | defaults to nil." | 605 | defaults to nil." |
| 584 | ;; check sanity | 606 | ;; check sanity |
| 585 | (cond | 607 | (cond |
| @@ -596,14 +618,16 @@ defaults to nil." | |||
| 596 | (let* ((var (car stepform)) | 618 | (let* ((var (car stepform)) |
| 597 | (countform (cadr stepform)) | 619 | (countform (cadr stepform)) |
| 598 | (resultform (caddr stepform)) | 620 | (resultform (caddr stepform)) |
| 599 | (newsym (gentemp))) | 621 | (testsym (if (consp countform) (gentemp) countform))) |
| 622 | (nconc | ||
| 600 | (list | 623 | (list |
| 601 | 'let* (list (list newsym countform)) | 624 | 'let (cons (list var -1) |
| 602 | (list* | 625 | (and (not (eq countform testsym)) |
| 603 | 'do* | 626 | (list (list testsym countform)))) |
| 604 | (list (list var 0 (list '+ var 1))) | 627 | (nconc |
| 605 | (list (list '>= var newsym) resultform) | 628 | (list 'while (list '< (list 'setq var (list '1+ var)) testsym)) |
| 606 | body)))) | 629 | body)) |
| 630 | (and resultform (list resultform))))) | ||
| 607 | 631 | ||
| 608 | (defmacro do-symbols (stepform &rest body) | 632 | (defmacro do-symbols (stepform &rest body) |
| 609 | "(do_symbols (VAR [OBARRAY [RESULTFORM]]) . BODY) | 633 | "(do_symbols (VAR [OBARRAY [RESULTFORM]]) . BODY) |
| @@ -671,11 +695,6 @@ The forms in BODY should be lists, as non-lists are reserved for new features." | |||
| 671 | ;;;; Cesar Quiroz @ UofR DofCSc - Dec. 1986 | 695 | ;;;; Cesar Quiroz @ UofR DofCSc - Dec. 1986 |
| 672 | ;;;; (quiroz@cs.rochester.edu) | 696 | ;;;; (quiroz@cs.rochester.edu) |
| 673 | 697 | ||
| 674 | |||
| 675 | |||
| 676 | ;;; To make these faster, we define them using defsubst. This directs the | ||
| 677 | ;;; compiler to open-code these functions. | ||
| 678 | |||
| 679 | ;;; Synonyms for list functions | 698 | ;;; Synonyms for list functions |
| 680 | (defsubst first (x) | 699 | (defsubst first (x) |
| 681 | "Synonym for `car'" | 700 | "Synonym for `car'" |
| @@ -721,7 +740,7 @@ The forms in BODY should be lists, as non-lists are reserved for new features." | |||
| 721 | "Synonym for `cdr'" | 740 | "Synonym for `cdr'" |
| 722 | (cdr x)) | 741 | (cdr x)) |
| 723 | 742 | ||
| 724 | (defun endp (x) | 743 | (defsubst endp (x) |
| 725 | "t if X is nil, nil if X is a cons; error otherwise." | 744 | "t if X is nil, nil if X is a cons; error otherwise." |
| 726 | (if (listp x) | 745 | (if (listp x) |
| 727 | (null x) | 746 | (null x) |
| @@ -758,18 +777,20 @@ The forms in BODY should be lists, as non-lists are reserved for new features." | |||
| 758 | "Return a new list like LIST but sans the last N elements. | 777 | "Return a new list like LIST but sans the last N elements. |
| 759 | N defaults to 1. If the list doesn't have N elements, nil is returned." | 778 | N defaults to 1. If the list doesn't have N elements, nil is returned." |
| 760 | (if (null n) (setq n 1)) | 779 | (if (null n) (setq n 1)) |
| 761 | (reverse (nthcdr n (reverse list)))) | 780 | (nreverse (nthcdr n (reverse list)))) ;optim. due to macrakis@osf.org |
| 762 | 781 | ||
| 782 | ;;; This version due to Aaron Larson (alarson@src.honeywell.com, 26 Jul 91) | ||
| 763 | (defun list* (arg &rest others) | 783 | (defun list* (arg &rest others) |
| 764 | "Return a new list containing the first arguments consed onto the last arg. | 784 | "Return a new list containing the first arguments consed onto the last arg. |
| 765 | Thus, (list* 1 2 3 '(a b)) returns (1 2 3 a b)." | 785 | Thus, (list* 1 2 3 '(a b)) returns (1 2 3 a b)." |
| 766 | (if (null others) | 786 | (if (null others) |
| 767 | arg | 787 | arg |
| 768 | (let* ((allargs (cons arg others)) | 788 | (let* ((others (cons arg (copy-sequence others))) |
| 769 | (front (butlast allargs)) | 789 | (a others)) |
| 770 | (back (last allargs))) | 790 | (while (cdr (cdr a)) |
| 771 | (rplacd (last front) (car back)) | 791 | (setq a (cdr a))) |
| 772 | front))) | 792 | (setcdr a (car (cdr a))) |
| 793 | others))) | ||
| 773 | 794 | ||
| 774 | (defun adjoin (item list) | 795 | (defun adjoin (item list) |
| 775 | "Return a list which contains ITEM but is otherwise like LIST. | 796 | "Return a list which contains ITEM but is otherwise like LIST. |
| @@ -790,8 +811,8 @@ SUBLIST must be one of the links in LIST; otherwise the value is LIST itself." | |||
| 790 | 811 | ||
| 791 | ;;; The popular c[ad]*r functions and other list accessors. | 812 | ;;; The popular c[ad]*r functions and other list accessors. |
| 792 | 813 | ||
| 793 | ;;; To implement this efficiently, we define them using defsubst, | 814 | ;;; To implement this efficiently, a new byte compile handler is used to |
| 794 | ;;; which directs the compiler to open-code these functions. | 815 | ;;; generate the minimal code, saving one function call. |
| 795 | 816 | ||
| 796 | (defsubst caar (X) | 817 | (defsubst caar (X) |
| 797 | "Return the car of the car of X." | 818 | "Return the car of the car of X." |
| @@ -907,25 +928,26 @@ SUBLIST must be one of the links in LIST; otherwise the value is LIST itself." | |||
| 907 | 928 | ||
| 908 | ;;; some inverses of the accessors are needed for setf purposes | 929 | ;;; some inverses of the accessors are needed for setf purposes |
| 909 | 930 | ||
| 910 | (defun setnth (n list newval) | 931 | (defsubst setnth (n list newval) |
| 911 | "Set (nth N LIST) to NEWVAL. Returns NEWVAL." | 932 | "Set (nth N LIST) to NEWVAL. Returns NEWVAL." |
| 912 | (rplaca (nthcdr n list) newval)) | 933 | (rplaca (nthcdr n list) newval)) |
| 913 | 934 | ||
| 914 | (defun setnthcdr (n list newval) | 935 | (defun setnthcdr (n list newval) |
| 915 | "(setnthcdr N LIST NEWVAL) => NEWVAL | 936 | "(setnthcdr N LIST NEWVAL) => NEWVAL |
| 916 | As a side effect, sets the Nth cdr of LIST to NEWVAL." | 937 | As a side effect, sets the Nth cdr of LIST to NEWVAL." |
| 917 | (cond ((< n 0) | 938 | (when (< n 0) |
| 918 | (error "N must be 0 or greater, not %d" n)) | 939 | (error "N must be 0 or greater, not %d" n)) |
| 919 | ((= n 0) | 940 | (while (> n 0) |
| 920 | (rplaca list (car newval)) | 941 | (setq list (cdr list) |
| 921 | (rplacd list (cdr newval)) | 942 | n (- n 1))) |
| 922 | newval) | 943 | ;; here only if (zerop n) |
| 923 | (t | 944 | (rplaca list (car newval)) |
| 924 | (rplacd (nthcdr (- n 1) list) newval)))) | 945 | (rplacd list (cdr newval)) |
| 946 | newval) | ||
| 925 | 947 | ||
| 926 | ;;; A-lists machinery | 948 | ;;; A-lists machinery |
| 927 | 949 | ||
| 928 | (defun acons (key item alist) | 950 | (defsubst acons (key item alist) |
| 929 | "Return a new alist with KEY paired with ITEM; otherwise like ALIST. | 951 | "Return a new alist with KEY paired with ITEM; otherwise like ALIST. |
| 930 | Does not copy ALIST." | 952 | Does not copy ALIST." |
| 931 | (cons (cons key item) alist)) | 953 | (cons (cons key item) alist)) |
| @@ -945,6 +967,7 @@ have the same length." | |||
| 945 | ((endp kptr) result) | 967 | ((endp kptr) result) |
| 946 | (setq result (acons key item result)))) | 968 | (setq result (acons key item result)))) |
| 947 | 969 | ||
| 970 | ;;;; end of cl-lists.el | ||
| 948 | 971 | ||
| 949 | ;;;; SEQUENCES | 972 | ;;;; SEQUENCES |
| 950 | ;;;; Emacs Lisp provides many of the 'sequences' functionality of | 973 | ;;;; Emacs Lisp provides many of the 'sequences' functionality of |
| @@ -952,18 +975,19 @@ have the same length." | |||
| 952 | ;;;; | 975 | ;;;; |
| 953 | 976 | ||
| 954 | 977 | ||
| 955 | (defkeyword :test "Used to designate positive (selection) tests.") | 978 | (defkeyword :test "Used to designate positive (selection) tests.") |
| 956 | (defkeyword :test-not "Used to designate negative (rejection) tests.") | 979 | (defkeyword :test-not "Used to designate negative (rejection) tests.") |
| 957 | (defkeyword :key "Used to designate component extractions.") | 980 | (defkeyword :key "Used to designate component extractions.") |
| 958 | (defkeyword :predicate "Used to define matching of sequence components.") | 981 | (defkeyword :predicate "Used to define matching of sequence components.") |
| 959 | (defkeyword :start "Inclusive low index in sequence") | 982 | (defkeyword :start "Inclusive low index in sequence") |
| 960 | (defkeyword :end "Exclusive high index in sequence") | 983 | (defkeyword :end "Exclusive high index in sequence") |
| 961 | (defkeyword :start1 "Inclusive low index in first of two sequences.") | 984 | (defkeyword :start1 "Inclusive low index in first of two sequences.") |
| 962 | (defkeyword :start2 "Inclusive low index in second of two sequences.") | 985 | (defkeyword :start2 "Inclusive low index in second of two sequences.") |
| 963 | (defkeyword :end1 "Exclusive high index in first of two sequences.") | 986 | (defkeyword :end1 "Exclusive high index in first of two sequences.") |
| 964 | (defkeyword :end2 "Exclusive high index in second of two sequences.") | 987 | (defkeyword :end2 "Exclusive high index in second of two sequences.") |
| 965 | (defkeyword :count "Number of elements to affect.") | 988 | (defkeyword :count "Number of elements to affect.") |
| 966 | (defkeyword :from-end "T when counting backwards.") | 989 | (defkeyword :from-end "T when counting backwards.") |
| 990 | (defkeyword :initial-value "For the syntax of #'reduce") | ||
| 967 | 991 | ||
| 968 | (defun some (pred seq &rest moreseqs) | 992 | (defun some (pred seq &rest moreseqs) |
| 969 | "Test PREDICATE on each element of SEQUENCE; is it ever non-nil? | 993 | "Test PREDICATE on each element of SEQUENCE; is it ever non-nil? |
| @@ -1195,7 +1219,7 @@ True if an -if style function was called and ITEM satisfies the | |||
| 1195 | predicate under :predicate in KLIST." | 1219 | predicate under :predicate in KLIST." |
| 1196 | (let ((predicate (extract-from-klist klist :predicate)) | 1220 | (let ((predicate (extract-from-klist klist :predicate)) |
| 1197 | (keyfn (extract-from-klist klist :key 'identity))) | 1221 | (keyfn (extract-from-klist klist :key 'identity))) |
| 1198 | (funcall predicate item (funcall keyfn elt)))) | 1222 | (funcall predicate (funcall keyfn item)))) |
| 1199 | 1223 | ||
| 1200 | (defun elt-satisfies-if-not-p (item klist) | 1224 | (defun elt-satisfies-if-not-p (item klist) |
| 1201 | "(elt-satisfies-if-not-p ITEM KLIST) => t or nil | 1225 | "(elt-satisfies-if-not-p ITEM KLIST) => t or nil |
| @@ -1204,7 +1228,7 @@ True if an -if-not style function was called and ITEM does not satisfy | |||
| 1204 | the predicate under :predicate in KLIST." | 1228 | the predicate under :predicate in KLIST." |
| 1205 | (let ((predicate (extract-from-klist klist :predicate)) | 1229 | (let ((predicate (extract-from-klist klist :predicate)) |
| 1206 | (keyfn (extract-from-klist klist :key 'identity))) | 1230 | (keyfn (extract-from-klist klist :key 'identity))) |
| 1207 | (not (funcall predicate item (funcall keyfn elt))))) | 1231 | (not (funcall predicate (funcall keyfn item))))) |
| 1208 | 1232 | ||
| 1209 | (defun elts-match-under-klist-p (e1 e2 klist) | 1233 | (defun elts-match-under-klist-p (e1 e2 klist) |
| 1210 | "(elts-match-under-klist-p E1 E2 KLIST) => t or nil | 1234 | "(elts-match-under-klist-p E1 E2 KLIST) => t or nil |
| @@ -1313,7 +1337,7 @@ if clumsier, control over this feature." | |||
| 1313 | allow-other-keys))) | 1337 | allow-other-keys))) |
| 1314 | (nreverse forms))) | 1338 | (nreverse forms))) |
| 1315 | body)))) | 1339 | body)))) |
| 1316 | (put 'with-keyword-args 'lisp-indent-function 1) | 1340 | (put 'with-keyword-args 'lisp-indent-hook 1) |
| 1317 | 1341 | ||
| 1318 | 1342 | ||
| 1319 | ;;; REDUCE | 1343 | ;;; REDUCE |
| @@ -1394,14 +1418,15 @@ returned." | |||
| 1394 | 1418 | ||
| 1395 | (defun member (item list &rest kargs) | 1419 | (defun member (item list &rest kargs) |
| 1396 | "Look for ITEM in LIST; return first tail of LIST the car of whose first | 1420 | "Look for ITEM in LIST; return first tail of LIST the car of whose first |
| 1397 | cons cell tests the same as ITEM. Admits arguments :key, :test, and :test-not." | 1421 | cons cell tests the same as ITEM. Admits arguments :key, :test, and |
| 1422 | :test-not." | ||
| 1398 | (if (null kargs) ;treat this fast for efficiency | 1423 | (if (null kargs) ;treat this fast for efficiency |
| 1399 | (memq item list) | 1424 | (memq item list) |
| 1400 | (let* ((klist (build-klist kargs '(:test :test-not :key))) | 1425 | (let* ((klist (build-klist kargs '(:test :test-not :key))) |
| 1401 | (test (extract-from-klist klist :test)) | 1426 | (test (extract-from-klist klist :test)) |
| 1402 | (testnot (extract-from-klist klist :test-not)) | 1427 | (testnot (extract-from-klist klist :test-not)) |
| 1403 | (key (extract-from-klist klist :key 'identity))) | 1428 | (key (extract-from-klist klist :key 'identity))) |
| 1404 | ;; another workaround allegledly for speed | 1429 | ;; another workaround allegedly for speed, BLAH |
| 1405 | (if (and (or (eq test 'eq) (eq test 'eql) | 1430 | (if (and (or (eq test 'eq) (eq test 'eql) |
| 1406 | (eq test (symbol-function 'eq)) | 1431 | (eq test (symbol-function 'eq)) |
| 1407 | (eq test (symbol-function 'eql))) | 1432 | (eq test (symbol-function 'eql))) |
| @@ -1448,11 +1473,11 @@ cons cell tests the same as ITEM. Admits arguments :key, :test, and :test-not." | |||
| 1448 | ;;;; (quiroz@cs.rochester.edu) | 1473 | ;;;; (quiroz@cs.rochester.edu) |
| 1449 | 1474 | ||
| 1450 | ;;; Lisp indentation information | 1475 | ;;; Lisp indentation information |
| 1451 | (put 'multiple-value-bind 'lisp-indent-function 2) | 1476 | (put 'multiple-value-bind 'lisp-indent-hook 2) |
| 1452 | (put 'multiple-value-setq 'lisp-indent-function 2) | 1477 | (put 'multiple-value-setq 'lisp-indent-hook 2) |
| 1453 | (put 'multiple-value-list 'lisp-indent-function nil) | 1478 | (put 'multiple-value-list 'lisp-indent-hook nil) |
| 1454 | (put 'multiple-value-call 'lisp-indent-function 1) | 1479 | (put 'multiple-value-call 'lisp-indent-hook 1) |
| 1455 | (put 'multiple-value-prog1 'lisp-indent-function 1) | 1480 | (put 'multiple-value-prog1 'lisp-indent-hook 1) |
| 1456 | 1481 | ||
| 1457 | ;;; Global state of the package is kept here | 1482 | ;;; Global state of the package is kept here |
| 1458 | (defvar *mvalues-values* nil | 1483 | (defvar *mvalues-values* nil |
| @@ -1478,7 +1503,7 @@ the first value." | |||
| 1478 | (car *mvalues-values*)) | 1503 | (car *mvalues-values*)) |
| 1479 | 1504 | ||
| 1480 | (defun values-list (&optional val-forms) | 1505 | (defun values-list (&optional val-forms) |
| 1481 | "Produce multiple values (zero or mode). Each element of LIST is one value. | 1506 | "Produce multiple values (zero or more). Each element of LIST is one value. |
| 1482 | This is equivalent to (apply 'values LIST)." | 1507 | This is equivalent to (apply 'values LIST)." |
| 1483 | (cond ((nlistp val-forms) | 1508 | (cond ((nlistp val-forms) |
| 1484 | (error "Argument to values-list must be a list, not `%s'" | 1509 | (error "Argument to values-list must be a list, not `%s'" |
| @@ -1589,29 +1614,29 @@ the length of VARS (a list of symbols). VALS is just a fresh symbol." | |||
| 1589 | ;;;; (quiroz@cs.rochester.edu) | 1614 | ;;;; (quiroz@cs.rochester.edu) |
| 1590 | 1615 | ||
| 1591 | 1616 | ||
| 1592 | (defun plusp (number) | 1617 | (defsubst plusp (number) |
| 1593 | "True if NUMBER is strictly greater than zero." | 1618 | "True if NUMBER is strictly greater than zero." |
| 1594 | (> number 0)) | 1619 | (> number 0)) |
| 1595 | 1620 | ||
| 1596 | (defun minusp (number) | 1621 | (defsubst minusp (number) |
| 1597 | "True if NUMBER is strictly less than zero." | 1622 | "True if NUMBER is strictly less than zero." |
| 1598 | (< number 0)) | 1623 | (< number 0)) |
| 1599 | 1624 | ||
| 1600 | (defun oddp (number) | 1625 | (defsubst oddp (number) |
| 1601 | "True if INTEGER is not divisible by 2." | 1626 | "True if INTEGER is not divisible by 2." |
| 1602 | (/= (% number 2) 0)) | 1627 | (/= (% number 2) 0)) |
| 1603 | 1628 | ||
| 1604 | (defun evenp (number) | 1629 | (defsubst evenp (number) |
| 1605 | "True if INTEGER is divisible by 2." | 1630 | "True if INTEGER is divisible by 2." |
| 1606 | (= (% number 2) 0)) | 1631 | (= (% number 2) 0)) |
| 1607 | 1632 | ||
| 1608 | (defun abs (number) | 1633 | (defsubst abs (number) |
| 1609 | "Return the absolute value of NUMBER." | 1634 | "Return the absolute value of NUMBER." |
| 1610 | (if (< number 0) | 1635 | (if (< number 0) |
| 1611 | (- number) | 1636 | (- number) |
| 1612 | number)) | 1637 | number)) |
| 1613 | 1638 | ||
| 1614 | (defun signum (number) | 1639 | (defsubst signum (number) |
| 1615 | "Return -1, 0 or 1 according to the sign of NUMBER." | 1640 | "Return -1, 0 or 1 according to the sign of NUMBER." |
| 1616 | (cond ((< number 0) | 1641 | (cond ((< number 0) |
| 1617 | -1) | 1642 | -1) |
| @@ -1701,59 +1726,56 @@ equal to the real square root of the argument." | |||
| 1701 | (defun floor (number &optional divisor) | 1726 | (defun floor (number &optional divisor) |
| 1702 | "Divide DIVIDEND by DIVISOR, rounding toward minus infinity. | 1727 | "Divide DIVIDEND by DIVISOR, rounding toward minus infinity. |
| 1703 | DIVISOR defaults to 1. The remainder is produced as a second value." | 1728 | DIVISOR defaults to 1. The remainder is produced as a second value." |
| 1704 | (cond | 1729 | (cond ((and (null divisor) ; trivial case |
| 1705 | ((and (null divisor) ; trivial case | 1730 | (numberp number)) |
| 1706 | (numberp number)) | 1731 | (values number 0)) |
| 1707 | (values number 0)) | 1732 | (t ; do the division |
| 1708 | (t ; do the division | 1733 | (multiple-value-bind |
| 1709 | (multiple-value-bind | 1734 | (q r s) |
| 1710 | (q r s) | 1735 | (safe-idiv number divisor) |
| 1711 | (safe-idiv number divisor) | 1736 | (cond ((zerop s) |
| 1712 | (cond ((zerop s) | 1737 | (values 0 0)) |
| 1713 | (values 0 0)) | 1738 | ((plusp s) |
| 1714 | ((plusp s) | 1739 | (values q r)) |
| 1715 | (values q r)) | 1740 | (t ;opposite-signs case |
| 1716 | (t ;opposite-signs case | 1741 | (if (zerop r) |
| 1717 | (if (zerop r) | 1742 | (values (- q) 0) |
| 1718 | (values (- q) 0) | 1743 | (let ((q (- (+ q 1)))) |
| 1719 | (let ((q (- (+ q 1)))) | 1744 | (values q (- number (* q divisor))))))))))) |
| 1720 | (values q (- number (* q divisor))))))))))) | ||
| 1721 | 1745 | ||
| 1722 | (defun ceiling (number &optional divisor) | 1746 | (defun ceiling (number &optional divisor) |
| 1723 | "Divide DIVIDEND by DIVISOR, rounding toward plus infinity. | 1747 | "Divide DIVIDEND by DIVISOR, rounding toward plus infinity. |
| 1724 | DIVISOR defaults to 1. The remainder is produced as a second value." | 1748 | DIVISOR defaults to 1. The remainder is produced as a second value." |
| 1725 | (cond | 1749 | (cond ((and (null divisor) ; trivial case |
| 1726 | ((and (null divisor) ; trivial case | 1750 | (numberp number)) |
| 1727 | (numberp number)) | 1751 | (values number 0)) |
| 1728 | (values number 0)) | 1752 | (t ; do the division |
| 1729 | (t ; do the division | 1753 | (multiple-value-bind |
| 1730 | (multiple-value-bind | 1754 | (q r s) |
| 1731 | (q r s) | 1755 | (safe-idiv number divisor) |
| 1732 | (safe-idiv number divisor) | 1756 | (cond ((zerop s) |
| 1733 | (cond ((zerop s) | 1757 | (values 0 0)) |
| 1734 | (values 0 0)) | 1758 | ((plusp s) |
| 1735 | ((plusp s) | 1759 | (values (+ q 1) (- r divisor))) |
| 1736 | (values (+ q 1) (- r divisor))) | 1760 | (t |
| 1737 | (t | 1761 | (values (- q) (+ number (* q divisor))))))))) |
| 1738 | (values (- q) (+ number (* q divisor))))))))) | ||
| 1739 | 1762 | ||
| 1740 | (defun truncate (number &optional divisor) | 1763 | (defun truncate (number &optional divisor) |
| 1741 | "Divide DIVIDEND by DIVISOR, rounding toward zero. | 1764 | "Divide DIVIDEND by DIVISOR, rounding toward zero. |
| 1742 | DIVISOR defaults to 1. The remainder is produced as a second value." | 1765 | DIVISOR defaults to 1. The remainder is produced as a second value." |
| 1743 | (cond | 1766 | (cond ((and (null divisor) ; trivial case |
| 1744 | ((and (null divisor) ; trivial case | 1767 | (numberp number)) |
| 1745 | (numberp number)) | 1768 | (values number 0)) |
| 1746 | (values number 0)) | 1769 | (t ; do the division |
| 1747 | (t ; do the division | 1770 | (multiple-value-bind |
| 1748 | (multiple-value-bind | 1771 | (q r s) |
| 1749 | (q r s) | 1772 | (safe-idiv number divisor) |
| 1750 | (safe-idiv number divisor) | 1773 | (cond ((zerop s) |
| 1751 | (cond ((zerop s) | 1774 | (values 0 0)) |
| 1752 | (values 0 0)) | 1775 | ((plusp s) ;same as floor |
| 1753 | ((plusp s) ;same as floor | 1776 | (values q r)) |
| 1754 | (values q r)) | 1777 | (t ;same as ceiling |
| 1755 | (t ;same as ceiling | 1778 | (values (- q) (+ number (* q divisor))))))))) |
| 1756 | (values (- q) (+ number (* q divisor))))))))) | ||
| 1757 | 1779 | ||
| 1758 | (defun round (number &optional divisor) | 1780 | (defun round (number &optional divisor) |
| 1759 | "Divide DIVIDEND by DIVISOR, rounding to nearest integer. | 1781 | "Divide DIVIDEND by DIVISOR, rounding to nearest integer. |
| @@ -1778,18 +1800,25 @@ DIVISOR defaults to 1. The remainder is produced as a second value." | |||
| 1778 | (setq r (- number (* q divisor))) | 1800 | (setq r (- number (* q divisor))) |
| 1779 | (values q r)))))) | 1801 | (values q r)))))) |
| 1780 | 1802 | ||
| 1803 | ;;; These two functions access the implementation-dependent representation of | ||
| 1804 | ;;; the multiple value returns. | ||
| 1805 | |||
| 1781 | (defun mod (number divisor) | 1806 | (defun mod (number divisor) |
| 1782 | "Return remainder of X by Y (rounding quotient toward minus infinity). | 1807 | "Return remainder of X by Y (rounding quotient toward minus infinity). |
| 1783 | That is, the remainder goes with the quotient produced by `floor'." | 1808 | That is, the remainder goes with the quotient produced by `floor'. |
| 1784 | (multiple-value-bind (q r) (floor number divisor) | 1809 | Emacs Lisp hint: |
| 1785 | r)) | 1810 | If you know that both arguments are positive, use `%' instead for speed." |
| 1811 | (floor number divisor) | ||
| 1812 | (cadr *mvalues-values*)) | ||
| 1786 | 1813 | ||
| 1787 | (defun rem (number divisor) | 1814 | (defun rem (number divisor) |
| 1788 | "Return remainder of X by Y (rounding quotient toward zero). | 1815 | "Return remainder of X by Y (rounding quotient toward zero). |
| 1789 | That is, the remainder goes with the quotient produced by `truncate'." | 1816 | That is, the remainder goes with the quotient produced by `truncate'. |
| 1790 | (multiple-value-bind (q r) (truncate number divisor) | 1817 | Emacs Lisp hint: |
| 1791 | r)) | 1818 | If you know that both arguments are positive, use `%' instead for speed." |
| 1792 | 1819 | (truncate number divisor) | |
| 1820 | (cadr *mvalues-values*)) | ||
| 1821 | |||
| 1793 | ;;; internal utilities | 1822 | ;;; internal utilities |
| 1794 | ;;; | 1823 | ;;; |
| 1795 | ;;; safe-idiv performs an integer division with positive numbers only. | 1824 | ;;; safe-idiv performs an integer division with positive numbers only. |
| @@ -1801,16 +1830,14 @@ That is, the remainder goes with the quotient produced by `truncate'." | |||
| 1801 | 1830 | ||
| 1802 | (defun safe-idiv (a b) | 1831 | (defun safe-idiv (a b) |
| 1803 | "SAFE-IDIV A B => Q R S | 1832 | "SAFE-IDIV A B => Q R S |
| 1804 | Q=|A|/|B|, R is the rest, S is the sign of A/B." | 1833 | Q=|A|/|B|, S is the sign of A/B, R is the rest A - S*Q*B." |
| 1805 | (unless (and (numberp a) (numberp b)) | 1834 | ;; (unless (and (numberp a) (numberp b)) |
| 1806 | (error "arguments to `safe-idiv' must be numbers")) | 1835 | ;; (error "arguments to `safe-idiv' must be numbers")) |
| 1807 | (when (zerop b) | 1836 | ;; (when (zerop b) |
| 1808 | (error "cannot divide %d by zero" a)) | 1837 | ;; (error "cannot divide %d by zero" a)) |
| 1809 | (let* ((absa (abs a)) | 1838 | (let* ((q (/ (abs a) (abs b))) |
| 1810 | (absb (abs b)) | 1839 | (s (* (signum a) (signum b))) |
| 1811 | (q (/ absa absb)) | 1840 | (r (- a (* s q b)))) |
| 1812 | (s (* (signum a) (signum b))) | ||
| 1813 | (r (- a (* (* s q) b)))) | ||
| 1814 | (values q r s))) | 1841 | (values q r s))) |
| 1815 | 1842 | ||
| 1816 | ;;;; end of cl-arith.el | 1843 | ;;;; end of cl-arith.el |
| @@ -1871,22 +1898,29 @@ the next PLACE is evaluated." | |||
| 1871 | (setq head (car place)) | 1898 | (setq head (car place)) |
| 1872 | (symbolp head) | 1899 | (symbolp head) |
| 1873 | (setq updatefn (get head :setf-update-fn))) | 1900 | (setq updatefn (get head :setf-update-fn))) |
| 1874 | (if (or (and (consp updatefn) (eq (car updatefn) 'lambda)) | 1901 | ;; dispatch on the type of update function |
| 1875 | (and (symbolp updatefn) | 1902 | (cond ((and (consp updatefn) (eq (car updatefn) 'lambda)) |
| 1876 | (fboundp updatefn) | 1903 | (cons 'funcall |
| 1877 | (let ((defn (symbol-function updatefn))) | 1904 | (cons (list 'function updatefn) |
| 1878 | (or (subrp defn) | 1905 | (append (cdr place) (list value))))) |
| 1879 | (and (consp defn) | 1906 | ((and (symbolp updatefn) |
| 1880 | (eq (car defn) 'lambda)))))) | 1907 | (fboundp updatefn) |
| 1881 | (cons updatefn (append (cdr place) (list value))) | 1908 | (let ((defn (symbol-function updatefn))) |
| 1882 | (multiple-value-bind | 1909 | (or (subrp defn) |
| 1883 | (bindings newsyms) | 1910 | (and (consp defn) |
| 1884 | (pair-with-newsyms (append (cdr place) (list value))) | 1911 | (or (eq (car defn) 'lambda) |
| 1885 | ;; this let gets new symbols to ensure adequate | 1912 | (eq (car defn) 'macro)))))) |
| 1886 | ;; order of evaluation of the subforms. | 1913 | (cons updatefn (append (cdr place) (list value)))) |
| 1887 | (list 'let | 1914 | (t |
| 1888 | bindings | 1915 | (multiple-value-bind |
| 1889 | (cons updatefn newsyms))))) | 1916 | (bindings newsyms) |
| 1917 | (pair-with-newsyms | ||
| 1918 | (append (cdr place) (list value))) | ||
| 1919 | ;; this let gets new symbols to ensure adequate | ||
| 1920 | ;; order of evaluation of the subforms. | ||
| 1921 | (list 'let | ||
| 1922 | bindings | ||
| 1923 | (cons updatefn newsyms)))))) | ||
| 1890 | (t | 1924 | (t |
| 1891 | (error "no `setf' update-function for `%s'" | 1925 | (error "no `setf' update-function for `%s'" |
| 1892 | (prin1-to-string place))))))))) | 1926 | (prin1-to-string place))))))))) |
| @@ -2242,6 +2276,70 @@ Thus, the values rotate through the PLACEs. Returns nil." | |||
| 2242 | (append (cdr newsyms) (list (car newsyms))))) | 2276 | (append (cdr newsyms) (list (car newsyms))))) |
| 2243 | nil)))) | 2277 | nil)))) |
| 2244 | 2278 | ||
| 2279 | ;;; GETF, REMF, and REMPROP | ||
| 2280 | ;;; | ||
| 2281 | |||
| 2282 | (defun getf (place indicator &optional default) | ||
| 2283 | "Return PLACE's PROPNAME property, or DEFAULT if not present." | ||
| 2284 | (while (and place (not (eq (car place) indicator))) | ||
| 2285 | (setq place (cdr (cdr place)))) | ||
| 2286 | (if place | ||
| 2287 | (car (cdr place)) | ||
| 2288 | default)) | ||
| 2289 | |||
| 2290 | (defmacro getf$setf$method (place indicator default &rest newval) | ||
| 2291 | "SETF method for GETF. Not for public use." | ||
| 2292 | (case (length newval) | ||
| 2293 | (0 (setq newval default default nil)) | ||
| 2294 | (1 (setq newval (car newval))) | ||
| 2295 | (t (error "Wrong number of arguments to (setf (getf ...)) form"))) | ||
| 2296 | (let ((psym (gentemp)) (isym (gentemp)) (vsym (gentemp))) | ||
| 2297 | (list 'let (list (list psym place) | ||
| 2298 | (list isym indicator) | ||
| 2299 | (list vsym newval)) | ||
| 2300 | (list 'while | ||
| 2301 | (list 'and psym | ||
| 2302 | (list 'not | ||
| 2303 | (list 'eq (list 'car psym) isym))) | ||
| 2304 | (list 'setq psym (list 'cdr (list 'cdr psym)))) | ||
| 2305 | (list 'if psym | ||
| 2306 | (list 'setcar (list 'cdr psym) vsym) | ||
| 2307 | (list 'setf place | ||
| 2308 | (list 'nconc place (list 'list isym newval)))) | ||
| 2309 | vsym))) | ||
| 2310 | |||
| 2311 | (defsetf getf | ||
| 2312 | getf$setf$method) | ||
| 2313 | |||
| 2314 | (defmacro remf (place indicator) | ||
| 2315 | "Remove from the property list at PLACE its PROPNAME property. | ||
| 2316 | Returns non-nil if and only if the property existed." | ||
| 2317 | (let ((psym (gentemp)) (isym (gentemp))) | ||
| 2318 | (list 'let (list (list psym place) (list isym indicator)) | ||
| 2319 | (list 'cond | ||
| 2320 | (list (list 'eq isym (list 'car psym)) | ||
| 2321 | (list 'setf place (list 'cdr (list 'cdr psym))) | ||
| 2322 | t) | ||
| 2323 | (list t | ||
| 2324 | (list 'setq psym (list 'cdr psym)) | ||
| 2325 | (list 'while | ||
| 2326 | (list 'and (list 'cdr psym) | ||
| 2327 | (list 'not | ||
| 2328 | (list 'eq (list 'car (list 'cdr psym)) | ||
| 2329 | isym))) | ||
| 2330 | (list 'setq psym (list 'cdr (list 'cdr psym)))) | ||
| 2331 | (list 'cond | ||
| 2332 | (list (list 'cdr psym) | ||
| 2333 | (list 'setcdr psym | ||
| 2334 | (list 'cdr | ||
| 2335 | (list 'cdr (list 'cdr psym)))) | ||
| 2336 | t))))))) | ||
| 2337 | |||
| 2338 | (defun remprop (symbol indicator) | ||
| 2339 | "Remove SYMBOL's PROPNAME property, returning non-nil if it was present." | ||
| 2340 | (remf (symbol-plist symbol) indicator)) | ||
| 2341 | |||
| 2342 | |||
| 2245 | ;;;; STRUCTS | 2343 | ;;;; STRUCTS |
| 2246 | ;;;; This file provides the structures mechanism. See the | 2344 | ;;;; This file provides the structures mechanism. See the |
| 2247 | ;;;; documentation for Common-Lisp's defstruct. Mine doesn't | 2345 | ;;;; documentation for Common-Lisp's defstruct. Mine doesn't |
| @@ -2402,9 +2500,7 @@ them. `setf' of the accessors sets their values." | |||
| 2402 | (list 'quote name) | 2500 | (list 'quote name) |
| 2403 | 'args)))) | 2501 | 'args)))) |
| 2404 | (list 'fset (list 'quote copier) | 2502 | (list 'fset (list 'quote copier) |
| 2405 | (list 'function | 2503 | (list 'function 'copy-sequence)) |
| 2406 | (list 'lambda (list 'struct) | ||
| 2407 | (list 'copy-sequence 'struct)))) | ||
| 2408 | (let ((typetag (gensym))) | 2504 | (let ((typetag (gensym))) |
| 2409 | (list 'fset (list 'quote predicate) | 2505 | (list 'fset (list 'quote predicate) |
| 2410 | (list | 2506 | (list |
| @@ -2441,7 +2537,7 @@ them. `setf' of the accessors sets their values." | |||
| 2441 | (list | 2537 | (list |
| 2442 | (cons 'vector | 2538 | (cons 'vector |
| 2443 | (mapcar | 2539 | (mapcar |
| 2444 | '(lambda (x) (list 'quote x)) | 2540 | (function (lambda (x) (list 'quote x))) |
| 2445 | (cons name slots))))) | 2541 | (cons name slots))))) |
| 2446 | ;; generate code | 2542 | ;; generate code |
| 2447 | (cons 'progn | 2543 | (cons 'progn |
| @@ -2891,7 +2987,7 @@ Beware: nconc destroys its first argument! See copy-list." | |||
| 2891 | 2987 | ||
| 2892 | ;;; Copiers | 2988 | ;;; Copiers |
| 2893 | 2989 | ||
| 2894 | (defun copy-list (list) | 2990 | (defsubst copy-list (list) |
| 2895 | "Build a copy of LIST" | 2991 | "Build a copy of LIST" |
| 2896 | (append list '())) | 2992 | (append list '())) |
| 2897 | 2993 | ||
| @@ -3037,7 +3133,28 @@ returns false, that tail of the list if returned. Else NIL." | |||
| 3037 | No checking is even attempted. This is just for compatibility with | 3133 | No checking is even attempted. This is just for compatibility with |
| 3038 | Common-Lisp codes." | 3134 | Common-Lisp codes." |
| 3039 | form) | 3135 | form) |
| 3136 | |||
| 3137 | ;;; Due to Aaron Larson (alarson@src.honeywell.com, 26 Jul 91) | ||
| 3138 | (put 'progv 'common-lisp-indent-hook '(4 4 &body)) | ||
| 3139 | (defmacro progv (vars vals &rest body) | ||
| 3140 | "progv vars vals &body forms | ||
| 3141 | bind vars to vals then execute forms. | ||
| 3142 | If there are more vars than vals, the extra vars are unbound, if | ||
| 3143 | there are more vals than vars, the extra vals are just ignored." | ||
| 3144 | (` (progv$runtime (, vars) (, vals) (function (lambda () (,@ body)))))) | ||
| 3145 | |||
| 3146 | ;;; To do this efficiently, it really needs to be a special form... | ||
| 3147 | (defun progv$runtime (vars vals body) | ||
| 3148 | (eval (let ((vars-n-vals nil) | ||
| 3149 | (unbind-forms nil)) | ||
| 3150 | (do ((r vars (cdr r)) | ||
| 3151 | (l vals (cdr l))) | ||
| 3152 | ((endp r)) | ||
| 3153 | (push (list (car r) (list 'quote (car l))) vars-n-vals) | ||
| 3154 | (if (null l) | ||
| 3155 | (push (` (makunbound '(, (car r)))) unbind-forms))) | ||
| 3156 | (` (let (, vars-n-vals) (,@ unbind-forms) (funcall '(, body))))))) | ||
| 3040 | 3157 | ||
| 3041 | (provide 'cl) | 3158 | (provide 'cl) |
| 3042 | 3159 | ||
| 3043 | ;;; cl.el ends here | 3160 | ;;;; end of cl.el |