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