|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.