Annotation of 43BSDReno/contrib/emacs-18.55/lisp/cl.el, revision 1.1

1.1     ! root        1: ;; Common-Lisp extensions for GNU Emacs Lisp.
        !             2: ;; Copyright (C) 1987, 1988 Free Software Foundation, Inc.
        !             3: 
        !             4: ;; This file is part of GNU Emacs.
        !             5: 
        !             6: ;; GNU Emacs is distributed in the hope that it will be useful,
        !             7: ;; but WITHOUT ANY WARRANTY.  No author or distributor
        !             8: ;; accepts responsibility to anyone for the consequences of using it
        !             9: ;; or for whether it serves any particular purpose or works at all,
        !            10: ;; unless he says so in writing.  Refer to the GNU Emacs General Public
        !            11: ;; License for full details.
        !            12: 
        !            13: ;; Everyone is granted permission to copy, modify and redistribute
        !            14: ;; GNU Emacs, but only under the conditions described in the
        !            15: ;; GNU Emacs General Public License.   A copy of this license is
        !            16: ;; supposed to have been given to you along with GNU Emacs so you
        !            17: ;; can know your rights and responsibilities.  It should be in a
        !            18: ;; file named COPYING.  Among other things, the copyright notice
        !            19: ;; and this notice must be preserved on all copies.
        !            20: 
        !            21: ;;;;
        !            22: ;;;; These are extensions to Emacs Lisp that provide some form of
        !            23: ;;;; Common Lisp compatibility, beyond what is already built-in
        !            24: ;;;; in Emacs Lisp.
        !            25: ;;;;
        !            26: ;;;; When developing them, I had the code spread among several files.
        !            27: ;;;; This file 'cl.el' is a concatenation of those original files,
        !            28: ;;;; minus some declarations that became redundant.  The marks between
        !            29: ;;;; the original files can be found easily, as they are lines that
        !            30: ;;;; begin with four semicolons (as this does).  The names of the
        !            31: ;;;; original parts follow the four semicolons in uppercase, those
        !            32: ;;;; names are GLOBAL, SYMBOLS, LISTS, SEQUENCES, CONDITIONALS,
        !            33: ;;;; ITERATIONS, MULTIPLE VALUES, ARITH, SETF and DEFSTRUCT.  If you
        !            34: ;;;; add functions to this file, you might want to put them in a place
        !            35: ;;;; that is compatible with the division above (or invent your own
        !            36: ;;;; categories).
        !            37: ;;;;
        !            38: ;;;; To compile this file, make sure you load it first.  This is
        !            39: ;;;; because many things are implemented as macros and now that all
        !            40: ;;;; the files are concatenated together one cannot ensure that
        !            41: ;;;; declaration always precedes use.
        !            42: ;;;;
        !            43: ;;;; Bug reports, suggestions and comments,
        !            44: ;;;; to [email protected]
        !            45: 
        !            46: (provide 'cl)
        !            47: 
        !            48: 
        !            49: ;;;; GLOBAL
        !            50: ;;;;    This file provides utilities and declarations that are global
        !            51: ;;;;    to Common Lisp and so might be used by more than one of the
        !            52: ;;;;    other libraries.  Especially, I intend to keep here some
        !            53: ;;;;    utilities that help parsing/destructuring some difficult calls. 
        !            54: ;;;;
        !            55: ;;;;
        !            56: ;;;;    Cesar Quiroz @ UofR DofCSc - Dec. 1986
        !            57: ;;;;       ([email protected])
        !            58: 
        !            59: (defmacro psetq (&rest pairs)
        !            60:   "(psetq {VARIABLE VALUE}...): In parallel, set each VARIABLE to its VALUE.
        !            61: All the VALUEs are evaluated, and then all the VARIABLEs are set.
        !            62: Aside from order of evaluation, this is the same as `setq'."
        !            63:   (let ((nforms (length pairs))                ;count of args
        !            64:        ;; next are used to destructure the call
        !            65:        symbols                         ;even numbered args
        !            66:        forms                           ;odd numbered args
        !            67:        ;; these are used to generate code
        !            68:        bindings                        ;for the let
        !            69:        newsyms                         ;list of gensyms
        !            70:        assignments                     ;for the setq
        !            71:        ;; auxiliary indices
        !            72:        i)
        !            73:     ;; check there is a reasonable number of forms
        !            74:     (if (/= (% nforms 2) 0)
        !            75:        (error "Odd number of arguments to `psetq'"))
        !            76: 
        !            77:     ;; destructure the args
        !            78:     (let ((ptr pairs)                  ;traverses the args
        !            79:          var                           ;visits each symbol position
        !            80:          )
        !            81:       (while ptr
        !            82:        (setq var (car ptr))            ;next variable
        !            83:        (if (not (symbolp var))
        !            84:            (error "`psetq' expected a symbol, found '%s'."
        !            85:                   (prin1-to-string var)))
        !            86:        (setq symbols (cons var symbols))
        !            87:        (setq forms   (cons (car (cdr ptr)) forms))
        !            88:        (setq ptr (cdr (cdr ptr)))))
        !            89: 
        !            90:     ;; assign new symbols to the bindings
        !            91:     (let ((ptr forms)                  ;traverses the forms
        !            92:          form                          ;each form goes here
        !            93:          newsym                        ;gensym for current value of form
        !            94:          )
        !            95:       (while ptr
        !            96:        (setq form (car ptr))
        !            97:        (setq newsym (gensym))
        !            98:        (setq bindings (cons (list newsym form) bindings))
        !            99:        (setq newsyms (cons newsym newsyms))
        !           100:        (setq ptr (cdr ptr))))
        !           101:     (setq newsyms (nreverse newsyms))  ;to sync with symbols
        !           102:     
        !           103:     ;; pair symbols with newsyms for assignment
        !           104:     (let ((ptr1 symbols)               ;traverses original names
        !           105:          (ptr2 newsyms)                ;traverses new symbols
        !           106:          )
        !           107:       (while ptr1
        !           108:        (setq assignments
        !           109:              (cons (car ptr1) (cons (car ptr2) assignments)))
        !           110:        (setq ptr1 (cdr ptr1))
        !           111:        (setq ptr2 (cdr ptr2))))
        !           112:     
        !           113:     ;; generate code
        !           114:     (list 'let
        !           115:          bindings
        !           116:          (cons 'setq assignments)
        !           117:          nil)))
        !           118: 
        !           119: ;;; utilities
        !           120: ;;;
        !           121: ;;; pair-with-newsyms takes a list and returns a list of lists of the
        !           122: ;;; form (newsym form), such that a let* can then bind the evaluation
        !           123: ;;; of the forms to the newsyms.  The idea is to guarantee correct
        !           124: ;;; order of evaluation of the subforms of a setf.  It also returns a
        !           125: ;;; list of the newsyms generated, in the corresponding order.
        !           126: 
        !           127: (defun pair-with-newsyms (oldforms)
        !           128:   "PAIR-WITH-NEWSYMS OLDFORMS
        !           129: The top-level components of the list oldforms are paired with fresh
        !           130: symbols, the pairings list and the newsyms list are returned."
        !           131:   (do ((ptr oldforms (cdr ptr))
        !           132:        (bindings '())
        !           133:        (newsyms  '()))
        !           134:       ((endp ptr) (values (nreverse bindings) (nreverse newsyms)))
        !           135:     (let ((newsym (gentemp)))
        !           136:       (setq bindings (cons (list newsym (car ptr)) bindings))
        !           137:       (setq newsyms  (cons newsym newsyms)))))
        !           138: 
        !           139: (defun zip-lists (evens odds)
        !           140:   "Merge two lists EVENS and ODDS, taking elts from each list alternatingly.
        !           141: EVENS and ODDS are two lists.  ZIP-LISTS constructs a new list, whose
        !           142: even numbered elements (0,2,...) come from EVENS and whose odd
        !           143: numbered elements (1,3,...) come from ODDS. 
        !           144: The construction stops when the shorter list is exhausted."
        !           145:   (do* ((p0   evens    (cdr p0))
        !           146:         (p1   odds     (cdr p1))
        !           147:         (even (car p0) (car p0))
        !           148:         (odd  (car p1) (car p1))
        !           149:         (result '()))
        !           150:       ((or (endp p0) (endp p1))
        !           151:        (nreverse result))
        !           152:     (setq result
        !           153:           (cons odd (cons even result)))))
        !           154: 
        !           155: (defun unzip-list (list)
        !           156:   "Extract even and odd elements of LIST into two separate lists.
        !           157: The argument LIST is separated in two strands, the even and the odd
        !           158: numbered elements.  Numbering starts with 0, so the first element
        !           159: belongs in EVENS. No check is made that there is an even number of
        !           160: elements to start with."
        !           161:   (do* ((ptr   list       (cddr ptr))
        !           162:         (this  (car ptr)  (car ptr))
        !           163:         (next  (cadr ptr) (cadr ptr))
        !           164:         (evens '())
        !           165:         (odds  '()))
        !           166:       ((endp ptr)
        !           167:        (values (nreverse evens) (nreverse odds)))
        !           168:     (setq evens (cons this evens))
        !           169:     (setq odds  (cons next odds))))
        !           170: 
        !           171: (defun reassemble-argslists (argslists)
        !           172:   "(reassemble-argslists ARGSLISTS).
        !           173: ARGSLISTS is a list of sequences.  Return a list of lists, the first
        !           174: sublist being all the entries coming from ELT 0 of the original
        !           175: sublists, the next those coming from ELT 1 and so on, until the
        !           176: shortest list is exhausted."
        !           177:   (let* ((minlen   (apply 'min (mapcar 'length argslists)))
        !           178:          (result   '()))
        !           179:     (dotimes (i minlen (nreverse result))
        !           180:       ;; capture all the elements at index i
        !           181:       (setq result
        !           182:             (cons (mapcar
        !           183:                    (function (lambda (sublist) (elt sublist i)))
        !           184:                    argslists)
        !           185:                   result)))))
        !           186: 
        !           187: ;;; to help parsing keyword arguments
        !           188: 
        !           189: (defun build-klist (argslist acceptable)
        !           190:   "Decode a keyword argument list ARGSLIST for keywords in ACCEPTABLE.
        !           191: ARGSLIST is a list, presumably the &rest argument of a call, whose
        !           192: even numbered elements must be keywords.
        !           193: ACCEPTABLE is a list of keywords, the only ones that are truly acceptable.
        !           194: The result is an alist containing the arguments named by the keywords
        !           195: in ACCEPTABLE, or nil if something failed."
        !           196: 
        !           197:   ;; check legality of the arguments, then destructure them
        !           198:   (unless (and (listp argslist)
        !           199:                (evenp (length argslist)))
        !           200:     (error "Odd number of keyword-args"))
        !           201:   (unless (and (listp acceptable)
        !           202:                (every 'keywordp acceptable))
        !           203:     (error "Second arg should be a list of keywords"))
        !           204:   (multiple-value-bind
        !           205:       (keywords forms)
        !           206:       (unzip-list argslist)
        !           207:     (unless (every 'keywordp keywords)
        !           208:       (error "Expected keywords, found `%s'"
        !           209:              (prin1-to-string keywords)))
        !           210:     (do*                                ;pick up the pieces
        !           211:         ((auxlist                       ;auxiliary a-list, may
        !           212:           (pairlis keywords forms))     ;contain repetitions and junk
        !           213:          (ptr    acceptable  (cdr ptr)) ;pointer in acceptable
        !           214:          (this  (car ptr)  (car ptr))   ;current acceptable keyword
        !           215:          (auxval nil)                   ;used to move values around
        !           216:          (alist  '()))                  ;used to build the result
        !           217:         ((endp ptr) alist)
        !           218:       ;; if THIS appears in auxlist, use its value
        !           219:       (when (setq auxval (assoc this auxlist))
        !           220:         (setq alist (cons auxval alist))))))
        !           221: 
        !           222: 
        !           223: ;;; Checking that a list of symbols contains no duplicates is a common
        !           224: ;;; task when checking the legality of some macros.  The check for 'eq
        !           225: ;;; pairs can be too expensive, as it is quadratic on the length of
        !           226: ;;; the list.  I use a 4-pass, linear, counting approach.  It surely
        !           227: ;;; loses on small lists (less than 5 elements?), but should win for
        !           228: ;;; larger lists.  The fourth pass could be eliminated.
        !           229: ;;; 10 dec 1986.  Emacs Lisp has no REMPROP, so I just eliminated the
        !           230: ;;; 4th pass.
        !           231: (defun duplicate-symbols-p (list)
        !           232:   "Find all symbols appearing more than once in LIST.
        !           233: Return a list of all such duplicates; `nil' if there are no duplicates."
        !           234:   (let  ((duplicates '())               ;result built here
        !           235:          (propname   (gensym))          ;we use a fresh property
        !           236:          )
        !           237:     ;; check validity
        !           238:     (unless (and (listp list)
        !           239:                  (every 'symbolp list))
        !           240:       (error "A list of symbols is needed"))
        !           241:     ;; pass 1: mark
        !           242:     (dolist (x list)
        !           243:       (put x propname 0))
        !           244:     ;; pass 2: count
        !           245:     (dolist (x list)
        !           246:       (put x propname (1+ (get x propname))))
        !           247:     ;; pass 3: collect
        !           248:     (dolist (x list)
        !           249:       (if (> (get x propname) 1)
        !           250:           (setq duplicates (cons x duplicates))))
        !           251:     ;; pass 4: unmark.  eliminated.
        !           252:     ;; (dolist (x list) (remprop x propname))
        !           253:     ;; return result
        !           254:     duplicates))
        !           255: 
        !           256: ;;;; end of cl-global.el
        !           257: 
        !           258: ;;;; SYMBOLS
        !           259: ;;;;    This file provides the gentemp function, which generates fresh
        !           260: ;;;;    symbols, plus some other minor Common Lisp symbol tools.
        !           261: ;;;;
        !           262: ;;;;    Cesar Quiroz @ UofR DofCSc - Dec. 1986
        !           263: ;;;;       ([email protected])
        !           264: 
        !           265: ;;; Keywords.  There are no packages in Emacs Lisp, so this is only a
        !           266: ;;; kludge around to let things be "as if" a keyword package was around.
        !           267: 
        !           268: (defmacro defkeyword (x &optional docstring)
        !           269:   "Make symbol X a keyword (symbol whose value is itself).
        !           270: Optional second argument is a documentation string for it."
        !           271:   (cond
        !           272:    ((symbolp x)
        !           273:     (list 'defconst x (list 'quote x)))
        !           274:    (t
        !           275:     (error "`%s' is not a symbol" (prin1-to-string x)))))
        !           276: 
        !           277: (defun keywordp (sym)
        !           278:   "Return `t' if SYM is a keyword."
        !           279:   (cond
        !           280:    ((and (symbolp sym)
        !           281:          (char-equal (aref (symbol-name sym) 0) ?\:))
        !           282:     ;; looks like one, make sure value is right
        !           283:     (set sym sym))
        !           284:    (t
        !           285:     nil)))
        !           286: 
        !           287: (defun keyword-of (sym)
        !           288:   "Return a keyword that is naturally associated with symbol SYM.
        !           289: If SYM is keyword, the value is SYM.
        !           290: Otherwise it is a keyword whose name is `:' followed by SYM's name."
        !           291:   (cond
        !           292:    ((keywordp sym)
        !           293:     sym)
        !           294:    ((symbolp sym)
        !           295:     (let ((newsym (intern (concat ":" (symbol-name sym)))))
        !           296:       (set newsym newsym)))
        !           297:    (t
        !           298:     (error "Expected a symbol, not `%s'" (prin1-to-string sym)))))
        !           299: 
        !           300: ;;; Temporary symbols.  
        !           301: ;;; 
        !           302: 
        !           303: (defvar *gentemp-index* 0
        !           304:   "Integer used by gentemp to produce new names.")
        !           305: 
        !           306: (defvar *gentemp-prefix* "T$$_"
        !           307:   "Names generated by gentemp begin with this string by default.")
        !           308: 
        !           309: (defun gentemp (&optional prefix oblist)
        !           310:   "Generate a fresh interned symbol.
        !           311: There are 2 optional arguments, PREFIX and OBLIST.  PREFIX is the
        !           312: string that begins the new name, OBLIST is the obarray used to search for
        !           313: old names.  The defaults are just right, YOU SHOULD NEVER NEED THESE
        !           314: ARGUMENTS IN YOUR OWN CODE."
        !           315:   (if (null prefix)
        !           316:       (setq prefix *gentemp-prefix*))
        !           317:   (if (null oblist)
        !           318:       (setq oblist obarray))            ;default for the intern functions
        !           319:   (let ((newsymbol nil)
        !           320:         (newname))
        !           321:     (while (not newsymbol)
        !           322:       (setq newname (concat prefix *gentemp-index*))
        !           323:       (setq *gentemp-index* (+ *gentemp-index* 1))
        !           324:       (if (not (intern-soft newname oblist))
        !           325:           (setq newsymbol (intern newname oblist))))
        !           326:     newsymbol))
        !           327: 
        !           328: (defvar *gensym-index* 0
        !           329:   "Integer used by gensym to produce new names.")
        !           330: 
        !           331: (defvar *gensym-prefix* "G$$_"
        !           332:   "Names generated by gensym begin with this string by default.")
        !           333: 
        !           334: (defun gensym (&optional prefix)
        !           335:   "Generate a fresh uninterned symbol.
        !           336: There is an  optional argument, PREFIX.  PREFIX is the
        !           337: string that begins the new name. Most people take just the default,
        !           338: except when debugging needs suggest otherwise."
        !           339:   (if (null prefix)
        !           340:       (setq prefix *gensym-prefix*))
        !           341:   (let ((newsymbol nil)
        !           342:         (newname   ""))
        !           343:     (while (not newsymbol)
        !           344:       (setq newname (concat prefix *gensym-index*))
        !           345:       (setq *gensym-index* (+ *gensym-index* 1))
        !           346:       (if (not (intern-soft newname))
        !           347:           (setq newsymbol (make-symbol newname))))
        !           348:     newsymbol))
        !           349: 
        !           350: ;;;; end of cl-symbols.el
        !           351: 
        !           352: ;;;; CONDITIONALS
        !           353: ;;;;    This file provides some of the conditional constructs of
        !           354: ;;;;    Common Lisp.  Total compatibility is again impossible, as the
        !           355: ;;;;    'if' form is different in both languages, so only a good
        !           356: ;;;;    approximation is desired.
        !           357: ;;;;
        !           358: ;;;;    Cesar Quiroz @ UofR DofCSc - Dec. 1986
        !           359: ;;;;       ([email protected])
        !           360: 
        !           361: ;;; indentation info
        !           362: (put 'case      'lisp-indent-hook 1)
        !           363: (put 'ecase     'lisp-indent-hook 1)
        !           364: (put 'when      'lisp-indent-hook 1)
        !           365: (put 'unless    'lisp-indent-hook 1)
        !           366: 
        !           367: ;;; WHEN and UNLESS
        !           368: ;;; These two forms are simplified ifs, with a single branch.
        !           369: 
        !           370: (defmacro when (condition &rest body)
        !           371:   "(when CONDITION . BODY) => evaluate BODY if CONDITION is true."
        !           372:   (list* 'if (list 'not condition) '() body))
        !           373: 
        !           374: (defmacro unless (condition &rest body)
        !           375:   "(unless CONDITION . BODY) => evaluate BODY if CONDITION is false."
        !           376:   (list* 'if condition '() body))
        !           377: 
        !           378: ;;; CASE and ECASE
        !           379: ;;; CASE selects among several clauses, based on the value (evaluated)
        !           380: ;;; of a expression and a list of (unevaluated) key values.  ECASE is
        !           381: ;;; the same, but signals an error if no clause is activated.
        !           382: 
        !           383: (defmacro case (expr &rest cases)
        !           384:   "(case EXPR . CASES) => evals EXPR, chooses from CASES on that value.
        !           385: EXPR   -> any form
        !           386: CASES  -> list of clauses, non empty
        !           387: CLAUSE -> HEAD . BODY
        !           388: HEAD   -> t             = catch all, must be last clause
        !           389:        -> otherwise     = same as t
        !           390:        -> nil           = illegal
        !           391:        -> atom          = activated if (eql  EXPR HEAD)
        !           392:        -> list of atoms = activated if (member EXPR HEAD)
        !           393: BODY   -> list of forms, implicit PROGN is built around it.
        !           394: EXPR is evaluated only once."
        !           395:   (let* ((newsym (gentemp))
        !           396:          (clauses (case-clausify cases newsym)))
        !           397:     ;; convert case into a cond inside a let
        !           398:     (list 'let
        !           399:          (list (list newsym expr))
        !           400:          (list* 'cond (nreverse clauses)))))
        !           401: 
        !           402: (defmacro ecase (expr &rest cases)
        !           403:   "(ecase EXPR . CASES) => like `case', but error if no case fits.
        !           404: `t'-clauses are not allowed."
        !           405:   (let* ((newsym (gentemp))
        !           406:          (clauses (case-clausify cases newsym)))
        !           407:     ;; check that no 't clause is present.
        !           408:     ;; case-clausify would put one such at the beginning of clauses
        !           409:     (if (eq (caar clauses) t)
        !           410:         (error "No clause-head should be `t' or `otherwise' for `ecase'"))
        !           411:     ;; insert error-catching clause
        !           412:     (setq clauses
        !           413:           (cons
        !           414:            (list 't (list 'error
        !           415:                           "ecase on %s = %s failed to take any branch."
        !           416:                           (list 'quote expr)
        !           417:                           (list 'prin1-to-string newsym)))
        !           418:            clauses))
        !           419:     ;; generate code as usual
        !           420:     (list 'let
        !           421:           (list (list newsym expr))
        !           422:           (list* 'cond (nreverse clauses)))))
        !           423: 
        !           424: 
        !           425: (defun case-clausify (cases newsym)
        !           426:   "CASE-CLAUSIFY CASES NEWSYM => clauses for a 'cond'
        !           427: Converts the CASES of a [e]case macro into cond clauses to be
        !           428: evaluated inside a let that binds NEWSYM.  Returns the clauses in
        !           429: reverse order."
        !           430:   (do* ((currentpos cases        (cdr currentpos))
        !           431:         (nextpos    (cdr cases)  (cdr nextpos))
        !           432:         (curclause  (car cases)  (car currentpos))
        !           433:         (result     '()))
        !           434:       ((endp currentpos) result)
        !           435:     (let ((head (car curclause))
        !           436:           (body (cdr curclause)))
        !           437:       ;; construct a cond-clause according to the head
        !           438:       (cond
        !           439:        ((null head)
        !           440:         (error "Case clauses cannot have null heads: `%s'"
        !           441:                (prin1-to-string curclause)))
        !           442:        ((or (eq head 't)
        !           443:             (eq head 'otherwise))
        !           444:         ;; check it is the last clause
        !           445:         (if (not (endp nextpos))
        !           446:             (error "Clause with `t' or `otherwise' head must be last"))
        !           447:         ;; accept this clause as a 't' for cond
        !           448:         (setq result (cons (cons 't body) result)))
        !           449:        ((atom head)
        !           450:         (setq result
        !           451:               (cons (cons (list 'eql newsym (list 'quote head)) body)
        !           452:                     result)))
        !           453:        ((listp head)
        !           454:         (setq result
        !           455:               (cons (cons (list 'member newsym (list 'quote head)) body)
        !           456:                     result)))
        !           457:        (t
        !           458:         ;; catch-all for this parser
        !           459:         (error "Don't know how to parse case clause `%s'."
        !           460:                (prin1-to-string head)))))))
        !           461: 
        !           462: ;;;; end of cl-conditionals.el
        !           463: 
        !           464: ;;;; ITERATIONS
        !           465: ;;;;    This file provides simple iterative macros (a la Common Lisp)
        !           466: ;;;;    constructed on the basis of let, let* and while, which are the
        !           467: ;;;;    primitive binding/iteration constructs of Emacs Lisp
        !           468: ;;;;
        !           469: ;;;;    The Common Lisp iterations use to have a block named nil
        !           470: ;;;;    wrapped around them, and allow declarations at the beginning
        !           471: ;;;;    of their bodies and you can return a value using (return ...).
        !           472: ;;;;    Nothing of the sort exists in Emacs Lisp, so I haven't tried
        !           473: ;;;;    to imitate these behaviors.
        !           474: ;;;;
        !           475: ;;;;    Other than the above, the semantics of Common Lisp are
        !           476: ;;;;    correctly reproduced to the extent this was reasonable.
        !           477: ;;;;
        !           478: ;;;;    Cesar Quiroz @ UofR DofCSc - Dec. 1986
        !           479: ;;;;       ([email protected])
        !           480: 
        !           481: ;;; some lisp-indentation information
        !           482: (put 'do                'lisp-indent-hook 2)
        !           483: (put 'do*               'lisp-indent-hook 2)
        !           484: (put 'dolist            'lisp-indent-hook 1)
        !           485: (put 'dotimes           'lisp-indent-hook 1)
        !           486: (put 'do-symbols        'lisp-indent-hook 1)
        !           487: (put 'do-all-symbols    'lisp-indent-hook 1)
        !           488: 
        !           489: 
        !           490: (defmacro do (stepforms endforms &rest body)
        !           491:   "(do STEPFORMS ENDFORMS . BODY): Iterate BODY, stepping some local variables.
        !           492: STEPFORMS must be a list of symbols or lists.  In the second case, the
        !           493: lists must start with a symbol and contain up to two more forms. In
        !           494: the STEPFORMS, a symbol is the same as a (symbol).  The other 2 forms
        !           495: are the initial value (def. NIL) and the form to step (def. itself).
        !           496: The values used by initialization and stepping are computed in parallel.
        !           497: The ENDFORMS are a list (CONDITION . ENDBODY).  If the CONDITION
        !           498: evaluates to true in any iteration, ENDBODY is evaluated and the last
        !           499: form in it is returned.
        !           500: The BODY (which may be empty) is evaluated at every iteration, with
        !           501: the symbols of the STEPFORMS bound to the initial or stepped values."
        !           502:   ;; check the syntax of the macro
        !           503:   (and (check-do-stepforms stepforms)
        !           504:        (check-do-endforms endforms))
        !           505:   ;; construct emacs-lisp equivalent
        !           506:   (let ((initlist (extract-do-inits stepforms))
        !           507:         (steplist (extract-do-steps stepforms))
        !           508:         (endcond  (car endforms))
        !           509:         (endbody  (cdr endforms)))
        !           510:     (cons 'let (cons initlist
        !           511:                      (cons (cons 'while (cons (list 'not endcond) 
        !           512:                                               (append body steplist)))
        !           513:                            (append endbody))))))
        !           514: 
        !           515: 
        !           516: (defmacro do* (stepforms endforms &rest body)
        !           517:   "`do*' is to `do' as `let*' is to `let'.
        !           518: STEPFORMS must be a list of symbols or lists.  In the second case, the
        !           519: lists must start with a symbol and contain up to two more forms. In
        !           520: the STEPFORMS, a symbol is the same as a (symbol).  The other 2 forms
        !           521: are the initial value (def. NIL) and the form to step (def. itself).
        !           522: Initializations and steppings are done in the sequence they are written.
        !           523: The ENDFORMS are a list (CONDITION . ENDBODY).  If the CONDITION
        !           524: evaluates to true in any iteration, ENDBODY is evaluated and the last
        !           525: form in it is returned.
        !           526: The BODY (which may be empty) is evaluated at every iteration, with
        !           527: the symbols of the STEPFORMS bound to the initial or stepped values."
        !           528:   ;; check the syntax of the macro
        !           529:   (and (check-do-stepforms stepforms)
        !           530:        (check-do-endforms endforms))
        !           531:   ;; construct emacs-lisp equivalent
        !           532:   (let ((initlist (extract-do-inits stepforms))
        !           533:         (steplist (extract-do*-steps stepforms))
        !           534:         (endcond  (car endforms))
        !           535:         (endbody  (cdr endforms)))
        !           536:     (cons 'let* (cons initlist
        !           537:                      (cons (cons 'while (cons (list 'not endcond) 
        !           538:                                               (append body steplist)))
        !           539:                            (append endbody))))))
        !           540: 
        !           541: 
        !           542: ;;; DO and DO* share the syntax checking functions that follow.
        !           543: 
        !           544: (defun check-do-stepforms (forms)
        !           545:   "True if FORMS is a valid stepforms for the do[*] macro (q.v.)"
        !           546:   (cond
        !           547:    ((nlistp forms)
        !           548:     (error "Init/Step form for do[*] should be a list, not `%s'"
        !           549:            (prin1-to-string forms)))
        !           550:    (t                                   ;valid list
        !           551:     ;; each entry must be a symbol, or a list whose car is a symbol
        !           552:     ;; and whose length is no more than three
        !           553:     (mapcar
        !           554:      (function
        !           555:       (lambda (entry)
        !           556:         (cond
        !           557:          ((or (symbolp entry)
        !           558:               (and (listp entry)
        !           559:                    (symbolp (car entry))
        !           560:                    (< (length entry) 4)))
        !           561:           t)
        !           562:          (t
        !           563:           (error
        !           564:            "Init/Step must be symbol or (symbol [init [step]]), not `%s'"
        !           565:            (prin1-to-string entry))))))
        !           566:      forms))))
        !           567: 
        !           568: (defun check-do-endforms (forms)
        !           569:   "True if FORMS is a valid endforms for the do[*] macro (q.v.)"
        !           570:   (cond
        !           571:    ((listp forms)
        !           572:     t)
        !           573:    (t
        !           574:     (error "Termination form for do macro should be a list, not `%s'"
        !           575:            (prin1-to-string forms)))))
        !           576: 
        !           577: (defun extract-do-inits (forms)
        !           578:   "Returns a list of the initializations (for do) in FORMS
        !           579: -a stepforms, see the do macro-. Forms is assumed syntactically valid."
        !           580:   (mapcar
        !           581:    (function
        !           582:     (lambda (entry)
        !           583:       (cond
        !           584:        ((symbolp entry)
        !           585:         (list entry nil))
        !           586:        ((listp entry)
        !           587:         (list (car entry) (cadr entry))))))
        !           588:    forms))
        !           589: 
        !           590: ;;; There used to be a reason to deal with DO differently than with
        !           591: ;;; DO*.  The writing of PSETQ has made it largely unnecessary.
        !           592: 
        !           593: (defun extract-do-steps (forms)
        !           594:   "EXTRACT-DO-STEPS FORMS => an s-expr
        !           595: FORMS is the stepforms part of a DO macro (q.v.).  This function
        !           596: constructs an s-expression that does the stepping at the end of an
        !           597: iteration."
        !           598:   (list (cons 'psetq (select-stepping-forms forms))))
        !           599: 
        !           600: (defun extract-do*-steps (forms)
        !           601:   "EXTRACT-DO*-STEPS FORMS => an s-expr
        !           602: FORMS is the stepforms part of a DO* macro (q.v.).  This function
        !           603: constructs an s-expression that does the stepping at the end of an
        !           604: iteration."
        !           605:   (list (cons 'setq (select-stepping-forms forms))))
        !           606: 
        !           607: (defun select-stepping-forms (forms)
        !           608:   "Separate only the forms that cause stepping."
        !           609:   (let ((result '())                   ;ends up being (... var form ...)
        !           610:        (ptr forms)                     ;to traverse the forms
        !           611:        entry                           ;to explore each form in turn
        !           612:        )
        !           613:     (while ptr                         ;(not (endp entry)) might be safer
        !           614:       (setq entry (car ptr))
        !           615:       (cond
        !           616:        ((and (listp entry)
        !           617:             (= (length entry) 3))
        !           618:        (setq result (append            ;append in reverse order!
        !           619:                      (list (caddr entry) (car entry))
        !           620:                      result))))
        !           621:       (setq ptr (cdr ptr)))            ;step in the list of forms
        !           622:     ;;put things back in the
        !           623:     ;;correct order before return
        !           624:     (nreverse result)))
        !           625: 
        !           626: ;;; Other iterative constructs
        !           627: 
        !           628: (defmacro dolist  (stepform &rest body)
        !           629:   "(dolist (VAR LIST [RESULTFORM]) . BODY): do BODY for each elt of LIST.
        !           630: The RESULTFORM defaults to nil.  The VAR is bound to successive
        !           631: elements of the value of LIST and remains bound (to the nil value) when the
        !           632: RESULTFORM is evaluated."
        !           633:   ;; check sanity
        !           634:   (cond
        !           635:    ((nlistp stepform)
        !           636:     (error "Stepform for `dolist' should be (VAR LIST [RESULT]), not `%s'"
        !           637:            (prin1-to-string stepform)))
        !           638:    ((not (symbolp (car stepform)))
        !           639:     (error "First component of stepform should be a symbol, not `%s'"
        !           640:            (prin1-to-string (car stepform))))
        !           641:    ((> (length stepform) 3)
        !           642:     (error "Too many components in stepform `%s'"
        !           643:            (prin1-to-string stepform))))
        !           644:   ;; generate code
        !           645:   (let* ((var (car stepform))
        !           646:          (listform (cadr stepform))
        !           647:          (resultform (caddr stepform)))
        !           648:     (list 'progn
        !           649:           (list 'mapcar
        !           650:                 (list 'function
        !           651:                       (cons 'lambda (cons (list var) body)))
        !           652:                 listform)
        !           653:           (list 'let
        !           654:                 (list (list var nil))
        !           655:                 resultform))))
        !           656: 
        !           657: (defmacro dotimes (stepform &rest body)
        !           658:   "(dotimes (VAR COUNTFORM [RESULTFORM]) .  BODY): Repeat BODY, counting in VAR.
        !           659: The COUNTFORM should return a positive integer.  The VAR is bound to
        !           660: successive integers from 0 to COUNTFORM-1 and the BODY is repeated for
        !           661: each of them.  At the end, the RESULTFORM is evaluated and its value
        !           662: returned. During this last evaluation, the VAR is still bound, and its
        !           663: value is the number of times the iteration occurred. An omitted RESULTFORM
        !           664: defaults to nil."
        !           665:   ;; check sanity 
        !           666:   (cond
        !           667:    ((nlistp stepform)
        !           668:     (error "Stepform for `dotimes' should be (VAR COUNT [RESULT]), not `%s'"
        !           669:            (prin1-to-string stepform)))
        !           670:    ((not (symbolp (car stepform)))
        !           671:     (error "First component of stepform should be a symbol, not `%s'"
        !           672:            (prin1-to-string (car stepform))))
        !           673:    ((> (length stepform) 3)
        !           674:     (error "Too many components in stepform `%s'"
        !           675:            (prin1-to-string stepform))))
        !           676:   ;; generate code
        !           677:   (let* ((var (car stepform))
        !           678:          (countform (cadr stepform))
        !           679:          (resultform (caddr stepform))
        !           680:          (newsym (gentemp)))
        !           681:     (list
        !           682:      'let* (list (list newsym countform))
        !           683:      (list*
        !           684:       'do*
        !           685:       (list (list var 0 (list '+ var 1)))
        !           686:       (list (list '>= var newsym) resultform)
        !           687:       body))))
        !           688: 
        !           689: (defmacro do-symbols (stepform &rest body)
        !           690:   "(do_symbols (VAR [OBARRAY [RESULTFORM]]) . BODY)
        !           691: The VAR is bound to each of the symbols in OBARRAY (def. obarray) and
        !           692: the BODY is repeatedly performed for each of those bindings. At the
        !           693: end, RESULTFORM (def. nil) is evaluated and its value returned.
        !           694: During this last evaluation, the VAR is still bound and its value is nil.
        !           695: See also the function `mapatoms'."
        !           696:   ;; check sanity
        !           697:   (cond
        !           698:    ((nlistp stepform)
        !           699:     (error "Stepform for `do-symbols' should be (VAR OBARRAY [RESULT]), not `%s'"
        !           700:            (prin1-to-string stepform)))
        !           701:    ((not (symbolp (car stepform)))
        !           702:     (error "First component of stepform should be a symbol, not `%s'"
        !           703:            (prin1-to-string (car stepform))))
        !           704:    ((> (length stepform) 3)
        !           705:     (error "Too many components in stepform `%s'"
        !           706:            (prin1-to-string stepform))))
        !           707:   ;; generate code
        !           708:   (let* ((var (car stepform))
        !           709:          (oblist (cadr stepform))
        !           710:          (resultform (caddr stepform)))
        !           711:     (list 'progn
        !           712:           (list 'mapatoms
        !           713:                 (list 'function
        !           714:                       (cons 'lambda (cons (list var) body)))
        !           715:                 oblist)
        !           716:           (list 'let
        !           717:                 (list (list var nil))
        !           718:                 resultform))))
        !           719: 
        !           720: 
        !           721: (defmacro do-all-symbols (stepform &rest body)
        !           722:   "(do-all-symbols (VAR [RESULTFORM]) . BODY)
        !           723: Is the same as (do-symbols (VAR obarray RESULTFORM) . BODY)."
        !           724:   (list*
        !           725:    'do-symbols
        !           726:    (list (car stepform) 'obarray (cadr stepform))
        !           727:    body))
        !           728: 
        !           729: (defmacro loop (&rest body)
        !           730:   "(loop . BODY) repeats BODY indefinitely and does not return.
        !           731: Normally BODY uses `throw' or `signal' to cause an exit.
        !           732: The forms in BODY should be lists, as non-lists are reserved for new features."
        !           733:   ;; check that the body doesn't have atomic forms
        !           734:   (if (nlistp body)
        !           735:       (error "Body of `loop' should be a list of lists or nil")
        !           736:     ;; ok, it is a list, check for atomic components
        !           737:     (mapcar
        !           738:      (function (lambda (component)
        !           739:                  (if (nlistp component)
        !           740:                      (error "Components of `loop' should be lists"))))
        !           741:      body)
        !           742:     ;; build the infinite loop
        !           743:     (cons 'while (cons 't body))))
        !           744: 
        !           745: ;;;; end of cl-iterations.el
        !           746: 
        !           747: ;;;; LISTS
        !           748: ;;;;    This file provides some of the lists machinery of Common-Lisp
        !           749: ;;;;    in a way compatible with Emacs Lisp.  Especially, see the the
        !           750: ;;;;    typical c[ad]*r functions.
        !           751: ;;;;
        !           752: ;;;;    Cesar Quiroz @ UofR DofCSc - Dec. 1986
        !           753: ;;;;       ([email protected])
        !           754: 
        !           755: 
        !           756: 
        !           757: ;;; Synonyms for list functions
        !           758: (defun first (x)
        !           759:   "Synonym for `car'"
        !           760:   (car x))
        !           761: 
        !           762: (defun second (x)
        !           763:   "Return the second element of the list LIST."
        !           764:   (nth 1 x))
        !           765: 
        !           766: (defun third (x)
        !           767:   "Return the third element of the list LIST."
        !           768:   (nth 2 x))
        !           769: 
        !           770: (defun fourth (x)
        !           771:   "Return the fourth element of the list LIST."
        !           772:   (nth 3 x))
        !           773: 
        !           774: (defun fifth (x)
        !           775:   "Return the fifth element of the list LIST."
        !           776:   (nth 4 x))
        !           777: 
        !           778: (defun sixth (x)
        !           779:   "Return the sixth element of the list LIST."
        !           780:   (nth 5 x))
        !           781: 
        !           782: (defun seventh (x)
        !           783:   "Return the seventh element of the list LIST."
        !           784:   (nth 6 x))
        !           785: 
        !           786: (defun eighth (x)
        !           787:   "Return the eighth element of the list LIST."
        !           788:   (nth 7 x))
        !           789: 
        !           790: (defun ninth (x)
        !           791:   "Return the ninth element of the list LIST."
        !           792:   (nth 8 x))
        !           793: 
        !           794: (defun tenth (x)
        !           795:   "Return the tenth element of the list LIST."
        !           796:   (nth 9 x))
        !           797: 
        !           798: (defun rest (x)
        !           799:   "Synonym for `cdr'"
        !           800:   (cdr x))
        !           801: 
        !           802: (defun endp (x)
        !           803:   "t if X is nil, nil if X is a cons; error otherwise."
        !           804:   (if (listp x)
        !           805:       (null x)
        !           806:     (error "endp received a non-cons, non-null argument `%s'"
        !           807:           (prin1-to-string x))))
        !           808: 
        !           809: (defun last (x)
        !           810:   "Returns the last link in the list LIST."
        !           811:   (if (nlistp x)
        !           812:       (error "Arg to `last' must be a list"))
        !           813:   (do ((current-cons    x       (cdr current-cons))
        !           814:        (next-cons    (cdr x)    (cdr next-cons)))
        !           815:       ((endp next-cons) current-cons)))
        !           816: 
        !           817: (defun list-length (x)                  ;taken from CLtL sect. 15.2
        !           818:   "Returns the length of a non-circular list, or `nil' for a circular one."
        !           819:   (do ((n 0)                            ;counter
        !           820:        (fast x (cddr fast))             ;fast pointer, leaps by 2
        !           821:        (slow x (cdr slow))              ;slow pointer, leaps by 1
        !           822:        (ready nil))                     ;indicates termination
        !           823:       (ready n)
        !           824:     (cond
        !           825:      ((endp fast)
        !           826:       (setq ready t))                   ;return n
        !           827:      ((endp (cdr fast))
        !           828:       (setq n (+ n 1))
        !           829:       (setq ready t))                   ;return n+1
        !           830:      ((and (eq fast slow) (> n 0))
        !           831:       (setq n nil)
        !           832:       (setq ready t))                   ;return nil
        !           833:      (t
        !           834:       (setq n (+ n 2))))))              ;just advance counter
        !           835: 
        !           836: (defun member (item list)
        !           837:   "Look for ITEM in LIST; return first link in LIST whose car is `eql' to ITEM."
        !           838:   (let ((ptr list)
        !           839:         (done nil)
        !           840:         (result '()))
        !           841:     (while (not (or done (endp ptr)))
        !           842:       (cond ((eql item (car ptr))
        !           843:              (setq done t)
        !           844:              (setq result ptr)))
        !           845:       (setq ptr (cdr ptr)))
        !           846:     result))
        !           847: 
        !           848: (defun butlast (list &optional n)
        !           849:   "Return a new list like LIST but sans the last N elements.
        !           850: N defaults to 1.  If the list doesn't have N elements, nil is returned."
        !           851:   (if (null n) (setq n 1))
        !           852:   (reverse (nthcdr n (reverse list))))
        !           853: 
        !           854: (defun list* (arg &rest others)
        !           855:   "Return a new list containing the first arguments consed onto the last arg.
        !           856: Thus, (list* 1 2 3 '(a b)) returns (1 2 3 a b)."
        !           857:   (if (null others)
        !           858:       arg
        !           859:     (let* ((allargs (cons arg others))
        !           860:            (front   (butlast allargs))
        !           861:            (back    (last allargs)))
        !           862:       (rplacd (last front) (car back))
        !           863:       front)))
        !           864: 
        !           865: (defun adjoin (item list)
        !           866:   "Return a list which contains ITEM but is otherwise like LIST.
        !           867: If ITEM occurs in LIST, the value is LIST.  Otherwise it is (cons ITEM LIST).
        !           868: When comparing ITEM against elements, `eql' is used."
        !           869:   (cond
        !           870:    ((member item list)
        !           871:     list)
        !           872:    (t
        !           873:     (cons item list))))
        !           874: 
        !           875: (defun ldiff (list sublist)
        !           876:   "Return a new list like LIST but sans SUBLIST.
        !           877: SUBLIST must be one of the links in LIST; otherwise the value is LIST itself."
        !           878:   (do ((result '())
        !           879:        (curcons list (cdr curcons)))
        !           880:       ((or (endp curcons) (eq curcons sublist))
        !           881:        (reverse result))
        !           882:     (setq result (cons (car curcons) result))))
        !           883: 
        !           884: ;;; The popular c[ad]*r functions.
        !           885: 
        !           886: (defun caar (X)
        !           887:   "Return the car of the car of X."
        !           888:   (car (car X)))
        !           889: 
        !           890: (defun cadr (X)
        !           891:   "Return the car of the cdr of X."
        !           892:   (car (cdr X)))
        !           893: 
        !           894: (defun cdar (X)
        !           895:   "Return the cdr of the car of X."
        !           896:   (cdr (car X)))
        !           897: 
        !           898: (defun cddr (X)
        !           899:   "Return the cdr of the cdr of X."
        !           900:   (cdr (cdr X)))
        !           901: 
        !           902: (defun caaar (X)
        !           903:   "Return the car of the car of the car of X."
        !           904:   (car (car (car X))))
        !           905: 
        !           906: (defun caadr (X)
        !           907:   "Return the car of the car of the cdr of X."
        !           908:   (car (car (cdr X))))
        !           909: 
        !           910: (defun cadar (X)
        !           911:   "Return the car of the cdr of the car of X."
        !           912:   (car (cdr (car X))))
        !           913: 
        !           914: (defun cdaar (X)
        !           915:   "Return the cdr of the car of the car of X."
        !           916:   (cdr (car (car X))))
        !           917: 
        !           918: (defun caddr (X)
        !           919:   "Return the car of the cdr of the cdr of X."
        !           920:   (car (cdr (cdr X))))
        !           921: 
        !           922: (defun cdadr (X)
        !           923:   "Return the cdr of the car of the cdr of X."
        !           924:   (cdr (car (cdr X))))
        !           925: 
        !           926: (defun cddar (X)
        !           927:   "Return the cdr of the cdr of the car of X."
        !           928:   (cdr (cdr (car X))))
        !           929: 
        !           930: (defun cdddr (X)
        !           931:   "Return the cdr of the cdr of the cdr of X."
        !           932:   (cdr (cdr (cdr X))))
        !           933: 
        !           934: (defun caaaar (X)
        !           935:   "Return the car of the car of the car of the car of X."
        !           936:   (car (car (car (car X)))))
        !           937: 
        !           938: (defun caaadr (X)
        !           939:   "Return the car of the car of the car of the cdr of X."
        !           940:   (car (car (car (cdr X)))))
        !           941: 
        !           942: (defun caadar (X)
        !           943:   "Return the car of the car of the cdr of the car of X."
        !           944:   (car (car (cdr (car X)))))
        !           945: 
        !           946: (defun cadaar (X)
        !           947:   "Return the car of the cdr of the car of the car of X."
        !           948:   (car (cdr (car (car X)))))
        !           949: 
        !           950: (defun cdaaar (X)
        !           951:   "Return the cdr of the car of the car of the car of X."
        !           952:   (cdr (car (car (car X)))))
        !           953: 
        !           954: (defun caaddr (X)
        !           955:   "Return the car of the car of the cdr of the cdr of X."
        !           956:   (car (car (cdr (cdr X)))))
        !           957: 
        !           958: (defun cadadr (X)
        !           959:   "Return the car of the cdr of the car of the cdr of X."
        !           960:   (car (cdr (car (cdr X)))))
        !           961: 
        !           962: (defun cdaadr (X)
        !           963:   "Return the cdr of the car of the car of the cdr of X."
        !           964:   (cdr (car (car (cdr X)))))
        !           965: 
        !           966: (defun caddar (X)
        !           967:   "Return the car of the cdr of the cdr of the car of X."
        !           968:   (car (cdr (cdr (car X)))))
        !           969: 
        !           970: (defun cdadar (X)
        !           971:   "Return the cdr of the car of the cdr of the car of X."
        !           972:   (cdr (car (cdr (car X)))))
        !           973: 
        !           974: (defun cddaar (X)
        !           975:   "Return the cdr of the cdr of the car of the car of X."
        !           976:   (cdr (cdr (car (car X)))))
        !           977: 
        !           978: (defun cadddr (X)
        !           979:   "Return the car of the cdr of the cdr of the cdr of X."
        !           980:   (car (cdr (cdr (cdr X)))))
        !           981: 
        !           982: (defun cddadr (X)
        !           983:   "Return the cdr of the cdr of the car of the cdr of X."
        !           984:   (cdr (cdr (car (cdr X)))))
        !           985: 
        !           986: (defun cdaddr (X)
        !           987:   "Return the cdr of the car of the cdr of the cdr of X."
        !           988:   (cdr (car (cdr (cdr X)))))
        !           989: 
        !           990: (defun cdddar (X)
        !           991:   "Return the cdr of the cdr of the cdr of the car of X."
        !           992:   (cdr (cdr (cdr (car X)))))
        !           993: 
        !           994: (defun cddddr (X)
        !           995:   "Return the cdr of the cdr of the cdr of the cdr of X."
        !           996:   (cdr (cdr (cdr (cdr X)))))
        !           997: 
        !           998: ;;; some inverses of the accessors are needed for setf purposes
        !           999: 
        !          1000: (defun setnth (n list newval)
        !          1001:   "Set (nth N LIST) to NEWVAL.  Returns NEWVAL."
        !          1002:   (rplaca (nthcdr n list) newval))
        !          1003: 
        !          1004: (defun setnthcdr (n list newval)
        !          1005:   "SETNTHCDR N LIST NEWVAL => NEWVAL
        !          1006: As a side effect, sets the Nth cdr of LIST to NEWVAL."
        !          1007:   (cond
        !          1008:    ((< n 0)
        !          1009:     (error "N must be 0 or greater, not %d" n))
        !          1010:    ((= n 0)
        !          1011:     (rplaca list (car newval))
        !          1012:     (rplacd list (cdr newval))
        !          1013:     newval)
        !          1014:    (t
        !          1015:     (rplacd (nthcdr (- n 1) list) newval))))
        !          1016: 
        !          1017: ;;; A-lists machinery
        !          1018: 
        !          1019: (defun acons (key item alist)
        !          1020:   "Return a new alist with KEY paired with ITEM; otherwise like ALIST.
        !          1021: Does not copy ALIST."
        !          1022:   (cons (cons key item) alist))
        !          1023: 
        !          1024: (defun pairlis (keys data &optional alist)
        !          1025:   "Return a new alist with each elt of KEYS paired with an elt of DATA;
        !          1026: optional 3rd arg ALIST is nconc'd at the end.  KEYS and DATA must
        !          1027: have the same length."
        !          1028:   (unless (= (length keys) (length data))
        !          1029:     (error "Keys and data should be the same length"))
        !          1030:   (do* ;;collect keys and data in front of alist
        !          1031:       ((kptr keys (cdr kptr))           ;traverses the keys
        !          1032:        (dptr data (cdr dptr))           ;traverses the data
        !          1033:        (key (car kptr) (car kptr))      ;current key
        !          1034:        (item (car dptr) (car dptr))     ;current data item
        !          1035:        (result alist))
        !          1036:       ((endp kptr) result)
        !          1037:     (setq result (acons key item result))))
        !          1038: 
        !          1039: ;;;; end of cl-lists.el
        !          1040: 
        !          1041: ;;;; SEQUENCES
        !          1042: ;;;; Emacs Lisp provides many of the 'sequences' functionality of
        !          1043: ;;;; Common Lisp.  This file provides a few things that were left out.
        !          1044: ;;;; 
        !          1045: 
        !          1046: 
        !          1047: (defkeyword :test      "Used to designate positive (selection) tests.")
        !          1048: (defkeyword :test-not  "Used to designate negative (rejection) tests.")
        !          1049: (defkeyword :key       "Used to designate component extractions.")
        !          1050: (defkeyword :predicate "Used to define matching of sequence components.")
        !          1051: (defkeyword :start     "Inclusive low index in sequence")
        !          1052: (defkeyword :end       "Exclusive high index in sequence")
        !          1053: (defkeyword :start1    "Inclusive low index in first of two sequences.")
        !          1054: (defkeyword :start2    "Inclusive low index in second of two sequences.")
        !          1055: (defkeyword :end1      "Exclusive high index in first of two sequences.")
        !          1056: (defkeyword :end2      "Exclusive high index in second of two sequences.")
        !          1057: (defkeyword :count     "Number of elements to affect.")
        !          1058: (defkeyword :from-end  "T when counting backwards.")
        !          1059: 
        !          1060: (defun some     (pred seq &rest moreseqs)
        !          1061:   "Test PREDICATE on each element of SEQUENCE; is it ever non-nil?
        !          1062: Extra args are additional sequences; PREDICATE gets one arg from each
        !          1063: sequence and we advance down all the sequences together in lock-step.
        !          1064: A sequence means either a list or a vector."
        !          1065:   (let ((args  (reassemble-argslists (list* seq moreseqs))))
        !          1066:     (do* ((ready nil)                   ;flag: return when t
        !          1067:           (result nil)                  ;resulting value
        !          1068:           (applyval nil)                ;result of applying pred once
        !          1069:           (remaining args
        !          1070:                      (cdr remaining))   ;remaining argument sets
        !          1071:           (current (car remaining)      ;current argument set
        !          1072:                    (car remaining)))
        !          1073:         ((or ready (endp remaining)) result)
        !          1074:       (setq applyval (apply pred current))
        !          1075:       (when applyval
        !          1076:         (setq ready t)
        !          1077:         (setq result applyval)))))
        !          1078: 
        !          1079: (defun every    (pred seq &rest moreseqs)
        !          1080:   "Test PREDICATE on each element of SEQUENCE; is it always non-nil?
        !          1081: Extra args are additional sequences; PREDICATE gets one arg from each
        !          1082: sequence and we advance down all the sequences together in lock-step.
        !          1083: A sequence means either a list or a vector."
        !          1084:   (let ((args  (reassemble-argslists (list* seq moreseqs))))
        !          1085:     (do* ((ready nil)                   ;flag: return when t
        !          1086:           (result t)                    ;resulting value
        !          1087:           (applyval nil)                ;result of applying pred once
        !          1088:           (remaining args
        !          1089:                      (cdr remaining))   ;remaining argument sets
        !          1090:           (current (car remaining)      ;current argument set
        !          1091:                    (car remaining)))
        !          1092:         ((or ready (endp remaining)) result)
        !          1093:       (setq applyval (apply pred current))
        !          1094:       (unless applyval
        !          1095:         (setq ready t)
        !          1096:         (setq result nil)))))
        !          1097: 
        !          1098: (defun notany   (pred seq &rest moreseqs)
        !          1099:   "Test PREDICATE on each element of SEQUENCE; is it always nil?
        !          1100: Extra args are additional sequences; PREDICATE gets one arg from each
        !          1101: sequence and we advance down all the sequences together in lock-step.
        !          1102: A sequence means either a list or a vector."
        !          1103:   (let ((args  (reassemble-argslists (list* seq moreseqs))))
        !          1104:     (do* ((ready nil)                   ;flag: return when t
        !          1105:           (result t)                    ;resulting value
        !          1106:           (applyval nil)                ;result of applying pred once
        !          1107:           (remaining args
        !          1108:                      (cdr remaining))   ;remaining argument sets
        !          1109:           (current (car remaining)      ;current argument set
        !          1110:                    (car remaining)))
        !          1111:         ((or ready (endp remaining)) result)
        !          1112:       (setq applyval (apply pred current))
        !          1113:       (when applyval
        !          1114:         (setq ready t)
        !          1115:         (setq result nil)))))
        !          1116: 
        !          1117: (defun notevery (pred seq &rest moreseqs)
        !          1118:   "Test PREDICATE on each element of SEQUENCE; is it sometimes nil?
        !          1119: Extra args are additional sequences; PREDICATE gets one arg from each
        !          1120: sequence and we advance down all the sequences together in lock-step.
        !          1121: A sequence means either a list or a vector."
        !          1122:   (let ((args  (reassemble-argslists (list* seq moreseqs))))
        !          1123:     (do* ((ready nil)                   ;flag: return when t
        !          1124:           (result nil)                  ;resulting value
        !          1125:           (applyval nil)                ;result of applying pred once
        !          1126:           (remaining args
        !          1127:                      (cdr remaining))   ;remaining argument sets
        !          1128:           (current (car remaining)      ;current argument set
        !          1129:                    (car remaining)))
        !          1130:         ((or ready (endp remaining)) result)
        !          1131:       (setq applyval (apply pred current))
        !          1132:       (unless applyval
        !          1133:         (setq ready t)
        !          1134:         (setq result t)))))
        !          1135: 
        !          1136: 
        !          1137: 
        !          1138: ;;; an inverse of elt is needed for setf purposes
        !          1139: 
        !          1140: (defun setelt (seq n newval)
        !          1141:   "In SEQUENCE, set the Nth element to NEWVAL.  Returns NEWVAL.
        !          1142: A sequence means either a list or a vector."
        !          1143:   (let ((l (length seq)))
        !          1144:     (cond
        !          1145:      ((or (< n 0)
        !          1146:           (>= n l))
        !          1147:       (error "N(%d) should be between 0 and %d" n l))
        !          1148:      (t
        !          1149:       ;; only two cases need be considered
        !          1150:       (cond
        !          1151:        ((listp seq)
        !          1152:         (setnth n seq newval))
        !          1153:        ((arrayp seq)
        !          1154:         (aset seq n newval))
        !          1155:        (t
        !          1156:         (error "SEQ should be a sequence, not `%s'"
        !          1157:                (prin1-to-string seq))))))))
        !          1158: 
        !          1159: ;;; Testing with keyword arguments.
        !          1160: ;;;
        !          1161: ;;; Many of the sequence functions use keywords to denote some stylized
        !          1162: ;;; form of selecting entries in a sequence.  The involved arguments
        !          1163: ;;; are collected with a &rest marker (as Emacs Lisp doesn't have a &key
        !          1164: ;;; marker), then they are passed to build-klist, who
        !          1165: ;;; constructs an association list.  That association list is used to
        !          1166: ;;; test for satisfaction and matching.
        !          1167: 
        !          1168: (defun extract-from-klist (key klist &optional default)
        !          1169:   "EXTRACT-FROM-KLIST KEY KLIST [DEFAULT] => value of KEY or DEFAULT
        !          1170: Extract value associated with KEY in KLIST (return DEFAULT if nil)."
        !          1171:   (let ((retrieved (cdr (assoc key klist))))
        !          1172:     (or retrieved default)))
        !          1173: 
        !          1174: (defun add-to-klist (key item klist)
        !          1175:   "ADD-TO-KLIST KEY ITEM KLIST => new KLIST
        !          1176: Add association (KEY . ITEM) to KLIST."
        !          1177:   (setq klist (acons key item klist)))
        !          1178: 
        !          1179: (defun elt-satisfies-test-p (item elt klist)
        !          1180:   "ELT-SATISFIES-TEST-P ITEM ELT KLIST => t or nil
        !          1181: KLIST encodes a keyword-arguments test, as in CH. 14 of CLtL.
        !          1182: True if the given ITEM and ELT satisfy the test."
        !          1183:   (let ((test     (extract-from-klist :test klist))
        !          1184:         (test-not (extract-from-klist :test-not klist))
        !          1185:         (keyfn    (extract-from-klist :key klist 'identity)))
        !          1186:     (cond
        !          1187:      (test
        !          1188:       (funcall test item (funcall keyfn elt)))
        !          1189:      (test-not
        !          1190:       (not (funcall test-not item (funcall keyfn elt))))
        !          1191:      (t                                 ;should never happen
        !          1192:       (error "Neither :test nor :test-not in `%s'"
        !          1193:              (prin1-to-string klist))))))
        !          1194: 
        !          1195: (defun elt-satisfies-if-p   (item klist)
        !          1196:   "ELT-SATISFIES-IF-P ITEM KLIST => t or nil
        !          1197: True if an -if style function was called and ITEM satisfies the
        !          1198: predicate under :predicate in KLIST."
        !          1199:   (let ((predicate (extract-from-klist :predicate klist))
        !          1200:         (keyfn     (extract-from-klist :key 'identity)))
        !          1201:     (funcall predicate item (funcall keyfn elt))))
        !          1202: 
        !          1203: (defun elt-satisfies-if-not-p (item klist)
        !          1204:   "ELT-SATISFIES-IF-NOT-P ITEM KLIST => t or nil
        !          1205: KLIST encodes a keyword-arguments test, as in CH. 14 of CLtL.
        !          1206: True if an -if-not style function was called and ITEM does not satisfy
        !          1207: the predicate under :predicate in KLIST."
        !          1208:   (let ((predicate (extract-from-klist :predicate klist))
        !          1209:         (keyfn     (extract-from-klist :key 'identity)))
        !          1210:     (not (funcall predicate item (funcall keyfn elt)))))
        !          1211: 
        !          1212: (defun elts-match-under-klist-p (e1 e2 klist)
        !          1213:   "ELTS-MATCH-UNDER-KLIST-P E1 E2 KLIST => t or nil
        !          1214: KLIST encodes a keyword-arguments test, as in CH. 14 of CLtL.
        !          1215: True if elements E1 and E2 match under the tests encoded in KLIST."
        !          1216:   (let ((test     (extract-from-klist :test klist))
        !          1217:         (test-not (extract-from-klist :test-not klist))
        !          1218:         (keyfn    (extract-from-klist :key klist 'identity)))
        !          1219:     (cond
        !          1220:      (test
        !          1221:       (funcall test (funcall keyfn e1) (funcall keyfn e2)))
        !          1222:      (test-not
        !          1223:       (not (funcall test-not (funcall keyfn e1) (funcall keyfn e2))))
        !          1224:      (t                                 ;should never happen
        !          1225:       (error "Neither :test nor :test-not in `%s'"
        !          1226:              (prin1-to-string klist))))))
        !          1227: 
        !          1228: ;;;; end of cl-sequences.el
        !          1229: 
        !          1230: ;;;; MULTIPLE VALUES
        !          1231: ;;;;    This package approximates the behavior of the multiple-values
        !          1232: ;;;;    forms of Common Lisp.  
        !          1233: ;;;;
        !          1234: ;;;;    Cesar Quiroz @ UofR DofCSc - Dec. 1986
        !          1235: ;;;;       ([email protected])
        !          1236: 
        !          1237: 
        !          1238: 
        !          1239: ;;; Lisp indentation information
        !          1240: (put 'multiple-value-bind  'lisp-indent-hook 2)
        !          1241: (put 'multiple-value-setq  'lisp-indent-hook 2)
        !          1242: (put 'multiple-value-list  'lisp-indent-hook nil)
        !          1243: (put 'multiple-value-call  'lisp-indent-hook 1)
        !          1244: (put 'multiple-value-prog1 'lisp-indent-hook 1)
        !          1245: 
        !          1246: 
        !          1247: ;;; Global state of the package is kept here
        !          1248: (defvar *mvalues-values* nil
        !          1249:   "Most recently returned multiple-values")
        !          1250: (defvar *mvalues-count*  nil
        !          1251:   "Count of multiple-values returned, or nil if the mechanism was not used")
        !          1252: 
        !          1253: ;;; values is the standard multiple-value-return form.  Must be the
        !          1254: ;;; last thing evaluated inside a function.  If the caller is not
        !          1255: ;;; expecting multiple values, only the first one is passed.  (values)
        !          1256: ;;; is the same as no-values returned (unaware callers see nil). The
        !          1257: ;;; alternative (values-list <list>) is just a convenient shorthand
        !          1258: ;;; and complements multiple-value-list.
        !          1259: 
        !          1260: (defun values (&rest val-forms)
        !          1261:   "Produce multiple values (zero or more).  Each arg is one value.
        !          1262: See also `multiple-value-bind', which is one way to examine the
        !          1263: multiple values produced by a form.  If the containing form or caller
        !          1264: does not check specially to see multiple values, it will see only
        !          1265: the first value."
        !          1266:   (setq *mvalues-values* val-forms)
        !          1267:   (setq *mvalues-count*  (length *mvalues-values*))
        !          1268:   (car *mvalues-values*))
        !          1269: 
        !          1270: 
        !          1271: (defun values-list (&optional val-forms)
        !          1272:   "Produce multiple values (zero or mode).  Each element of LIST is one value.
        !          1273: This is equivalent to (apply 'values LIST)."
        !          1274:   (cond ((nlistp val-forms)
        !          1275:          (error "Argument to values-list must be a list, not `%s'"
        !          1276:                 (prin1-to-string val-forms))))
        !          1277:   (setq *mvalues-values* val-forms)
        !          1278:   (setq *mvalues-count* (length *mvalues-values*))
        !          1279:   (car *mvalues-values*))
        !          1280: 
        !          1281: 
        !          1282: ;;; Callers that want to see the multiple values use these macros.
        !          1283: 
        !          1284: (defmacro multiple-value-list (form)
        !          1285:   "Execute FORM and return a list of all the (multiple) values FORM produces.
        !          1286: See `values' and `multiple-value-bind'."
        !          1287:   (list 'progn
        !          1288:         (list 'setq '*mvalues-count* nil)
        !          1289:         (list 'let (list (list 'it '(gensym)))
        !          1290:               (list 'set 'it form)
        !          1291:               (list 'if '*mvalues-count*
        !          1292:                     (list 'copy-sequence '*mvalues-values*)
        !          1293:                     (list 'progn
        !          1294:                           (list 'setq '*mvalues-count* 1)
        !          1295:                           (list 'setq '*mvalues-values*
        !          1296:                                 (list 'list (list 'symbol-value 'it)))
        !          1297:                           (list 'copy-sequence '*mvalues-values*))))))
        !          1298: 
        !          1299: (defmacro multiple-value-call (function &rest args)
        !          1300:   "Call FUNCTION on all the values produced by the remaining arguments.
        !          1301: (multiple-value-call '+ (values 1 2) (values 3 4)) is 10."
        !          1302:   (let* ((result (gentemp))
        !          1303:          (arg    (gentemp)))
        !          1304:     (list 'apply (list 'function (eval function))
        !          1305:           (list 'let* (list (list result '()))
        !          1306:                 (list 'dolist (list arg (list 'quote args) result)
        !          1307:                       (list 'setq result
        !          1308:                             (list 'append
        !          1309:                                   result
        !          1310:                                   (list 'multiple-value-list
        !          1311:                                         (list 'eval arg)))))))))
        !          1312: 
        !          1313: (defmacro multiple-value-bind (vars form &rest body)
        !          1314:   "Bind VARS to the (multiple) values produced by FORM, then do BODY.
        !          1315: VARS is a list of variables; each is bound to one of FORM's values.
        !          1316: If FORM doesn't make enough values, the extra variables are bound to nil.
        !          1317: (Ordinary forms produce only one value; to produce more, use `values'.)
        !          1318: Extra values are ignored.
        !          1319: BODY (zero or more forms) is executed with the variables bound,
        !          1320: then the bindings are unwound."
        !          1321:   (let* ((vals   (gentemp))             ;name for intermediate values
        !          1322:          (clauses (mv-bind-clausify     ;convert into clauses usable
        !          1323:                    vars vals)))         ; in a let form
        !          1324:     (list* 'let*
        !          1325:            (cons (list vals (list 'multiple-value-list form))
        !          1326:                  clauses)
        !          1327:            body)))
        !          1328: 
        !          1329: (defmacro multiple-value-setq (vars form)
        !          1330:   "Set VARS to the (multiple) values produced by FORM.
        !          1331: VARS is a list of variables; each is set to one of FORM's values.
        !          1332: If FORM doesn't make enough values, the extra variables are set to nil.
        !          1333: (Ordinary forms produce only one value; to produce more, use `values'.)
        !          1334: Extra values are ignored."
        !          1335:   (let* ((vals (gentemp))               ;name for intermediate values
        !          1336:          (clauses (mv-bind-clausify     ;convert into clauses usable
        !          1337:                    vars vals)))         ; in a setq (after append).
        !          1338:     (list 'let*
        !          1339:           (list (list vals (list 'multiple-value-list form)))
        !          1340:           (cons 'setq (apply (function append) clauses)))))
        !          1341: 
        !          1342: (defmacro multiple-value-prog1 (form &rest body)
        !          1343:   "Evaluate FORM, then BODY, then produce the same values FORM produced.
        !          1344: Thus, (multiple-value-prog1 (values 1 2) (foobar)) produces values 1 and 2.
        !          1345: This is like `prog1' except that `prog1' would produce only one value,
        !          1346: which would be the first of FORM's values."
        !          1347:   (let* ((heldvalues (gentemp)))
        !          1348:     (cons 'let*
        !          1349:           (cons (list (list heldvalues (list 'multiple-value-list form)))
        !          1350:                 (append body (list (list 'values-list heldvalues)))))))
        !          1351: 
        !          1352: ;;; utility functions
        !          1353: ;;;
        !          1354: ;;; mv-bind-clausify makes the pairs needed to have the variables in
        !          1355: ;;; the variable list correspond with the values returned by the form.
        !          1356: ;;; vals is a fresh symbol that intervenes in all the bindings.
        !          1357: 
        !          1358: (defun mv-bind-clausify (vars vals)
        !          1359:   "MV-BIND-CLAUSIFY VARS VALS => Auxiliary list
        !          1360: Forms a list of pairs `(,(nth i vars) (nth i vals)) for i from 0 to
        !          1361: the length of VARS (a list of symbols).  VALS is just a fresh symbol."
        !          1362:   (if (or (nlistp vars)
        !          1363:           (notevery 'symbolp vars))
        !          1364:       (error "Expected a list of symbols, not `%s'"
        !          1365:              (prin1-to-string vars)))
        !          1366:   (let* ((nvars    (length vars))
        !          1367:          (clauses '()))
        !          1368:     (dotimes (n nvars clauses)
        !          1369:       (setq clauses (cons (list (nth n vars)
        !          1370:                                 (list 'nth n vals)) clauses)))))
        !          1371: 
        !          1372: ;;;; end of cl-multiple-values.el
        !          1373: 
        !          1374: ;;;; ARITH
        !          1375: ;;;;    This file provides integer arithmetic extensions.  Although
        !          1376: ;;;;    Emacs Lisp doesn't really support anything but integers, that
        !          1377: ;;;;    has still to be made to look more or less standard.
        !          1378: ;;;;
        !          1379: ;;;;
        !          1380: ;;;;    Cesar Quiroz @ UofR DofCSc - Dec. 1986
        !          1381: ;;;;       ([email protected])
        !          1382: 
        !          1383: 
        !          1384: (defun plusp (number)
        !          1385:   "True if NUMBER is strictly greater than zero."
        !          1386:   (> number 0))
        !          1387: 
        !          1388: (defun minusp (number)
        !          1389:   "True if NUMBER is strictly less than zero."
        !          1390:   (< number 0))
        !          1391: 
        !          1392: (defun oddp (number)
        !          1393:   "True if INTEGER is not divisible by 2."
        !          1394:   (/= (% number 2) 0))
        !          1395: 
        !          1396: (defun evenp (number)
        !          1397:   "True if INTEGER is divisible by 2."
        !          1398:   (= (% number 2) 0))
        !          1399: 
        !          1400: (defun abs (number)
        !          1401:   "Return the absolute value of NUMBER."
        !          1402:   (cond
        !          1403:    ((< number 0)
        !          1404:     (- 0 number))
        !          1405:    (t                                   ;number is >= 0
        !          1406:     number)))
        !          1407: 
        !          1408: (defun signum (number)
        !          1409:   "Return -1, 0 or 1 according to the sign of NUMBER."
        !          1410:   (cond
        !          1411:    ((< number 0)
        !          1412:     -1)
        !          1413:    ((> number 0)
        !          1414:     1)
        !          1415:    (t                                   ;exactly zero
        !          1416:     0)))
        !          1417: 
        !          1418: (defun gcd (&rest integers)
        !          1419:   "Return the greatest common divisor of all the arguments.
        !          1420: The arguments must be integers.  With no arguments, value is zero."
        !          1421:   (let ((howmany (length integers)))
        !          1422:     (cond
        !          1423:      ((= howmany 0)
        !          1424:       0)
        !          1425:      ((= howmany 1)
        !          1426:       (abs (car integers)))
        !          1427:      ((> howmany 2)
        !          1428:       (apply (function gcd)
        !          1429:        (cons (gcd (nth 0 integers) (nth 1 integers))
        !          1430:              (nthcdr 2 integers))))
        !          1431:      (t                                 ;howmany=2
        !          1432:       ;; essentially the euclidean algorithm
        !          1433:       (when (zerop (* (nth 0 integers) (nth 1 integers)))
        !          1434:         (error "A zero argument is invalid for `gcd'"))
        !          1435:       (do* ((absa (abs (nth 0 integers))) ; better to operate only
        !          1436:             (absb (abs (nth 1 integers))) ;on positives.
        !          1437:             (dd (max absa absb))        ; setup correct order for the
        !          1438:             (ds (min absa absb))        ;succesive divisions.
        !          1439:             ;; intermediate results
        !          1440:             (q 0)
        !          1441:             (r 0)
        !          1442:             ;; final results
        !          1443:             (done nil)                  ; flag: end of iterations
        !          1444:             (result 0))                 ; final value
        !          1445:           (done result)
        !          1446:         (setq q (/ dd ds))
        !          1447:         (setq r (% dd ds))
        !          1448:         (cond 
        !          1449:          ((zerop r) (setq done t) (setq result ds))
        !          1450:          ( t        (setq dd ds)  (setq ds r))))))))
        !          1451: 
        !          1452: (defun lcm (integer &rest more)
        !          1453:   "Return the least common multiple of all the arguments.
        !          1454: The arguments must be integers and there must be at least one of them."
        !          1455:   (let ((howmany (length more))
        !          1456:         (a       integer)
        !          1457:         (b       (nth 0 more))
        !          1458:         prod                            ; intermediate product
        !          1459:         (yetmore (nthcdr 1 more)))
        !          1460:     (cond
        !          1461:      ((zerop howmany)
        !          1462:       (abs a))
        !          1463:      ((> howmany 1)                     ; recursive case
        !          1464:       (apply (function lcm)
        !          1465:              (cons (lcm a b) yetmore)))
        !          1466:      (t                                 ; base case, just 2 args
        !          1467:       (setq prod (* a b))
        !          1468:       (cond
        !          1469:        ((zerop prod)
        !          1470:         0)
        !          1471:        (t
        !          1472:         (/ (abs prod) (gcd a b))))))))
        !          1473: 
        !          1474: (defun isqrt (number)
        !          1475:   "Return the integer square root of NUMBER.
        !          1476: NUMBER must not be negative.  Result is largest integer less than or
        !          1477: equal to the real square root of the argument."
        !          1478:   (cond
        !          1479:    ((minusp number)
        !          1480:     (error "Argument to `isqrt' must not be negative"))
        !          1481:    ((zerop number)
        !          1482:     0)
        !          1483:    ((<= number 3)
        !          1484:     1)
        !          1485:    (t
        !          1486:     ;; This is some sort of newtonian iteration, trying not to get in
        !          1487:     ;; an infinite loop.  That's why I catch 0, 1, 2 and 3 as special
        !          1488:     ;; cases, so then rounding won't make this iteration loop.
        !          1489:     (do* ((approx (/ number 2) iter)
        !          1490:           (done nil)
        !          1491:           (iter   0))
        !          1492:         (done (if (> (* approx approx) number)
        !          1493:                   (- approx 1)          ;reached from above
        !          1494:                   approx))
        !          1495:       (setq iter
        !          1496:             (/ (+ approx
        !          1497:                   (/ number approx)
        !          1498:                   (if (>= (% number approx) (/ approx 2))
        !          1499:                       1 0))
        !          1500:                2))
        !          1501:       (setq done (eql approx iter))))))
        !          1502: 
        !          1503: (defun floor (number &optional divisor)
        !          1504:   "Divide DIVIDEND by DIVISOR, rounding toward minus infinity.
        !          1505: DIVISOR defaults to 1.  The remainder is produced as a second value."
        !          1506:   (cond
        !          1507:    ((and (null divisor)                 ; trivial case
        !          1508:          (numberp number))
        !          1509:     (values number 0))
        !          1510:    (t                                   ; do the division
        !          1511:     (multiple-value-bind
        !          1512:         (q r s)
        !          1513:         (safe-idiv number divisor)
        !          1514:       (cond
        !          1515:        ((zerop s)
        !          1516:         (values 0 0))
        !          1517:        ((plusp s)
        !          1518:         (values q r))
        !          1519:        (t
        !          1520:         (unless (zerop r)
        !          1521:           (setq q (- 0 (+ q 1)))
        !          1522:           (setq r (- number (* q divisor))))
        !          1523:         (values q r)))))))
        !          1524: 
        !          1525: (defun ceiling (number &optional divisor)
        !          1526:   "Divide DIVIDEND by DIVISOR, rounding toward plus infinity.
        !          1527: DIVISOR defaults to 1.  The remainder is produced as a second value."
        !          1528:   (cond
        !          1529:    ((and (null divisor)                 ; trivial case
        !          1530:          (numberp number))
        !          1531:     (values number 0))
        !          1532:    (t                                   ; do the division
        !          1533:     (multiple-value-bind
        !          1534:         (q r s)
        !          1535:         (safe-idiv number divisor)
        !          1536:       (cond
        !          1537:        ((zerop s)
        !          1538:         (values 0 0))
        !          1539:        ((minusp s)
        !          1540:         (values q r))
        !          1541:        (t
        !          1542:         (unless (zerop r)
        !          1543:           (setq q (+ q 1))
        !          1544:           (setq r (- number (* q divisor))))
        !          1545:         (values q r)))))))
        !          1546: 
        !          1547: (defun truncate (number &optional divisor)
        !          1548:   "Divide DIVIDEND by DIVISOR, rounding toward zero.
        !          1549: DIVISOR defaults to 1.  The remainder is produced as a second value."
        !          1550:   (cond
        !          1551:    ((and (null divisor)                 ; trivial case
        !          1552:          (numberp number))
        !          1553:     (values number 0))
        !          1554:    (t                                   ; do the division
        !          1555:     (multiple-value-bind
        !          1556:         (q r s)
        !          1557:         (safe-idiv number divisor)
        !          1558:       (cond
        !          1559:        ((zerop s)
        !          1560:         (values 0 0))
        !          1561:        ((plusp s)
        !          1562:         (values q r))
        !          1563:        (t
        !          1564:         (unless (zerop r)
        !          1565:           (setq q (- 0 q))
        !          1566:           (setq r (- number (* q divisor))))
        !          1567:         (values q r)))))))
        !          1568: 
        !          1569: (defun round (number &optional divisor)
        !          1570:   "Divide DIVIDEND by DIVISOR, rounding to nearest integer.
        !          1571: DIVISOR defaults to 1.  The remainder is produced as a second value."
        !          1572:   (cond
        !          1573:    ((and (null divisor)                 ; trivial case
        !          1574:          (numberp number))
        !          1575:     (values number 0))    
        !          1576:    (t                                   ; do the division
        !          1577:     (multiple-value-bind
        !          1578:         (q r s)
        !          1579:         (safe-idiv number divisor)
        !          1580:       (setq r (abs r))
        !          1581:       ;; adjust magnitudes first, and then signs
        !          1582:       (let ((other-r (- (abs divisor) r)))
        !          1583:         (cond
        !          1584:          ((> r other-r)
        !          1585:           (setq q (+ q 1)))
        !          1586:          ((and (= r other-r)
        !          1587:                (oddp q))
        !          1588:           ;; round to even is mandatory
        !          1589:           (setq q (+ q 1))))
        !          1590:         (setq q (* s q))
        !          1591:         (setq r (- number (* q divisor)))
        !          1592:         (values q r))))))
        !          1593: 
        !          1594: (defun mod (number divisor)
        !          1595:   "Return remainder of X by Y (rounding quotient toward minus infinity).
        !          1596: That is, the remainder goes with the quotient produced by `floor'."
        !          1597:   (multiple-value-bind (q r) (floor number divisor)
        !          1598:     r))
        !          1599: 
        !          1600: (defun rem (number divisor)
        !          1601:   "Return remainder of X by Y (rounding quotient toward zero).
        !          1602: That is, the remainder goes with the quotient produced by `truncate'."
        !          1603:   (multiple-value-bind (q r) (truncate number divisor)
        !          1604:     r))
        !          1605: 
        !          1606: ;;; internal utilities
        !          1607: ;;;
        !          1608: ;;; safe-idiv performs an integer division with positive numbers only.
        !          1609: ;;; It is known that some machines/compilers implement weird remainder
        !          1610: ;;; computations when working with negatives, so the idea here is to
        !          1611: ;;; make sure we know what is coming back to the caller in all cases.
        !          1612: 
        !          1613: (defun safe-idiv (a b)
        !          1614:   "SAFE-IDIV A B => Q R S
        !          1615: Q=|A|/|B|, R is the rest, S is the sign of A/B."
        !          1616:   (unless (and (numberp a) (numberp b))
        !          1617:     (error "Arguments to `safe-idiv' must be numbers"))
        !          1618:   (when (zerop b)
        !          1619:     (error "Cannot divide %d by zero" a))
        !          1620:   (let* ((absa (abs a))
        !          1621:          (absb (abs b))
        !          1622:          (q    (/ absa absb))
        !          1623:          (s    (signum (* a b)))
        !          1624:          (r    (- a (* (* s q) b))))
        !          1625:     (values q r s)))
        !          1626: 
        !          1627: ;;;; end of cl-arith.el
        !          1628: 
        !          1629: ;;;; SETF
        !          1630: ;;;;    This file provides the setf macro and friends. The purpose has
        !          1631: ;;;;    been modest, only the simplest defsetf forms are accepted.
        !          1632: ;;;;    Use it and enjoy.
        !          1633: ;;;;
        !          1634: ;;;;    Cesar Quiroz @ UofR DofCSc - Dec. 1986
        !          1635: ;;;;       ([email protected])
        !          1636: 
        !          1637: 
        !          1638: (defkeyword :setf-update-fn
        !          1639:   "Property, its value is the function setf must invoke to update a
        !          1640: generalized variable whose access form is a function call of the
        !          1641: symbol that has this property.")
        !          1642: 
        !          1643: (defkeyword :setf-update-doc
        !          1644:   "Property of symbols that have a `defsetf' update function on them,
        !          1645: installed by the `defsetf' from its optional third argument.")
        !          1646: 
        !          1647: (defmacro setf (&rest pairs)
        !          1648:   "Generalized `setq' that can set things other than variable values.
        !          1649: A use of `setf' looks like (setf {PLACE VALUE}...).
        !          1650: The behavior of (setf PLACE VALUE) is to access the generalized variable
        !          1651: at PLACE and store VALUE there.  It returns VALUE.  If there is more
        !          1652: than one PLACE and VALUE, each PLACE is set from its VALUE before
        !          1653: the next PLACE is evaluated."
        !          1654:   (let ((nforms (length pairs)))
        !          1655:     ;; check the number of subforms
        !          1656:     (cond
        !          1657:      ((/= (% nforms 2) 0)
        !          1658:       (error "Odd number of arguments to `setf'"))
        !          1659:      ((= nforms 0)
        !          1660:       nil)
        !          1661:      ((> nforms 2)
        !          1662:       ;; this is the recursive case
        !          1663:       (cons 'progn
        !          1664:             (do*                        ;collect the place-value pairs
        !          1665:                 ((args pairs (cddr args))
        !          1666:                  (place (car args) (car args))
        !          1667:                  (value (cadr args) (cadr args))
        !          1668:                  (result '()))
        !          1669:                 ((endp args) (nreverse result))
        !          1670:               (setq result
        !          1671:                     (cons (list 'setf place value)
        !          1672:                           result)))))
        !          1673:      (t                                 ;i.e., nforms=2
        !          1674:       ;; this is the base case (SETF PLACE VALUE)
        !          1675:       (let* ((place (car pairs))
        !          1676:              (value (cadr pairs))
        !          1677:              (head  nil)
        !          1678:              (updatefn nil))
        !          1679:         ;; dispatch on the type of the PLACE
        !          1680:         (cond
        !          1681:          ((symbolp place)
        !          1682:           (list 'setq place value))
        !          1683:          ((and (listp place)
        !          1684:                (setq head (car place))
        !          1685:                (symbolp head)
        !          1686:                (setq updatefn (get head :setf-update-fn)))
        !          1687:          (if (or (and (consp updatefn) (eq (car updatefn) 'lambda))
        !          1688:                  (and (symbolp updatefn)
        !          1689:                       (fboundp updatefn)
        !          1690:                       (let ((defn (symbol-function updatefn)))
        !          1691:                         (or (subrp defn)
        !          1692:                             (and (consp defn) (eq (car defn) 'lambda))))))
        !          1693:              (cons updatefn (append (cdr place) (list value)))
        !          1694:            (multiple-value-bind
        !          1695:                (bindings newsyms)
        !          1696:                (pair-with-newsyms (append (cdr place) (list value)))
        !          1697:              ;; this let* gets new symbols to ensure adequate order of
        !          1698:              ;; evaluation of the subforms.
        !          1699:              (list 'let
        !          1700:                    bindings              
        !          1701:                    (cons updatefn newsyms)))))
        !          1702:          (t
        !          1703:           (error "No `setf' update-function for `%s'"
        !          1704:                  (prin1-to-string place)))))))))
        !          1705: 
        !          1706: (defmacro defsetf (accessfn updatefn &optional docstring)
        !          1707:   "Define how `setf' works on a certain kind of generalized variable.
        !          1708: A use of `defsetf' looks like (defsetf ACCESSFN UPDATEFN [DOCSTRING]).
        !          1709: ACCESSFN is a symbol.  UPDATEFN is a function or macro which takes
        !          1710: one more argument than ACCESSFN does.  DEFSETF defines the translation
        !          1711: of (SETF (ACCESFN . ARGS) NEWVAL) to be a form like (UPDATEFN ARGS... NEWVAL).
        !          1712: The function UPDATEFN must return its last arg, after performing the
        !          1713: updating called for."
        !          1714:   ;; reject ill-formed requests.  too bad one can't test for functionp
        !          1715:   ;; or macrop.
        !          1716:   (when (not (symbolp accessfn))
        !          1717:     (error "First argument of `defsetf' must be a symbol, not `%s'"
        !          1718:            (prin1-to-string accessfn)))
        !          1719:   ;; update properties
        !          1720:   (put accessfn :setf-update-fn updatefn)
        !          1721:   (put accessfn :setf-update-doc docstring))
        !          1722: 
        !          1723: ;;; This section provides the "default" setfs for Common-Emacs-Lisp
        !          1724: ;;; The user will not normally add anything to this, although
        !          1725: ;;; defstruct will introduce new ones as a matter of fact.
        !          1726: ;;;
        !          1727: ;;; Apply is a special case.   The Common Lisp
        !          1728: ;;; standard makes the case of apply be useful when the user writes
        !          1729: ;;; something like (apply #'name ...), Emacs Lisp doesn't have the #
        !          1730: ;;; stuff, but it has (function ...).  Notice that V18 includes a new
        !          1731: ;;; apply: this file is compatible with V18 and pre-V18 Emacses.
        !          1732: 
        !          1733: ;;; INCOMPATIBILITY: the SETF macro evaluates its arguments in the
        !          1734: ;;; (correct) left to right sequence *before* checking for apply
        !          1735: ;;; methods (which should really be an special case inside setf).  Due
        !          1736: ;;; to this, the lambda expression defsetf'd to apply will succeed in
        !          1737: ;;; applying the right function even if the name was not quoted, but
        !          1738: ;;; computed!  That extension is not Common Lisp (nor is particularly
        !          1739: ;;; useful, I think).
        !          1740: 
        !          1741: (defsetf apply
        !          1742:   (lambda (&rest args)
        !          1743:     ;; dissasemble the calling form
        !          1744:     ;; "(((quote fn) x1 x2 ... xn) val)" (function instead of quote, too)
        !          1745:     (let* ((fnform (car args))          ;functional form
        !          1746:            (applyargs (append           ;arguments "to apply fnform"
        !          1747:                        (apply 'list* (butlast (cdr args)))
        !          1748:                        (last args)))
        !          1749:            (newupdater nil))            ; its update-fn, if any
        !          1750:       (cond
        !          1751:        ((and (symbolp fnform)
        !          1752:              (setq newupdater (get fnform :setf-update-fn)))
        !          1753:         ;; just do it
        !          1754:         (apply  newupdater applyargs))
        !          1755:        (t
        !          1756:         (error "Can't `setf' to `%s'"
        !          1757:                (prin1-to-string fnform))))))
        !          1758:   "`apply' is a special case for `setf'")
        !          1759: 
        !          1760: 
        !          1761: (defsetf aref
        !          1762:   aset
        !          1763:   "`setf' inversion for `aref'")
        !          1764: 
        !          1765: (defsetf nth
        !          1766:   setnth
        !          1767:   "`setf' inversion for `nth'")
        !          1768: 
        !          1769: (defsetf nthcdr
        !          1770:   setnthcdr
        !          1771:   "`setf' inversion for `nthcdr'")
        !          1772: 
        !          1773: (defsetf elt
        !          1774:   setelt
        !          1775:   "`setf' inversion for `elt'")
        !          1776: 
        !          1777: (defsetf first
        !          1778:   (lambda (list val) (setnth 0 list val))
        !          1779:   "`setf' inversion for `first'")
        !          1780: 
        !          1781: (defsetf second
        !          1782:   (lambda (list val) (setnth 1 list val))
        !          1783:   "`setf' inversion for `second'")
        !          1784: 
        !          1785: (defsetf third
        !          1786:   (lambda (list val) (setnth 2 list val))
        !          1787:   "`setf' inversion for `third'")
        !          1788: 
        !          1789: (defsetf fourth
        !          1790:   (lambda (list val) (setnth 3 list val))
        !          1791:   "`setf' inversion for `fourth'")
        !          1792: 
        !          1793: (defsetf fifth
        !          1794:   (lambda (list val) (setnth 4 list val))
        !          1795:   "`setf' inversion for `fifth'")
        !          1796: 
        !          1797: (defsetf sixth
        !          1798:   (lambda (list val) (setnth 5 list val))
        !          1799:   "`setf' inversion for `sixth'")
        !          1800: 
        !          1801: (defsetf seventh
        !          1802:   (lambda (list val) (setnth 6 list val))
        !          1803:   "`setf' inversion for `seventh'")
        !          1804: 
        !          1805: (defsetf eighth
        !          1806:   (lambda (list val) (setnth 7 list val))
        !          1807:   "`setf' inversion for `eighth'")
        !          1808: 
        !          1809: (defsetf ninth
        !          1810:   (lambda (list val) (setnth 8 list val))
        !          1811:   "`setf' inversion for `ninth'")
        !          1812: 
        !          1813: (defsetf tenth
        !          1814:   (lambda (list val) (setnth 9 list val))
        !          1815:   "`setf' inversion for `tenth'")
        !          1816: 
        !          1817: (defsetf rest
        !          1818:   (lambda (list val) (setcdr list val))
        !          1819:   "`setf' inversion for `rest'")
        !          1820: 
        !          1821: (defsetf car setcar "Replace the car of a cons")
        !          1822: 
        !          1823: (defsetf cdr setcdr "Replace the cdr of a cons")
        !          1824: 
        !          1825: (defsetf caar
        !          1826:   (lambda (list val) (setcar (nth 0 list) val))
        !          1827:   "`setf' inversion for `caar'")
        !          1828: 
        !          1829: (defsetf cadr
        !          1830:   (lambda (list val) (setcar (cdr list) val))
        !          1831:   "`setf' inversion for `cadr'")
        !          1832: 
        !          1833: (defsetf cdar
        !          1834:   (lambda (list val) (setcdr (car list) val))
        !          1835:   "`setf' inversion for `cdar'")
        !          1836: 
        !          1837: (defsetf cddr
        !          1838:   (lambda (list val) (setcdr (cdr list) val))
        !          1839:   "`setf' inversion for `cddr'")
        !          1840: 
        !          1841: (defsetf caaar
        !          1842:   (lambda (list val) (setcar (caar list) val))
        !          1843:   "`setf' inversion for `caaar'")
        !          1844: 
        !          1845: (defsetf caadr
        !          1846:   (lambda (list val) (setcar (cadr list) val))
        !          1847:   "`setf' inversion for `caadr'")
        !          1848: 
        !          1849: (defsetf cadar
        !          1850:   (lambda (list val) (setcar (cdar list) val))
        !          1851:   "`setf' inversion for `cadar'")
        !          1852: 
        !          1853: (defsetf cdaar
        !          1854:   (lambda (list val) (setcdr (caar list) val))
        !          1855:   "`setf' inversion for `cdaar'")
        !          1856: 
        !          1857: (defsetf caddr
        !          1858:   (lambda (list val) (setcar (cddr list) val))
        !          1859:   "`setf' inversion for `caddr'")
        !          1860: 
        !          1861: (defsetf cdadr
        !          1862:   (lambda (list val) (setcdr (cadr list) val))
        !          1863:   "`setf' inversion for `cdadr'")
        !          1864: 
        !          1865: (defsetf cddar
        !          1866:   (lambda (list val) (setcdr (cdar list) val))
        !          1867:   "`setf' inversion for `cddar'")
        !          1868: 
        !          1869: (defsetf cdddr
        !          1870:   (lambda (list val) (setcdr (cddr list) val))
        !          1871:   "`setf' inversion for `cdddr'")
        !          1872: 
        !          1873: (defsetf caaaar
        !          1874:   (lambda (list val) (setcar (caaar list) val))
        !          1875:   "`setf' inversion for `caaaar'")
        !          1876: 
        !          1877: (defsetf caaadr
        !          1878:   (lambda (list val) (setcar (caadr list) val))
        !          1879:   "`setf' inversion for `caaadr'")
        !          1880: 
        !          1881: (defsetf caadar
        !          1882:   (lambda (list val) (setcar (cadar list) val))
        !          1883:   "`setf' inversion for `caadar'")
        !          1884: 
        !          1885: (defsetf cadaar
        !          1886:   (lambda (list val) (setcar (cdaar list) val))
        !          1887:   "`setf' inversion for `cadaar'")
        !          1888: 
        !          1889: (defsetf cdaaar
        !          1890:   (lambda (list val) (setcdr (caar list) val))
        !          1891:   "`setf' inversion for `cdaaar'")
        !          1892: 
        !          1893: (defsetf caaddr
        !          1894:   (lambda (list val) (setcar (caddr list) val))
        !          1895:   "`setf' inversion for `caaddr'")
        !          1896: 
        !          1897: (defsetf cadadr
        !          1898:   (lambda (list val) (setcar (cdadr list) val))
        !          1899:   "`setf' inversion for `cadadr'")
        !          1900: 
        !          1901: (defsetf cdaadr
        !          1902:   (lambda (list val) (setcdr (caadr list) val))
        !          1903:   "`setf' inversion for `cdaadr'")
        !          1904: 
        !          1905: (defsetf caddar
        !          1906:   (lambda (list val) (setcar (cddar list) val))
        !          1907:   "`setf' inversion for `caddar'")
        !          1908: 
        !          1909: (defsetf cdadar
        !          1910:   (lambda (list val) (setcdr (cadar list) val))
        !          1911:   "`setf' inversion for `cdadar'")
        !          1912: 
        !          1913: (defsetf cddaar
        !          1914:   (lambda (list val) (setcdr (cdaar list) val))
        !          1915:   "`setf' inversion for `cddaar'")
        !          1916: 
        !          1917: (defsetf cadddr
        !          1918:   (lambda (list val) (setcar (cdddr list) val))
        !          1919:   "`setf' inversion for `cadddr'")
        !          1920: 
        !          1921: (defsetf cddadr
        !          1922:   (lambda (list val) (setcdr (cdadr list) val))
        !          1923:   "`setf' inversion for `cddadr'")
        !          1924: 
        !          1925: (defsetf cdaddr
        !          1926:   (lambda (list val) (setcdr (caddr list) val))
        !          1927:   "`setf' inversion for `cdaddr'")
        !          1928: 
        !          1929: (defsetf cdddar
        !          1930:   (lambda (list val) (setcdr (cddar list) val))
        !          1931:   "`setf' inversion for `cdddar'")
        !          1932: 
        !          1933: (defsetf cddddr
        !          1934:   (lambda (list val) (setcdr (cddr list) val))
        !          1935:   "`setf' inversion for `cddddr'")
        !          1936: 
        !          1937: 
        !          1938: (defsetf get
        !          1939:   put
        !          1940:   "`setf' inversion for `get' is `put'")
        !          1941: 
        !          1942: (defsetf symbol-function
        !          1943:   fset
        !          1944:   "`setf' inversion for `symbol-function' is `fset'")
        !          1945: 
        !          1946: (defsetf symbol-plist
        !          1947:   setplist
        !          1948:   "`setf' inversion for `symbol-plist' is `setplist'")
        !          1949: 
        !          1950: (defsetf symbol-value
        !          1951:   set
        !          1952:   "`setf' inversion for `symbol-value' is `set'")
        !          1953: 
        !          1954: ;;; Modify macros
        !          1955: ;;;
        !          1956: ;;; It could be nice to implement define-modify-macro, but I don't
        !          1957: ;;; think it really pays.
        !          1958: 
        !          1959: (defmacro incf (ref &optional delta)
        !          1960:   "(incf REF [DELTA]) -> increment the g.v. REF by DELTA (default 1)"
        !          1961:   (if (null delta)
        !          1962:       (setq delta 1))
        !          1963:   (list 'setf ref (list '+ ref delta)))
        !          1964: 
        !          1965: (defmacro decf (ref &optional delta)
        !          1966:   "(decf REF [DELTA]) -> decrement the g.v. REF by DELTA (default 1)"
        !          1967:   (if (null delta)
        !          1968:       (setq delta 1))
        !          1969:   (list 'setf ref (list '- ref delta)))
        !          1970: 
        !          1971: (defmacro push (item ref)
        !          1972:   "(push ITEM REF) -> cons ITEM at the head of the g.v. REF (a list)"
        !          1973:   (list 'setf ref (list 'cons item ref)))
        !          1974: 
        !          1975: (defmacro pushnew (item ref)
        !          1976:   "(pushnew ITEM REF): adjoin ITEM at the head of the g.v. REF (a list)"
        !          1977:   (list 'setf ref (list 'adjoin item ref)))
        !          1978: 
        !          1979: (defmacro pop (ref)
        !          1980:   "(pop REF) -> (prog1 (car REF) (setf REF (cdr REF)))"
        !          1981:   (let ((listname (gensym)))
        !          1982:     (list 'let (list (list listname ref))
        !          1983:           (list 'prog1
        !          1984:                 (list 'car listname)
        !          1985:                 (list 'setf ref (list 'cdr listname))))))
        !          1986: 
        !          1987: ;;; PSETF
        !          1988: ;;;
        !          1989: ;;; Psetf is the generalized variable equivalent of psetq.  The right
        !          1990: ;;; hand sides are evaluated and assigned (via setf) to the left hand
        !          1991: ;;; sides. The evaluations are done in an environment where they
        !          1992: ;;; appear to occur in parallel.
        !          1993: 
        !          1994: (defmacro psetf (&rest pairs)
        !          1995:   "(psetf {PLACE VALUE}...): Set several generalized variables in parallel.
        !          1996: All the VALUEs are computed, and then all the PLACEs are stored as in `setf'.
        !          1997: See also `psetq', `shiftf' and `rotatef'."
        !          1998:   (unless (evenp (length pairs))
        !          1999:     (error "Odd number of arguments to `psetf'"))
        !          2000:   (multiple-value-bind
        !          2001:       (places forms)
        !          2002:       (unzip-list pairs)
        !          2003:     ;; obtain fresh symbols to simulate the parallelism
        !          2004:     (multiple-value-bind
        !          2005:         (bindings newsyms)
        !          2006:         (pair-with-newsyms forms)
        !          2007:       (list 'let
        !          2008:             bindings
        !          2009:             (cons 'setf (zip-lists places newsyms))
        !          2010:             nil))))
        !          2011: 
        !          2012: ;;; SHIFTF and ROTATEF 
        !          2013: ;;;
        !          2014: 
        !          2015: (defmacro shiftf (&rest forms)
        !          2016:   "(shiftf PLACE1 PLACE2... NEWVALUE): set PLACE1 to PLACE2, PLACE2 to PLACE3...
        !          2017: Each PLACE is set to the old value of the following PLACE,
        !          2018: and the last PLACE is set to the value NEWVALUE."
        !          2019:   (unless (> (length forms) 1)
        !          2020:     (error "`shiftf' needs more than one argument"))
        !          2021:   (let ((places (butlast forms))
        !          2022:        (newvalue (car (last forms))))
        !          2023:     ;; the places are accessed to fresh symbols
        !          2024:     (multiple-value-bind
        !          2025:        (bindings newsyms)
        !          2026:        (pair-with-newsyms places)
        !          2027:       (list 'let bindings
        !          2028:            (cons 'setf
        !          2029:                  (zip-lists places
        !          2030:                             (append (cdr newsyms) (list newvalue))))
        !          2031:            (car newsyms)))))
        !          2032: 
        !          2033: (defmacro rotatef (&rest places)
        !          2034:   "(rotatef PLACE...) sets each PLACE to the old value of the following PLACE.
        !          2035: The last PLACE is set to the old value of the first PLACE.
        !          2036: Thus, the values rotate through the PLACEs."
        !          2037:   (cond
        !          2038:    ((null places)
        !          2039:     nil)
        !          2040:    (t
        !          2041:     (multiple-value-bind
        !          2042:        (bindings newsyms)
        !          2043:        (pair-with-newsyms places)
        !          2044:       (list
        !          2045:        'let bindings
        !          2046:        (cons 'setf
        !          2047:             (zip-lists places
        !          2048:                        (append (cdr newsyms) (list (car newsyms)))))
        !          2049:        nil)))))
        !          2050: 
        !          2051: ;;;; STRUCTS
        !          2052: ;;;;    This file provides the structures mechanism.  See the
        !          2053: ;;;;    documentation for Common-Lisp's defstruct.  Mine doesn't
        !          2054: ;;;;    implement all the functionality of the standard, although some
        !          2055: ;;;;    more could be grafted if so desired.  More details along with
        !          2056: ;;;;    the code.
        !          2057: ;;;;
        !          2058: ;;;;
        !          2059: ;;;;    Cesar Quiroz @ UofR DofCSc - Dec. 1986
        !          2060: ;;;;       ([email protected])
        !          2061: 
        !          2062: 
        !          2063: (defkeyword :include             "Syntax of `defstruct'")
        !          2064: (defkeyword :named               "Syntax of `defstruct'")
        !          2065: (defkeyword :conc-name           "Syntax of `defstruct'")
        !          2066: (defkeyword :copier              "Syntax of `defstruct'")
        !          2067: (defkeyword :predicate           "Syntax of `defstruct'")
        !          2068: (defkeyword :print-function      "Syntax of `defstruct'")
        !          2069: (defkeyword :type                "Syntax of `defstruct'")
        !          2070: (defkeyword :initial-offset      "Syntax of `defstruct'")
        !          2071: 
        !          2072: (defkeyword :structure-doc       "Documentation string for a structure.")
        !          2073: (defkeyword :structure-slotsn    "Number of slots in structure")
        !          2074: (defkeyword :structure-slots     "List of the slot's names")
        !          2075: (defkeyword :structure-indices   "List of (KEYWORD-NAME . INDEX)")
        !          2076: (defkeyword :structure-initforms "List of (KEYWORD-NAME . INITFORM)")
        !          2077: 
        !          2078: 
        !          2079: (defmacro defstruct (&rest args)
        !          2080:   "(defstruct NAME [DOC-STRING] . SLOTS)  define NAME as structure type.
        !          2081: NAME must be a symbol, the name of the new structure.  It could also
        !          2082: be a list (NAME . OPTIONS), but not all options are supported currently.
        !          2083: As of Dec. 1986, this is supporting :conc-name, :copier and :predicate
        !          2084: completely, :include arguably completely and :constructor only to
        !          2085: change the name of the default constructor.  No BOA constructors allowed.
        !          2086: The DOC-STRING is established as the 'structure-doc' property of NAME.
        !          2087: The SLOTS are one or more of the following:
        !          2088: SYMBOL -- meaning the SYMBOL is the name of a SLOT of NAME
        !          2089: list of SYMBOL and VALUE -- meaning that VALUE is the initial value of
        !          2090: the slot.
        !          2091: `defstruct' defines functions `make-NAME', `NAME-p', `copy-NAME' for the
        !          2092: structure, and functions with the same name as the slots to access
        !          2093: them.  `setf' of the accessors sets their values."
        !          2094:   (multiple-value-bind
        !          2095:       (name options docstring slotsn slots initlist)
        !          2096:       (parse$defstruct$args args)
        !          2097:     ;; Names for the member functions come from the options.  The
        !          2098:     ;; slots* stuff collects info about the slots declared explicitly. 
        !          2099:     (multiple-value-bind
        !          2100:         (conc-name constructor copier predicate moreslotsn moreslots moreinits)
        !          2101:         (parse$defstruct$options name options slots)
        !          2102:       ;; The moreslots* stuff refers to slots gained as a consequence
        !          2103:       ;; of (:include clauses).
        !          2104:       (when (and (numberp moreslotsn)
        !          2105:                  (> moreslotsn 0))
        !          2106:         (setf slotsn (+ slotsn moreslotsn))
        !          2107:         (setf slots (append moreslots slots))
        !          2108:         (setf initlist (append moreinits initlist)))
        !          2109:       (unless (> slotsn 0)
        !          2110:         (error "%s needs at least one slot"
        !          2111:                (prin1-to-string name)))
        !          2112:       (let ((dups (duplicate-symbols-p slots)))
        !          2113:         (when dups
        !          2114:           (error "`%s' are duplicates"
        !          2115:                  (prin1-to-string dups))))
        !          2116:       (setq initlist (simplify$inits slots initlist))
        !          2117:       (let (properties functions keywords accessors alterators returned)
        !          2118:         ;; compute properties of NAME
        !          2119:         (setq properties
        !          2120:               (list
        !          2121:                (list 'put (list 'quote name) :structure-doc
        !          2122:                      docstring)
        !          2123:                (list 'put (list 'quote name) :structure-slotsn
        !          2124:                      slotsn)
        !          2125:                (list 'put (list 'quote name) :structure-slots
        !          2126:                      (list 'quote slots))
        !          2127:                (list 'put (list 'quote name) :structure-initforms
        !          2128:                      (list 'quote initlist))
        !          2129:                (list 'put (list 'quote name) :structure-indices
        !          2130:                      (list 'quote (extract$indices initlist)))))
        !          2131: 
        !          2132:         ;; Compute functions associated with NAME.  This is not
        !          2133:        ;; handling BOA constructors yet, but here would be the place.
        !          2134:         (setq functions
        !          2135:               (list
        !          2136:                (list 'fset (list 'quote constructor)
        !          2137:                      (list 'function
        !          2138:                            (list 'lambda (list '&rest 'args)
        !          2139:                                  (list 'make$structure$instance
        !          2140:                                        (list 'quote name)
        !          2141:                                        'args))))
        !          2142:                (list 'fset (list 'quote copier)
        !          2143:                      (list 'function
        !          2144:                            (list 'lambda (list 'struct)
        !          2145:                                  (list 'copy-vector 'struct))))
        !          2146:                (list 'fset (list 'quote predicate)
        !          2147:                      (list 'function
        !          2148:                            (list 'lambda (list 'thing)
        !          2149:                                  (list 'and
        !          2150:                                        (list 'vectorp 'thing)
        !          2151:                                        (list 'eq
        !          2152:                                              (list 'elt 'thing 0)
        !          2153:                                              (list 'quote name))
        !          2154:                                        (list '=
        !          2155:                                              (list 'length 'thing)
        !          2156:                                              (1+ slotsn))))))))
        !          2157:         ;; compute accessors for NAME's slots
        !          2158:         (multiple-value-setq
        !          2159:             (accessors alterators keywords)
        !          2160:             (build$accessors$for name conc-name predicate slots slotsn))
        !          2161:         ;; generate returned value -- not defined by the standard
        !          2162:         (setq returned
        !          2163:               (list
        !          2164:                (cons 'vector
        !          2165:                      (mapcar
        !          2166:                       '(lambda (x) (list 'quote x))
        !          2167:                       (cons name slots)))))
        !          2168:         ;; generate code
        !          2169:         (cons 'progn
        !          2170:               (nconc properties functions keywords
        !          2171:                      accessors alterators returned))))))
        !          2172: 
        !          2173: (defun parse$defstruct$args (args)
        !          2174:   "PARSE$DEFSTRUCT$ARGS ARGS => NAME OPTIONS DOCSTRING SLOTSN SLOTS INITLIST
        !          2175: NAME=symbol, OPTIONS=list of, DOCSTRING=string, SLOTSN=count of slots,
        !          2176: SLOTS=list of their names, INITLIST=alist (keyword . initform)."
        !          2177:   (let (name                            ;args=(symbol...) or ((symbol...)...)
        !          2178:         options                         ;args=((symbol . options) ...)
        !          2179:         (docstring "")                  ;args=(head docstring . slotargs)
        !          2180:         slotargs                        ;second or third cdr of args
        !          2181:         (slotsn 0)                      ;number of slots 
        !          2182:         (slots '())                     ;list of slot names
        !          2183:         (initlist '()))                 ;list of (slot keyword . initform)
        !          2184:     ;; extract name and options
        !          2185:     (cond
        !          2186:      ((symbolp (car args))              ;simple name
        !          2187:       (setq name    (car args)
        !          2188:             options '()))
        !          2189:      ((and (listp   (car args))         ;(name . options)
        !          2190:            (symbolp (caar args)))
        !          2191:       (setq name    (caar args)
        !          2192:             options (cdar args)))
        !          2193:      (t
        !          2194:       (error "First arg to `defstruct' must be symbol or (symbol ...)")))
        !          2195:     (setq slotargs (cdr args))
        !          2196:     ;; is there a docstring?
        !          2197:     (when (stringp (car slotargs))
        !          2198:       (setq docstring (car slotargs)
        !          2199:             slotargs  (cdr slotargs)))
        !          2200:     ;; now for the slots
        !          2201:     (multiple-value-bind
        !          2202:         (slotsn slots initlist)
        !          2203:         (process$slots slotargs)
        !          2204:       (values name options docstring slotsn slots initlist))))
        !          2205: 
        !          2206: (defun process$slots (slots)
        !          2207:   "PROCESS$SLOTS SLOTS => SLOTSN SLOTSLIST INITLIST
        !          2208: Converts a list of symbols or lists of symbol and form into the last 3
        !          2209: values returned by PARSE$DEFSTRUCT$ARGS."
        !          2210:   (let ((slotsn (length slots))         ;number of slots
        !          2211:         slotslist                       ;(slot1 slot2 ...)
        !          2212:         initlist)                       ;((:slot1 . init1) ...)
        !          2213:     (do*
        !          2214:         ((ptr  slots     (cdr ptr))
        !          2215:          (this (car ptr) (car ptr)))
        !          2216:         ((endp ptr))
        !          2217:       (cond
        !          2218:        ((symbolp this)
        !          2219:         (setq slotslist (cons this slotslist))
        !          2220:         (setq initlist (acons (keyword-of this) nil initlist)))
        !          2221:        ((and (listp this)
        !          2222:              (symbolp (car this)))
        !          2223:         (let ((name (car this))
        !          2224:               (form (cadr this)))
        !          2225:           ;; this silently ignores any slot options.  bad...
        !          2226:           (setq slotslist (cons name slotslist))
        !          2227:           (setq initlist  (acons (keyword-of name) form initlist))))
        !          2228:        (t
        !          2229:         (error "Slot should be symbol or (symbol ...), not `%s'"
        !          2230:                (prin1-to-string this)))))
        !          2231:     (values slotsn (nreverse slotslist) (nreverse initlist))))
        !          2232: 
        !          2233: (defun parse$defstruct$options (name options slots)
        !          2234:   "PARSE$DEFSTRUCT$OPTIONS NAME OPTIONS SLOTS => CONC-NAME CONST COPIER PRED
        !          2235: Returns at least those 4 values (a string and 3 symbols, to name the necessary
        !          2236: functions),  might return also things discovered by actually
        !          2237: inspecting the options, namely MORESLOTSN MORESLOTS MOREINITS, as can
        !          2238: be created by :include, and perhaps a list of BOACONSTRUCTORS."
        !          2239:   (let* ((namestring (symbol-name name))
        !          2240:          ;; to build the return values
        !          2241:          (conc-name  (concat namestring "-"))
        !          2242:          (const (intern (concat "make-" namestring)))
        !          2243:          (copier (intern (concat "copy-" namestring)))
        !          2244:          (pred (intern (concat namestring "-p")))
        !          2245:          (moreslotsn 0)
        !          2246:          (moreslots '())
        !          2247:          (moreinits '())
        !          2248:          ;; auxiliaries
        !          2249:          option-head                    ;When an option is not a plain
        !          2250:          option-second                  ; keyword, it must be a list of
        !          2251:          option-rest                    ; the form (head second . rest)
        !          2252:          these-slotsn                   ;When :include is found, the
        !          2253:          these-slots                    ; info about the included
        !          2254:          these-inits                    ; structure is added here.
        !          2255:          )
        !          2256:     ;; Values above are the defaults.  Now we read the options themselves
        !          2257:     (dolist (option options)
        !          2258:       ;; 2 cases arise, as options must be a keyword or a list
        !          2259:       (cond
        !          2260:        ((keywordp option)
        !          2261:         (case option
        !          2262:           (:named
        !          2263:            )                            ;ignore silently
        !          2264:           (t
        !          2265:            (error "Can't recognize option `%s'"
        !          2266:                   (prin1-to-string option)))))
        !          2267:        ((and (listp option)
        !          2268:              (keywordp (setq option-head (car option))))
        !          2269:         (setq option-second (second option))
        !          2270:         (setq option-rest   (nthcdr 2 option))
        !          2271:         (case option-head
        !          2272:           (:conc-name
        !          2273:            (setq conc-name
        !          2274:                  (cond
        !          2275:                   ((stringp option-second)
        !          2276:                    option-second)
        !          2277:                   ((null option-second)
        !          2278:                    "")
        !          2279:                   (t
        !          2280:                    (error "`%s' is invalid as `conc-name'"
        !          2281:                           (prin1-to-string option-second))))))
        !          2282:           (:copier
        !          2283:            (setq copier
        !          2284:                  (cond
        !          2285:                   ((and (symbolp option-second)
        !          2286:                         (null option-rest))
        !          2287:                    option-second)
        !          2288:                   (t
        !          2289:                    (error "Can't recognize option `%s'"
        !          2290:                           (prin1-to-string option))))))
        !          2291: 
        !          2292:           (:constructor                 ;no BOA-constructors allowed
        !          2293:            (setq const
        !          2294:                  (cond
        !          2295:                   ((and (symbolp option-second)
        !          2296:                         (null option-rest))
        !          2297:                    option-second)
        !          2298:                   (t
        !          2299:                    (error "Can't recognize option `%s'"
        !          2300:                           (prin1-to-string option))))))
        !          2301:           (:predicate
        !          2302:            (setq pred
        !          2303:                  (cond
        !          2304:                   ((and (symbolp option-second)
        !          2305:                         (null option-rest))
        !          2306:                    option-second)
        !          2307:                   (t
        !          2308:                    (error "Can't recognize option `%s'"
        !          2309:                           (prin1-to-string option))))))
        !          2310:           (:include
        !          2311:            (unless (symbolp option-second)
        !          2312:              (error "Arg to `:include' should be a symbol, not `%s'"
        !          2313:                     (prin1-to-string option-second)))
        !          2314:            (setq these-slotsn (get option-second :structure-slotsn)
        !          2315:                  these-slots  (get option-second :structure-slots)
        !          2316:                  these-inits  (get option-second :structure-initforms))
        !          2317:            (unless (and (numberp these-slotsn)
        !          2318:                         (> these-slotsn 0))
        !          2319:              (error "`%s' is not a valid structure"
        !          2320:                     (prin1-to-string option-second)))
        !          2321:            (multiple-value-bind
        !          2322:                (xtra-slotsn xtra-slots xtra-inits)
        !          2323:                (process$slots option-rest)
        !          2324:              (when (> xtra-slotsn 0)
        !          2325:                (dolist (xslot xtra-slots)
        !          2326:                  (unless (memq xslot these-slots)
        !          2327:                    (error "`%s' is not a slot of `%s'"
        !          2328:                           (prin1-to-string xslot)
        !          2329:                           (prin1-to-string option-second))))
        !          2330:                (setq these-inits (append xtra-inits these-inits)))
        !          2331:              (setq moreslotsn (+ moreslotsn these-slotsn))
        !          2332:              (setq moreslots  (append these-slots moreslots))
        !          2333:              (setq moreinits  (append these-inits moreinits))))
        !          2334:           ((:print-function :type :initial-offset)
        !          2335:            )                            ;ignore silently
        !          2336:           (t
        !          2337:            (error "Can't recognize option `%s'"
        !          2338:                   (prin1-to-string option)))))
        !          2339:        (t
        !          2340:         (error "Can't recognize option `%s'"
        !          2341:                (prin1-to-string option)))))
        !          2342:     ;; Return values found
        !          2343:     (values conc-name const copier pred
        !          2344:             moreslotsn moreslots moreinits)))
        !          2345: 
        !          2346: (defun simplify$inits (slots initlist)
        !          2347:   "SIMPLIFY$INITS SLOTS INITLIST => new INITLIST
        !          2348: Removes from INITLIST - an ALIST - any shadowed bindings."
        !          2349:   (let ((result '())                    ;built here
        !          2350:         key                             ;from the slot 
        !          2351:         )
        !          2352:     (dolist (slot slots)
        !          2353:       (setq key (keyword-of slot))
        !          2354:       (setq result (acons key (cdr (assoc key initlist)) result)))
        !          2355:     (nreverse result)))
        !          2356: 
        !          2357: (defun extract$indices (initlist)
        !          2358:   "EXTRACT$INDICES INITLIST => indices list
        !          2359: Kludge.  From a list of pairs (keyword . form) build a list of pairs
        !          2360: of the form (keyword . position in list from 0).  Useful to precompute
        !          2361: some of the work of MAKE$STRUCTURE$INSTANCE."
        !          2362:   (let ((result '())
        !          2363:         (index   0))
        !          2364:     (dolist (entry initlist (nreverse result))
        !          2365:       (setq result (acons (car entry) index result)
        !          2366:             index  (+ index 1)))))
        !          2367: 
        !          2368: (defun build$accessors$for (name conc-name predicate slots slotsn)
        !          2369:   "BUILD$ACCESSORS$FOR NAME PREDICATE SLOTS SLOTSN  => FSETS DEFSETFS KWDS
        !          2370: Generate the code for accesors and defsetfs of a structure called
        !          2371: NAME, whose slots are SLOTS.  Also, establishes the keywords for the
        !          2372: slots names."
        !          2373:   (do ((i 0 (1+ i))
        !          2374:        (accessors '())
        !          2375:        (alterators '())
        !          2376:        (keywords '())
        !          2377:        (canonic  ""))                   ;slot name with conc-name prepended
        !          2378:       ((>= i slotsn)
        !          2379:        (values
        !          2380:         (nreverse accessors) (nreverse alterators) (nreverse keywords)))
        !          2381:     (setq canonic (intern (concat conc-name (symbol-name (nth i slots)))))
        !          2382:     (setq accessors
        !          2383:           (cons
        !          2384:            (list 'fset (list 'quote canonic)
        !          2385:                  (list 'function
        !          2386:                        (list 'lambda (list 'object)
        !          2387:                              (list 'cond
        !          2388:                                    (list (list predicate 'object)
        !          2389:                                          (list 'aref 'object (1+ i)))
        !          2390:                                    (list 't
        !          2391:                                          (list 'error
        !          2392:                                                "`%s' not a %s."
        !          2393:                                                (list 'prin1-to-string
        !          2394:                                                      'object)
        !          2395:                                                (list 'prin1-to-string
        !          2396:                                                      (list 'quote
        !          2397:                                                            name))))))))
        !          2398:            accessors))
        !          2399:     (setq alterators
        !          2400:            (cons
        !          2401:             (list 'defsetf canonic
        !          2402:                   (list 'lambda (list 'object 'newval)
        !          2403:                         (list 'cond
        !          2404:                               (list (list predicate 'object)
        !          2405:                                     (list 'aset 'object (1+ i) 'newval))
        !          2406:                               (list 't
        !          2407:                                     (list 'error
        !          2408:                                           "`%s' not a `%s'"
        !          2409:                                           (list 'prin1-to-string
        !          2410:                                                 'object)
        !          2411:                                           (list 'prin1-to-string
        !          2412:                                                 (list 'quote
        !          2413:                                                       name)))))))
        !          2414:             alterators))
        !          2415:     (setq keywords
        !          2416:           (cons (list 'defkeyword (keyword-of (nth i slots)))
        !          2417:                 keywords))))
        !          2418: 
        !          2419: (defun make$structure$instance (name args)
        !          2420:   "MAKE$STRUCTURE$INSTANCE NAME ARGS => new struct NAME
        !          2421: A struct of type NAME is created, some slots might be initialized
        !          2422: according to ARGS (the &rest argument of MAKE-name)."
        !          2423:   (unless (symbolp name)
        !          2424:     (error "`%s' is not a possible name for a structure"
        !          2425:            (prin1-to-string name)))
        !          2426:   (let ((initforms (get name :structure-initforms))
        !          2427:         (slotsn    (get name :structure-slotsn))
        !          2428:         (indices   (get name :structure-indices))
        !          2429:         initalist                       ;pairlis'd on initforms
        !          2430:         initializers                    ;definitive initializers
        !          2431:         )
        !          2432:     ;; check sanity of the request
        !          2433:     (unless (and (numberp slotsn)
        !          2434:                  (> slotsn 0))
        !          2435:       (error "`%s' is not a defined structure"
        !          2436:              (prin1-to-string name)))
        !          2437:     (unless (evenp (length args))
        !          2438:       (error "Slot initializers `%s' not of even length"
        !          2439:              (prin1-to-string args)))
        !          2440:     ;; analyze the initializers provided by the call
        !          2441:     (multiple-value-bind
        !          2442:         (speckwds specvals)             ;keywords and values given 
        !          2443:         (unzip-list args)               ; by the user
        !          2444:       ;; check that all the arguments are introduced by keywords 
        !          2445:       (unless (every (function keywordp) speckwds)
        !          2446:         (error "All of the names in `%s' should be keywords"
        !          2447:                (prin1-to-string speckwds)))
        !          2448:       ;; check that all the keywords are known
        !          2449:       (dolist (kwd speckwds)
        !          2450:         (unless (numberp (cdr (assoc kwd indices)))
        !          2451:           (error "`%s' is not a valid slot name for %s"
        !          2452:                  (prin1-to-string kwd) (prin1-to-string name))))
        !          2453:       ;; update initforms
        !          2454:       (setq initalist
        !          2455:             (pairlis speckwds
        !          2456:                      (do* ;;protect values from further evaluation
        !          2457:                          ((ptr specvals (cdr ptr))
        !          2458:                           (val (car ptr) (car ptr))
        !          2459:                           (result '()))
        !          2460:                          ((endp ptr) (nreverse result))
        !          2461:                        (setq result
        !          2462:                              (cons (list 'quote val)
        !          2463:                                    result)))
        !          2464:                      (copy-sequence initforms)))
        !          2465:       ;; compute definitive initializers
        !          2466:       (setq initializers
        !          2467:             (do* ;;gather the values of the most definitive forms
        !          2468:                 ((ptr indices (cdr ptr))
        !          2469:                  (key (caar ptr) (caar ptr))
        !          2470:                  (result '()))
        !          2471:                 ((endp ptr) (nreverse result))
        !          2472:               (setq result
        !          2473:                     (cons (eval (cdr (assoc key initalist))) result))))
        !          2474:       ;; do real initialization
        !          2475:       (apply (function vector)
        !          2476:              (cons name initializers)))))
        !          2477: 
        !          2478: ;;;; end of cl-structs.el
        !          2479: 
        !          2480: ;;;; end of cl.el

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.