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