BSD 4_3_Net_2 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Thu, 16 Sep 1982 08:40:09 +0000 (00:40 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Thu, 16 Sep 1982 08:40:09 +0000 (00:40 -0800)
Work on file usr/src/usr.bin/lisp/lisplib/cmuedit.l
Work on file usr/src/usr.bin/lisp/lisplib/charmac.l
Work on file usr/src/usr.bin/lisp/lisplib/cmufncs.l
Work on file usr/src/usr.bin/lisp/lisplib/cmufile.l
Work on file usr/src/usr.bin/lisp/lisplib/cmuenv.l
Work on file usr/src/usr.bin/lisp/lisplib/cmumacs.l
Work on file usr/src/usr.bin/lisp/lisplib/cmutpl.l
Work on file usr/src/usr.bin/lisp/lisplib/jkfmacs.l
Work on file usr/src/usr.bin/lisp/lisplib/loop.l
Work on file usr/src/usr.bin/lisp/lisplib/step.l
Work on file usr/src/usr.bin/lisp/lisplib/syntax.l
Work on file usr/src/usr.bin/lisp/lisplib/syscall.l
Work on file usr/src/usr.bin/lisp/lisplib/ucifnc.l

Synthesized-from: CSRG/cd2/net.2

13 files changed:
usr/src/usr.bin/lisp/lisplib/charmac.l [new file with mode: 0644]
usr/src/usr.bin/lisp/lisplib/cmuedit.l [new file with mode: 0644]
usr/src/usr.bin/lisp/lisplib/cmuenv.l [new file with mode: 0644]
usr/src/usr.bin/lisp/lisplib/cmufile.l [new file with mode: 0644]
usr/src/usr.bin/lisp/lisplib/cmufncs.l [new file with mode: 0644]
usr/src/usr.bin/lisp/lisplib/cmumacs.l [new file with mode: 0644]
usr/src/usr.bin/lisp/lisplib/cmutpl.l [new file with mode: 0644]
usr/src/usr.bin/lisp/lisplib/jkfmacs.l [new file with mode: 0644]
usr/src/usr.bin/lisp/lisplib/loop.l [new file with mode: 0644]
usr/src/usr.bin/lisp/lisplib/step.l [new file with mode: 0644]
usr/src/usr.bin/lisp/lisplib/syntax.l [new file with mode: 0644]
usr/src/usr.bin/lisp/lisplib/syscall.l [new file with mode: 0644]
usr/src/usr.bin/lisp/lisplib/ucifnc.l [new file with mode: 0644]

diff --git a/usr/src/usr.bin/lisp/lisplib/charmac.l b/usr/src/usr.bin/lisp/lisplib/charmac.l
new file mode 100644 (file)
index 0000000..0606429
--- /dev/null
@@ -0,0 +1,223 @@
+;;
+;; charmac.l                           -[Sat Jan 29 18:13:40 1983 by jkf]-
+;;
+;; character macros
+;; this contains the definition of the backquote and sharpsign
+;; character macros.  [the backquote macro also defines the comma macro]
+;;
+
+(setq rcs-charmac-
+   "$Header: /usr/lib/lisp/charmac.l,v 1.1 83/01/29 18:33:29 jkf Exp $")
+
+
+(declare (macros t))
+
+(setq **backquote** 1)
+
+(declare (special **backquote**  Backquote-comma Backquote-comma-at
+                 Backquote-comma-dot))
+
+(setq Backquote-comma (gensym)
+   Backquote-comma-at (gensym)
+   Backquote-comma-dot (gensym))
+
+(def back-quote-ch-macro 
+  (lambda nil 
+         (back=quotify  ((lambda (**backquote**) (read)) 
+                         (1+ **backquote**)))))
+
+(def back-quote-comma-macro
+ (lambda nil
+  ((lambda (**backquote**)
+          (cond ((zerop **backquote**)
+                 (error "comma not inside a backquote."))
+                ((eq (tyipeek) 64)
+                 (tyi)
+                 (cons Backquote-comma-at (read)))
+                ((eq (tyipeek) 46)
+                 (tyi)
+                 (cons Backquote-comma-dot (read)))
+                (t (cons Backquote-comma (read)))))
+   (1- **backquote**))))
+
+(def back=quotify 
+  (lambda (x)
+         ((lambda (a d aa ad dqp)
+                  (cond ((atom x) (list 'quote x))
+                        ((eq (car x) Backquote-comma) (cdr x))
+                        ((or (atom (car x))
+                             (not (or (eq (caar x) Backquote-comma-at)
+                                      (eq (caar x) Backquote-comma-dot))))
+                         (setq a (back=quotify (car x)) d (back=quotify (cdr x))
+                               ad (atom d) aa (atom a)
+                               dqp (and (not ad) (eq (car d) 'quote)))
+                         (cond ((and dqp (not (atom a)) (eq (car a) 'quote))
+                                (list 'quote (cons (cadr a) (cadr d))))
+                               ((and dqp (null (cadr d)))
+                                (list 'list a))
+                               ((and (not ad) (eq (car d) 'list))
+                                (cons 'list (cons a (cdr d))))
+                               (t (list 'cons a d))))
+                        ((eq (caar x) Backquote-comma-at)
+                         (list 'append (cdar x) (back=quotify (cdr x))))
+                        ((eq (caar x) Backquote-comma-dot)
+                         (list 'nconc (cdar x)(back=quotify (cdr x))))
+                        ))
+          nil nil nil nil nil)))
+
+
+(setsyntax '\` 'macro 'back-quote-ch-macro)
+(setsyntax '\, 'macro 'back-quote-comma-macro)
+
+
+;------- sharpsign macro, used for conditional assembly
+
+;#O <SEXP> or #o <SEXP> reads sexp with ibase bound to 8.
+;#+<FEATURE> <SEXP> makes <SEXP> exist if (STATUS FEATURE <FEATURE>) is T
+;#-<FEATURE> <SEXP> makes <SEXP> exist if (STATUS FEATURE <FEATURE>) is NIL
+;#+(OR F1 F2 ...) <SEXP> makes <SEXP> exist of any one of F1,F2,... are in
+;                       the (STATUS FEATURES) list.
+;#+(AND F1 F2 ...) works similarly except all must be present in the list.
+;#+(NOT <FEATURE>) is the same as #-<FEATURE>.
+;#/CHAR returns the numerical character code of CHAR.
+;#\SYMBOL gets the numerical character code of non-printing characters.
+;#' is to FUNCTION as ' is to QUOTE.
+;#.<SEXP> evaluates <SEXP> at read time and leaves the result.
+;#,<SEXP> evaluates <SEXP> at load time.  Here it is the same as "#.".
+;#t returns t, this means something in NIL, I am not sure what.
+
+
+(declare (special sharpm-function-names franz-symbolic-character-names))
+(setq sharpm-function-names nil)
+
+(def new-sharp-sign-macro
+   (lambda ()
+      ((lambda (char entry)
+         (cond ((setq entry (assq char sharpm-function-names))
+                (funcall (cdr entry) char))
+               (t (error "Unknown character after #:" (ascii char)))))
+       (tyi) nil)))
+
+(setsyntax '\# 'splicing 'new-sharp-sign-macro)
+
+;--- defsharp  ::  define a sharp sign handler
+; form is (defsharp key arglist body ...)
+; where key is a number or a list of numbers (fixnum equivalents of chars)
+; arglist is a list of one argument, which will be bound to the fixnum
+; representation of the character typed.
+; body is the function to be executed when #key is seen.  it should return
+; either nil or (list x) where x is what will be spliced in.
+;
+(def defsharp
+   (macro (arg)    ; arg is (defsharp number-or-list arglist function-body)
+         (prog (name)
+            (setq name (concat "Sharpm" (cond ((dtpr (cadr arg)) (caadr arg))
+                                              (t (cadr arg)))
+                               (gensym)))
+            (cond ((dtpr (cadr arg))
+                   (return `(progn 'compile
+                                   ,@(mapcar
+                                        '(lambda (x)
+                                            (defsharp-expand x name))
+                                        (cadr arg))
+                                   (defun ,name ,(caddr arg) ,@(cdddr arg)))))
+                  (t (return `(progn 'compile
+                                     ,(defsharp-expand (cadr arg) name)
+                                     (defun ,name ,(caddr arg) ,@(cdddr arg)))))))))
+
+(eval-when (compile load eval)
+   (defun defsharp-expand (code name)
+         (cond ((symbolp code) (setq code (car (aexploden code)))))
+         `((lambda (current)
+              (cond ((setq current (assq ,code sharpm-function-names))
+                     (rplacd current ',name))
+                    (t (setq sharpm-function-names
+                             (cons '(,code . ,name)
+                                   sharpm-function-names)))))
+           nil)))
+
+
+;; standard sharp sign functions:
+(declare (special ibase))
+
+(defsharp (o O) (x) ((lambda (ibase) (list (read))) 8.))  ;#o #O
+(defsharp (x X) (x) (do ((res 0)                         ;#x #X (hex)
+                        (this (tyi) (tyi))
+                        (firstch t nil)
+                        (factor 1))
+                       (nil)
+                       (cond ((not (or (> this 57.)    ; #/0 <= this <= #/9
+                                       (< this 48.)))
+                              (setq res (+ (* res 16.) (- this 48.))))
+                             ((not (or (> this 102.)   ; #/a <= this <= #/f
+                                       (< this  97.)))
+                              (setq res (+ (* res 16.) (- this (- 97 10)))))
+                             ((not (or (> this 70.)
+                                       (< this 65.)))
+                              (setq res (+ (* res 16.) (- this (- 65 10)))))
+                             ((and firstch (eq this 43.)))             ; #/+
+                             ((and firstch (eq this 45.))              ; #/-
+                              (setq factor (* -1 factor)))
+                             (t (untyi this)
+                                (return (list (* factor res)))))))
+                           
+                             
+
+(defsharp + (x) ((lambda (frob)                                ; #+
+                     (cond ((not (feature-present frob)) (read)))
+                     nil)
+                  (read)))
+(defsharp - (x) ((lambda (frob)                                ; #-
+                     (cond ((feature-present frob) (read)))
+                     nil)
+                  (read)))
+(defsharp / (x) (list (tyi)))                          ;#/  fixum equiv
+(defsharp ^ (x) (list (boole 1 31. (tyi))))            ;#^  cntrl next char
+(defsharp \' (x) (list (list 'function (read))))       ;#'  function
+(defsharp (\, \.) (x) (list (eval (read))))            ;#, or #.
+(defsharp \\ (x) ((lambda (frob char)                  ;#\
+                     (setq char
+                           (cdr (assq frob franz-symbolic-character-names)))
+                     (or char (error '|Illegal character name in #\\| frob))
+                     (list char))
+                  (read) nil))
+(defsharp (t T) (x) (list t))                  ;#t (for NIL)
+(defsharp (M m  Q q  F f) (char)  ;M m Q q F f
+   (cond ((not (feature-present
+                 (cadr (assoc char '((77. maclisp) (109. maclisp)
+                                     (81. lispm) (113. lispm)
+                                     (70. franz) (102. franz))))))
+         (read)))
+   nil)
+                     
+
+(defun feature-present (feature)
+       (cond ((atom feature)
+             (memq feature (status features))) ;damn fsubrs
+            ((eq (car feature) 'not)
+             (not (feature-present (cadr feature))))
+            ((eq (car feature) 'and)
+             (do ((list (cdr feature) (cdr list)))
+                 ((null list) t)
+                 (cond ((not (feature-present (car list)))
+                        (return nil)))))
+            ((eq (car feature) 'or)
+             (do ((list (cdr feature) (cdr list)))
+                 ((null list) nil)
+                 (cond ((feature-present (car list))
+                        (return t)))))
+            (t (error '|Unknown form after #+ or #-| feature))))
+
+(setq franz-symbolic-character-names
+      '((eof . -1)  (backspace . 8.)(bs . 8.)
+        (tab . 9.) (lf . 10.) (linefeed . 10.)
+       (ff . 12.) (form . 12.) (return . 13.) (cr . 13.)
+       (newline . 10.) (vt . 11.)
+        (esc . 27.) (alt . 27.) 
+       (space . 32.) (sp . 32.)
+       (dq . 34.)     ; "
+       (lpar . 40.) (rpar . 41.)
+       (vert . 124.)  ; |
+       (rubout . 127.)
+       ))
+
diff --git a/usr/src/usr.bin/lisp/lisplib/cmuedit.l b/usr/src/usr.bin/lisp/lisplib/cmuedit.l
new file mode 100644 (file)
index 0000000..afdebbe
--- /dev/null
@@ -0,0 +1,1550 @@
+(setq rcs-cmuedit-
+   "$Header: /usr/lib/lisp/cmuedit.l,v 1.1 83/01/29 18:33:36 jkf Exp $")
+
+(eval-when (compile load eval) (load 'cmumacs) (load 'cmufncs))
+
+(declare (special c2 c3 tem nopr %changes))
+
+(dv editsfns
+    ((declare
+      (special |#1|
+               |#2|
+               |#3|
+               $%dotflg
+               %lookdpth
+               %prevfn%
+               atm
+               autop
+               com
+               com0
+               coms
+               copyflg
+               editcomsl
+               editracefn
+               %%w
+               findflag
+               l
+               l0
+               lastail
+               lastp1
+               lastp2
+               lastword
+               lcflg
+               marklst
+               maxlevel
+               maxloop
+               mess
+               noprint
+               oldprompt
+               readbuf
+               %%x
+               toflg
+               topflg
+               undolst
+               undolst1
+               unfind
+               upfindflg
+               usermacros
+               findarg
+               commentflg
+               changed))
+     |##|
+     editfns
+     editf
+     editv
+     editp
+     edite
+     editl
+     editl0
+     edval
+     editread
+     (declare (*expr editracefn))
+     editcom
+     editcoma
+     editcoml
+     editmac
+     editcoms
+     edith
+     edit!undo
+     undoeditcom
+     editsmash
+     editnconc
+     editdsubst
+     edit1f
+     edit2f
+     edit4e
+     editqf
+     edit4f
+     editfpat
+     edit4f1
+     editfindp
+     editbf
+     editbf1
+     editnth
+     bpnt0
+     bpnt
+     editri
+     editro
+     editli
+     editlo
+     editbi
+     editbo
+     editdefault
+     edup
+     edit*l
+     edit*
+     edor
+     errcom
+     edrpt
+     edloc
+     edlocl
+     edit:
+     editmbd
+     editxtr
+     editelt
+     editcont
+     editsw
+     editmv
+     editto
+     editbelow
+     editran
+     edit!0
+     editrepack
+     editmakefn
+     usermacros
+     editracefn
+     lastword
+     maxlevel
+     maxloop
+     editcomsl
+     autop
+     upfindflg))
+
+(declare
+ (special |#1|
+          |#2|
+          |#3|
+          $%dotflg
+          %lookdpth
+          %prevfn%
+          atm
+          autop
+          com
+          com0
+          coms
+          copyflg
+          editcomsl
+          editracefn
+          %%w
+          findflag
+          l
+          l0
+          lastail
+          lastp1
+          lastp2
+          lastword
+          lcflg
+          marklst
+          maxlevel
+          maxloop
+          mess
+          noprint
+          oldprompt
+          readbuf
+          %%x
+          toflg
+          topflg
+          undolst
+          undolst1
+          unfind
+          upfindflg
+          usermacros
+          findarg
+          commentflg
+          changed))
+(declare (special c nopr))     ; LWE 1/11/80 Hacks for new compiler.
+(def |##|
+  (nlambda (coms)
+    ((lambda (l undolst1) (editcoms coms)) l nil)))
+
+(def editfns
+  (nlambda (x)
+    (prog (y)
+          (setq y (eval (car x)))
+     l1   (cond
+           (y (print (car y))
+              (eval
+               (list 'errset
+                     (cons 'editf (cons (car y) (cdr x)))))
+              (setq y (cdr y))
+              (go l1))))))
+
+(def editf
+  (nlambda (x)
+    (prog (y fn changed)
+          (cond
+           ((null x)
+            (print '=)
+            (prin1 lastword)
+            (setq x (ncons lastword))))
+          (cond ((symbolp (car x))
+                 (setq fn (car x))
+                 (cond ((*** setq y (get fn 'trace)) (setq fn (cdr y))))
+                 (cond ((setq y (getd fn))
+                        (edite y (cdr x) (car x))
+                        (cond
+                         (changed
+                          (*** cond
+                               ((eq (car x) fn)
+                                (*** move property to front)
+                                (remprop (car x) (car y))
+                                (putprop (car x) (cadr y) (car y)))
+                               ((setq y (cdr (get fn 'funtype)))
+                                (*** move the *right* property of the
+                                 original word to the front)
+                                (setq fn (get (car x) y))
+                                (remprop (car x) y)
+                                (putprop (car x) fn y)))))
+                        (return (setq lastword (car x))))
+                       ((and (boundp fn) (dtpr (cdr y))) (go l1))))
+                ((dtpr (car x)) (go l1)))
+          (print (car x))
+          (princ '" not editable")
+          (err nil)
+     l1   (print '=editv)
+          (return (eval (cons 'editv x))))))
+
+(def editv
+  (nlambda (x)
+    (prog (y)
+          (cond
+           ((null x)
+            (print '=)
+            (prin1 lastword)
+            (setq x (ncons lastword))))
+          (cond ((dtpr (car x)) (edite (eval (car x)) (cdr x) nil) (return t))
+                ((and (symbolp (car x))
+                      (boundp (car x))
+                      (setq y (eval (car x))))
+                 (edite y (cdr x) (car x))
+                 (return (setq lastword (car x))))
+                (t (print (car x)) (princ '" not editable") (err nil))))))
+
+(def editp
+  (nlambda (x)
+    (cond
+     ((null x) (print '=) (prin1 lastword) (setq x (ncons lastword))))
+    (cond ((dtpr (car x)) (print '=editv) (eval (cons 'editv x)))
+          ((symbolp (car x))
+           (edite (plist (car x)) (cdr x) (car x))
+           (setq lastword (car x)))
+          (t (print (car x)) (princ '" not editable") (err nil)))))
+
+(def edite
+  (lambda (expr coms atm)
+    (cond ((atom expr) (print expr) (princ '" not editable") (err nil))
+          (t (car (last (editl (ncons expr) coms atm nil nil)))))))
+
+(def editl
+  (lambda (l coms atm marklst mess)
+    (prog (com lastail undolst undolst1 findflag lcflg unfind lastp1 lastp2 readbuf l0 com0 oldprompt upfindflg noprint findarg)
+          (makunbound 'findarg)
+          (setq upfindflg t)
+          (cond ((dtpr (setq l (catch (eval '(editl0)) edit-abort)))
+                 (return l))
+                (t (err nil))))))
+
+(def editl0
+  (lambda nil
+    (prog nil
+          (cond
+           (coms
+            (cond ((eq (car coms) 'start)
+                   (setq readbuf (append (cdr coms) (list nil)))
+                   (setq coms nil)
+                   (*** don 't quit if command fails))
+                  (t (editcoms (append coms (list 'ok))) (return l)))))
+          (cond
+           ((or (null coms) (eq (car coms) 'start))
+            (print (or mess 'edit))))
+          (cond
+           ((or (eq (car l)
+                    (car
+                     (last
+                      (car
+                       (cond ((setq com
+                                    (get 'edit 'lastvalue)))
+                             (t '((nil))))))))
+                (and atm
+                     (eq (car l)
+                         (car
+                          (last
+                           (car
+                            (cond ((setq com
+                                         (get atm 'edit-save)))
+                                  (t '((nil))))))))))
+            (setq l (car com))
+            (setq marklst (cadr com))
+            (setq undolst (caddr com))
+            (cond ((car undolst) (setq undolst (cons nil undolst))))
+            (setq unfind (cdddr com))))
+          (*** setq
+               oldprompt
+               (cons (sub1 (stkcount 'editl0 (add1 (spdlpt)) 0))
+                     (prompt 35)))
+     ct   (setq noprint t)
+          (setq findflag nil)
+     a    (setq undolst1 nil)
+          (cond
+           ((and autop (null readbuf) (not noprint)) (bpnt (list 0 autop))))
+          (setq com (editread))
+          (setq l0 l)
+          (setq com0 (cond ((atom com) com) (t (car com))))
+          (cond
+           ((dtpr
+             (prog1 (errset (editcom com t))
+                    (cond
+                     (undolst1 (setq undolst1
+                                     (cons com0 (cons l0 undolst1)))
+                               (setq undolst (cons undolst1 undolst))))))
+            (go a)))
+          (setq readbuf nil)
+          (cond (coms (err nil)))
+          (terpri)
+          (cond (com (prin1 com) (princ '"  ?") (terpri)))
+          (go ct))))
+
+(def edval
+  (lambda (%%x)
+    (errset (eval %%x))))
+
+(def editread
+  (lambda nil
+    (prog (x)
+          (cond
+           ((null readbuf)
+            (prog nil
+             l1   (terpri)
+                  (princ '|#|)
+                  (*** cond
+                       ((neq (car oldprompt) 0) (princ (car oldprompt))))
+                  (*** prompt 35)
+                  (cond
+                   ((atom (setq readbuf (errset (lineread))))
+                    (terpri)
+                    (go l1)))
+                  (setq readbuf (car readbuf)))))
+          (setq x (car readbuf))
+          (setq readbuf (cdr readbuf))
+          (return x))))
+
+(declare (*expr editracefn))
+
+(def editcom
+  (lambda (c topflg)
+    (setq com c)
+    (cond (editracefn (editracefn c)))
+    (cond (findflag
+           (cond ((eq findflag 'bf) (setq findflag nil) (editbf c nil))
+                 (t (setq findflag nil) (editqf c))))
+          ((numberp c) (setq l (edit1f c l)) (setq noprint nil))
+          ((atom c) (editcoma c (null topflg)))
+          (t (editcoml c (null topflg))))
+    (car l)))
+
+(def editcoma
+  (lambda (c copyflg)
+    (prog (tem nopr)
+          (selectq c
+                   (help (setq nopr t)
+                         (eval (cons 'help readbuf))
+                         (setq readbuf nil)
+                         (*** inserted dec 78 by don cohen))
+                   (!0 (edit!0))
+                   (!nx
+                    (setq l
+                          ((lambda (l)
+                                   (prog (uf)
+                                         (setq uf l)
+                                    lp   (cond ((or (null (setq l (cdr l)))
+                                                    (null (cdr l)))
+                                                (err nil))
+                                               ((or (null
+                                                     (setq tem
+                                                           (memq (car l)
+                                                                 (cadr
+                                                                  l))))
+                                                    (null (cdr tem)))
+                                                (go lp)))
+                                         (edit* 1)
+                                         (setq unfind uf)
+                                         (return l)))
+                           l)))
+                   (!undo (edit!undo t t nil))
+                   (? (bpnt0 (car l) 64) (setq nopr t))
+                   (?? (edith undolst) (setq nopr t))
+                   (bk (edit* -1))
+                   (delete (setq c '(delete)) (edit: ': nil nil))
+                   (mark (setq marklst (cons l marklst)) (setq nopr t))
+                   (nex
+                    (setq l
+                          ((lambda (l) (editbelow '_ 1) (edit* 1) l)
+                           l)))
+                   ((f bf)
+                    (cond ((null topflg) (setq findflag c))
+                          (t (setq findarg
+                                   (cond ((or readbuf
+                                              (not
+                                               (boundp 'findarg)))
+                                          (editread))
+                                         (t findarg)))
+                             (selectq c
+                                      (f (editqf findarg))
+                                      (bf (editbf findarg nil))
+                                      (err nil)))))
+                   (nil (setq nopr t))
+                   (autop nil)
+                   (nx (edit* 1))
+                   (ok (cond
+                        (atm (cond
+                              ((and (dtpr undolst) (car undolst))
+                               (setq changed t)
+                               (*** bound in editf)
+                               (mark!changed atm)))
+                             (remprop atm 'edit-save)))
+                       (putprop 'edit
+                                (cons (last l) (cons marklst (cons undolst l)))
+                                'lastvalue)
+                       (throw l edit-abort)
+                       (*** prompt (cdr oldprompt))
+                       (*** retfrom 'editl0 l))
+                   (p (bpnt0 (car l) 2) (setq nopr t))
+                   (pp (bpnt0 (car l) nil) (setq nopr t))
+                   (pp* ((lambda (commentflg) (bpnt0 (car l) nil)) t)
+                        (setq nopr t))
+                   (repack (editrepack))
+                   (save (cond
+                          (atm (cond
+                                ((and (dtpr undolst) (car undolst))
+                                 (mark!changed atm)))
+                               (putprop 'edit
+                                        (putprop atm
+                                                 (cons l
+                                                       (cons marklst
+                                                             (cons undolst
+                                                                   unfind)))
+                                                 'edit-save)
+                                        'lastvalue)))
+                         (*** prompt (cdr oldprompt))
+                         (*** retfrom 'editl0 l)
+                         (throw l edit-abort))
+                   (stop (*** prompt (cdr oldprompt))
+                         (*** spreval
+                              (stksrch 'editl0 (spdlpt) nil)
+                              '(err nil))
+                         (throw nil edit-abort))
+                   (test (setq undolst (cons nil undolst)) (setq nopr t))
+                   (tty: (setq com com0)
+                         (setq l (editl l nil atm nil 'tty:)))
+                   (unblock (cond ((setq tem (memq nil undolst))
+                                   (editsmash tem (ncons nil) (cdr tem)))
+                                  (t (terpri) (princ '"not blocked")))
+                            (setq nopr t))
+                   (undo (edit!undo topflg nil (cond (readbuf (editread)))))
+                   (up (edup))
+                   (/
+                    (cond (unfind (setq c l)
+                                  (setq l unfind)
+                                  (and (cdr c) (setq unfind c)))
+                          (t (err nil))))
+                   (/p
+                    (cond ((and lastp1 (neq lastp1 l)) (setq l lastp1))
+                          ((and lastp2 (neq lastp2 l)) (setq l lastp2))
+                          (t (err nil))))
+                   (^ (and (cdr l) (setq unfind l)) (setq l (last l)))
+                   (_
+                    (cond (marklst (and (cdr l) (setq unfind l))
+                                   (setq l (car marklst)))
+                          (t (err nil))))
+                   (__
+                    (cond (marklst
+                           (and (cdr l)
+                                (setq unfind l)
+                                (setq l (car marklst))
+                                (setq marklst (cdr marklst))))
+                          (t (err nil))))
+                   (tl (top-level) (setq nopr t))
+                   (cond ((null (setq tem (editmac c usermacros nil)))
+                          (editdefault c)
+                          (setq nopr noprint))
+                         (t (editcoms (copy (cdr tem))) (setq nopr noprint))))
+          (setq noprint nopr))))
+
+(def editcoml
+  (lambda (c copyflg)
+    (prog (c2 c3 tem nopr)
+     lp   (cond ((dtpr (cdr c))
+                 (setq c2 (cadr c))
+                 (cond ((dtpr (cddr c)) (setq c3 (caddr c)))
+                       (t (setq c3 nil))))
+                (t (setq c2 (setq c3 nil))))
+          (cond ((and lcflg
+                      (selectq c2
+                               ((to thru through)
+                                (cond
+                                 ((null (cddr c))
+                                  (setq c3 -1)
+                                  (setq c2 'thru)))
+                                t)
+                               nil))
+                 (editto (car c) c3 c2)
+                 (return nil))
+                ((numberp (car c))
+                 (edit2f (car c) (cdr c))
+                 (setq noprint nil)
+                 (return nil))
+                ((eq c2 '::)
+                 (editcont (car c) (cddr c))
+                 (setq noprint nil)
+                 (return nil)))
+          (selectq (car c)
+                   ((a b :) (edit: (car c) nil (cdr c)))
+                   (below (editbelow c2 (cond ((cddr c) c3) (t 1))))
+                   (bf (editbf c2 c3))
+                   (bi
+                    (editbi c2
+                            (cond ((cddr c) c3) (t c2))
+                            (and (cdr c) (car l))))
+                   (bind (prog (|#1| |#2| |#3|)
+                               (editcoms (cdr c)))
+                         (setq nopr noprint))
+                   (bk (edit* (minus c2)))
+                   (bo (editbo c2 (and (cdr c) (car l))))
+                   (change (editran c '((to) (edit: : |#1| |#3|))))
+                   (coms (prog nil
+                          l1   (cond
+                                ((setq c (cdr c))
+                                 (editcom (setq com (eval (car c))) nil)
+                                 (go l1))))
+                         (setq nopr noprint))
+                   (comsq (editcoms (cdr c)) (setq nopr noprint))
+                   (copy
+                    (editran c '((to) (editmv |#1| (car |#3|) (cdr |#3|) t))))
+                   (cp (editmv nil (cadr c) (cddr c) t))
+                   (delete (editran c '(nil (edit: : |#1| nil))))
+                   (e (setq tem (eval c2))
+                      (cond ((null (cddr c)) (print tem)))
+                      (setq nopr t))
+                   (embed (editran c '((in with) (editmbd |#1| |#3|))))
+                   (extract (editran c '((from) (editxtr |#3| |#1|))))
+                   (f (edit4f c2 c3))
+                   (f= (edit4f (cons '== c2) c3))
+                   (fs
+                    (prog nil
+                     l1   (cond
+                           ((setq c (cdr c))
+                            (editqf (setq com (car c)))
+                            (go l1)))))
+                   (help (eval c)
+                         (setq nopr t)
+                         (*** inserted dec 78 by don cohen))
+                   (i (setq c
+                            (cons (cond ((atom c2) c2) (t (eval c2)))
+                                  (mapcar (function
+                                           (lambda (x)
+                                                   (cond (topflg (print
+                                                                  (setq x
+                                                                        (eval
+                                                                         x)))
+                                                                 x)
+                                                         (t (eval x)))))
+                                          (cddr c))))
+                      (setq copyflg nil)
+                      (go lp))
+                   (if (cond ((and (dtpr (setq tem (edval c2))) (car tem))
+                              (cond ((cdr c) (editcoms c3))))
+                             ((and (cddr c) (cdddr c)) (editcoms (cadddr c)))
+                             (t (err nil)))
+                       (setq nopr noprint))
+                   (insert
+                    (editran c '((before after for) (edit: |#2| |#3| |#1|))))
+                   (lc (edloc (cdr c)))
+                   (lcl (edlocl (cdr c)))
+                   (li (editli c2 (and (cdr c) (car l))))
+                   (lo (editlo c2 (and (cdr c) (car l))))
+                   ((lp lpq)
+                    (edrpt (cdr c) (eq (car c) 'lpq))
+                    (setq nopr noprint))
+                   (m (cond ((atom c2)
+                             (cond ((setq tem (editmac c2 usermacros nil))
+                                    (rplacd tem (cddr c)))
+                                   (t
+                                    (setq usermacros
+                                          (cons (cons c2
+                                                      (cons nil (cddr c)))
+                                                usermacros)))))
+                            (t
+                             (cond ((setq tem
+                                          (editmac (car c2) usermacros t))
+                                    (rplaca tem (caddr c))
+                                    (rplacd tem (cdddr c)))
+                                   (t (nconc editcomsl (ncons (car c2)))
+                                      (mark!changed 'editcomsl)
+                                      (setq usermacros
+                                            (cons (cons (car c2) (cddr c))
+                                                  usermacros))))))
+                      (mark!changed 'usermacros)
+                      (setq nopr t))
+                   (makefn
+                    (cond ((or (null c2) (null c3) (null (cdddr c)))
+                           (err nil))
+                          (t
+                           (editmakefn c2
+                                       c3
+                                       (cadddr c)
+                                       (cond ((null (cddddr c)) (cadddr c))
+                                             (t (car (cddddr c))))))))
+                   (mbd (editmbd nil (cdr c)))
+                   (move
+                    (editran c
+                             '((to) (editmv |#1| (car |#3|) (cdr |#3|) nil))))
+                   (mv (editmv nil (cadr c) (cddr c) nil))
+                   (n (cond ((atom (car l)) (err nil)))
+                      (editnconc (car l)
+                                 (cond (copyflg (copy (cdr c)))
+                                       (t (append (cdr c) nil)))))
+                   (nex
+                    (setq l
+                          ((lambda (l)
+                                   (editbelow c2 (cond ((cddr c) c3) (t 1)))
+                                   (edit* 1)
+                                   l)
+                           l)))
+                   (nth
+                    (cond
+                     ((neq (setq tem (editnth (car l) c2)) (car l))
+                      (setq l (cons tem l)))))
+                   (nx (edit* c2))
+                   (orf (edit4f (cons '*any* (cdr c)) 'n))
+                   (orr (edor (cdr c)) (setq nopr noprint))
+                   (p (cond
+                       ((neq lastp1 l) (setq lastp2 lastp1) (setq lastp1 l)))
+                      (bpnt (cdr c))
+                      (setq nopr t))
+                   (r ((lambda (l)
+                               (edit4f c2 t)
+                               (setq unfind l)
+                               (setq c2
+                                     (cond ((and (atom c2)
+                                                 upfindflg
+                                                 (dtpr (car l)))
+                                            (caar l))
+                                           (t (car l)))))
+                       (ncons (car l)))
+                      (editdsubst c3 c2 (car l)))
+                   (repack (edloc (cdr c)) (editrepack))
+                   (replace (editran c '((with by) (edit: : |#1| |#3|))))
+                   (ri (editri c2 c3 (and (cdr c) (cddr c) (car l))))
+                   (ro (editro c2 (and (cdr c) (car l))))
+                   (s (set c2
+                           (cond ((null c2) (err nil))
+                                 (t ((lambda (l) (edloc (cddr c))) l))))
+                      (setq nopr t))
+                   (second (edloc (append (cdr c) (cdr c))))
+                   (surround (editran c '((with in) (editmbd |#1| |#3|))))
+                   (sw (editsw (cadr c) (caddr c)))
+                   (third (edloc (append (cdr c) (cdr c) (cdr c))))
+                   ((thru to) (editto nil c2 (car c)))
+                   (undo (edit!undo topflg nil c2))
+                   (xtr (editxtr nil (cdr c)))
+                   (_
+                    (setq l
+                          ((lambda (l)
+                                   (prog (uf)
+                                         (setq uf l)
+                                         (setq c2 (editfpat c2))
+                                    lp   (cond ((cond ((and (atom c2)
+                                                            (dtpr (car l)))
+                                                       (eq c2 (caar l)))
+                                                      ((eq (car c2)
+                                                           'if)
+                                                       (cond ((atom
+                                                               (setq tem
+                                                                     (edval
+                                                                      (cadr
+                                                                       c2))))
+                                                              nil)
+                                                             (t tem)))
+                                                      (t
+                                                       (edit4e c2
+                                                               (cond ((eq (car
+                                                                           c2)
+                                                                          '@)
+                                                                      (caar
+                                                                       l))
+                                                                     (t
+                                                                      (car
+                                                                       l))))))
+                                                (setq unfind uf)
+                                                (return l))
+                                               ((setq l (cdr l)) (go lp)))
+                                         (err nil)))
+                           l)))
+                   (cond ((null (setq tem (editmac (car c) usermacros t)))
+                          (editdefault c)
+                          (setq nopr noprint))
+                         ((not (atom (setq c3 (car tem))))
+                          (editcoms (subpair c3 (cdr c) (cdr tem)))
+                          (setq nopr noprint))
+                         (t (editcoms (subst (cdr c) c3 (cdr tem)))
+                            (setq nopr noprint))))
+          (setq noprint nopr))))
+
+(def editmac
+  (lambda (c lst flg)
+    (prog (x y)
+     lp   (cond ((null lst) (return nil))
+                ((eq c (car (setq x (car lst))))
+                 (setq y (cdr x))
+                 (cond ((cond (flg (car y)) (t (null (car y)))) (return y)))))
+          (setq lst (cdr lst))
+          (go lp))))
+
+(def editcoms
+  (lambda (coms)
+    (prog nil
+     l1   (cond ((atom coms) (return (car l))))
+          (editcom (car coms) nil)
+          (setq coms (cdr coms))
+          (go l1))))
+
+(def edith
+  (lambda (lst)
+    (prog nil
+          (terpri)
+     l1   (cond ((null lst) (return nil))
+                ((null (car lst)) (prin1 'block) (go l2))
+                ((null (caar lst)) (go l3))
+                ((numberp (caar lst))
+                 (prin1 (list (caar lst) '--))
+                 (go l2)))
+          (prin1 (caar lst))
+     l2   (princ '" ")
+     l3   (setq lst (cdr lst))
+          (go l1))))
+
+(def edit!undo
+  (lambda (printflg !undoflg undop)
+    (prog (lst flg)
+          (setq lst undolst)
+     lp   (cond ((or (null lst) (null (car lst))) (go out)))
+          (cond ((null undop)
+                 (selectq (caar lst)
+                          ((nil !undo unblock) (go lp1))
+                          (undo (cond ((null !undoflg) (go lp1))))
+                          nil))
+                ((neq undop (caar lst)) (go lp1)))
+          (undoeditcom (car lst) printflg)
+          (cond ((null !undoflg) (return nil)))
+          (setq flg t)
+     lp1  (setq lst (cdr lst))
+          (go lp)
+     out  (cond (flg (return nil))
+                ((and lst (cdr lst)) (print 'blocked))
+                (t (terpri) (princ '"nothing saved"))))))
+
+(def undoeditcom
+  (lambda (x flg)
+    (prog (c)
+          (cond ((atom x) (err nil))
+                ((neq (car (last l)) (car (last (cadr x))))
+                 (terpri)
+                 (princ '"different expression")
+                 (setq com nil)
+                 (err nil)))
+          (setq c (car x))
+          (setq l (cadr x))
+          (prog (y z)
+                (setq y (cdr x))
+           l1   (cond
+                 ((setq y (cdr y))
+                  (setq z (car y))
+                  (cond ((eq (car z) 'r)
+                         ((lambda (l)
+                                  (editcom (list 'r
+                                                 (cadr z)
+                                                 (caddr z))
+                                           nil))
+                          (cadddr z)))
+                        (t (editsmash (car z) (cadr z) (cddr z))))
+                  (go l1))))
+          (editsmash x nil (cons (car x) (cdr x)))
+          (and flg
+               (setq flg
+                     (cond ((not (numberp c)) c) (t (cons c '(--)))))
+               (print flg)
+               (princ 'undone))
+          (return t))))
+
+(def editsmash
+  (lambda (old a d)
+    (cond ((atom old) (err nil)))
+    (setq undolst1 (cons (cons old (cons (car old) (cdr old))) undolst1))
+    (rplaca old a)
+    (rplacd old d)))
+
+(def editnconc
+  (lambda (x y)
+    (prog (tem)
+          (return
+           (cond ((null x) y)
+                 ((atom x) (err nil))
+                 (t (editsmash (setq tem (last x)) (car tem) y) x))))))
+
+(def editdsubst
+  (lambda (x y z)
+    (prog nil
+     lp   (cond ((atom z) (return nil))
+                ((cond ((symbolp y)
+                        (or (eq y (car z))
+                            (and (stringp (car z)) (eqstr y (car z)))))
+                       (t (equal y (car z))))
+                 (editsmash z (copy x) (cdr z)))
+                (t (editdsubst x y (car z))))
+          (cond
+           ((and y (eq y (cdr z)))
+            (editsmash z (car z) (copy x))
+            (return nil)))
+          (setq z (cdr z))
+          (go lp))))
+
+(def edit1f
+  (lambda (c l)
+    (cond ((eq c 0) (cond ((null (cdr l)) (err nil)) (t (cdr l))))
+          ((atom (car l)) (err nil))
+          ((> c 0)
+           (cond ((> c (length (car l))) (err nil))
+                 (t (cons (car (setq lastail (Cnth (car l) c))) l))))
+          ((> (minus c) (length (car l))) (err nil))
+          (t
+           (cons (car
+                  (setq lastail
+                        (Cnth (car l) (+ (length (car l)) (add1 c)))))
+                 l)))))
+
+(def edit2f
+  (lambda (n x)
+    (prog (cl)
+          (setq cl (car l))
+          (cond ((atom cl) (err nil))
+                (copyflg (setq x (copy x)))
+                (t (setq x (append x nil))))
+          (cond ((> n 0)
+                 (cond ((> n (length cl)) (err nil))
+                       ((null x) (go delete))
+                       (t (go replace))))
+                ((or (eq n 0) (null x) (> (minus n) (length cl))) (err nil))
+                (t (cond ((neq n -1) (setq cl (Cnth cl (minus n)))))
+                   (editsmash cl (car x) (cons (car cl) (cdr cl)))
+                   (cond
+                    ((cdr x)
+                     (editsmash cl (car cl) (nconc (cdr x) (cdr cl)))))
+                   (return nil)))
+     delete
+          (cond ((eq n 1)
+                 (or (dtpr (cdr cl)) (err nil))
+                 (editsmash cl (cadr cl) (cddr cl)))
+                (t (setq cl (Cnth cl (sub1 n)))
+                   (editsmash cl (car cl) (cddr cl))))
+          (return nil)
+     replace
+          (cond ((neq n 1) (setq cl (Cnth cl n))))
+          (editsmash cl (car x) (cdr cl))
+          (cond ((cdr x) (editsmash cl (car cl) (nconc (cdr x) (cdr cl))))))))
+
+(def edit4e
+  (lambda (pat y)
+    (cond ((eq pat y) t)
+          ((atom pat)
+           (or (eq pat '&)
+               (equal pat y)
+               (and (stringp y) (stringp pat) (eqstr pat y))))
+          ((eq (car pat) '*any*)
+           (prog nil
+            lp   (cond ((null (setq pat (cdr pat))) (return nil))
+                       ((edit4e (car pat) y) (return t)))
+                 (go lp)))
+          ((and (eq (car pat) '@) (atom y))
+           (prog (z)
+                 (setq pat (cdr pat))
+                 (setq z (explodec y))
+            lp   (cond ((eq (car pat) '@)
+                        (*** freelist z)
+                        (print '=)
+                        (prin1 y)
+                        (return t))
+                       ((null z) (return nil))
+                       ((neq (car pat) (car z))
+                        (*** freelist z)
+                        (return nil)))
+                 (setq pat (cdr pat))
+                 (setq z (cdr z))
+                 (go lp)))
+          ((eq (car pat) '--)
+           (or (null (setq pat (cdr pat)))
+               (prog nil
+                lp   (cond ((edit4e pat y) (return t))
+                           ((atom y) (return nil)))
+                     (setq y (cdr y))
+                     (go lp))))
+          ((eq (car pat) '==) (eq (cdr pat) y))
+          ((atom y) nil)
+          ((edit4e (car pat) (car y)) (edit4e (cdr pat) (cdr y))))))
+
+(def editqf
+  (lambda (pat)
+    (prog (q1)
+          (cond ((and (dtpr (car l))
+                      (dtpr (setq q1 (cdar l)))
+                      (setq q1 (memq pat q1)))
+                 (setq l
+                       (cons (cond (upfindflg q1)
+                                   (t (setq lastail q1) (car q1)))
+                             l)))
+                (t (edit4f pat 'n))))))
+
+(def edit4f
+  (lambda (pat %%x)
+    (prog (ll x %%w)
+          (setq %%w (ncons nil))
+          (setq com pat)
+          (setq pat (editfpat pat))
+          (setq ll l)
+          (cond
+           ((eq %%x 'n)
+            (setq %%x 1)
+            (cond ((atom (car l)) (go lp1))
+                  ((and (atom (caar l)) upfindflg)
+                   (setq ll (cons (caar l) l))
+                   (go lp1))
+                  (t (setq ll (cons (caar l) l))))))
+          (cond ((and %%x (not (numberp %%x))) (setq %%x 1)))
+          (cond
+           ((and (edit4e (cond ((and (dtpr pat) (eq (car pat) ':::))
+                                (cdr pat))
+                               (t pat))
+                         (car ll))
+                 (or (null %%x) (eq (setq %%x (sub1 %%x)) 0)))
+            (return (setq l ll))))
+          (setq x (car ll))
+     lp   (cond ((edit4f1 pat x maxlevel)
+                 (and (cdr l) (setq unfind l))
+                 (return
+                  (car
+                   (setq l
+                         (nconc (car %%w)
+                                (cond ((eq (cadr %%w) (car ll)) (cdr ll))
+                                      (t ll)))))))
+                ((null %%x) (err nil)))
+     lp1  (setq x (car ll))
+          (cond ((null (setq ll (cdr ll))) (err nil))
+                ((and (setq x (memq x (car ll))) (dtpr (setq x (cdr x))))
+                 (go lp)))
+          (go lp1))))
+
+(def editfpat
+  (lambda (pat)
+    (cond ((dtpr pat)
+           (cond ((or (eq (car pat) '==) (eq (car pat) '@)) pat)
+                 (t (mapcar (function editfpat) pat))))
+          ((eq (nthchar pat -1) '@) (cons '@ (explodec pat)))
+          (t pat))))
+
+(def edit4f1
+  (lambda (pat x lvl)
+    (prog nil
+     lp   (cond ((not (> lvl 0))
+                 (terpri)
+                 (princ '"maxlevel exceeded")
+                 (return nil))
+                ((atom x) (return nil))
+                ((and (dtpr pat)
+                      (eq (car pat) ':::)
+                      (edit4e (cdr pat) x)
+                      (or (null %%x) (eq (setq %%x (sub1 %%x)) 0))))
+                ((and (or (atom pat) (neq (car pat) ':::))
+                      (edit4e pat (car x))
+                      (or (null %%x) (eq (setq %%x (sub1 %%x)) 0)))
+                 (cond
+                  ((or (null upfindflg) (dtpr (car x)))
+                   (setq lastail x)
+                   (setq x (car x)))))
+                ((and pat
+                      (eq pat (cdr x))
+                      (or (null %%x) (eq (setq %%x (sub1 %%x)) 0)))
+                 (setq x (cdr x)))
+                ((and %%x
+                      (dtpr (car x))
+                      (edit4f1 pat (car x) (sub1 lvl))
+                      (eq %%x 0))
+                 (setq x (car x)))
+                (t (setq x (cdr x)) (setq lvl (sub1 lvl)) (go lp)))
+          (cond ((and %%w (neq x (cadr %%w))) (tconc %%w x)))
+          (return (or %%w t)))))
+
+(def editfindp
+  (lambda (x pat flg)
+    (prog (%%x lastail %%w)
+          (setq %%x 1)
+          (and (null flg) (setq pat (editfpat pat)))
+          (return (or (edit4e pat x) (edit4f1 pat x maxlevel))))))
+
+(def editbf
+  (lambda (pat n)
+    (prog (ll x y %%w)
+          (setq ll l)
+          (setq %%w (ncons nil))
+          (setq com pat)
+          (setq pat (editfpat pat))
+          (cond ((and (null n) (cdr ll)) (go lp1)))
+     lp   (cond
+           ((editbf1 pat (car ll) maxlevel y)
+            (setq unfind l)
+            (return
+             (car
+              (setq l
+                    (nconc (car %%w)
+                           (cond ((eq (car ll) (cadr %%w)) (cdr ll))
+                                 (t ll))))))))
+     lp1  (setq x (car ll))
+          (cond ((null (setq ll (cdr ll))) (err nil))
+                ((or (setq y (memq x (car ll))) (setq y (tailp x (car ll))))
+                 (go lp)))
+          (go lp1))))
+
+(def editbf1
+  (lambda (pat x lvl tail)
+    (prog (y)
+     lp   (cond ((not (> lvl 0))
+                 (terpri)
+                 (princ '"maxlevel exceeded")
+                 (return nil))
+                ((eq tail x)
+                 (return
+                  (cond
+                   ((edit4e (cond ((and (dtpr pat)
+                                        (eq (car pat) ':::))
+                                   (cdr pat))
+                                  (t pat))
+                            x)
+                    (tconc %%w x))))))
+          (setq y x)
+     lp1  (cond
+           ((null (or (eq (cdr y) tail) (atom (cdr y))))
+            (setq y (cdr y))
+            (go lp1)))
+          (setq tail y)
+          (cond ((and (dtpr (car tail))
+                      (editbf1 pat (car tail) (sub1 lvl) nil))
+                 (setq tail (car tail)))
+                ((and (dtpr pat)
+                      (eq (car pat) ':::)
+                      (edit4e (cdr pat) tail)))
+                ((and (or (atom pat) (neq (car pat) ':::))
+                      (edit4e pat (car tail)))
+                 (cond
+                  ((or (null upfindflg) (dtpr (car tail)))
+                   (setq lastail tail)
+                   (setq tail (car tail)))))
+                ((and pat (eq pat (cdr tail))) (setq x (cdr x)))
+                (t (setq lvl (sub1 lvl)) (go lp)))
+          (cond ((neq tail (cadr %%w)) (tconc %%w tail)))
+          (return %%w))))
+
+(def editnth
+  (lambda (x n)
+    (cond ((atom x) (err nil))
+          ((not (numberp n))
+           (or (memq n x) (memq (setq n (editelt n (ncons x))) x) (tailp n x)))
+          ((eq n 0) (err nil))
+          ((null
+            (setq n
+                  (cond
+                   ((or (not (minusp n))
+                        (> (setq n (plus (length x) n 1)) 0))
+                    (Cnth x n)))))
+           (err nil))
+          (t n))))
+
+(def bpnt0
+  (lambda (y n)
+    (cond ((neq lastp1 l) (setq lastp2 lastp1) (setq lastp1 l)))
+    (cond (n (setq $%dotflg (tailp (car l) (cadr l)))
+             (setq %prevfn% '" ")
+             (printlev y n))
+          (t (terpri) (*** sprint y 1) ($prpr y) (terpri)))))
+
+(def bpnt
+  (lambda (x)
+    (prog (y n)
+          (cond ((eq (car x) 0)
+                 (setq y (car l))
+                 (setq $%dotflg (tailp (car l) (cadr l))))
+                (t (setq y (car (editnth (car l) (car x))))))
+          (cond ((null (cdr x)) (setq n 2))
+                ((not (numberp (setq n (cadr x)))) (err nil))
+                ((minusp n) (err nil)))
+          (setq %prevfn% '" ")
+          (return (printlev y n)))))
+
+(def editri
+  (lambda (m n x)
+    (prog (a b)
+          (setq a (editnth x m))
+          (setq b (editnth (car a) n))
+          (cond ((or (null a) (null b)) (err nil)))
+          (editsmash a (car a) (editnconc (cdr b) (cdr a)))
+          (editsmash b (car b) nil))))
+
+(def editro
+  (lambda (n x)
+    (setq x (editnth x n))
+    (cond ((or (null x) (atom (car x))) (err nil)))
+    (editsmash (setq n (last (car x))) (car n) (cdr x))
+    (editsmash x (car x) nil)))
+
+(def editli
+  (lambda (n x)
+    (setq x (editnth x n))
+    (cond ((null x) (err nil)))
+    (editsmash x (cons (car x) (cdr x)) nil)))
+
+(def editlo
+  (lambda (n x)
+    (setq x (editnth x n))
+    (cond ((or (null x) (atom (car x))) (err nil)))
+    (editsmash x (caar x) (cdar x))))
+
+(def editbi
+  (lambda (m n x)
+    (prog (a b)
+          (setq b (cdr (setq a (editnth x n))))
+          (setq x (editnth x m))
+          (cond ((and a (not (> (length a) (length x))))
+                 (editsmash a (car a) nil)
+                 (editsmash x (cons (car x) (cdr x)) b))
+                (t (err nil))))))
+
+(def editbo
+  (lambda (n x)
+    (setq x (editnth x n))
+    (cond ((atom (car x)) (err nil)))
+    (editsmash x (caar x) (editnconc (cdar x) (cdr x)))))
+
+(def editdefault
+  (lambda (editx)
+    (prog nil
+          (cond (lcflg
+                 (return
+                  (cond ((eq lcflg t) (editqf editx))
+                        (t (editcom (list lcflg editx) topflg)))))
+                ((null topflg) (err nil))
+                ((memq editx editcomsl)
+                 (cond (readbuf (setq editx (cons editx readbuf))
+                                (setq readbuf nil))
+                       (t (err nil))))
+                (t (err nil)))
+          (return (editcom (setq com editx) topflg)))))
+
+(def edup
+  (lambda nil
+    (prog (c-exp l1 x y)
+          (setq c-exp (car l))
+     lp   (cond ((null (setq l1 (cdr l))) (err nil))
+                ((tailp c-exp (car l1)) (return nil))
+                ((not (setq x (memq c-exp (car l1)))) (err nil))
+                ((or (eq x lastail) (not (setq y (memq c-exp (cdr x))))))
+                ((and (eq c-exp (car lastail)) (tailp lastail y))
+                 (setq x lastail))
+                (t (terpri)
+                   (princ c-exp)
+                   (princ '"- location uncertain")))
+          (cond ((eq x (car l1)) (setq l l1)) (t (setq l (cons x l1))))
+          (return nil))))
+
+(def edit*l
+  (lambda (l)
+    (edup)
+    (length (car l))))
+
+(def edit*
+  (lambda (n)
+    (car
+     (setq l
+           ((lambda (com l m)
+                    (cond ((not (> m n)) (err nil)))
+                    (edit!0)
+                    (edit1f (difference n m) l))
+            nil
+            l
+            (edit*l l))))))
+
+(def edor
+  (lambda (coms)
+    (prog nil
+     lp   (cond ((null coms) (err nil))
+                ((dtpr
+                  (errset
+                   (setq l
+                         ((lambda (l)
+                                  (cond ((atom (car coms))
+                                         (editcom (car coms) nil))
+                                        (t (editcoms (car coms))))
+                                  l)
+                          l))))
+                 (return (car l))))
+          (setq coms (cdr coms))
+          (go lp))))
+
+(def errcom
+  (lambda (coms)
+    (errset (editcoms coms))))
+
+(def edrpt
+  (lambda (edrx quiet)
+    (prog (edrl edrptcnt)
+          (setq edrl l)
+          (setq edrptcnt 0)
+     lp   (cond ((> edrptcnt maxloop)
+                 (terpri)
+                 (princ '"maxloop exceeded"))
+                ((dtpr (errcom edrx))
+                 (setq edrl l)
+                 (setq edrptcnt (add1 edrptcnt))
+                 (go lp))
+                ((null quiet) (print edrptcnt) (princ 'occurrences)))
+          (setq l edrl))))
+
+(def edloc
+  (lambda (edx)
+    (prog (oldl oldf lcflg edl)
+          (setq oldl l)
+          (setq oldf unfind)
+          (setq lcflg t)
+          (cond ((atom edx) (editcom edx nil))
+                ((and (null (cdr edx)) (atom (car edx)))
+                 (editcom (car edx) nil))
+                (t (go lp)))
+          (setq unfind oldl)
+          (return (car l))
+     lp   (setq edl l)
+          (cond ((dtpr (errcom edx)) (setq unfind oldl) (return (car l))))
+          (cond ((equal edl l) (setq l oldl) (setq unfind oldf) (err nil)))
+          (go lp))))
+
+(def edlocl
+  (lambda (coms)
+    (car
+     (setq l
+           (nconc ((lambda (l unfind) (edloc coms) l) (ncons (car l)) nil)
+                  (cdr l))))))
+
+(def edit:
+  (lambda (type lc x)
+    (prog (toflg l0)
+          (setq l0 l)
+          (setq x
+                (mapcar (function
+                         (lambda (x)
+                                 (cond ((and (dtpr x)
+                                             (eq (car x) '|##|))
+                                        ((lambda (l undolst1)
+                                                 (copy (editcoms (cdr x))))
+                                         l
+                                         nil))
+                                       (t x))))
+                        x))
+          (cond
+           (lc (cond ((eq (car lc) 'here) (setq lc (cdr lc))))
+               (edloc lc)))
+          (edup)
+          (cond ((eq l0 l) (setq lc nil)))
+          (selectq type
+                   ((b before) (edit2f -1 x))
+                   ((a after)
+                    (cond ((cdar l) (edit2f -2 x))
+                          (t (editcoml (cons 'n x) copyflg))))
+                   ((: for)
+                    (cond ((or x (cdar l)) (edit2f 1 x))
+                          ((memq (car l) (cadr l))
+                           (edup)
+                           (edit2f 1 (ncons nil)))
+                          (t (editcoms '(0 (nth -2) (2)))))
+                    (return (cond ((null lc) l))))
+                   (err nil))
+          (return nil))))
+
+(def editmbd
+  (lambda (lc x)
+    (prog (y toflg)
+          (cond (lc (edloc lc)))
+          (edup)
+          (setq y (cond (toflg (caar l)) (t (ncons (caar l)))))
+          (edit2f 1
+                  (ncons
+                   (cond ((or (atom (car x)) (cdr x)) (append x y))
+                         (t (lsubst y '* (car x))))))
+          (setq l
+                (cons (caar l)
+                      (cond ((tailp (car l) (cadr l)) (cdr l)) (t l))))
+          (return (cond ((null lc) l))))))
+
+(def editxtr
+  (lambda (lc x)
+    (prog (toflg)
+          (cond (lc (edloc lc)))
+          ((lambda (l unfind)
+                   (edloc x)
+                   (setq x
+                         (cond ((tailp (car l) (cadr l)) (caar l))
+                               (t (car l)))))
+           (ncons (cond ((tailp (car l) (cadr l)) (caar l)) (t (car l))))
+           nil)
+          (edup)
+          (edit2f 1 (cond (toflg (append x nil)) (t (ncons x))))
+          (and (null toflg)
+               (dtpr (caar l))
+               (setq l
+                     (cons (caar l)
+                           (cond ((tailp (car l) (cadr l)) (cdr l)) (t l))))))))
+
+(def editelt
+  (lambda (lc l)
+    (prog (y)
+          (edloc lc)
+     lp   (setq y l)
+          (cond ((cdr (setq l (cdr l))) (go lp)))
+          (return (car y)))))
+
+(def editcont
+  (lambda (lc1 %%x)
+    (setq l
+          ((lambda (l)
+                   (prog nil
+                         (setq lc1 (editfpat lc1))
+                    lp   (cond ((null (edit4f lc1 'n)) (err nil))
+                               ((atom (errset (edlocl %%x))) (go lp)))
+                    lp1  (cond ((null (setq l (cdr l))) (err nil))
+                               ((cond ((atom lc1) (eq lc1 (caar l)))
+                                      ((eq (car lc1) '@)
+                                       (edit4e lc1 (caar l)))
+                                      (t (edit4e lc1 (car l))))
+                                (return l)))
+                         (go lp1)))
+           l))))
+
+(def editsw
+  (lambda (m n)
+    (prog (y z tem)
+          (setq y (editnth (car l) m))
+          (setq z (editnth (car l) n))
+          (setq tem (car y))
+          (editsmash y (car z) (cdr y))
+          (editsmash z tem (cdr z)))))
+
+(def editmv
+  (lambda (lc op x cp)
+    (prog (l0 l1 z toflg)
+          (setq l0 l)
+          (and lc (edloc lc))
+          (cond ((eq op 'here)
+                 (cond ((null lc) (edloc x) (setq x nil)))
+                 (setq op ':))
+                ((eq (car x) 'here)
+                 (cond ((null lc) (edloc (cdr x)) (setq x nil))
+                       (t (setq x (cdr x))))))
+          (edup)
+          (setq l1 l)
+          (setq z (cond (cp (copy (caar l))) (t (caar l))))
+          (setq l l0)
+          (and x (edloc x))
+          (cond ((eq op 'after) (setq op 'a))
+                ((eq op 'before) (setq op 'b)))
+          (editcoml (cond (toflg (cons op (append z nil))) (t (list op z)))
+                    nil)
+          (prog (l)
+                (setq l l1)
+                (cond ((not cp) (editcoms '(1 delete)))
+                      (toflg (editcoml '(bo 1) nil))))
+          (return
+           (cond ((null lc) (setq unfind l1) l)
+                 ((null x) (setq unfind l1) l0)
+                 (t (setq unfind l) l0))))))
+
+(def editto
+  (lambda (lc1 lc2 flg)
+    (setq l
+          ((lambda (l)
+                   (cond (lc1 (edloc lc1) (edup)))
+                   (editbi 1
+                           (cond ((and (numberp lc1)
+                                       (numberp lc2)
+                                       (> lc2 lc1))
+                                  (difference (add1 lc2) lc1))
+                                 (t lc2))
+                           (car l))
+                   (cond
+                    ((and (eq flg 'to) (cdaar l))
+                     (editri 1 -2 (car l))))
+                   (editcom 1 nil)
+                   l)
+           l))
+    (setq toflg t)))
+
+(def editbelow
+  (lambda (place depth)
+    (cond ((minusp (setq depth (eval depth))) (err nil)))
+    (prog (n1 n2)
+          (setq n1
+                (length
+                 ((lambda (l lcflg) (editcom place nil) l) l '_)))
+          (setq n2 (length l))
+          (cond ((< n2 (+ n1 depth)) (err nil)))
+          (setq unfind l)
+          (setq l (Cnth l (difference (add1 n2) n1 depth))))))
+
+(def editran
+  (lambda (c def)
+    (setq l
+          (or ((lambda (l)
+                       (prog (z w)
+                             (cond ((null def) (err nil))
+                                   ((null (setq z (car def))) (go out)))
+                        lp   (cond ((null z) (err nil))
+                                   ((null (setq w (memq (car z) c)))
+                                    (setq z (cdr z))
+                                    (go lp)))
+                        out  (setq z
+                                   (apply (car (setq def (cadr def)))
+                                          (prog (|#1| |#2| |#3|)
+                                                (setq |#1| (cdr
+                                                            (ldiff c w)))
+                                                (setq |#2| (car z))
+                                                (setq |#3| (cdr w))
+                                                (return
+                                                 (mapcar (function
+                                                          (lambda (x)
+                                                                  (cond ((atom
+                                                                          x)
+                                                                         (selectq x
+                                                                                  (|#1|
+                                                                                   |#1|)
+                                                                                  (|#2|
+                                                                                   |#2|)
+                                                                                  (|#3|
+                                                                                   |#3|)
+                                                                                  x))
+                                                                        (t
+                                                                         (eval
+                                                                          x)))))
+                                                         (cdr def))))))
+                             (return
+                              (cond ((null z) (setq unfind l) nil) (t z)))))
+               l)
+              l))))
+
+(def edit!0
+  (lambda nil
+    (cond ((null (cdr l)) (err nil)))
+    (prog nil
+     lp   (setq l (cdr l))
+          (cond ((tailp (car l) (cadr l)) (go lp))))))
+
+(def editrepack
+  (lambda nil
+    (cond ((dtpr (car l)) (setq l (edit1f 1 l))))
+    (edit: ': nil (ncons (readlist (edite (explode (car l)) nil nil))))))
+
+(def editmakefn
+  (lambda (ex args n m)
+    (editbi n m (car l))
+    (edloc n)
+    (editbelow '/ 1)
+    (mapc (function (lambda (x y) (editdsubst x y (car l)))) args (cdr ex))
+    (putprop (car ex) (cons 'lambda (cons args (car l))) 'expr)
+    (mark!changed (car ex))
+    (edup)
+    (edit2f 1 (ncons ex))))
+
+(dv usermacros nil)
+
+(dv editracefn nil)
+
+(dv lastword editsfns)
+
+(dv maxlevel 192)
+
+(dv maxloop 24)
+
+(dv editcomsl
+    (: a
+       b
+       below
+       bf
+       bi
+       bind
+       bk
+       bo
+       change
+       coms
+       comsq
+       copy
+       cp
+       delete
+       e
+       embed
+       extract
+       f
+       f=
+       fs
+       help
+       i
+       if
+       insert
+       lc
+       lcl
+       li
+       lo
+       lp
+       lpq
+       m
+       makefn
+       mbd
+       move
+       mv
+       n
+       nex
+       nth
+       nx
+       orf
+       orr
+       p
+       r
+       repack
+       replace
+       ri
+       ro
+       s
+       second
+       surround
+       sw
+       third
+       thru
+       to
+       undo
+       xtr
+       _))
+
+(dv autop 2)
+
+(dv upfindflg t)
diff --git a/usr/src/usr.bin/lisp/lisplib/cmuenv.l b/usr/src/usr.bin/lisp/lisplib/cmuenv.l
new file mode 100644 (file)
index 0000000..7489a42
--- /dev/null
@@ -0,0 +1,7 @@
+(setq rcs-cmuenv-
+   "$Header: /usr/lib/lisp/cmuenv.l,v 1.1 83/01/29 18:33:54 jkf Exp $")
+
+(load 'cmumacs)
+(load 'cmufncs)
+(load 'cmutpl)
+(load 'cmufile)
diff --git a/usr/src/usr.bin/lisp/lisplib/cmufile.l b/usr/src/usr.bin/lisp/lisplib/cmufile.l
new file mode 100644 (file)
index 0000000..17aa1a0
--- /dev/null
@@ -0,0 +1,316 @@
+;;; cmu file package.
+;;;
+(setq rcs-cmufile-
+   "$Header: /usr/lib/lisp/cmufile.l,v 1.1 83/01/29 18:34:10 jkf Exp $")
+
+(eval-when (compile eval)
+   (load 'cmumacs)
+   (load 'cmufncs)
+   )
+
+(declare (special $cur$ dc-switch piport %indent dc-switch
+                 vars body form var init label part incr limit
+                 getdeftable $outport$ tlmacros f tmp))
+
+(declare (nlambda msg))
+
+(declare
+ (special %changes
+          def-comment
+          filelst
+          found
+          getdefchan
+          getdefprops
+          history
+          historylength
+          args
+          i
+          l
+          lasthelp
+          prop
+          special
+          special
+          tlbuffer
+          z))
+
+(dv dc-switch dc-define)
+
+(dv %indent 0)
+
+(dv *digits ("0" "1" "2" "3" "4" "5" "6" "7" "8" "9"))
+
+(dv *letters (a b c d e f g h i j k l m n o p q r s t u v w x y z))
+
+(def changes
+  (lambda nil
+    (changes1)
+    (for-each f
+              filelst
+              (cond
+               ((get f 'changes)
+                (terpri)
+                (princ f)
+                (tab 15)
+                (princ (get f 'changes)))))
+    (cond
+     (%changes (terpri) (princ '<no-file>) (tab 15) (princ %changes)))
+    nil))
+
+(def changes1
+  (lambda nil
+    (cond ((null %changes) nil)
+          (t
+           (prog (found prop)
+                 (for-each f
+                           filelst
+                           (setq found
+                                 (cons (set-of fn
+                                               (cons (concat f 'fns)
+                                                     (eval
+                                                      (concat f
+                                                              'fns)))
+                                               (memq fn %changes))
+                                       found))
+                           (setq prop (get f 'changes))
+                           (for-each fn
+                                     (car found)
+                                     (setq prop (insert fn prop nil t)))
+                           (putprop f prop 'changes))
+                 (setq found (apply 'append found))
+                 (setq %changes (set-of fn %changes (not (memq fn found)))))))))
+
+(def dc
+  (nlambda (args)
+    (eval (cons dc-switch args]
+
+(def dc-define
+  (nlambda (args)
+    (msg "Enter comment followed by <esc>" (N 1))
+    (drain piport)
+    (eval (cons 'dc-dskin args]
+
+(def dc-help
+  (nlambda (args)
+    (cond
+     ((eval (cons 'helpfilter (cons (car args) (caddr args))))
+      (transprint getdefchan)))))
+
+(def dskin
+  (nlambda (files)
+    (mapc (function
+           (lambda (f)
+                   (prog nil
+                         (setq dc-switch 'dc-dskin)
+                         (file f)
+                         (load f)
+                         (changes1)
+                         (putprop f nil 'changes)
+                        (setq dc-switch 'dc-define)
+)))
+          files]
+
+(***
+The new version of dskout (7/26/80) tries to keep backup versions  It returns
+the setof its arguments that were successfully written  If it can not write
+a file (typically because of protection restrictions) it offers to (try to)
+write a copy to /tmp  A file written to /tmp is not considered to have been
+successfully written (and changes will not consider it to be up-to-date) )
+
+(def dskout
+  (nlambda (files)
+    (changes1)
+    (set-of f
+            files
+            (prog (ffns p tmp)
+                  (cond ((atom (errset (setq p (infile f)) nil))
+                         (msg "creating " f N D))
+                        (t (close p)
+                           (cond ((zerop
+                                   (eval
+                                    (list 'exec
+                                          'mv
+                                          f
+                                          (setq tmp
+                                                (concat f '|.back|)))))
+                                  (msg  "old version moved to " 
+                                       tmp N D))
+                                 (t (msg 
+                                         "Unable to back up "
+                                         f
+                                         " - continue? (y/n) " D)
+                                    (cond ((not (ttyesno)) (return nil)))))))
+                  (cond
+                   ((atom
+                     (errset (apply (function pp)
+                                    (cons (list 'F f)
+                                          (cons (setq ffns
+                                                      (concat f
+                                                              'fns))
+                                                (eval ffns))))
+                             nil))
+                    (msg
+                         "Unable to write "
+                         f
+                         " - try to put it on /tmp? (y/n) " D)
+                    (cond
+                     ((ttyesno)
+                      (setq f (explode f))
+                      (while (memq '/ f)
+                             (setq f (cdr (memq '/ f))))
+                      (setq f
+                            (apply (function concat)
+                                   (cons '/tmp/ f)))
+                      (cond ((atom
+                              (errset
+                               (apply (function pp)
+                                      (cons (list 'F f)
+                                            (cons ffns (eval ffns))))))
+                             (msg
+                                  "Unable to create "
+                                 f
+                                  " - I give up! " N D  ))
+                            (t (msg f " written " N D  )))))
+                    (return nil)))
+                  (putprop f nil 'changes)
+                  (return t)))))
+
+(def dskouts
+  (lambda nil
+    (changes1)
+    (apply (function dskout) (set-of f filelst (get f 'changes)))))
+
+(def evl-trace
+  (nlambda (exp)
+    (prog (val)
+          (tab %indent)
+          (prinlev (car exp) 2)
+          ((lambda (%indent) (setq val (eval (car exp)))) (+ 2 %indent))
+          (tab %indent)
+          (prinlev val 2)
+          (return val))))
+
+
+(def file
+  (lambda (name)
+    (setq filelst (insert name filelst nil t))
+    (cond
+     ((not (boundp (concat name 'fns)))
+      (set (concat name 'fns) nil)))
+    name))
+
+(def getdef
+  (nlambda (%%l)
+    (prog (x u getdefchan found)
+          (setq getdefchan (infile (car %%l)))
+     l    (cond ((atom
+                  (setq u
+                        (errset
+                         (prog (x y z)
+                               (cond
+                                ((eq (tyipeek getdefchan) -1)
+                                 (err 'EOF)))
+                               (cond
+                                ((memq (tyipeek getdefchan)
+                                       '(12 13))
+                                 (tyi getdefchan)))
+                               (return
+                                (cond
+                                 ((memq (tyipeek getdefchan)
+                                        '(40 91))
+                                  (tyi getdefchan)
+                                  (cond
+                                   ((and (symbolp
+                                          (setq y (ratom getdefchan)))
+                                         (cond (t (comment - what about
+                                                   intern?)
+                                                  (setq x y)
+                                                  t)
+                                               ((neq y
+                                                     (setq x
+                                                           (intern y)))
+                                                t)
+                                               (t (remob1 x) nil))
+                                         (assoc x getdeftable)
+                                         (or (setq z (ratom getdefchan))
+                                             t)
+                                         (some (cdr %%l)
+                                               (function
+                                                (lambda (x)
+                                                        (matchq x z)))
+                                               nil)
+                                         (cond ((symbolp z)
+                                                (setq y z)
+                                                t)
+                                               (t (setq y z) t))
+                                         (cond ((memq y found))
+                                               ((setq found
+                                                      (cons y found))))
+                                         (not
+                                          (cond
+                                           ((memq (tyipeek
+                                                   getdefchan)
+                                                  '(40 91))
+                                            (print x)
+                                            (terpri)
+                                            (princ y)
+                                            (tyo 32)
+                                            (princ
+                                             '" -- bad format")
+                                            t))))
+                                    (cons x
+                                          (cons y
+                                                (cond ((memq (tyipeek
+                                                              getdefchan)
+                                                             '(41
+                                                               93))
+                                                       (tyi
+                                                        getdefchan)
+                                                       nil)
+                                                      (t (untyi 40
+                                                                getdefchan)
+                                                         (read
+                                                          getdefchan))))))))))))))
+                 (close getdefchan)
+                 (return found))
+                (t (setq x (car u))
+                   (*** free u)
+                   (setq u nil)
+                   (cond
+                    ((not (atom x))
+                     (apply (cdr (assoc (car x) getdeftable)) (ncons x))))))
+          (cond ((not (eq (tyi getdefchan) 10)) (zap getdefchan)))
+          (go l))))
+
+(def getdefact
+  (lambda (i p exp)
+    (prog nil
+          (cond ((or (null getdefprops) (memq p getdefprops))
+                 (terpri)
+                 (print (eval exp))
+                 (princ '" ")
+                 (prin1 p))
+                (t (terpri)
+                   (print i)
+                   (princ '" ")
+                   (prin1 p)
+                   (princ '" ")
+                   (princ 'bypassed))))))
+
+(dv getdefprops (function value expr fexpr macro))
+
+(dv getdeftable
+    ((defprop lambda (x) (getdefact (cadr x) (cadddr x) x))
+     (dc lambda
+         (x)
+         (cond
+          ((or (null getdefprops) (memq 'comment getdefprops))
+           (eval x))))
+     (de lambda (x) (getdefact (cadr x) 'expr x))
+     (df lambda (x) (getdefact (cadr x) 'fexpr x))
+     (dm lambda (x) (getdefact (cadr x) 'macro x))
+     (setq lambda (x) (getdefact (cadr x) 'value x))
+     (dv lambda (x) (getdefact (cadr x) 'value x))
+     (def lambda (x) (getdefact (cadr x) 'function x))))
+
+(setq filelst nil)     ;; initial values
+(setq %changes nil)
diff --git a/usr/src/usr.bin/lisp/lisplib/cmufncs.l b/usr/src/usr.bin/lisp/lisplib/cmufncs.l
new file mode 100644 (file)
index 0000000..6641df2
--- /dev/null
@@ -0,0 +1,429 @@
+(setq rcs-cmufncs-
+   "$Header: /usr/lib/lisp/cmufncs.l,v 1.1 83/01/29 18:34:20 jkf Exp $")
+
+(eval-when (compile eval) (load 'cmumacs))
+
+(declare (special filelst %changes $%dotflg %prevfn% %%cfn part %%l
+                 lastword %trcflg form fn))
+(def tab (lexpr (n)
+               (prog (nn prt) (setq nn (arg 1))
+                              (cond ((> n 1)(setq prt (arg 2))))
+                              (cond ((> (nwritn prt) nn) (terpri prt)))
+                              (printblanks (- nn (nwritn prt)) prt))))
+
+
+(dv $%dotflg nil)
+(def %lineread
+     (lambda 
+      (chan)
+      (prog (ans)
+       loop (setq ans (cons (read chan 'EOF) ans))
+           (cond ((eq (car ans) 'EOF) (return (reverse (cdr ans)))))
+       loop2(cond ((eq 10 (tyipeek chan)) (return (reverse ans)))
+                  ((memq (tyipeek chan) '(41 93))
+                   (tyi chan)
+                   (go loop2))
+                  (t (go loop))))))
+
+
+(dv %prevfn% " ")
+(dv %trcflg t)
+   
+(def attach
+     (lambda 
+      (x y)
+      (cond ((dtpr y) (rplacd y (cons (car y) (cdr y))) (rplaca y x))
+            (t (eprint y) (error '"IS AN ATOM, CAN'T BE ATTACHED TO")))))
+
+(dv %changes ())
+
+(def dremove
+   (lambda (x l)
+          (cond ((atom l) nil)
+                ((eq x (car l))
+                 (cond ((cdr l)
+                        (rplaca l (cadr l))
+                        (rplacd l (cddr l))
+                        (dremove x l))))
+                (t (prog (z)
+                         (setq z l)
+                   lp    (cond ((atom (cdr l)) (return z))
+                               ((eq x (cadr l)) (rplacd l (cddr l)))
+                               (t (setq l (cdr l))))
+                         (go lp))))))
+(def dreverse
+     (lambda (l)
+      (prog (l1 y z)
+            (setq l1 l)
+       l1   (cond
+             ((atom (setq y l))
+              (cond ((or (null z) (null (cdr z))) (return z))
+                    ((null (cddr z))
+                     (setq y (car l1))
+                     (rplaca l1 (car z))
+                     (rplaca z y)
+                     (rplacd l1 z)
+                     (rplacd z nil)
+                     (return l1))
+                    (t (rplacd (Cnth z (sub1 (length z))) z)
+                       (setq y (car l1))
+                       (rplaca l1 (car z))
+                       (rplaca z y)
+                       (rplacd l1 (cdr z))
+                       (rplacd z nil)
+                       (return l1)))))
+            (setq l (cdr l))
+            (setq z (rplacd y z))
+            (go l1))))
+
+(def dsubst
+     (lambda (x y z)
+      (prog (b)
+            (cond ((eq y (setq b z)) (return (copy x))))
+       lp   (cond ((atom z) (return b))
+                  ((cond ((symbolp y) (eq y (car z))) (t (equal y (car z))))
+                   (rplaca z (copy x)))
+                  (t (dsubst x y (car z))))
+            (cond ((and y (eq y (cdr z))) (rplacd z (copy x)) (return b)))
+            (setq z (cdr z))
+            (go lp))))
+
+(putd 'eqstr (getd 'equal))
+
+; where are the functions this calls??
+(def every
+     (lambda 
+      (everyx everyfn1 everyfn2)
+      (prog nil
+       a    (cond ((null everyx) (return t))
+                  ((funcall everyfn1 (car everyx))
+                   (setq everyx
+                         (cond ((null everyfn2) (cdr everyx))
+                               (t (funcall everyfn2 everyx))))
+                   (go a))
+                  (t (return nil))))))
+(def insert
+     (lambda 
+      (x l comparefn nodups)
+      (cond ((null l) (list x))
+            ((atom l)
+             (eprint l)
+             (error '"is an atom, can't be inserted into"))
+            (t (cond
+                ((null comparefn) (setq comparefn (function alphalessp))))
+               (prog (l1 n n1 y)
+                     (setq l1 l)
+                     (setq n (length l))
+                a    (setq n1 (*quo (add1 n) 2))
+                     (setq y (Cnth l1 n1))
+                     (cond ((< n 3)
+                            (cond ((funcall comparefn x (car y))
+                                   (cond
+                                    ((not
+                                      (and nodups (equal x (car y))))
+                                     (rplacd y (cons (car y) (cdr y)))
+                                     (rplaca y x))))
+                                  ((eq n 1) (rplacd y (cons x (cdr y))))
+                                  ((funcall comparefn x (cadr y))
+                                   (cond
+                                    ((not
+                                      (and nodups (equal x (cadr y))))
+                                     (rplacd (cdr y)
+                                             (cons (cadr y) (cddr y)))
+                                     (rplaca (cdr y) x))))
+                                  (t (rplacd (cdr y) (cons x (cddr y))))))
+                           ((funcall comparefn x (car y))
+                            (cond
+                             ((not (and nodups (equal x (car y))))
+                              (setq n (sub1 n1))
+                              (go a))))
+                           (t (setq l1 (cdr y)) (setq n (- n n1)) (go a))))
+               l))))
+
+(def kwote (lambda (x) (list 'quote x)))
+
+(def lconc
+     (lambda 
+      (ptr x)
+      (prog (xx)
+            (return
+             (cond ((atom x) ptr)
+                   (t (setq xx (last x))
+                      (cond ((atom ptr) (cons x xx))
+                            ((dtpr (cdr ptr))
+                             (rplacd (cdr ptr) x)
+                             (rplacd ptr xx))
+                            (t (rplaca (rplacd ptr xx) x)))))))))
+
+(def ldiff
+     (lambda 
+      (x y)
+      (cond ((eq x y) nil)
+            ((null y) x)
+            (t
+             (prog (v z)
+                   (setq z (setq v (ncons (car x))))
+              loop (setq x (cdr x))
+                   (cond ((eq x y) (return z))
+                         ((null x) (error '"NOT A TAIL - LDIFF")))
+                   (setq v (cdr (rplacd v (ncons (car x)))))
+                   (go loop))))))
+
+
+(def lsubst
+     (lambda 
+      (x y z)
+      (cond ((null z) nil)
+            ((atom z) (cond ((eq y z) x) (t z)))
+            ((equal y (car z)) (nconc (copy x) (lsubst x y (cdr z))))
+            (t (cons (lsubst x y (car z)) (lsubst x y (cdr z)))))))
+
+(def memcdr
+     (lambda 
+      (%x% %y%)
+      (prog nil
+       l1   (cond ((eq %x% (cdr %y%)) (return t))
+                  ((eq %x% %y%) (return nil)))
+            (setq %x% (cdr %x%))
+            (go l1))))
+
+(def merge
+     (lambda 
+      (a b %%cfn)
+      (cond ((null %%cfn) (setq %%cfn (function alphalessp))))
+      (merge1 a b)))
+
+(def merge1
+     (lambda 
+      (a b)
+      (cond ((null a) b)
+            ((null b) a)
+            (t
+             (prog (val end)
+                   (setq val
+                         (setq end
+                               (cond ((funcall %%cfn (car a) (car b))
+                                      (prog1 a (setq a (cdr a))))
+                                     (t (prog1 b (setq b (cdr b)))))))
+              loop (cond ((null a) (rplacd end b) (return val))
+                         ((null b) (rplacd end a) (return val))
+                         ((funcall %%cfn (car a) (car b))
+                          (rplacd end a)
+                          (setq a (cdr a)))
+                         (t (rplacd end b) (setq b (cdr b))))
+                   (setq end (cdr end))
+                   (go loop))))))
+
+(def notany
+     (lambda (somex somefn1 somefn2) (not (some somex somefn1 somefn2))))
+
+(def notevery
+     (lambda 
+      (everyx everyfn1 everyfn2)
+      (not (every everyx everyfn1 everyfn2))))
+
+(def Cnth
+     (lambda 
+      (x n)
+      (cond ((> 1 n) (cons nil x))
+            (t
+             (prog nil
+              lp   (cond ((or (atom x) (eq n 1)) (return x)))
+                   (setq x (cdr x))
+                   (setq n (sub1 n))
+                   (go lp))))))
+
+(def nthchar
+     (lambda 
+      (x n)
+      (cond ((plusp n) (car (Cnth (explodec x) n)))
+            ((minusp n) (car (Cnth (reverse (explodec x)) (minus n))))
+            ((zerop n) nil))))
+
+(def prinlev
+     (lambda 
+      ($%x $%n)
+      (cond ((not (dtpr $%x)) (print $%x))
+            ((and %trcflg (eq (car $%x) 'evl-trace) (dtpr (cdr $%x)))
+             (prinlev (cadr $%x) $%n))
+            ((and %trcflg
+                  (eq (car $%x) '\#)
+                  (dtpr (cdr $%x))
+                  (dtpr (cddr $%x)))
+             (prinlev (caddr $%x) $%n))
+            ((eq %prevfn% $%x) (princ '//\#//))
+            ((eq $%n 0) (princ '"& "))
+            (t
+             (prog ($%kk $%cl)
+                   (princ
+                    (cond ($%dotflg (setq $%dotflg nil) '"... ")
+                          (t '"(")))
+                   (prinlev (car $%x) (sub1 $%n))
+                   (setq $%kk $%x)
+              lp   (cond
+                    ((memcdr $%x $%kk)
+                     (cond ($%cl (princ '" ...]") (return nil))
+                           (t (setq $%cl t)))))
+                   (cond ((not (*** eq (cdr $%kk) (unbound)))
+                          (setq $%kk (cdr $%kk)))
+                         (t (princ '" . unbound)") (return nil)))
+                   (cond ((null $%kk) (princ '")") (return nil))
+                         ((atom $%kk)
+                          (princ '" . ")
+                          (patom $%kk)
+                          (princ '")")
+                          (return nil)))
+                   (princ '" ")
+                   (prinlev (car $%kk) (sub1 $%n))
+                   (go lp))))))
+
+(def printlev (lambda ($%x $%n) (terpri) (prinlev $%x $%n) $%x))
+
+
+
+(def remove
+     (lambda 
+      (elt list)
+      (cond ((atom list) list)
+            ((equal (car list) elt) (remove elt (cdr list)))
+            ((cons (car list) (remove elt (cdr list)))))))
+
+(def some
+     (lambda 
+      (somex somefn1 somefn2)
+      (prog nil
+       a    (cond ((null somex) (return nil))
+                  ((funcall somefn1 (car somex)) (return somex))
+                  (t (setq somex
+                           (cond ((null somefn2) (cdr somex))
+                                 (t (funcall somefn2 somex))))
+                     (go a))))))
+
+; this probably should have another names since is   ****
+; just a duplication of an existing function and since it has a
+; default second arg which I believe is not documented.
+(def sort
+     (lambda 
+      (%%l %%cfn)
+      (prog (val n)
+            (cond ((null %%cfn) (setq %%cfn (function alphalessp))))
+            (setq n 0)
+            (setq val (sort1 0))
+       loop (cond ((null %%l) (return val))
+                  (t (setq val (merge1 val (sort1 n)))
+                     (setq n (add1 n))
+                     (go loop))))))
+
+(def sort1
+     (lambda 
+      (n)
+      (cond ((null %%l) nil)
+            ((zerop n)
+             (prog (run end)
+                   (setq run %%l)
+              loop (setq end %%l)
+                   (setq %%l (cdr %%l))
+                   (cond ((or (null %%l)
+                              (not (funcall %%cfn (car end) (car %%l))))
+                          (rplacd end nil)
+                          (return run))
+                         (t (go loop)))))
+            (t (merge1 (sort1 (sub1 n)) (sort1 (sub1 n)))))))
+
+(def subpair
+     (lambda 
+      (old new expr)
+      (cond (old (subpr expr old (or new '(nil)))) (t expr))))
+
+(def subpr
+     (lambda 
+      (expr l1 l2)
+      (prog (d a)
+            (cond ((atom expr) (go lp))
+                  ((setq d (cdr expr)) (setq d (subpr d l1 l2))))
+            (setq a (subpr (car expr) l1 l2))
+            (return
+             (cond ((or (neq a (car expr)) (neq d (cdr expr))) (cons a d))
+                   (t expr)))
+       lp   (cond ((null l1) (return expr))
+                  (l2 (cond ((eq expr (car l1)) (return (car l2)))))
+                  (t (cond ((eq expr (caar l1)) (return (cdar l1))))))
+            (setq l1 (cdr l1))
+            (and l2 (setq l2 (or (cdr l2) '(nil))))
+            (go lp))))
+
+(def tailp
+     (lambda 
+      (x y)
+      (and x
+           (prog nil
+            lp   (cond ((atom y) (return nil)) ((eq x y) (return x)))
+                 (setq y (cdr y))
+                 (go lp)))))
+
+(def tconc
+     (lambda 
+      (p x)
+      (cond ((atom p) (cons (setq x (ncons x)) x))
+            ((dtpr (cdr p)) (rplacd p (cdr (rplacd (cdr p) (ncons x)))))
+            (t (rplaca p (cdr (rplacd p (ncons x))))))))
+
+(def ttyesno (lambda nil (yesno (read))))
+
+(def yesno (lambda (x) (selectq x ((t y yes) t) ((nil n no) nil) x)))
+
+; this really duplicates a function in auxfns1.l but this does more
+; error checking.
+(defun nth (N L)
+       (cond ((null L)nil)
+             (t(do ((LCDR L (cdr LCDR))
+                    (COUNT N (1- COUNT)))
+                   ((or (and (atom LCDR) LCDR
+                             (err '"non-proper list passed to nth"))
+                        (or (lessp COUNT 0)(zerop COUNT)))
+                    (car LCDR))
+                   nil))))
+(declare (special piport))
+(def dc-dskin                  ; LWE Hacking to compile OK
+   (nlambda (args)
+           (prog (tmp tmp1 tmp2)
+                 (setq tmp
+                       (prog (c cc)
+                             (setq cc (get (car args) 'comment))
+                             loop
+                             (cond ((not cc)(return nil)))
+                             (setq c (car cc))
+                             (cond ((eq (car c)(cadr args))
+                                    (return nil)))
+                             (setq cc (cdr cc))
+                             (go loop)))
+                 (setq tmp2 piport)
+                 (setq tmp1 (get-comment 27 tmp2))
+                 (cond (tmp  (disgusting tmp
+                                         (cons (cadr args)
+                                               (cons (caddr args) tmp1))))
+                       (t (putprop (car args)
+                                   (cons (cons (cadr args)
+                                               (cons (caddr args) tmp1))
+                                         (get (car args) 'comment))
+                                   'comment)))
+                 (mark!changed (car args))
+                 (return nil))))
+
+(def disgusting (lambda (a b) ; (rplaca a b)))
+b))
+
+(def get-comment
+  (lambda (stopper piport)
+    (prog (ans line)
+          (cond ((eq 10 (tyipeek piport)) (tyi piport)))
+     l:   (setq line nil)
+;          (until (member (car line) (list 10 stopper))
+;                 (setq line (cons (tyi piport) line)))
+          (prog nil loop
+               (cond ((member (car line)(list 10 stopper))
+                      (return nil)))
+               (setq line (cons (tyi piport) line))
+               (go loop))
+          (setq ans (cons (implode (dreverse (cdr line))) ans))
+          (cond ((eq (car line) 10) (go l:)) (t (return (dreverse ans)))))))
diff --git a/usr/src/usr.bin/lisp/lisplib/cmumacs.l b/usr/src/usr.bin/lisp/lisplib/cmumacs.l
new file mode 100644 (file)
index 0000000..0085747
--- /dev/null
@@ -0,0 +1,324 @@
+;; file of common cmu functions which should be macros 
+;; I hope that by just loading in the file an environment will be
+;; created which will permit the cmu files to be compiled.
+
+(setq rcs-cmumacs-
+   "$Header: /usr/lib/lisp/cmumacs.l,v 1.1 83/01/29 18:34:31 jkf Exp $")
+
+(declare (macros t))
+
+(eval-when (compile eval load)
+   (or (boundp 'CMU-fcn-def) (setq CMU-fcn-def (getd 'def))))
+
+;-- contents
+;      dv      mark!changed    ***     list* [construct-list* lambda]
+;      neq     push    pop     mukname (equivlance)
+;      prin1 (equiv to print)  selectq lineread
+;
+
+;--- dv :: set variable to value and remember it was changed
+; (dv name value)   name is setq'ed to value (no evaluation) and
+;               the fact that it was done is remembered
+;
+(defmacro dv (name value)
+  `(progn 'compile
+         (setq ,name ',value)
+         (mark!changed ',name)))
+
+(defmacro mark!changed (name)
+  `(let ((atomname ,name))
+        (and (boundp '%changes) (setq %changes (cons atomname %changes)))
+       atomname))
+
+;--- *** :: comment macro
+;
+(defmacro *** (&rest x) nil)
+
+;; this must be rewritten as a macro           ****
+;(def quote! (nlambda (a) (quote!-expr a)))
+
+; this will be thrown away if the code below it works
+(def quote!-expr
+     (lambda 
+      (x)
+      (cond ((atom x) x)
+            ((eq (car x) '!)
+             (cons (eval (cadr x)) (quote!-expr (cddr x))))
+            ((eq (car x) '!!)
+             (cond ((cddr x)
+                    (append (eval (cadr x)) (quote!-expr (cddr x))))
+                   (t (eval (cadr x)))))
+            (t
+             (prog (u v)
+                   (setq u (quote!-expr (car x)))
+                   (setq v (quote!-expr (cdr x)))
+                   (cond ((and (eq u (car x)) (eq v (cdr x))) (return x)))
+                   (return (cons u v)))))))
+;; this is probably what the above forms do. (jkf)
+(defmacro quote! (&rest a) (quote!-expr-mac a))
+(eval-when (compile eval load)
+   
+(defun quote!-expr-mac (form)
+   (cond ((null form) nil)
+        ((atom form) `',form)
+        ((eq (car form) '!)
+         `(cons ,(cadr form) ,(quote!-expr-mac (cddr form))))
+        ((eq (car form) '!!)
+         (cond ((cddr form) `(append ,(cadr form)
+                                      ,(quote!-expr-mac (cddr form))))
+               (t (cadr form))))
+        (t `(cons ,(quote!-expr-mac (car form))
+                   ,(quote!-expr-mac (cdr form))))))
+
+); end eval-when
+                
+        
+;--- the following are macroizations from cmu3.l
+
+;(jkf)- ucb list* macro.
+;
+(defmacro list* (&rest forms)
+         (cond ((null forms) nil)
+               ((null (cdr forms)) (car forms))
+               (t (construct-list* forms))))
+
+(defun construct-list* (forms)
+       (setq forms (reverse forms))
+       (do ((forms (cddr forms) (cdr forms))
+           (return-form `(cons ,(cadr forms) ,(car forms))
+                        `(cons ,(car forms) ,return-form)))
+          ((null forms) return-form))) 
+
+(defmacro neq (a b) `(not (eq ,a ,b)))
+
+
+(defmacro push (value stack) `(setq ,stack (cons ,value ,stack)))
+
+
+
+
+
+;(jkf) this is actually maknum is the maclisp terminology
+(putd 'munknam (getd 'maknum))
+
+; added for CMULisp compatibilty (used by editor etc)
+(putd 'prin1 (getd 'print))
+
+;--- selectq :: case statement type construct
+;
+;   (selectq <form>
+;           (<tag1> <expr1> ...)
+;           (<tag2> <expr2> ...)
+;               ...
+;           (<tagn> <exprn> ...)
+;            (<exprfinal> ...))
+; <form> is evaluated and then compared with the tagi, if it matches
+; the expri are evaluated.  If it doesn't match, then <exprfinal> are
+; evaluated.
+;
+(def selectq
+   (macro (form)
+         ((lambda (x)
+                  `((lambda (,x)
+                            (cond
+                                 ,@(maplist
+                                        '(lambda (ff)
+                                                 (cond ((null (cdr ff))
+                                                        `(t  ,(car ff)))
+                                                       ((atom (caar ff))
+                                                        `((eq ,x ',(caar ff))
+                                                          . ,(cdar ff)))
+                                                       (t
+                                                            `((memq ,x ',(caar ff))
+                                                              . ,(cdar ff)))))
+                                         (cddr form))))
+                    ,(cadr form)))
+         (gensym 'Z))))
+
+(defmacro lineread (&optional (x nil)) 
+  `(%lineread ,x))
+
+
+
+(defmacro de (name &rest body)
+   (cond ((status feature complr) `(def ,name (lambda ,@body)))
+        (t `(progn (putd ,name '(lambda ,@body))
+                   (mark!changed ',name)))))
+(defmacro dn (name &rest body)
+   (cond ((status feature complr) `(def ,name (nlambda ,@body)))
+        (t `(progn (putd ,name '(nlambda ,@body))
+                   (mark!changed ',name)))))
+(defmacro dm (name &rest body)
+   (cond ((status feature complr) `(def ,name (macro ,@body)))
+        (t `(progn (putd ,name '(macro ,@body))
+                   (mark!changed ',name)))))
+
+(eval-when (compile eval load)
+   (or (boundp 'OLD-fcn-def) (setq OLD-fcn-def (getd 'def))))
+
+(defmacro def (&rest form)
+    (cond ((status feature complr)
+          `(progn 'compile
+                   (eval-when (compile) (putd 'def OLD-fcn-def))
+                   (def ,@form)
+                   (eval-when (compile) (putd 'def CMU-fcn-def))))
+         (t `(progn (putd ',(car form) ',(cadr form))
+                   (mark!changed ',(car form))))))
+
+(eval-when (compile eval load)
+   (or (boundp 'CMU-fcn-def) (setq CMU-fcn-def (getd 'def))))
+
+;--iteration macros
+
+(def Cdo (macro (l) (expand-do l)))
+
+(def exists (macro (l) (expand-ex 'some l)))
+
+(declare (special var))
+
+(eval-when (compile eval load)
+   
+(def expand-ex
+     (lambda 
+      (fn form)
+      (quote! !
+              fn
+              !
+              (caddr form)
+              (function
+               (lambda 
+                !
+                (cond ((atom (cadr form)) (ncons (cadr form)))
+                      (t (cadr form)))
+                !
+                (car (setq form (cdddr form)))))
+              !
+              (cond ((cdr form) (list 'function (cadr form)))))))
+) ; end eval-when
+
+(def expand-do
+     (lambda 
+      (l)
+      (prog (label var init incr limit part)
+            (cond
+             ((setq part (memq 'for l))
+              (setq var (cadr part))
+              (setq l (append (ldiff l part) (cddr part)))))
+            (cond
+             ((setq part (exists w l (memq w '(gets = _ :=))))
+              (setq init (cadr part))
+              (setq l (append (ldiff l part) (cddr part)))))
+            (cond
+             ((setq part (exists w l (memq w '(step by))))
+              (setq incr (cadr part))
+              (setq l (append (ldiff l part) (cddr part)))))
+            (cond
+             ((setq part (memq 'to l))
+              (setq limit (cadr part))
+              (setq l (append (ldiff l part) (cddr part)))))
+            (return
+             (quote! prog
+                     !
+                     (cond (var (ncons var)))
+                     !!
+                     (cond
+                      (var
+                       (ncons
+                        (list 'setq var (cond (init) (t 1))))))
+                     !
+                     (setq label (gensym))
+                     !!
+                     (mapcan (function
+                              (lambda 
+                               (exp)
+                               (cond ((eq part 'while)
+                                      (setq part nil)
+                                      (quote!
+                                       (cond
+                                        ((not ! exp) (return nil)))))
+                                     ((eq part 'until)
+                                      (setq part nil)
+                                      (quote!
+                                       (cond (! exp (return nil)))))
+                                     ((memq (setq part exp)
+                                            '(while until do Cdo))
+                                      nil)
+                                     (t (ncons exp)))))
+                             l)
+                     !!
+                     (cond
+                      (var
+                       (quote!
+                        (setq ! var (+ ! var ! (cond (incr) (t 1)))))))
+                     !!
+                     (cond
+                      ((and var limit)
+                       (quote! (cond ((> ! var ! limit) (return nil))))))
+                     (go ! label))))))
+
+
+(def expand-fe
+     (lambda 
+      (form)
+      (prog (vars body)
+            (return
+             (cons (cond ((memq (cadr form)
+                                (quote
+                                 (map mapc
+                                      mapcan
+                                      mapcar
+                                      mapcon
+                                      mapconc
+                                      maplist)))
+                          (setq form (cdr form))
+                          (car form))
+                         (t 'mapc))
+                   (progn (setq vars (cadr form))
+                          (cond ((atom vars) (setq vars (list vars))))
+                          (cons (cons 'function
+                                      (ncons
+                                       (cons 'lambda
+                                             (cons vars
+                                                   (setq body
+                                                         (Cnth (cdddr
+                                                                form)
+                                                               (length
+                                                                vars)))))))
+                                (ldiff (cddr form) body))))))))
+(def expand-set-of
+     (lambda 
+      (form)
+      (prog (vars body)
+            (setq vars (cadr form))
+            (cond ((atom vars) (setq vars (list vars))))
+            (setq form (cddr form))
+            (return
+             (quote! mapcan
+                     (function
+                      (lambda 
+                       !
+                       vars
+                       (cond
+                        (! (car
+                            (setq body (Cnth (cdr form) (length vars))))
+                           (list ! (car vars))))))
+                     !!
+                     (ldiff form body))))))
+
+(dv filelst nil)
+
+(def for (macro (l) (expand-do l)))
+
+(def for-each (macro (l) (expand-fe l)))
+
+(def forall (macro (l) (expand-ex 'every l)))
+
+(def set-of (macro (l) (expand-set-of l)))
+
+(def ty (macro (f) (append '(exec cat) (cdr f))))
+
+(def until (macro (l) (expand-do l)))
+
+(def while (macro (l) (expand-do l)))
+
+(putprop 'cmumacs t 'version)
diff --git a/usr/src/usr.bin/lisp/lisplib/cmutpl.l b/usr/src/usr.bin/lisp/lisplib/cmutpl.l
new file mode 100644 (file)
index 0000000..28d6074
--- /dev/null
@@ -0,0 +1,191 @@
+;;; cmu top level.
+;;; Eventually this file will be able to be read in along with
+;;; the standard franz top level and thus allow the user to select
+;;; (possible via the .lisprc) the top level he wants.
+;;;
+(setq rcs-cmutpl-
+   "$Header: /usr/lib/lisp/cmutpl.l,v 1.1 83/01/29 18:34:38 jkf Exp $")
+
+(eval-when (compile eval)
+   (or (get 'cmumacs 'version) (load 'cmumacs))
+   (or (get 'cmufncs 'version) (load 'cmufncs)))
+
+(declare (special history tlbuffer tlmacros historylength))
+
+(dv historylength 25)
+
+(def matchq
+  (lambda (x y)
+    (prog (xx yy)
+          (return
+           (cond
+            ((and (atom x) (atom y))
+             (cond ((matchq1 (setq xx (explode x)) (setq yy (explode y)))
+                    (*** freelist xx)
+                    (*** freelist yy)
+                    t)
+                   (t (*** freelist xx) (*** freelist yy)))))))))
+
+(def matchq1
+  (lambda (x y)
+    (prog nil
+     l1   (cond ((eq x y) (return t))
+                ((or (equal y '(@)) (equal x '(@))) (return t))
+                ((or (null x) (null y)) (return nil))
+                ((eq (car x) (car y))
+                 (setq x (cdr x))
+                 (setq y (cdr y))
+                 (go l1))
+                (t (return nil))))))
+
+(def showevents
+  (lambda (evs)
+    (for-each ev
+              evs
+              (terpri)
+              (princ (car ev))
+              (princ '".")
+              (tlprint (cadr ev))
+              (cond ((cddr ev) (terpri) (tlprint (caddr ev)))))))
+
+(def tleval
+  (lambda (exp)
+    (prog (val)
+          (setq val (eval exp))
+          (rplacd (cdar history) (ncons val))
+          (return val))))
+
+(def tlgetevent
+  (lambda (x)
+    (cond ((null x) (car history))
+          ((and (fixp x) (plusp x)) (assoc x history))
+          ((and (fixp x) (minusp x)) (car (Cnth history (minus x)))))))
+
+(dv tlmacros
+    ((ed lambda
+         (x)
+         (prog (exp)
+               (cond ((setq exp (copy (cadr (tlgetevent (cadr x)))))
+                      (edite exp nil nil)
+                      (return (ncons exp)))
+                     (t (princ '"No such event")))))
+     (redo lambda
+           (x)
+           (prog (exp)
+                 (cond ((setq exp (tlgetevent (cadr x)))
+                        (return (ncons (cadr exp))))
+                       (t (princ '"No such event")))))
+     (?? lambda
+         (x)
+         (prog (e1 e2 rest)
+               (cond ((null (cdr x)) (showevents (reverse history)))
+                     ((null (setq e1 (tlgetevent (cadr x))))
+                      (princ '"No such event as ")
+                      (princ (cadr x)))
+                     ((null (cddr x)) (showevents (ncons e1)))
+                     ((null (setq e2 (tlgetevent (caddr x))))
+                      (princ '"No such event as ")
+                      (princ (caddr x)))
+                     (t (setq e1 (memq e1 history))
+                        (cond ((setq rest (memq e2 e1))
+                               (showevents
+                                (cons e2 (reverse (ldiff e1 rest)))))
+                              (t
+                               (showevents
+                                (cons (car e1)
+                                      (reverse
+                                       (ldiff (memq e2 history) e1))))))))))))
+
+(def tlprint
+  (lambda (x)
+    (prinlev x 4)))
+
+(def tlquote
+  (lambda (x)
+    (prog (ans)
+     l    (cond ((null x) (return (reverse ans)))
+                ((eq (car x) '!)
+                 (setq ans (cons (cadr x) ans))
+                 (setq x (cddr x)))
+                (t (setq ans (cons (kwote (car x)) ans)) (setq x (cdr x))))
+          (go l))))
+
+(def tlread
+  (lambda nil
+    (prog (cmd tmp)
+     top  (cond ((not (boundp 'history)) (setq history nil)))
+          (cond
+           ((null tlbuffer)
+            (terpri)
+            (princ (add1 (cond (history (caar history)) (t 0))))
+            (princ '".")
+            (cond
+             ((null (setq tlbuffer (lineread)))
+              (princ 'Bye)
+              (terpri)
+              (exit)))))
+          (cond ((not (atom (setq cmd (car tlbuffer))))
+                 (setq tlbuffer (cdr tlbuffer))
+                 (go record))
+                ((setq cmd (assoc cmd tlmacros))
+                 (setq tmp tlbuffer)
+                 (setq tlbuffer nil)
+                 (setq cmd (apply (cdr cmd) (ncons tmp)))
+                 (cond ((atom cmd) (go top))
+                       (t (setq cmd (car cmd)) (go record))))
+                ((and (null (cdr tlbuffer))
+                      (or (numberp (car tlbuffer))
+                          (stringp (car tlbuffer))
+                          (hunkp (car tlbuffer))
+                          (boundp (car tlbuffer))))
+                 (setq cmd (car tlbuffer))
+                 (setq tlbuffer nil)
+                 (go record))
+                ((or (and (dtpr (getd (car tlbuffer)))
+                          (memq (car (getd (car tlbuffer)))
+                                '(lexpr lambda)))
+                     (and (bcdp (getd (car tlbuffer)))
+                          (eq (getdisc (getd (car tlbuffer)))
+                              'lambda)))
+                 (setq cmd (cons (car tlbuffer) (tlquote (cdr tlbuffer))))
+                 (setq tlbuffer nil)
+                 (go record)))
+          (setq cmd tlbuffer)
+          (setq tlbuffer nil)
+     record
+          (setq history
+                (cons (list (add1 (cond (history (caar history)) (t 0))) cmd)
+                      history))
+          (cond
+           ((dtpr (cdr (setq tmp (Cnth history historylength))))
+            (rplacd tmp nil)))
+          (return cmd)))]
+
+(def cmu-top-level
+  (lambda nil
+    (prog (tlbuffer)
+     l    (tlprint (tleval (tlread)))
+          (go l)))]
+
+; LWE 1/11/81 The following might make this sucker work after resets:
+
+(setq user-top-level 'cmu-top-level)
+(putd 'user-top-level (getd 'cmu-top-level))
+(setq top-level 'cmu-top-level)
+(putd 'top-level (getd 'cmu-top-level))
+
+(def transprint
+  (lambda (prt)
+    (prog nil
+     l    (cond ((memq (tyipeek prt) '(27 -1)) (return nil))
+                (t (tyo (tyi prt)) (go l))))))
+
+(def valueof
+  (lambda (x)
+    (caddr (tlgetevent x))))
+
+(def zap
+  (lambda (prt)
+    (prog nil
+     l    (cond ((memq (tyi prt) '(10 -1)) (return nil)) (t (go l))))))
+(dv dc-switch dc-define)
diff --git a/usr/src/usr.bin/lisp/lisplib/jkfmacs.l b/usr/src/usr.bin/lisp/lisplib/jkfmacs.l
new file mode 100644 (file)
index 0000000..716dd8e
--- /dev/null
@@ -0,0 +1,15 @@
+(setq SCCS-jkfmacs "%Z%%M%     %I%     %G%")
+
+;------ jkfmacs :: common and useful macros
+;
+;; as of Franz opus 38.36 all the macros in this file all available in
+;; the standard lisp system, so there is no reason to load this file.
+;;
+
+(msg "message from jkfmacs: " N
+     "All the macros in this file are now available in the default franz." N
+     "Thus you should not be loading jkfmacs." N
+     "One warning: the order of the arguments is different in the version " N
+     "of the push macro in the default franz.  it is now (push val stack) " N
+     "You should check your code " N
+     "Also, there isn't an 'unpush' macro any more " N)
diff --git a/usr/src/usr.bin/lisp/lisplib/loop.l b/usr/src/usr.bin/lisp/lisplib/loop.l
new file mode 100644 (file)
index 0000000..0eb3d8d
--- /dev/null
@@ -0,0 +1,2223 @@
+(setq rcs-loop-
+   "$Header: /usr/lib/lisp/loop.l,v 1.1 83/01/29 18:38:49 jkf Exp $")
+
+;;;   LOOP  -*- Mode:LISP; Package:System-Internals; Base:8; Lowercase:T -*-
+;;;   **********************************************************************
+;;;   ****** Universal ******** LOOP Iteration Macro ***********************
+;;;   **********************************************************************
+;;;   **** (C) COPYRIGHT 1980, 1981 MASSACHUSETTS INSTITUTE OF TECHNOLOGY **
+;;;   ******** THIS IS A READ-ONLY FILE! (ALL WRITES RESERVED) *************
+;;;   **********************************************************************
+
+;;;; LOOP Iteration Macro
+
+;The master copy of this file is on ML:LSB1;LOOP >
+;The current Lisp machine copy is on AI:LISPM2;LOOP >
+;The FASL and QFASL should also be accessible from LIBLSP; on all machines.
+;(Is this necessary anymore? LOOP is now in the Lisp Machine system and
+; is accessible on LISP; and distributed with PDP10 Maclisp.)
+;Duplicate source is usually also maintained on MC:LSB1;LOOP >
+;Printed documentation is available as MIT-LCS Technical Memo 169,
+; "LOOP Iteration Macro", from:
+;      Publications
+;      MIT Laboratory for Computer Science
+;      545 Technology Square
+;      Cambridge, MA 02139
+; the text of which appears in only slightly modified form in the Lisp
+; Machine manual.
+
+; Bugs/complaints/suggestions/solicitations-for-documentation to BUG-LOOP
+; at any ITS site (MIT-ML preferred).
+
+
+; **********************************************************************
+; *************************** NOTE WELL ********************************
+; **********************************************************************
+;Incremental compiling of things in this file will generate wrong code
+; unless you first evaluate the 'feature' stuff on the next page
+; ("readtime environment setup").  (This mainly of Lispm interest.)
+;This source sincerely believes that it can run compatibly, WITHOUT ANY
+; TEXTUAL MODIFICATIONS AT ALL, in PDP-10 Maclisp, Multics Maclisp, Lisp
+; Machine Lisp (Zetalisp), VAX NIL, and Franz Lisp.  PLEASE do not make
+; changes to this file (the master copy) if you are in any way unsure
+; of the implications in a dialect you are not very familiar with;  let
+; a LOOP maintainer take the responsibility for breaking the master copy
+; and maintaining some semblance of sanity among the disparities.  Note
+; in particular that LOOP also runs in the PDP10 Maclisp -> Vax NIL
+; cross-compiler;  that environment requires LOOP to produce code which
+; can at the same time be interpreted in Maclisp, and compiled for NIL.
+
+
+; Bootstrap up our basic primitive environment.
+; This includes backquote, sharpsign, defmacro, let.
+
+(eval-when (eval compile)
+  (cond ((status feature Multics)
+          (defun include-for-multics macro (x)
+            (cons '%include (cdr x))))
+       ('t #-Franz (macro include-for-multics (x) ())
+           #+Franz (defmacro include-for-multics (x) nil))))
+
+(include-for-multics lisp_prelude)
+(include-for-multics lisp_dcls)
+
+#+Franz (environment-maclisp)
+
+\f
+;;;; Readtime Environment Setup
+
+;Now set up the readtime conditionalization environment.   This won't work
+; in any compiler that reads the whole file before compiling anything.
+; It is a good idea to pretend that case matters in ALL contexts.
+; This is in fact true in Franz at the present.  Case matters to Multics
+; in symbols, except for <frob> in (status feature <frob>).
+(eval-when (eval compile)
+  #+NIL (progn
+          (defmacro loop-featurep (f)
+            `(featurep ',f target-features))
+          (defmacro loop-nofeaturep (f)
+            `(nofeaturep ',f target-features))
+          (defmacro loop-set-feature (f)
+            `(set-feature ',f target-features))
+          (defmacro loop-set-nofeature (f)
+            `(set-nofeature ',f target-features))
+          )
+  #-NIL (progn
+          (defmacro loop-featurep (f)
+            `(status feature ,f))
+          (defmacro loop-nofeaturep (f)
+            ; Multics doesn't have (status nofeature)...
+            `(not (status feature ,f)))
+          (defmacro loop-set-feature (f)
+            `(sstatus feature ,f))
+          (defmacro loop-set-nofeature (f)
+            ; Does this work on Multics???  I think not but we don't use.
+            `(sstatus nofeature ,f))
+          )
+  ;Note:  NEVER in this file is "PDP-10" a valid feature or substring of
+  ; a feature.  It is NEVER hyphenated.  Keep it that way.  (This because
+  ; of continuous lossage with not setting up one or the other of the
+  ; hyphenated/non-hyphenated one.)
+  (cond ((and (loop-featurep PDP10)
+             (loop-featurep NILAID))
+          ;Compiling a PDP10 -> NIL cross-compiling LOOP.
+          ; We check the PDP10 feature first sort of gratuitously so that
+          ; other implementations don't think we are asking about an undefined
+          ; feature name.  (Vax-NIL specifically.)
+          (loop-set-feature For-NIL)
+          (loop-set-nofeature For-Maclisp)
+          (loop-set-nofeature For-PDP10)
+          (loop-set-feature Run-in-Maclisp)
+          (loop-set-feature Run-on-PDP10)
+          (loop-set-nofeature Franz))
+       ((and (loop-featurep Maclisp) (loop-nofeaturep For-NIL))
+          ; Standard in-Maclisp for-Maclisp.
+          (loop-set-feature For-Maclisp)
+          (loop-set-feature Run-In-Maclisp)
+          (cond ((loop-nofeaturep Multics)
+                   (loop-set-feature For-PDP10)
+                   (loop-set-feature PDP10)
+                   (loop-set-feature Run-on-PDP10))))
+       ((loop-featurep NIL)
+          ; Real NIL
+          (loop-set-nofeature PDP10)
+          (loop-set-nofeature Multics)
+          (loop-set-nofeature Run-on-PDP10)
+          (loop-set-nofeature For-PDP10)
+          (loop-set-nofeature Run-In-Maclisp)
+          (loop-set-nofeature For-Maclisp))
+       ((loop-featurep Lispm))
+       ((loop-featurep franz)
+          ;The "natural" case of features in franz is all lower.
+          ; Since that is unlike the others used in here, we synonymize
+          ; the obvious other choice.
+          (loop-set-feature Franz))
+       ('t (break loop-implementation-unknown)))
+  (cond ((or (loop-featurep Lispm) (loop-featurep For-PDP10))
+          (loop-set-feature Hairy-Collection))
+       ('t (loop-set-nofeature Hairy-Collection)))
+  (cond ((or (loop-featurep For-NIL) (loop-featurep For-PDP10))
+          (loop-set-feature System-Destructuring))
+       ('t (loop-set-nofeature System-Destructuring)))
+  (cond ((or (loop-featurep For-NIL) (loop-featurep Lispm))
+          (loop-set-feature Named-PROGs))
+       ('t (loop-set-nofeature Named-PROGs)))
+  ;In the following two features, "Local" means the Lisp LOOP will be
+  ; running in, not the one it is being compiled in.  "Targeted" means
+  ; the Lisp it will be producing code for.  (All from the point of view
+  ; of the running LOOP, you see.)
+  (cond ((or (loop-featurep For-NIL) (loop-featurep Lispm))
+          (loop-set-feature Targeted-Lisp-has-Packages))
+       ('t (loop-set-nofeature Targeted-Lisp-has-Packages)))
+  (cond ((or (loop-featurep Franz) (loop-featurep Run-in-Maclisp))
+          (loop-set-nofeature Local-Lisp-has-Packages))
+       ('t (loop-set-feature Local-Lisp-has-Packages)))
+  (cond ((loop-featurep For-NIL) (loop-set-feature Vector-Destructuring))
+       ('t (loop-set-nofeature Vector-Destructuring)))
+  ;Meaningful-Type-Declarations means that the declarations are (1)
+  ; implemented by the compiler and (2) used for something.
+  ; Assume minimally maclisp-like FIXNUM and FLONUM dcls, for local
+  ; variables or function results.
+  (cond ((loop-featurep Run-in-Maclisp)
+          (loop-set-feature Meaningful-Type-Declarations))
+       ('t (loop-set-nofeature Meaningful-Type-Declarations)))
+  ;Hair for 3600 cross-compilation?
+  (cond ((and (loop-featurep Lispm) (not (loop-featurep 3600.)))
+          (loop-set-feature Loop-Small-Floatp))
+       ('t (loop-set-nofeature Loop-Small-Floatp)))
+  ; -> insert more conditionals here <-
+  ())
+
+#+Franz
+(eval-when (eval compile)
+  (setsyntax #// 143.) ; Make slash be slash
+  (setsyntax #/\ 2.) ; make backslash alphabetic
+  )
+
+
+#+Run-on-PDP10
+(eval-when (compile)
+  ;Note this hack used when compiled only.
+  ;Its purpose in life is to save a bit of space in the load-time environment,
+  ; since loop doesn't actually need the PDP10 Maclisp doublequoted crocks
+  ; to remember their origin as "strings".
+  (setsyntax #/" 'macro
+            '(lambda ()
+               (do ((ch (tyi) (tyi)) (l () (cons ch l)))
+                   ((= ch #/")
+                    (list squid (list 'quote (implode (nreverse l)))))
+                 (and (= ch #//) (setq ch (tyi)))))))
+\f
+
+;;;; Other basic header stuff
+
+
+; Following isn't needed on Lispm, as loop is installed there (ie, these
+; symbols are already in GLOBAL).
+#+(and Targeted-Lisp-has-Packages (not Lispm))
+(mapc 'globalize
+      '("LOOP"                                 ; Major macro
+       "LOOP-FINISH"                           ; Handy macro
+       "DEFINE-LOOP-MACRO"
+       "DEFINE-LOOP-PATH"                      ; for users to define paths
+       "DEFINE-LOOP-SEQUENCE-PATH"             ; this too
+       ))
+
+#+(or For-NIL For-PDP10)
+(herald LOOP)
+\f
+
+;;;; Macro Environment Setup
+
+;Wrapper for putting around DEFMACRO etc. forms to determine whether
+; they are defined in the compiled output file or not.  (It is assumed
+; that DEFMACRO forms will be.)  Making loop-macro-progn output for loading
+; is convenient if loop will have incremental-recompilation done on it.
+; (Note, of course, that the readtime environment is NOT set up.)
+
+#+Lispm
+(defmacro loop-macro-progn (&rest forms)
+    `(progn 'compile ,@forms))
+#-Lispm
+(eval-when (eval compile)
+    (defmacro loop-macro-progn (&rest forms)
+       `(eval-when (eval compile) ,@forms)))
+
+
+; Hack up the stuff for data-types.  DATA-TYPE? will always be a macro
+; so that it will not require the data-type package at run time if
+; all uses of the other routines are conditionalized upon that value.
+(eval-when (eval compile)
+  ; Crock for DATA-TYPE? derives from DTDCL.  We just copy it rather
+  ; than load it in, which requires knowing where it comes from (sigh).
+  ; 
+  #-Local-Lisp-has-Packages
+    (defmacro data-type? (x) `(get ,x ':data-type))
+  #+Local-Lisp-has-Packages
+    (defmacro data-type? (frob)
+      (let ((foo (gensym)))
+       `((lambda (,foo)
+           ; NIL croaks if () given to GET...
+           (and #+NIL (symbolp ,foo) #-NIL 't
+                (or (get ,foo ':data-type)
+                    (and (setq ,foo (intern-soft (get-pname ,foo) ""))
+                         (get ,foo ':data-type)))))
+         ,frob))))
+
+(declare (*lexpr variable-declarations)
+        ; Multics defaults to free-functional-variable since it is declared
+        ; special & used as function before it is defined:
+        (*expr loop-when-it-variable)
+        (*expr initial-value primitive-type)
+       #+(or Maclisp Franz) (macros t) ; Defmacro dependency
+       #+Run-in-Maclisp
+        (muzzled t)    ; I know what i'm doing
+        )
+
+#+Run-on-PDP10
+(declare (mapex ())
+        (genprefix loop/|-)
+        (special squid)
+       #+(and Run-in-Maclisp For-NIL) ; patch it up
+         (*expr stringp vectorp vref vector-length)
+         )
+
+#-Run-on-PDP10
+(declare
+  #+Lispm (setq open-code-map-switch t)
+  #+Run-in-Maclisp (mapex t)
+  #+Run-in-Maclisp (genprefix loop-iteration/|-))
+
+#+Run-on-PDP10
+(mapc '(lambda (x)
+          (or (getl x '(subr lsubr fsubr macro fexpr expr autoload))
+              ; This dtdcl will sort of work for NIL code generation,
+              ; if declarations will ignored.
+              (putprop x '((lisp) dtdcl fasl) 'autoload)))
+      '(data-type? variable-declarations initial-value primitive-type))
+
+(loop-macro-progn
+ (defmacro loop-copylist* (l)
+    #+Lispm `(copylist* ,l)
+    #-Lispm `(append ,l ())))
+\f
+
+;;;; Random Macros
+
+; Error macro.  Note that in the PDP10 version we call LOOP-DIE rather
+; than ERROR -- there are so many occurences of it in this source that
+; it is worth breaking off that function, since calling the lsubr ERROR
+; takes more inline code.
+(loop-macro-progn
+ (defmacro loop-simple-error (unquoted-message &optional (datum () datump))
+    #+(and Run-In-Maclisp (not Multics))
+      (progn (cond ((symbolp unquoted-message))
+                  ((and (not (atom unquoted-message))
+                        compiler-state
+                        (eq (car unquoted-message) squid)
+                        (not (atom (setq unquoted-message
+                                         (cadr unquoted-message))))
+                        (eq (car unquoted-message) 'quote)
+                        (symbolp (cadr unquoted-message)))
+                     (setq unquoted-message (cadr unquoted-message)))
+                  ('t (error '|Uloze -- LOOP-SIMPLE-ERROR|
+                             (list 'loop-simple-error
+                                   unquoted-message datum))))
+            (cond (datump `(loop-die ',unquoted-message ,datum))
+                  ('t `(error ',unquoted-message))))
+    #+(or Franz Multics)
+      (progn (or (memq (typep unquoted-message) '(string symbol))
+                (error '|Uloze -- | (list 'loop-simple-error
+                                          unquoted-message datum)))
+            `(error ,(let ((l (list "lisp:  " unquoted-message
+                                    (if datump " -- " ""))))
+                       #+Franz (get_pname (apply 'uconcat l))
+                       #-Franz (apply 'catenate l))
+                    . ,(and datump (list datum))))
+    #-(or Run-In-Maclisp Franz)
+      `(ferror () ,(if datump (string-append "~S " unquoted-message)
+                      unquoted-message)
+              . ,(and datump (list datum)))))
+
+
+#+(and Run-in-Maclisp (not Multics))
+(defun loop-die (arg1 arg2)
+    (error arg1 arg2))
+
+
+; This is a KLUDGE.  But it apparently saves an average of two inline
+; instructions per call in the PDP10 version...  The ACS prop is
+; fairly gratuitous.
+
+#+Run-on-PDP10
+(progn 'compile
+   (lap-a-list 
+     '((lap loop-pop-source subr)
+       (args loop-pop-source (() . 0))
+          (hlrz a @ (special loop-source-code))
+          (hrrz b @ (special loop-source-code))
+          (movem b (special loop-source-code))
+          (popj p)
+       nil))
+   (eval-when (compile)
+       (defprop loop-pop-source 2 acs)
+       ))
+
+#-Run-on-PDP10
+(loop-macro-progn
+ (defmacro loop-pop-source () '(pop loop-source-code)))
+
+(loop-macro-progn
+ (defmacro object-that-cares-p (x)
+   #+Lispm `(listp ,x)
+   #+(or NIL PDP10) `(pairp ,x)
+   #-(or Lispm NIL PDP10) `(eq (typep ,x) 'list)))
+\f
+
+;;;; Variable defining macros
+
+;There is some confusion among lisps as to whether or not a file containing
+; a DEFVAR will declare the variable when the compiled file is loaded
+; into a compiler.  LOOP assumes that DEFVAR does so (this is needed for
+; various user-accessible variables).  DEFIVAR is for "private" variables.
+; Note that this is moot for Lispm due to incremental-recompilation support
+; anyway.
+;Multics lcp has some bug whereby DECLARE and (EVAL-WHEN (COMPILE) ...)
+; don't get hacked properly inside of more than one level of
+; (PROGN 'COMPILE ...).  Thus we hack around DEFVAR and DEFIVAR to bypass
+; this lossage.
+;Franz DEFVAR does not make the declaration on loading, so we redefine it.
+
+#+(or Multics Franz)
+(loop-macro-progn
+ (defmacro defvar (name &optional (init nil initp) documentation
+                  &aux (dclform `(and #+Franz (getd 'special)
+                                      #-Franz (status feature compiler)
+                                      (special ,name))))
+    ; For some obscure reason, (DECLARE ...) doesn't take effect within 2
+    ; (PROGN 'COMPILE ...)s, but (EVAL-WHEN (COMPILE) ...) does, on Multics.
+    (eval dclform) ; sigh
+    (cond ((not initp) dclform)
+         (t `(progn 'compile
+                    ,dclform
+                    (or (boundp ',name) (setq ,name ,init)))))))
+
+(loop-macro-progn
+ ; A DEFVAR alternative - "DEFine Internal VARiable".
+ (defmacro defivar (name &optional (init () initp))
+    ; The Lispm choice here is based on likelihood of incremental compilation.
+    #+Lispm `(defvar ,name ,@(and initp `(,init)))
+    #+Multics (progn (apply 'special (list name))
+                    (if initp `(or (boundp ',name) (setq ,name ,init))
+                        `(progn 'compile)))
+    #-(or Lispm Multics)
+      `(progn 'compile
+             (declare (special ,name))
+             . ,(and initp `((or (boundp ',name) (setq ,name ,init)))))))
+
+#+Franz
+;Defconst is like defvar but always initializes.
+; It happens in this case that we really don't care about the global
+; declaration on loading, so actually treat it more like DEFIVAR.
+; (This is now in Multics and PDP10 Maclisp, thanks to Maclisp Extensions
+; Manual.)
+(loop-macro-progn
+  (defmacro defconst (name init &optional documentation)
+    `(progn 'compile (declare (special ,name)) (setq ,name ,init))))
+\f
+
+
+;;;; Setq Hackery
+
+; Note:  LOOP-MAKE-PSETQ is NOT flushable depending on the existence
+; of PSETQ, unless PSETQ handles destructuring.  Even then it is
+; preferable for the code LOOP produces to not contain intermediate
+; macros, especially in the PDP10 version.
+
+(defun loop-make-psetq (frobs)
+    (and frobs
+        (loop-make-setq
+           (list (car frobs)
+                 (if (null (cddr frobs)) (cadr frobs)
+                     `(prog1 ,(cadr frobs)
+                             ,(loop-make-psetq (cddr frobs))))))))
+
+#-System-Destructuring
+(progn 'compile
+
+(defvar si:loop-use-system-destructuring?
+    ())
+
+(defivar loop-desetq-temporary)
+
+; Do we want this???  It is, admittedly, useful...
+;(defmacro loop-desetq (&rest x)
+;  (let ((loop-desetq-temporary ()))
+;     (let ((setq-form (loop-make-desetq x)))
+;      (if loop-desetq-temporary
+;          `((lambda (,loop-desetq-temporary) ,setq-form) ())
+;          setq-form))))
+
+
+(defun loop-make-desetq (x)
+   (if si:loop-use-system-destructuring?
+       (cons (do ((l x (cddr l))) ((null l) 'setq)
+              (or (and (not (null (car l))) (symbolp (car l)))
+                  (return 'desetq)))
+            x)
+       (do ((x x (cddr x)) (r ()) (var) (val))
+          ((null x) (and r (cons 'setq r)))
+        (setq var (car x) val (cadr x))
+        (cond ((and (not (atom var))
+                    (not (atom val))
+                    (not (and (memq (car val)
+                                    '(car cdr cadr cddr caar cdar))
+                              (atom (cadr val)))))
+                 (setq x (list* (or loop-desetq-temporary
+                                    (setq loop-desetq-temporary (gensym)))
+                                val var loop-desetq-temporary (cddr x)))))
+        (setq r (nconc r (loop-desetq-internal (car x) (cadr x)))))))
+
+(defun loop-desetq-internal (var val)
+  (cond ((null var) ())
+       ((atom var) (list var val))
+       ('t (nconc (loop-desetq-internal (car var) `(car ,val))
+                  (loop-desetq-internal (cdr var) `(cdr ,val))))))
+); End desetq hackery for #-System-Destructuring
+
+
+(defun loop-make-setq (pairs)
+    (and pairs
+        #-System-Destructuring
+          (loop-make-desetq pairs)
+        #+System-Destructuring
+          (cons (do ((l pairs (cddr l))) ((null l) 'setq)
+                  (or (and (car l) (symbolp (car l))) (return 'desetq)))
+                pairs)))
+\f
+
+(defconst loop-keyword-alist                   ;clause introducers
+     '(
+      #+Named-PROGs
+       (named loop-do-named)
+       (initially loop-do-initially)
+       (finally loop-do-finally)
+       (nodeclare loop-nodeclare)
+       (do loop-do-do)
+       (doing loop-do-do)
+       (return loop-do-return)
+       (collect loop-do-collect list)
+       (collecting loop-do-collect list)
+       (append loop-do-collect append)
+       (appending loop-do-collect append)
+       (nconc loop-do-collect nconc)
+       (nconcing loop-do-collect nconc)
+       (count loop-do-collect count)
+       (counting loop-do-collect count)
+       (sum loop-do-collect sum)
+       (summing loop-do-collect sum)
+       (maximize loop-do-collect max)
+       (minimize loop-do-collect min)
+       (always loop-do-always or)
+       (never loop-do-always and)
+       (thereis loop-do-thereis)
+       (while loop-do-while or while)
+       (until loop-do-while and until)
+       (when loop-do-when ())
+       (if loop-do-when ())
+       (unless loop-do-when t)
+       (with loop-do-with)))
+
+
+(defconst loop-iteration-keyword-alist
+    `((for loop-do-for)
+      (as loop-do-for)
+      (repeat loop-do-repeat)))
+
+
+(defconst loop-for-keyword-alist                       ;Types of FOR
+     '( (= loop-for-equals)
+        (first loop-for-first)
+       (in loop-list-stepper car)
+       (on loop-list-stepper ())
+       (from loop-for-arithmetic from)
+       (downfrom loop-for-arithmetic downfrom)
+       (upfrom loop-for-arithmetic upfrom)
+       (below loop-for-arithmetic below)
+       (to loop-for-arithmetic to)
+       (being loop-for-being)))
+
+#+Named-PROGs
+(defivar loop-prog-names)
+
+(defvar loop-path-keyword-alist ())            ; PATH functions
+(defivar loop-named-variables)                 ; see SI:LOOP-NAMED-VARIABLE
+(defivar loop-collection-crocks)               ; see LOOP-DO-COLLECT etc
+(defivar loop-variables)                       ;Variables local to the loop
+(defivar loop-declarations)                    ; Local dcls for above
+(defivar loop-nodeclare)                       ; but don't declare these
+(defivar loop-variable-stack)
+(defivar loop-declaration-stack)
+#-System-Destructuring
+(defivar loop-desetq-crocks)                   ; see loop-make-variable
+#-System-Destructuring
+(defivar loop-desetq-stack)                    ; and loop-translate-1
+(defivar loop-prologue)                                ;List of forms in reverse order
+(defivar loop-before-loop)
+(defivar loop-body)                            ;..
+(defivar loop-after-body)                      ;.. for FOR steppers
+(defivar loop-epilogue)                                ;..
+(defivar loop-after-epilogue)                  ;So COLLECT's RETURN comes after FINALLY
+(defivar loop-conditionals)                    ;If non-NIL, condition for next form in body
+  ;The above is actually a list of entries of the form
+  ;(cond (condition forms...))
+  ;When it is output, each successive condition will get
+  ;nested inside the previous one, but it is not built up
+  ;that way because you wouldn't be able to tell a WHEN-generated
+  ;COND from a user-generated COND.
+  ;When ELSE is used, each cond can get a second clause
+
+(defivar loop-when-it-variable)                        ;See LOOP-DO-WHEN
+(defivar loop-never-stepped-variable)          ; see LOOP-FOR-FIRST
+(defivar loop-emitted-body?)                   ; see LOOP-EMIT-BODY,
+                                               ; and LOOP-DO-FOR
+(defivar loop-iteration-variables)             ; LOOP-MAKE-ITERATION-VARIABLE
+(defivar loop-iteration-variablep)             ; ditto
+(defivar loop-collect-cruft)                   ; for multiple COLLECTs (etc)
+(defivar loop-source-code)
+(defvar loop-duplicate-code ())  ; see LOOP-OPTIMIZE-DUPLICATED-CODE-ETC
+\f
+
+;;;; Token Hackery
+
+;Compare two "tokens".  The first is the frob out of LOOP-SOURCE-CODE,
+;the second a symbol to check against.
+
+; Consider having case-independent comparison on Multics.
+#+(or Multics Franz)
+(progn 'compile
+    (defmacro si:loop-tequal (x1 x2)
+       `(eq ,x1 ,x2))
+    (defmacro si:loop-tmember (x l)
+       `(memq ,x ,l))
+    (defmacro si:loop-tassoc (x l)
+       `(assq ,x ,l)))
+
+
+#+Lispm
+(progn 'compile
+   (defun si:loop-tequal (x1 x2)
+       (and (symbolp x1) (string-equal x1 x2)))
+   (defun si:loop-tassoc (kwd alist)
+       (and (symbolp kwd) (ass #'string-equal kwd alist)))
+   (defun si:loop-tmember (kwd list)
+       (and (symbolp kwd) (mem #'string-equal kwd list))))
+
+
+#+Run-on-PDP10
+(progn 'compile
+   #+For-NIL
+     (defun si:loop-tequal (x1 x2)
+        (eq x1 x2))
+   #-For-NIL
+     (progn 'compile
+       (eval-when (load compile)
+          (cond ((status feature complr)
+                   ; Gross me out!
+                   (setq macrolist
+                         (cons '(si:loop-tequal
+                                   . (lambda (x) (cons 'eq (cdr x))))
+                               (delq (assq 'si:loop-tequal macrolist)
+                                     macrolist)))
+                   (*expr si:loop-tmember si:loop-tassoc))))
+       (defun si:loop-tequal (x1 x2)
+          (eq x1 x2)))
+     (defun si:loop-tmember (kwd list)
+        (memq kwd list))
+     (defun si:loop-tassoc (kwd alist)
+        (assq kwd alist))
+     )
+
+#+(and For-NIL (not Run-in-Maclisp))
+(progn 'compile
+  ; STRING-EQUAL only accepts strings.  GET-PNAME can be open-coded
+  ; however.
+  (defun si:loop-tequal (kwd1 kwd2)
+      (and (symbolp kwd1) (string-equal (get-pname kwd1) (get-pname kwd2))))
+  (defun si:loop-tassoc (kwd alist)
+    (cond ((symbolp kwd)
+            (setq kwd (get-pname kwd))
+            (do ((l alist (cdr l))) ((null l) ())
+              (and (string-equal kwd (get-pname (caar l)))
+                   (return (car l)))))))
+  (defun si:loop-tmember (token list)
+     (cond ((symbolp token)
+             (setq token (get-pname token))
+             (do ((l list (cdr l))) ((null l))
+               (and (string-equal token (get-pname (car l)))
+                    (return l)))))))
+\f
+
+#+(or For-PDP10 For-NIL)
+(eval-when (eval compile) (setq defmacro-displace-call ()))
+
+(defmacro define-loop-macro (keyword)
+    (or (eq keyword 'loop)
+       (si:loop-tassoc keyword loop-keyword-alist)
+       (si:loop-tassoc keyword loop-iteration-keyword-alist)
+       (loop-simple-error "not a loop keyword - define-loop-macro" keyword))
+    (subst keyword 'keyword
+          '(eval-when (compile load eval)
+             #+(or For-NIL Run-on-PDP10)
+               (progn (flush-macromemos 'keyword ())
+                      (flush-macromemos 'loop ()))
+             #-Run-in-Maclisp
+               (progn
+                 #+Franz
+                   (putd 'keyword
+                         '(macro (macroarg) (loop-translate macroarg)))
+                 #-Franz
+                   (fset-carefully 'keyword '(macro . loop-translate)))
+             #+Run-in-Maclisp
+               (progn (defprop keyword loop-translate macro))
+             )))
+
+#+(or For-PDP10 For-NIL)
+(eval-when (eval compile) (setq defmacro-displace-call 't))
+
+(define-loop-macro loop)
+
+#+Run-in-Maclisp
+(defun (loop-finish macro) (form)
+    ;This definition solves two problems:
+    ; (1) wasted address space
+    ; (2) displacing of a form which might tend to be pure.
+    ; There is little point in macro-memoizing a constant anyway.
+    (and (cdr form) (loop-simple-error "Wrong number of args" form))
+    '(go end-loop))
+
+#-Run-in-Maclisp
+(defmacro loop-finish () 
+    '(go end-loop))
+
+
+(defun loop-translate (x)
+    #-(or For-NIL Run-on-PDP10) (displace x (loop-translate-1 x))
+    #+(or For-NIL Run-on-PDP10)
+      (or (macrofetch x) (macromemo x (loop-translate-1 x) 'loop)))
+
+
+(defun loop-end-testify (list-of-forms)
+    (if (null list-of-forms) ()
+       `(and ,(if (null (cdr (setq list-of-forms (nreverse list-of-forms))))
+                  (car list-of-forms)
+                  (cons 'or list-of-forms))
+             (go end-loop))))
+\f
+(defun loop-optimize-duplicated-code-etc (&aux before after groupa groupb a b
+                                              lastdiff)
+    (do ((l1 (nreverse loop-before-loop) (cdr l1))
+        (l2 (nreverse loop-after-body) (cdr l2)))
+       ((equal l1 l2)
+          (setq loop-body (nconc (delq '() l1) (nreverse loop-body))))
+      (push (car l1) before) (push (car l2) after))
+    (cond ((not (null loop-duplicate-code))
+            (setq loop-before-loop (nreverse (delq () before))
+                  loop-after-body (nreverse (delq () after))))
+         ('t (setq loop-before-loop () loop-after-body ()
+                   before (nreverse before) after (nreverse after))
+             (do ((bb before (cdr bb)) (aa after (cdr aa)))
+                 ((null aa))
+               (cond ((not (equal (car aa) (car bb))) (setq lastdiff aa))
+                     ((not (si:loop-simplep (car aa))) ;Mustn't duplicate
+                      (return ()))))
+             (cond (lastdiff  ;Down through lastdiff should be duplicated
+                    (do () (())
+                      (and (car before) (push (car before) loop-before-loop))
+                      (and (car after) (push (car after) loop-after-body))
+                      (setq before (cdr before) after (cdr after))
+                      (and (eq after (cdr lastdiff)) (return ())))
+                    (setq loop-before-loop (nreverse loop-before-loop)
+                          loop-after-body (nreverse loop-after-body))))
+             (do ((bb (nreverse before) (cdr bb))
+                  (aa (nreverse after) (cdr aa)))
+                 ((null aa))
+               (setq a (car aa) b (car bb))
+               (cond ((and (null a) (null b)))
+                     ((equal a b)
+                        (loop-output-group groupb groupa)
+                        (push a loop-body)
+                        (setq groupb () groupa ()))
+                     ('t (and a (push a groupa)) (and b (push b groupb)))))
+             (loop-output-group groupb groupa)))
+    (and loop-never-stepped-variable
+        (push `(setq ,loop-never-stepped-variable ()) loop-after-body))
+    ())
+
+
+(defun loop-output-group (before after)
+    (and (or after before)
+        (let ((v (or loop-never-stepped-variable
+                     (setq loop-never-stepped-variable
+                           (loop-make-variable (gensym) ''t ())))))
+           (push (cond ((not before) `(or ,v (progn . ,after)))
+                       ((not after) `(and ,v (progn . ,before)))
+                       ('t `(cond (,v . ,before) ('t . ,after))))
+                 loop-body))))
+\f
+
+(defun loop-translate-1 (loop-source-code)
+  (and (eq (car loop-source-code) 'loop)
+       (setq loop-source-code (cdr loop-source-code)))
+  (do ((loop-iteration-variables ())
+       (loop-iteration-variablep ())
+       (loop-variables ())
+       (loop-nodeclare ())
+       (loop-named-variables ())
+       (loop-declarations ())
+     #-System-Destructuring
+       (loop-desetq-crocks ())
+       (loop-variable-stack ())
+       (loop-declaration-stack ())
+     #-System-destructuring
+       (loop-desetq-stack ())
+       (loop-prologue ())
+       (loop-before-loop ())
+       (loop-body ())
+       (loop-emitted-body? ())
+       (loop-after-body ())
+       (loop-epilogue ())
+       (loop-after-epilogue ())
+       (loop-conditionals ())
+       (loop-when-it-variable ())
+       (loop-never-stepped-variable ())
+     #-System-Destructuring
+       (loop-desetq-temporary ())
+     #+Named-PROGs
+       (loop-prog-names ())
+       (loop-collect-cruft ())
+       (loop-collection-crocks ())
+       (keyword)
+       (tem)
+       (progvars))
+      ((null loop-source-code)
+       (and loop-conditionals
+           (loop-simple-error "Hanging conditional in loop macro"
+                              (caadar loop-conditionals)))
+       (loop-optimize-duplicated-code-etc)
+       (loop-bind-block)
+       (setq progvars loop-collection-crocks)
+     #-System-Destructuring
+       (and loop-desetq-temporary (push loop-desetq-temporary progvars))
+       (setq tem `(prog #+Named-PROGs ,.loop-prog-names
+                       ,progvars
+                     #+Hairy-Collection
+                       ,.(do ((l loop-collection-crocks (cddr l))
+                              (v () (cons `(loop-collect-init
+                                               ,(cadr l) ,(car l))
+                                           v)))
+                             ((null l) v))
+                     ,.(nreverse loop-prologue)
+                     ,.loop-before-loop
+                  next-loop
+                     ,.loop-body
+                     ,.loop-after-body
+                     (go next-loop)
+                     ; Multics complr notices when end-loop is not gone
+                     ; to.  So we put in a dummy go.  This does not generate
+                     ; extra code, at least in the simple example i tried,
+                     ; but it does keep it from complaining about unused
+                     ; go tag.
+           #+Multics (go end-loop)
+                  end-loop
+                     ,.(nreverse loop-epilogue)
+                     ,.(nreverse loop-after-epilogue)))
+       (do ((vars) (dcls) #-System-Destructuring (crocks))
+          ((null loop-variable-stack))
+        (setq vars (car loop-variable-stack)
+              loop-variable-stack (cdr loop-variable-stack)
+              dcls (car loop-declaration-stack)
+              loop-declaration-stack (cdr loop-declaration-stack)
+              tem (ncons tem))
+        #-System-Destructuring
+          (and (setq crocks (pop loop-desetq-stack))
+               (push (loop-make-desetq crocks) tem))
+        (and dcls (push (cons 'declare dcls) tem))
+        (cond ((do ((l vars (cdr l))) ((null l) ())
+                 (and (not (atom (car l)))
+                      (or (null (caar l)) (not (symbolp (caar l))))
+                      (return 't)))
+                 (setq tem `(let ,(nreverse vars) ,.tem)))
+              ('t (let ((lambda-vars ()) (lambda-vals ()))
+                    (do ((l vars (cdr l)) (v)) ((null l))
+                      (cond ((atom (setq v (car l)))
+                               (push v lambda-vars)
+                               (push () lambda-vals))
+                            ('t (push (car v) lambda-vars)
+                                (push (cadr v) lambda-vals))))
+                    (setq tem `((lambda ,lambda-vars ,.tem)
+                                ,.lambda-vals))))))
+       tem)
+    (if (symbolp (setq keyword (loop-pop-source)))
+       (if (setq tem (si:loop-tassoc keyword loop-keyword-alist))
+           (apply (cadr tem) (cddr tem))
+           (if (setq tem (si:loop-tassoc
+                            keyword loop-iteration-keyword-alist))
+               (loop-hack-iteration tem)
+               (if (si:loop-tmember keyword '(and else))
+                   ; Alternative is to ignore it, ie let it go around to the
+                   ; next keyword...
+                   (loop-simple-error
+                      "secondary clause misplaced at top level in LOOP macro"
+                      (list keyword (car loop-source-code)
+                            (cadr loop-source-code)))
+                   (loop-simple-error
+                      "unknown keyword in LOOP macro" keyword))))
+       (loop-simple-error
+          "found where keyword expected in LOOP macro" keyword))))
+
+
+(defun loop-bind-block ()
+   (cond ((not (null loop-variables))
+           (push loop-variables loop-variable-stack)
+           (push loop-declarations loop-declaration-stack)
+           (setq loop-variables () loop-declarations ())
+           #-System-Destructuring
+             (progn (push loop-desetq-crocks loop-desetq-stack)
+                    (setq loop-desetq-crocks ())))))
+\f
+
+;Get FORM argument to a keyword.  Read up to atom.  PROGNify if necessary.
+(defun loop-get-form ()
+  (do ((forms (ncons (loop-pop-source)) (cons (loop-pop-source) forms))
+       (nextform (car loop-source-code) (car loop-source-code)))
+      ((atom nextform)
+       (if (null (cdr forms)) (car forms)
+          (cons 'progn (nreverse forms))))))
+
+
+;Note that this function is not absolutely general.  For instance, in Maclisp,
+; the functions < and > can only take 2 args, whereas greaterp and lessp
+; may take any number.  Also, certain of the generic functions behave
+; differently from the type-specific ones in "degenerate" cases, like
+; QUOTIENT or DIFFERENCE of one arg.
+;And of course one always must be careful doing textual substitution.
+(defun loop-typed-arith (substitutable-expression data-type)
+  #-(or Lispm Franz)
+    (if (setq data-type (car (si:loop-tmember (if (data-type? data-type)
+                                                 (primitive-type data-type)
+                                                 data-type)
+                                             '(fixnum flonum))))
+       (sublis (cond ((eq data-type 'fixnum)
+                        #+For-NIL
+                          '((plus . +&) (add1 . 1+&)
+                            (difference . -&) (sub1 . 1-&)
+                            (quotient . //&) (remainder . \&) (times . *&)
+                            (zerop . 0p) (plusp . +p) (minusp . -p)
+                            (greaterp . >&) (lessp . <&)
+                            (min . min&) (max . max&))
+                        #-For-NIL
+                          '((plus . +) (add1 . 1+)
+                            (difference . -) (sub1 . 1-)
+                            (quotient . //) (remainder . \) (times . *)
+                            (greaterp . >) (lessp . <)))
+                     ('t #+For-NIL
+                           '((plus . +$) (difference . -$)
+                             (add1 . 1+$) (sub1 . 1-$)
+                             (quotient . //$) (times . *$)
+                             (greaterp . >$) (lessp . <$)
+                             (max . max$) (min . min$))
+                         #-For-NIL
+                           '((plus . +$) (difference . -$)
+                             (add1 . 1+$) (sub1 . 1-$)
+                             (quotient . //$) (times . *$)
+                             (greaterp . >) (lessp . <))))
+               substitutable-expression)
+       substitutable-expression)
+  #+Lispm
+    (progn data-type substitutable-expression)
+  #+Franz
+    (if (si:loop-tequal data-type 'fixnum)
+       (sublis '((add1 . 1+) (sub1 . 1-) (plus . +) (difference . -)
+                 (times . *) (quotient . //) (remainder . \))
+               substitutable-expression)
+       substitutable-expression)
+  )
+
+
+(defun loop-typed-init (data-type)
+    (cond ((data-type? data-type) (initial-value data-type))
+         ((setq data-type (car (si:loop-tmember
+                                  data-type '(fixnum flonum integer number
+                                              #+Loop-Small-Floatp
+                                                small-flonum))))
+            (cond ((eq data-type 'flonum) 0.0)
+                #+Loop-Small-Floatp
+                  ((eq data-type 'small-flonum)
+                     #.(and (loop-featurep Loop-Small-Floatp)
+                            (small-float 0)))
+                  ('t 0)))))
+\f
+
+(defun loop-make-variable (name initialization dtype)
+  (cond ((null name)
+          (cond ((not (null initialization))
+                   (push (list #+Lispm 'ignore
+                               #+Multics (setq name (gensym))
+                               #-(or Lispm Multics) ()
+                               initialization)
+                         loop-variables)
+                   #+Multics (push `(progn ,name) loop-prologue))))
+       (#-Vector-Destructuring (atom name)
+        #+Vector-Destructuring (symbolp name)
+          (cond (loop-iteration-variablep
+                   (if (memq name loop-iteration-variables)
+                       (loop-simple-error
+                          "Duplicated iteration variable somewhere in LOOP"
+                          name)
+                       (push name loop-iteration-variables)))
+                ((assq name loop-variables)
+                   (loop-simple-error
+                      "Duplicated var in LOOP bind block" name)))
+        #-Vector-Destructuring
+          (or (symbolp name)
+              (loop-simple-error "Bad variable somewhere in LOOP" name))
+          (loop-declare-variable name dtype)
+          ; We use ASSQ on this list to check for duplications (above),
+          ; so don't optimize out this list:
+          (push (list name (or initialization (loop-typed-init dtype)))
+                loop-variables))
+       (initialization
+          #+System-Destructuring
+            (progn (loop-declare-variable name dtype)
+                   (push (list name initialization) loop-variables))
+          #-System-Destructuring
+            (cond (si:loop-use-system-destructuring?
+                     (loop-declare-variable name dtype)
+                     (push (list name initialization) loop-variables))
+                  ('t (let ((newvar (gensym)))
+                         (push (list newvar initialization) loop-variables)
+                         ; LOOP-DESETQ-CROCKS gathered in reverse order.
+                         (setq loop-desetq-crocks
+                               (list* name newvar loop-desetq-crocks))
+                         (loop-make-variable name () dtype)))))
+       ('t
+         #-Vector-Destructuring
+           (let ((tcar) (tcdr))
+             (if (atom dtype) (setq tcar (setq tcdr dtype))
+                 (setq tcar (car dtype) tcdr (cdr dtype)))
+             (loop-make-variable (car name) () tcar)
+             (loop-make-variable (cdr name) () tcdr))
+         #+Vector-Destructuring
+           (cond ((object-that-cares-p name)
+                    (let ((tcar) (tcdr))
+                       (if (object-that-cares-p dtype)
+                           (setq tcar (car dtype) tcdr (cdr dtype))
+                           (setq tcar (setq tcdr dtype)))
+                       (loop-make-variable (car name) () tcar)
+                       (loop-make-variable (cdr name) () tcdr)))
+                 ((vectorp name)
+                    (do ((i 0 (1+ i))
+                         (n (vector-length name))
+                         (dti 0 (1+ dti))
+                         (dtn (and (vectorp dtype) (vector-length dtype))))
+                        ((= i n))
+                      #+Run-in-Maclisp (declare (fixnum i n dti))
+                      (loop-make-variable
+                         (vref name i) ()
+                         (if (null dtn) dtype
+                             (and (< dti dtn) (vref dtype dti))))))
+                 ('t (loop-simple-error
+                        "bad variable somewhere in LOOP" name)))
+         ))
+  name)
+
+
+(defun loop-make-iteration-variable (name initialization dtype)
+    (let ((loop-iteration-variablep 't))
+       (loop-make-variable name initialization dtype)))
+
+
+(defun loop-declare-variable (name dtype)
+    (cond ((or (null name) (null dtype)) ())
+         ((symbolp name)
+            (cond ((memq name loop-nodeclare))
+                #+Multics
+                  ; local type dcls of specials lose.  This doesn't work
+                  ; for locally-declared specials.
+                  ((get name 'special))
+                  ((data-type? dtype)
+                     (setq loop-declarations
+                           (append (variable-declarations dtype name)
+                                   loop-declarations)))
+               #+Meaningful-Type-Declarations
+                  ((si:loop-tmember dtype '(fixnum flonum))
+                     (push `(,dtype ,name) loop-declarations))))
+         ((object-that-cares-p name)
+             (cond ((object-that-cares-p dtype)
+                      (loop-declare-variable (car name) (car dtype))
+                      (loop-declare-variable (cdr name) (cdr dtype)))
+                   ('t (loop-declare-variable (car name) dtype)
+                       (loop-declare-variable (cdr name) dtype))))
+       #+Vector-Destructuring
+         ((vectorp name)
+            (do ((i 0 (1+ i))
+                 (n (vector-length name))
+                 (dtn (and (vectorp dtype) (vector-length dtype)))
+                 (dti 0 (1+ dti)))
+                ((= i n))
+              #+Meaningful-Type-Declarations (declare (fixnum i n dti))
+              (loop-declare-variable
+                 (vref name i)
+                 (if (null dtn) dtype (and (< dti dtn) (vref dtype dti))))))
+         ('t (loop-simple-error "can't hack this"
+                                (list 'loop-declare-variable name dtype)))))
+\f
+
+#+For-PDP10
+(declare (special squid))
+
+(defun loop-constantp (form)
+    (or (numberp form)
+       #+For-NIL (or (null form) (vectorp form))
+       #-For-NIL (memq form '(t ()))
+       #-For-PDP10 (stringp form)
+       (and (not (atom form))
+            #-Run-on-PDP10 (eq (car form) 'quote)
+            #+Run-on-PDP10 (or (eq (car form) 'quote)
+                               ; SQUID implies quoting.
+                               (and compiler-state (eq (car form) squid))))
+       ))
+
+(defun loop-maybe-bind-form (form data-type?)
+    ; Consider implementations which will not keep EQ quoted constants
+    ; EQ after compilation & loading.
+    ; Note FUNCTION is not hacked, multiple occurences might cause the
+    ; compiler to break the function off multiple times!
+    ; Hacking it probably isn't too important here anyway.  The ones that
+    ; matter are the ones that use it as a stepper (or whatever), which
+    ; handle it specially.
+    (if (loop-constantp form) form
+       (loop-make-variable (gensym) form data-type?)))
+
+
+(defun loop-optional-type ()
+    (let ((token (car loop-source-code)))
+       (and (not (null token))
+            (or (not (atom token))
+                (data-type? token)
+                (si:loop-tmember token '(fixnum flonum integer number notype
+                                         #+Loop-Small-Floatp small-flonum)))
+            (loop-pop-source))))
+
+
+;Incorporates conditional if necessary
+(defun loop-make-conditionalization (form)
+  (cond ((not (null loop-conditionals))
+          (rplacd (last (car (last (car (last loop-conditionals)))))
+                  (ncons form))
+          (cond ((si:loop-tequal (car loop-source-code) 'and)
+                   (loop-pop-source)
+                   ())
+                ((si:loop-tequal (car loop-source-code) 'else)
+                   (loop-pop-source)
+                   ;; If we are already inside an else clause, close it off
+                   ;; and nest it inside the containing when clause
+                   (let ((innermost (car (last loop-conditionals))))
+                     (cond ((null (cddr innermost)))   ;Now in a WHEN clause, OK
+                           ((null (cdr loop-conditionals))
+                            (loop-simple-error "More ELSEs than WHENs"
+                                               (list 'else (car loop-source-code)
+                                                     (cadr loop-source-code))))
+                           ('t (setq loop-conditionals (cdr (nreverse loop-conditionals)))
+                               (rplacd (last (car (last (car loop-conditionals))))
+                                       (ncons innermost))
+                               (setq loop-conditionals (nreverse loop-conditionals)))))
+                   ;; Start a new else clause
+                   (rplacd (last (car (last loop-conditionals)))
+                           (ncons (ncons ''t)))
+                   ())
+                ('t ;Nest up the conditionals and output them
+                    (do ((prev (car loop-conditionals) (car l))
+                         (l (cdr loop-conditionals) (cdr l)))
+                        ((null l))
+                      (rplacd (last (car (last prev))) (ncons (car l))))
+                    (prog1 (car loop-conditionals)
+                           (setq loop-conditionals ())))))
+       ('t form)))
+
+(defun loop-pseudo-body (form &aux (z (loop-make-conditionalization form)))
+   (cond ((not (null z))
+           (cond (loop-emitted-body? (push z loop-body))
+                 ('t (push z loop-before-loop) (push z loop-after-body))))))
+
+(defun loop-emit-body (form)
+  (setq loop-emitted-body? 't)
+  (loop-pseudo-body form))
+\f
+
+#+Named-PROGs
+(defun loop-do-named ()
+    (let ((name (loop-pop-source)))
+       (or (and name (symbolp name))
+          (loop-simple-error "Bad name for your loop construct" name))
+       (and (cdr (setq loop-prog-names (cons name loop-prog-names)))
+           (loop-simple-error "Too many names for your loop construct"
+                              loop-prog-names))))
+
+(defun loop-do-initially ()
+  (push (loop-get-form) loop-prologue))
+
+(defun loop-nodeclare (&aux (varlist (loop-pop-source)))
+    (or (and varlist (eq (typep varlist) 'list))
+       (loop-simple-error "Bad varlist to nodeclare loop clause" varlist))
+    (setq loop-nodeclare (append varlist loop-nodeclare)))
+
+(defun loop-do-finally ()
+  (push (loop-get-form) loop-epilogue))
+
+(defun loop-do-do ()
+  (loop-emit-body (loop-get-form)))
+
+(defun loop-do-return ()
+   (loop-pseudo-body `(return ,(loop-get-form))))
+\f
+
+;;;; List Collection
+
+; The way we collect (list-collect) things is to bind two variables.
+; One is the final result, and is accessible for value during the
+; loop compuation.  The second is the "tail".  In implementations where
+; we can do so, the tail var is initialized to a locative of the first,
+; such that it can be updated with RPLACD.  In other implementations,
+; the update must be conditionalized (on whether or not the tail is NIL).
+
+; For PDP10 Maclisp:
+; The "value cell" of a special variable is a (pseudo) list cell, the CDR
+; of which is the value.  Hence the abovementioned tail variable gets
+; initialized to this.  (It happens to be the CDAR of the symbol.)
+; For local variables in compiled code, the Maclisp compiler implements
+; a (undocumented private) form of the
+; "(setq tail (variable-location var))" construct;  specifically, it
+; is of the form  (#.gofoo var tail).  This construct must appear in
+; the binding environment those variables are bound in, currently.
+; Note that this hack only currently works for local variables, so loop
+; has to check to see if the variable is special.  It is anticipated,
+; however, that the compiler will be able to do this all by itself
+; at some point.
+
+#+For-PDP10
+  (progn 'compile
+     (cond ((status feature complr)
+             (setq loop-specvar-hack ((lambda (obarray)
+                                          (implode '(s p e c v a r s)))
+                                      sobarray))
+             (defun loop-collect-init-compiler (form)
+               (cond ((memq compiler-state '(toplevel maklap))
+                        ; We are being "toplevel" macro expanded.
+                        ; We MUST expand into something which can be
+                        ; evaluated without loop, in the interpreter.
+                        `(setq ,(caddr form) (munkam (value-cell-location
+                                                        ',(cadr form)))))
+                     ((or specials
+                          (get (cadr form) 'special)
+                          (assq (cadr form) (symeval loop-specvar-hack)))
+                        `(setq ,(caddr form) (cdar ',(cadr form))))
+                     (t (cons gofoo (cdr form)))))
+             (push '(loop-collect-init . loop-collect-init-compiler)
+                   macrolist)))
+     (defun loop-collect-init fexpr (x)
+       (set (cadr x) (cdar (car x)))))
+
+#+(and Hairy-Collection (not For-PDP10))
+(defmacro loop-collect-init (var1 var2)
+   #+Lispm ;*****  Remove kludgey fboundp when everyone up-to-date *****
+          `(setq ,var2 ,(if (fboundp 'variable-location)
+                            `(variable-location ,var1)
+                            `(value-cell-location ',var1)))
+   #-Lispm `(setq ,var2 (munkam (value-cell-location ',var1))))
+\f
+
+(defun loop-do-collect (type)
+  (let ((var) (form) (tem) (tail) (dtype) (cruft) (rvar)
+       (ctype (cond ((memq type '(max min)) 'maxmin)
+                    ((memq type '(nconc list append)) 'list)
+                    ((memq type '(count sum)) 'sum)
+                    ('t (loop-simple-error
+                           "unrecognized LOOP collecting keyword" type)))))
+    (setq form (loop-get-form) dtype (loop-optional-type))
+    (cond ((si:loop-tequal (car loop-source-code) 'into)
+            (loop-pop-source)
+            (setq rvar (setq var (loop-pop-source)))))
+    ; CRUFT will be (varname ctype dtype var tail (optional tem))
+    (cond ((setq cruft (assq var loop-collect-cruft))
+            (cond ((not (eq ctype (car (setq cruft (cdr cruft)))))
+                     (loop-simple-error
+                        "incompatible LOOP collection types"
+                        (list ctype (car cruft))))
+                  ((and dtype (not (eq dtype (cadr cruft))))
+                     ;Conditional should be on data-type reality
+                     #+Run-in-Maclisp
+                       (loop-simple-error
+                          "Unequal data types in multiple collections"
+                          (list dtype (cadr cruft) (car cruft)))
+                     #-Run-in-Maclisp
+                       (ferror () "~A and ~A Unequal data types into ~A"
+                               dtype (cadr cruft) (car cruft))))
+            (setq dtype (car (setq cruft (cdr cruft)))
+                  var (car (setq cruft (cdr cruft)))
+                  tail (car (setq cruft (cdr cruft)))
+                  tem (cadr cruft))
+            (and (eq ctype 'maxmin)
+                 (not (atom form)) (null tem)
+                 (rplaca (cdr cruft) (setq tem (loop-make-variable
+                                                  (gensym) () dtype)))))
+         ('t (and (null dtype)
+                  (setq dtype (cond ((eq type 'count) 'fixnum)
+                                    ((memq type '(min max sum)) 'number))))
+            (or var (push `(return ,(setq var (gensym)))
+                          loop-after-epilogue))
+            (or (eq ctype 'list) (loop-make-iteration-variable var () dtype))
+            (setq tail 
+                  (cond ((eq ctype 'list)
+                           #-Hairy-Collection
+                             (setq tem (loop-make-variable (gensym) () ()))
+                           (car (setq loop-collection-crocks
+                                      (list* (gensym) var
+                                             loop-collection-crocks))))
+                        ((eq ctype 'maxmin)
+                           (or (atom form)
+                               (setq tem (loop-make-variable
+                                            (gensym) () dtype)))
+                           (loop-make-variable (gensym) ''t ()))))
+            (push (list rvar ctype dtype var tail tem)
+                  loop-collect-cruft)))
+    (loop-emit-body
+       (caseq type
+         (count (setq tem `(setq ,var (,(loop-typed-arith 'add1 dtype)
+                                       ,var)))
+                (if (member form '(t 't)) tem `(and ,form ,tem)))
+         (sum `(setq ,var (,(loop-typed-arith 'plus dtype) ,form ,var)))
+         ((max min)
+            (let ((forms ()) (arglist ()))
+               ; TEM is temporary, properly typed.
+               (and tem (setq forms `((setq ,tem ,form)) form tem))
+               (setq arglist (list var form))
+               (push (if (si:loop-tmember dtype '(fixnum flonum
+                                                  #+Loop-Small-Floatp
+                                                    small-flonum))
+                         ; no contagious arithmetic
+                         `(and (or ,tail
+                                   (,(loop-typed-arith
+                                        (if (eq type 'max) 'lessp 'greaterp)
+                                        dtype)
+                                    . ,arglist))
+                               (setq ,tail () . ,arglist))
+                         ; potentially contagious arithmetic -- must use
+                         ; MAX or MIN so that var will be contaminated
+                         `(setq ,var (cond (,tail (setq ,tail ()) ,form)
+                                           ((,type . ,arglist)))))
+                     forms)
+               (if (cdr forms) (cons 'progn (nreverse forms)) (car forms))))
+         (t (caseq type
+               (list (setq form (list 'list form)))
+               (append (or (and (not (atom form)) (eq (car form) 'list))
+                           (setq form #+Lispm `(copylist* ,form)
+                                      #-Lispm `(append ,form ())))))
+          #+Hairy-Collection
+            (let ((q `(rplacd ,tail ,form)))
+               (cond ((and (not (atom form)) (eq (car form) 'list)
+                           (not (null (cdr form))))
+                        ; RPLACD of cdr-coded list:
+                        #+Lispm
+                          (rplaca (cddr q)
+                                  (if (cddr form) `(list* ,@(cdr form) ())
+                                      `(ncons ,(cadr form))))
+                        `(setq ,tail ,(loop-cdrify (cdr form) q)))
+                     ('t `(and (cdr ,q)
+                               (setq ,tail (last (cdr ,tail)))))))
+          #-Hairy-Collection
+            (let ((q `(cond (,tail (cdr (rplacd ,tail ,tem)))
+                            ((setq ,var ,tem)))))
+               (if (and (not (atom form)) (eq (car form) 'list) (cdr form))
+                   `(setq ,tem ,form ,tail ,(loop-cdrify (cddr form) q))
+                   `(and (setq ,tem ,form) (setq ,tail (last ,q))))))))))
+
+
+(defun loop-cdrify (arglist form)
+    (do ((size (length arglist) (- size 4)))
+       ((< size 4)
+        (if (zerop size) form
+            (list (cond ((= size 1) 'cdr) ((= size 2) 'cddr) ('t 'cdddr))
+                  form)))
+      #+Meaningful-Type-Declarations (declare (fixnum size))
+      (setq form (list 'cddddr form))))
+\f
+
+(defun loop-do-while (cond kwd &aux (form (loop-get-form)))
+    (and loop-conditionals (loop-simple-error
+                             "not allowed inside LOOP conditional"
+                             (list kwd form)))
+    (loop-pseudo-body `(,cond ,form (go end-loop))))
+
+
+(defun loop-do-when (negate?)
+  (let ((form (loop-get-form)) (cond))
+    (cond ((si:loop-tequal (cadr loop-source-code) 'it)
+            ;WHEN foo RETURN IT and the like
+            (setq cond `(setq ,(loop-when-it-variable) ,form))
+            (setq loop-source-code             ;Plug in variable for IT
+                  (list* (car loop-source-code)
+                         loop-when-it-variable
+                         (cddr loop-source-code))))
+         ('t (setq cond form)))
+    (and negate? (setq cond `(not ,cond)))
+    (setq loop-conditionals (nconc loop-conditionals `((cond (,cond)))))))
+
+(defun loop-do-with ()
+  (do ((var) (equals) (val) (dtype)) (())
+    (setq var (loop-pop-source) equals (car loop-source-code))
+    (cond ((si:loop-tequal equals '=)
+            (loop-pop-source)
+            (setq val (loop-get-form) dtype ()))
+         ((or (si:loop-tequal equals 'and)
+              (si:loop-tassoc equals loop-keyword-alist)
+              (si:loop-tassoc equals loop-iteration-keyword-alist))
+            (setq val () dtype ()))
+         ('t (setq dtype (loop-pop-source) equals (car loop-source-code))
+             (cond ((si:loop-tequal equals '=)
+                      (loop-pop-source)
+                      (setq val (loop-get-form)))
+                   ((and (not (null loop-source-code))
+                         (not (si:loop-tassoc equals loop-keyword-alist))
+                         (not (si:loop-tassoc
+                                 equals loop-iteration-keyword-alist))
+                         (not (si:loop-tequal equals 'and)))
+                      (loop-simple-error "Garbage where = expected" equals))
+                   ('t (setq val ())))))
+    (loop-make-variable var val dtype)
+    (if (not (si:loop-tequal (car loop-source-code) 'and)) (return ())
+       (loop-pop-source)))
+  (loop-bind-block))
+
+(defun loop-do-always (pred)
+  (let ((form (loop-get-form)))
+    (loop-emit-body `(,pred ,form (return ())))
+    (push '(return 't) loop-after-epilogue)))
+
+;THEREIS expression
+;If expression evaluates non-nil, return that value.
+(defun loop-do-thereis ()
+   (loop-emit-body `(and (setq ,(loop-when-it-variable) ,(loop-get-form))
+                        (return ,loop-when-it-variable))))
+\f
+
+;;;; Hacks
+
+#+Meaningful-Type-Declarations
+  (declare (fixnum (loop-simplep-1 notype)))
+
+(defun si:loop-simplep (expr)
+    (if (null expr) 0
+       (*catch 'si:loop-simplep
+           (let ((ans (si:loop-simplep-1 expr)))
+              #+Meaningful-Type-Declarations (declare (fixnum ans))
+              (and (< ans 20.) ans)))))
+
+(defvar si:loop-simplep
+  (append '(> < greaterp lessp plusp minusp typep zerop
+           plus difference + - add1 sub1 1+ 1-
+           +$ -$ 1+$ 1-$ boole rot ash ldb equal atom
+           setq prog1 prog2 and or =)
+         #+(or Lispm NIL) '(aref ar-1 ar-2 ar-3)
+         #+Lispm '#.(and (loop-featurep Lispm)
+                         (mapcar 'ascii '(#/\1c #/\1d #/\1a)))
+         #+For-NIL '(vref vector-length 1+& 1-& +& -& +p -p 0p *& //& \&
+                      si:xref char string-length)
+         ))
+
+(defun si:loop-simplep-1 (x)
+  (let ((z 0))
+    #+Meaningful-Type-Declarations (declare (fixnum z))
+    (cond ((loop-constantp x) 0)
+         ((atom x) 1)
+         ((eq (car x) 'cond)
+            (do ((cl (cdr x) (cdr cl))) ((null cl))
+              (do ((f (car cl) (cdr f))) ((null f))
+                (setq z (+ (si:loop-simplep-1 (car f)) z 1))))
+            z)
+         ((symbolp (car x))
+            (let ((fn (car x)) (tem ()))
+              (cond ((setq tem (get fn 'si:loop-simplep))
+                       (if (fixp tem) (setq z tem)
+                           (setq z (funcall tem x) x ())))
+                    ((memq fn '(null not eq go return progn)))
+                    (#+Run-on-PDP10
+                       (or (not (minusp (+internal-carcdrp fn)))
+                                     (eq fn 'cxr))
+                     #-Run-on-PDP10 (memq fn '(car cdr))
+                       (setq z 1))
+                  #-Run-on-PDP10
+                    ((memq fn '(caar cadr cdar cddr)) (setq z 2))
+                  #-Run-on-PDP10
+                    ((memq fn '(caaar caadr cadar caddr
+                                cdaar cdadr cddar cdddr))
+                       (setq z 3))
+                  #-Run-on-PDP10
+                    ((memq fn '(caaaar caaadr caadar caaddr
+                                cadaar cadadr caddar cadddr
+                                cdaaar cdaadr cdadar cdaddr
+                                cddaar cddadr cdddar cddddr))
+                       (setq z 4))
+                    ((memq fn si:loop-simplep)
+                       (setq z 2))
+                    (#+(or Lispm For-PDP10 For-NIL)
+                       (not (eq (setq tem (macroexpand-1 x)) x))
+                     #+Franz (not (eq (setq tem (macroexpand x)) x))
+                     #+Multics
+                       (setq tem (get (car x) 'macro))
+                     #+Multics (setq tem (funcall tem x))
+                     (setq z (si:loop-simplep-1 tem) x ()))
+                    ('t (*throw 'si:loop-simplep ())))
+              (do ((l (cdr x) (cdr l))) ((null l))
+                (setq z (+ (si:loop-simplep-1 (car l)) 1 z)))
+              z))
+         ('t (*throw 'si:loop-simplep ())))))
+\f
+
+;;;; The iteration driver
+(defun loop-hack-iteration (entry)
+  (do ((last-entry entry)
+       (source loop-source-code loop-source-code)
+       (pre-step-tests ())
+       (steps ())
+       (post-step-tests ())
+       (pseudo-steps ())
+       (pre-loop-pre-step-tests ())
+       (pre-loop-steps ())
+       (pre-loop-post-step-tests ())
+       (pre-loop-pseudo-steps ())
+       (tem) (data) (foo) (bar))
+      (())
+    ; Note we collect endtests in reverse order, but steps in correct
+    ; order.  LOOP-END-TESTIFY does the nreverse for us.
+    (setq tem (setq data (apply (cadr entry) (cddr entry))))
+    (and (car tem) (push (car tem) pre-step-tests))
+    (setq steps (nconc steps (loop-copylist* (car (setq tem (cdr tem))))))
+    (and (car (setq tem (cdr tem))) (push (car tem) post-step-tests))
+    (setq pseudo-steps
+         (nconc pseudo-steps (loop-copylist* (car (setq tem (cdr tem))))))
+    (setq tem (cdr tem))
+    (and (or loop-conditionals loop-emitted-body?)
+        (or tem pre-step-tests post-step-tests pseudo-steps)
+        (let ((cruft (list (car entry) (car source)
+                           (cadr source) (caddr source))))
+           (if loop-emitted-body?
+               (loop-simple-error
+                  "Iteration is not allowed to follow body code" cruft)
+               (loop-simple-error
+                  "Iteration starting inside of conditional in LOOP"
+                  cruft))))
+    (or tem (setq tem data))
+    (and (car tem) (push (car tem) pre-loop-pre-step-tests))
+    (setq pre-loop-steps
+         (nconc pre-loop-steps (loop-copylist* (car (setq tem (cdr tem))))))
+    (and (car (setq tem (cdr tem))) (push (car tem) pre-loop-post-step-tests))
+    (setq pre-loop-pseudo-steps
+         (nconc pre-loop-pseudo-steps (loop-copylist* (cadr tem))))
+    (cond ((or (not (si:loop-tequal (car loop-source-code) 'and))
+              (and loop-conditionals
+                   (not (si:loop-tassoc (cadr loop-source-code)
+                                        loop-iteration-keyword-alist))))
+            (setq foo (list (loop-end-testify pre-loop-pre-step-tests)
+                            (loop-make-psetq pre-loop-steps)
+                            (loop-end-testify pre-loop-post-step-tests)
+                            (loop-make-setq pre-loop-pseudo-steps))
+                  bar (list (loop-end-testify pre-step-tests)
+                            (loop-make-psetq steps)
+                            (loop-end-testify post-step-tests)
+                            (loop-make-setq pseudo-steps)))
+            (cond ((not loop-conditionals)
+                     (setq loop-before-loop (nreconc foo loop-before-loop)
+                           loop-after-body (nreconc bar loop-after-body)))
+                  ('t ((lambda (loop-conditionals)
+                          (push (loop-make-conditionalization
+                                   (cons 'progn (delq () foo)))
+                                loop-before-loop))
+                       (mapcar '(lambda (x)    ;Copy parts that will get rplacd'ed
+                                  (cons (car x)
+                                        (mapcar '(lambda (x) (loop-copylist* x)) (cdr x))))
+                               loop-conditionals))
+                      (push (loop-make-conditionalization
+                               (cons 'progn (delq () bar)))
+                            loop-after-body)))
+            (loop-bind-block)
+            (return ())))
+    (loop-pop-source) ; flush the "AND"
+    (setq entry (cond ((setq tem (si:loop-tassoc
+                                   (car loop-source-code)
+                                   loop-iteration-keyword-alist))
+                        (loop-pop-source)
+                        (setq last-entry tem))
+                     ('t last-entry)))))
+\f
+
+;FOR variable keyword ..args..
+(defun loop-do-for ()
+  (let ((var (loop-pop-source))
+       (data-type? (loop-optional-type))
+       (keyword (loop-pop-source))
+       (first-arg (loop-get-form))
+       (tem ()))
+    (or (setq tem (si:loop-tassoc keyword loop-for-keyword-alist))
+       (loop-simple-error
+          "Unknown keyword in FOR or AS clause in LOOP"
+          (list 'for var keyword)))
+    (lexpr-funcall (cadr tem) var first-arg data-type? (cddr tem))))
+
+
+(defun loop-do-repeat ()
+    (let ((var (loop-make-variable (gensym) (loop-get-form) 'fixnum)))
+       `((not (,(loop-typed-arith 'plusp 'fixnum) ,var))
+         () ()
+         (,var (,(loop-typed-arith 'sub1 'fixnum) ,var)))))
+
+
+; Kludge the First
+(defun loop-when-it-variable ()
+    (or loop-when-it-variable
+       (setq loop-when-it-variable
+             (loop-make-variable (gensym) () ()))))
+\f
+
+
+(defun loop-for-equals (var val data-type?)
+  (cond ((si:loop-tequal (car loop-source-code) 'then)
+          ;FOR var = first THEN next
+          (loop-pop-source)
+          (loop-make-iteration-variable var val data-type?)
+          `(() (,var ,(loop-get-form)) () ()
+            () () () ()))
+       ('t (loop-make-iteration-variable var () data-type?)
+           (let ((varval (list var val)))
+             (cond (loop-emitted-body?
+                    (loop-emit-body (loop-make-setq varval))
+                    '(() () () ()))
+                   (`(() ,varval () ())))))))
+
+(defun loop-for-first (var val data-type?)
+    (or (si:loop-tequal (car loop-source-code) 'then)
+       (loop-simple-error "found where THEN expected in FOR ... FIRST"
+                          (car loop-source-code)))
+    (loop-pop-source)
+    (loop-make-iteration-variable var () data-type?)
+    `(() (,var ,(loop-get-form)) () () () (,var ,val) () ()))
+\f
+
+(defun loop-list-stepper (var val data-type? fn)
+    (let ((stepper (cond ((si:loop-tequal (car loop-source-code) 'by)
+                           (loop-pop-source) (loop-get-form))
+                        ('t '(function cdr))))
+         (var1 ()) (stepvar ()) (step ()) (et ()) (pseudo ()))
+       (setq step (if (or (atom stepper)
+                         (not (memq (car stepper) '(quote function))))
+                     `(funcall ,(setq stepvar (gensym)))
+                     (list (cadr stepper))))
+       (cond ((and (atom var)
+                  ;; (eq (car step) 'cdr)
+                  (not fn))
+               (setq var1 (loop-make-iteration-variable var val data-type?)))
+            ('t (loop-make-iteration-variable var () data-type?)
+                (setq var1 (loop-make-variable (gensym) val ()))
+                (setq pseudo (list var (if fn (list fn var1) var1)))))
+       (rplacd (last step) (list var1))
+       (and stepvar (loop-make-variable stepvar stepper ()))
+       (setq stepper (list var1 step) et `(null ,var1))
+       (if (not pseudo) `(() ,stepper ,et () () () ,et ())
+          (if (eq (car step) 'cdr) `(,et ,pseudo () ,stepper)
+              `((null (setq . ,stepper)) () () ,pseudo ,et () () ,pseudo)))))
+
+
+(defun loop-for-arithmetic (var val data-type? kwd)
+  ; Args to loop-sequencer:
+  ; indexv indexv-type variable? vtype? sequencev? sequence-type
+  ; stephack? default-top? crap prep-phrases
+  (si:loop-sequencer
+     var (or data-type? 'fixnum) () () () () () () `(for ,var ,kwd ,val)
+     (cons (list kwd val)
+          (loop-gather-preps
+             '(from upfrom downfrom to upto downto above below by)
+             ()))))
+\f
+
+(defun si:loop-named-variable (name)
+    (let ((tem (si:loop-tassoc name loop-named-variables)))
+       (cond ((null tem) (gensym))
+            ('t (setq loop-named-variables (delq tem loop-named-variables))
+                (cdr tem)))))
+
+#+Run-in-Maclisp ;Gross me out
+(and (status feature #+Multics Compiler #-Multics complr)
+     (*expr si:loop-named-variable))
+
+
+; Note:  path functions are allowed to use loop-make-variable, hack
+; the prologue, etc.
+(defun loop-for-being (var val data-type?)
+   ; FOR var BEING something ... - var = VAR, something = VAL.
+   ; If what passes syntactically for a pathname isn't, then
+   ; we trap to the DEFAULT-LOOP-PATH path;  the expression which looked like
+   ; a path is given as an argument to the IN preposition.  Thus,
+   ; by default, FOR var BEING EACH expr OF expr-2
+   ; ==> FOR var BEING DEFAULT-LOOP-PATH IN expr OF expr-2.
+   (let ((tem) (inclusive?) (ipps) (each?) (attachment))
+     (if (or (si:loop-tequal val 'each) (si:loop-tequal val 'the))
+        (setq each? 't val (car loop-source-code))
+        (push val loop-source-code))
+     (cond ((and (setq tem (si:loop-tassoc val loop-path-keyword-alist))
+                (or each? (not (si:loop-tequal (cadr loop-source-code)
+                                               'and))))
+             ;; FOR var BEING {each} path {prep expr}..., but NOT
+             ;; FOR var BEING var-which-looks-like-path AND {ITS} ...
+             (loop-pop-source))
+          ('t (setq val (loop-get-form))
+              (cond ((si:loop-tequal (car loop-source-code) 'and)
+                       ;; FOR var BEING value AND ITS path-or-ar
+                       (or (null each?)
+                           (loop-simple-error
+                              "Malformed BEING EACH clause in LOOP" var))
+                       (setq ipps `((of ,val)) inclusive? 't)
+                       (loop-pop-source)
+                       (or (si:loop-tmember (setq tem (loop-pop-source))
+                                            '(its his her their each))
+                           (loop-simple-error
+                              "found where ITS or EACH expected in LOOP path"
+                              tem))
+                       (if (setq tem (si:loop-tassoc
+                                        (car loop-source-code)
+                                        loop-path-keyword-alist))
+                           (loop-pop-source)
+                           (push (setq attachment `(in ,(loop-get-form)))
+                                 ipps)))
+                    ((not (setq tem (si:loop-tassoc
+                                       (car loop-source-code)
+                                       loop-path-keyword-alist)))
+                       ; FOR var BEING {each} a-r ...
+                       (setq ipps (list (setq attachment (list 'in val)))))
+                    ('t ; FOR var BEING {each} pathname ...
+                        ; Here, VAL should be just PATHNAME.
+                        (loop-pop-source)))))
+     (cond ((not (null tem)))
+          ((not (setq tem (si:loop-tassoc 'default-loop-path
+                                          loop-path-keyword-alist)))
+             (loop-simple-error "Undefined LOOP iteration path"
+                                (cadr attachment))))
+     (setq tem (funcall (cadr tem) (car tem) var data-type?
+                       (nreconc ipps (loop-gather-preps (caddr tem) 't))
+                       inclusive? (caddr tem) (cdddr tem)))
+     (and loop-named-variables
+         (loop-simple-error "unused USING variables" loop-named-variables))
+     ; For error continuability (if there is any):
+     (setq loop-named-variables ())
+     ;; TEM is now (bindings prologue-forms . stuff-to-pass-back)
+     (do ((l (car tem) (cdr l)) (x)) ((null l))
+       (if (atom (setq x (car l)))
+          (loop-make-iteration-variable x () ())
+          (loop-make-iteration-variable (car x) (cadr x) (caddr x))))
+     (setq loop-prologue (nconc (reverse (cadr tem)) loop-prologue))
+     (cddr tem)))
+\f
+
+(defun loop-gather-preps (preps-allowed crockp)
+   (do ((token (car loop-source-code) (car loop-source-code)) (preps ()))
+       (())
+     (cond ((si:loop-tmember token preps-allowed)
+             (push (list (loop-pop-source) (loop-get-form)) preps))
+          ((si:loop-tequal token 'using)
+             (loop-pop-source)
+             (or crockp (loop-simple-error
+                           "USING used in illegal context"
+                           (list 'using (car loop-source-code))))
+             (do ((z (car loop-source-code) (car loop-source-code)) (tem))
+                 ((atom z))
+               (and (or (atom (cdr z))
+                        (not (null (cddr z)))
+                        (not (symbolp (car z)))
+                        (and (cadr z) (not (symbolp (cadr z)))))
+                    (loop-simple-error
+                       "bad variable pair in path USING phrase" z))
+               (cond ((not (null (cadr z)))
+                        (and (setq tem (si:loop-tassoc
+                                          (car z) loop-named-variables))
+                             (loop-simple-error
+                                "Duplicated var substitition in USING phrase"
+                                (list tem z)))
+                        (push (cons (car z) (cadr z)) loop-named-variables)))
+               (loop-pop-source)))
+          ('t (return (nreverse preps))))))
+
+(defun loop-add-path (name data)
+    (setq loop-path-keyword-alist
+         (cons (cons name data)
+               ; Don't change this to use DELASSQ in PDP10, the lsubr
+               ; calling sequence makes that lose.
+               (delq (si:loop-tassoc name loop-path-keyword-alist)
+                     loop-path-keyword-alist)))
+    ())
+
+#+Run-on-PDP10
+(declare ; Suck my obarray...
+        (own-symbol define-loop-path define-loop-sequence-path))
+
+(defmacro define-loop-path (names &rest cruft)
+  (setq names (if (atom names) (list names) names))
+  #-For-Maclisp
+    (let ((forms (mapcar #'(lambda (name) `(loop-add-path ',name ',cruft))
+                        names)))
+       `(eval-when (eval load compile)
+           #+For-NIL (flush-macromemos 'loop ())
+           ,@forms))
+  #+For-Maclisp
+    (subst (do ((l)) ((null names) l)
+            (setq l (cons `(setq loop-path-keyword-alist
+                                 (cons '(,(car names) . ,cruft)
+                                       (delq (assq ',(car names)
+                                                   loop-path-keyword-alist)
+                                             loop-path-keyword-alist)))
+                          l)
+                  names (cdr names)))
+          'progn
+          '(eval-when (eval load compile)
+            #-For-PDP10 (or (boundp 'loop-path-keyword-alist)
+                             (setq loop-path-keyword-alist ()))
+            #+For-PDP10 (and (or (boundp 'loop-path-keyword-alist)
+                                  (setq loop-path-keyword-alist ()))
+                              (flush-macromemos 'loop ()))
+              . progn)))
+\f
+
+(defun si:loop-sequencer (indexv indexv-type
+                         variable? vtype?
+                         sequencev? sequence-type?
+                         stephack? default-top?
+                         crap prep-phrases)
+   (let ((endform) (sequencep) (test)
+        (step ; Gross me out!
+              (add1 (or (loop-typed-init indexv-type) 0)))
+        (dir) (inclusive-iteration?) (start-given?) (limit-given?))
+     (and variable? (loop-make-iteration-variable variable? () vtype?))
+     (do ((l prep-phrases (cdr l)) (prep) (form) (odir)) ((null l))
+       (setq prep (caar l) form (cadar l))
+       (cond ((si:loop-tmember prep '(of in))
+               (and sequencep (loop-simple-error
+                                 "Sequence duplicated in LOOP path"
+                                 (list variable? (car l))))
+               (setq sequencep 't)
+               (loop-make-variable sequencev? form sequence-type?))
+            ((si:loop-tmember prep '(from downfrom upfrom))
+               (and start-given?
+                    (loop-simple-error
+                       "Iteration start redundantly specified in LOOP sequencing"
+                       (append crap l)))
+               (setq start-given? 't)
+               (cond ((si:loop-tequal prep 'downfrom) (setq dir 'down))
+                     ((si:loop-tequal prep 'upfrom) (setq dir 'up)))
+               (loop-make-iteration-variable indexv form indexv-type))
+            ((cond ((si:loop-tequal prep 'upto)
+                      (setq inclusive-iteration? (setq dir 'up)))
+                   ((si:loop-tequal prep 'to)
+                      (setq inclusive-iteration? 't))
+                   ((si:loop-tequal prep 'downto)
+                      (setq inclusive-iteration? (setq dir 'down)))
+                   ((si:loop-tequal prep 'above) (setq dir 'down))
+                   ((si:loop-tequal prep 'below) (setq dir 'up)))
+               (and limit-given?
+                    (loop-simple-error
+                      "Endtest redundantly specified in LOOP sequencing path"
+                      (append crap l)))
+               (setq limit-given? 't)
+               (setq endform (loop-maybe-bind-form form indexv-type)))
+            ((si:loop-tequal prep 'by)
+               (setq step (if (loop-constantp form) form
+                              (loop-make-variable (gensym) form 'fixnum))))
+            ('t ; This is a fatal internal error...
+                (loop-simple-error "Illegal prep in sequence path"
+                                   (append crap l))))
+       (and odir dir (not (eq dir odir))
+           (loop-simple-error
+              "Conflicting stepping directions in LOOP sequencing path"
+              (append crap l)))
+       (setq odir dir))
+     (and sequencev? (not sequencep)
+         (loop-simple-error "Missing OF phrase in sequence path" crap))
+     ; Now fill in the defaults.
+     (setq step (list indexv step))
+     (cond ((memq dir '(() up))
+             (or start-given?
+                 (loop-make-iteration-variable indexv 0 indexv-type))
+             (and (or limit-given?
+                      (cond (default-top?
+                               (loop-make-variable
+                                  (setq endform (gensym)) () indexv-type)
+                               (push `(setq ,endform ,default-top?)
+                                     loop-prologue))))
+                  (setq test (if inclusive-iteration? '(greaterp . args)
+                                 '(not (lessp . args)))))
+             (push 'plus step))
+          ('t (cond ((not start-given?)
+                       (or default-top?
+                           (loop-simple-error
+                              "Don't know where to start stepping"
+                              (append crap prep-phrases)))
+                       (loop-make-iteration-variable indexv 0 indexv-type)
+                       (push `(setq ,indexv
+                                    (,(loop-typed-arith 'sub1 indexv-type)
+                                     ,default-top?))
+                             loop-prologue)))
+              (cond ((and default-top? (not endform))
+                       (setq endform (loop-typed-init indexv-type)
+                             inclusive-iteration? 't)))
+              (and (not (null endform))
+                   (setq test (if inclusive-iteration? '(lessp . args)
+                                  '(not (greaterp . args)))))
+              (push 'difference step)))
+     (and (member (caddr step)
+                 #+Loop-Small-Floatp
+                   '(1 1.0 #.(and (loop-featurep Loop-Small-Floatp)
+                                  (small-float 1)))
+                 #-Loop-Small-Floatp '(1 1.0))
+         (rplacd (cdr (rplaca step (if (eq (car step) 'plus) 'add1 'sub1)))
+                 ()))
+     (rplaca step (loop-typed-arith (car step) indexv-type))
+     (setq step (list indexv step))
+     (setq test (loop-typed-arith test indexv-type))
+     (setq test (subst (list indexv endform) 'args test))
+     (and stephack? (setq stephack? `(,variable? ,stephack?)))
+     `(() ,step ,test ,stephack?
+       () () ,test ,stephack?)))
+
+
+; Although this function is no longer documented, the "SI:" is needed
+; because compiled files may reference it that way (via
+; DEFINE-LOOP-SEQUENCE-PATH).
+(defun si:loop-sequence-elements-path (path variable data-type
+                                      prep-phrases inclusive?
+                                      allowed-preps data)
+    allowed-preps ; unused
+    (let ((indexv (si:loop-named-variable 'index))
+         (sequencev (si:loop-named-variable 'sequence))
+         (fetchfun ()) (sizefun ()) (type ()) (default-var-type ())
+         (crap `(for ,variable being the ,path)))
+       (cond ((not (null inclusive?))
+               (rplacd (cddr crap) `(,(cadar prep-phrases) and its ,path))
+               (loop-simple-error "Can't step sequence inclusively" crap)))
+       (setq fetchfun (car data)
+            sizefun (car (setq data (cdr data)))
+            type (car (setq data (cdr data)))
+            default-var-type (cadr data))
+       (list* () () ; dummy bindings and prologue
+             (si:loop-sequencer
+                indexv 'fixnum
+                variable (or data-type default-var-type)
+                sequencev type
+                `(,fetchfun ,sequencev ,indexv) `(,sizefun ,sequencev)
+                crap prep-phrases))))
+
+
+#+Run-on-PDP10
+(defun (define-loop-sequence-path macro) (x)
+    `(define-loop-path ,(cadr x) si:loop-sequence-elements-path
+       (of in from downfrom to downto below above by)
+       . ,(cddr x)))
+
+#-Run-on-PDP10
+(defmacro define-loop-sequence-path (path-name-or-names fetchfun sizefun
+                                    &optional sequence-type element-type)
+    `(define-loop-path ,path-name-or-names
+       si:loop-sequence-elements-path
+       (of in from downfrom to downto below above by)
+       ,fetchfun ,sizefun ,sequence-type ,element-type))
+\f
+
+;;;; NIL interned-symbols path
+
+#+For-NIL
+(progn 'compile
+(defun loop-interned-symbols-path (path variable data-type prep-phrases
+                                  inclusive? allowed-preps data
+                                  &aux statev1 statev2 statev3
+                                       (localp (car data)))
+   allowed-preps       ; unused
+   (and inclusive? (loop-simple-error
+                     "INTERNED-SYMBOLS path doesn't work inclusively"
+                     variable))
+   (and (not (null prep-phrases))
+       (or (cdr prep-phrases)
+           (not (si:loop-tmember (caar prep-phrases) '(in of))))
+       (ferror () "Illegal prep phrase(s) in ~A path of ~A - ~A"
+               path variable prep-phrases))
+   (loop-make-variable variable () data-type)
+   (loop-make-variable
+      (setq statev1 (gensym))
+      `(loop-find-package
+         ,@(and prep-phrases `(,(cadar prep-phrases))))
+      ())
+   (loop-make-variable (setq statev2 (gensym)) () ())
+   (loop-make-variable (setq statev3 (gensym)) () ())
+   (push `(multiple-value (,statev1 ,statev2 ,statev3)
+              (loop-initialize-mapatoms-state ,statev1 ',localp))
+        loop-prologue)
+   `(() () (multiple-value (() ,statev1 ,statev2 ,statev3)
+             (,(if localp 'loop-test-and-step-mapatoms-local
+                   'loop-test-and-step-mapatoms)
+              ,statev1 ,statev2 ,statev3))
+     (,variable (loop-get-mapatoms-symbol ,statev1 ,statev2 ,statev3)) () ()))
+
+(defun loop-find-package (&optional (pkg () pkgp))
+  #+Run-in-Maclisp
+    (if pkgp pkg obarray)
+  #-Run-in-Maclisp
+    (if pkgp (pkg-find-package pkg) package))
+
+(defun loop-find-package-translate (form)
+  ; Note that we can only be compiling for nil-nil, so we only need
+  ; to consider that.  The run-in-maclisp conditionals in the functions
+  ; are for the benefit of running interpreted code.
+  (values (if (null (cdr form)) 'package `(pkg-find-package ,(cadr form))) 't))
+
+(putprop 'loop-find-package
+        '(loop-find-package-translate)
+        'source-trans)
+
+#-Run-in-Maclisp
+(defun loop-initialize-mapatoms-state (pkg localp)
+    (let* ((symtab (si:package-symbol-table pkg))
+          (len (vector-length symtab)))
+       (values pkg len (if localp symtab (cons (ncons pkg) ())))))
+
+#+Run-in-Maclisp
+(defun loop-initialize-mapatoms-state (ob ())
+    (values ob (ncons nil) 511.))
+
+#-Run-in-Maclisp
+(defun loop-test-and-step-mapatoms (pkg index location &aux val)
+    (prog (symtab)
+        (setq symtab (si:package-symbol-table pkg))
+      lp (cond ((-p (setq index (1-& index)))
+                  ;(do ((l (si:package-super-packages pkg) (cdr l)))
+                 ;    ((null l) (cdr location))
+                 ;  (or (memq (car l) (car location))
+                 ;      (memq (car l) (cdr location))
+                 ;      (rplacd location (cons (car l) (cdr location)))))
+                  (let ((p (si:package-super-package pkg)))
+                    (or (memq p (car location))
+                        (memq p (cdr location))
+                        (rplacd location (cons p (cdr location)))))
+                 (or (cdr location) (return (setq val 't)))
+                 (rplacd location
+                         (prog1 (cddr location)
+                                (rplaca location
+                                        (rplacd (cdr location)
+                                                (car location)))))
+                 (setq pkg (caar location))
+                 (setq symtab (si:package-symbol-table pkg))
+                 (setq index (vector-length symtab))
+                 (go lp))
+              ((symbolp (vref symtab index)) (return ()))
+              ('t (go lp))))
+    (values val pkg index location))
+
+#+Run-in-Maclisp
+(defun loop-test-and-step-mapatoms (ob list index)
+    (loop-test-and-step-mapatoms-local ob list index))
+
+#-Run-in-Maclisp
+(defun loop-test-and-step-mapatoms-local (pkg index symtab &aux val)
+    (prog ()
+      lp (cond ((-p (setq index (1-& index))) (return (setq val 't)))
+              ((symbolp (vref symtab index)) (return ()))
+              ('t (go lp))))
+    (values val pkg index symtab))
+
+#+Run-in-Maclisp
+(defun loop-test-and-step-mapatoms-local (ob list index &aux val)
+    (declare (fixnum index))
+    (prog () 
+     lp (cond ((not (null (cdr list)))
+                (rplaca list (cadr list))
+                (rplacd list (cddr list))
+                (return ()))
+             ((minusp (setq index (1- index))) (return (setq val 't)))
+             ('t ; If this is going to run in multics maclisp also the
+                 ; arraycall should be hacked to have type `obarray'.
+                 (rplacd list (arraycall t ob index))
+                 (go lp))))
+    (values val ob list index))
+
+#-Run-in-Maclisp
+(defun loop-get-mapatoms-symbol (pkg index something-or-other)
+    ;Note there is a potential bug/timing screw in here.  We should be
+    ; looking in the symbol-table saved initially, not the current one.
+    ; There just isn't enough state saved (sigh).
+    (declare (ignore something-or-other))
+    (vref (si:package-symbol-table pkg) index))
+
+#+Run-in-Maclisp
+(defun loop-get-mapatoms-symbol (ob list index)
+    (declare (ignore ob index))
+    (car list))
+
+(and #+Run-in-Maclisp (status feature complr)
+     (*expr loop-get-mapatoms-symbol
+           loop-initialize-mapatoms-state
+           loop-test-and-step-mapatoms
+           loop-test-and-step-mapatoms-local))
+)
+\f
+
+;;;; Maclisp interned-symbols path
+
+#+For-Maclisp
+(defun loop-interned-symbols-path (path variable data-type prep-phrases
+                                  inclusive? allowed-preps data
+                                  &aux indexv listv ob)
+   allowed-preps data  ; unused vars
+   (and inclusive? (loop-simple-error
+                     "INTERNED-SYMBOLS path doesn't work inclusively"
+                     variable))
+   (and (not (null prep-phrases))
+       (or (cdr prep-phrases)
+           (not (si:loop-tmember (caar prep-phrases) '(in of))))
+       (loop-simple-error
+          "Illegal prep phrase(s) in INTERNED-SYMBOLS LOOP path"
+          (list* variable 'being path prep-phrases)))
+   (loop-make-variable variable () data-type)
+   (loop-make-variable
+      (setq ob (gensym)) (if prep-phrases (cadar prep-phrases) 'obarray) ())
+   ; Multics lisp does not store single-char-obs in the obarray buckets.
+   ; Thus, we need to iterate over the portion of the obarray
+   ; containing them also.  (511. = (ascii 0))
+   (loop-make-variable
+      (setq indexv (gensym)) #+Multics 639. #-Multics 511. 'fixnum)
+   (loop-make-variable (setq listv (gensym)) () ())
+   `(() ()
+     (and #-Multics (null ,listv)
+         #+Multics (or (> ,indexv 510.) (null ,listv))
+         (prog ()
+          lp (cond ((minusp (setq ,indexv (1- ,indexv))) (return t))
+                   ((setq ,listv (arraycall ; The following is the kind of
+                                            ; gratuity that pisses me off:
+                                            #+Multics obarray #-Multics t
+                                            ,ob ,indexv))
+                      (return ()))
+                   ((go lp)))))
+     (,variable
+       #+Multics (cond ((> ,indexv 510.) ,listv)
+                      (t (prog2 () (car ,listv) (setq ,listv (cdr ,listv)))))
+       #-Multics (car ,listv))
+      ()
+     #+Multics () #-Multics (,listv (cdr ,listv))))
+
+\f
+;;;; Lispm interned-symbols path
+
+#+Lispm
+(progn 'compile
+
+ (defun loop-interned-symbols-path (path variable data-type prep-phrases
+                                   inclusive? allowed-preps data
+                                   &aux statev1 statev2 statev3
+                                        (localp (car data)))
+    path data-type allowed-preps                       ; unused vars
+    (and inclusive? (loop-simple-error
+                      "INTERNED-SYMBOLS path doesn't work inclusively"
+                      variable))
+    (and (not (null prep-phrases))
+        (or (cdr prep-phrases)
+            (not (si:loop-tmember (caar prep-phrases) '(in of))))
+          (ferror () "Illegal prep phrase(s) in ~A path of ~A - ~A"
+                  path variable prep-phrases))
+    (loop-make-variable variable () data-type)
+    (loop-make-variable
+       (setq statev1 (gensym))
+       (if prep-phrases `(pkg-find-package ,(cadar prep-phrases)) 'package)
+       ())
+    (loop-make-variable (setq statev2 (gensym)) () ())
+    (loop-make-variable (setq statev3 (gensym)) () ())
+    (push `(multiple-value (,statev1 ,statev2 ,statev3)
+                 (loop-initialize-mapatoms-state ,statev1 ,localp))
+           loop-prologue)
+    `(() () (multiple-value (nil ,statev1 ,statev2 ,statev3)
+              (,(if localp 'loop-test-and-step-mapatoms-local
+                    'loop-test-and-step-mapatoms)
+               ,statev1 ,statev2 ,statev3)) 
+      (,variable (loop-get-mapatoms-symbol ,statev1 ,statev2 ,statev3))
+      () ()))
+
+ (defun loop-initialize-mapatoms-state (pkg localp)
+    ; Return the initial values of the three state variables.
+    ; This scheme uses them to be:
+    ; (1)  Index into the package (decremented as we go)
+    ; (2)  Temporary (to hold the symbol)
+    ; (3)  the package
+    localp ; ignored
+    (prog ()
+       (return (array-dimension-n 2 pkg) () pkg)))
+
+ (defun loop-test-and-step-mapatoms (index temp pkg)
+    temp ; ignored
+    (prog ()
+     lp (cond ((< (setq index (1- index)) 0)
+                (cond ((setq pkg (pkg-super-package pkg))
+                         (setq index (array-dimension-n 2 pkg))
+                         (go lp))
+                      (t (return t))))
+             ((numberp (ar-2 pkg 0 index))
+                (return nil index (ar-2 pkg 1 index) pkg))
+             (t (go lp)))))
+
+ (defun loop-test-and-step-mapatoms-local (index temp pkg)
+    temp ; ignored
+    (prog ()
+     lp (cond ((minusp (setq index (1- index))) (return t))
+             ((numberp (ar-2 pkg 0 index))
+                (return () index (ar-2 pkg 1 index) pkg))
+             (t (go lp)))))
+
+ (defun loop-get-mapatoms-symbol (index temp pkg)
+    index pkg ; ignored
+    temp)
+ )
+\f
+; We don't want these defined in the compilation environment because
+; the appropriate environment hasn't been set up.  So, we just bootstrap
+; them up.
+(mapc '(lambda (x)
+         (mapc '(lambda (y)
+                   (setq loop-path-keyword-alist
+                         (cons (cons y (cdr x))
+                               (delq (si:loop-tassoc
+                                        y loop-path-keyword-alist)
+                                     loop-path-keyword-alist))))
+               (car x)))
+      '(
+      #+(or For-NIL For-Maclisp Lispm)
+       ((interned-symbols interned-symbol)
+          loop-interned-symbols-path (in))
+      #+(or For-NIL Lispm)
+       ((local-interned-symbols local-interned-symbol)
+          loop-interned-symbols-path (in) t)
+       ))
+
+#-Multics ; none defined yet
+(mapc '(lambda (x)
+        (mapc '(lambda (y)
+                 (setq loop-path-keyword-alist
+                       (cons `(,y si:loop-sequence-elements-path
+                               (of in from downfrom to downto below above by)
+                               . ,(cdr x))
+                             (delq (si:loop-tassoc
+                                     y loop-path-keyword-alist)
+                                   loop-path-keyword-alist))))
+              (car x)))
+      '(#+Lispm
+        ((array-element array-elements) aref array-active-length)
+       ; These NIL guys are set up by NILAID in the PDP10 version but no one
+       ; sets them up on the VAX.  Anyway redundancy won't hurt unless i
+       ; break something.
+       #+(and For-NIL (not Run-in-Maclisp))
+         ((vector-element vector-elements) vref vector-length vector)
+        #+(and For-NIL (not Run-in-Maclisp))
+         ((bit bits) bit bits-length bits fixnum)
+       #+(and For-NIL (not Run-in-Maclisp))
+         ((character characters) char string-length string character)
+       )
+      )
+
+; Sigh. (c.f. loop-featurep, note macro-expansion lossage.)
+; Note that we end up doing both in the PDP10 NIL version.
+#+(or (not For-NIL) Run-in-Maclisp)
+  (or (status feature loop) (sstatus feature loop))
+#+For-NIL
+  (set-feature 'loop 'local)
+
diff --git a/usr/src/usr.bin/lisp/lisplib/step.l b/usr/src/usr.bin/lisp/lisplib/step.l
new file mode 100644 (file)
index 0000000..96d6a76
--- /dev/null
@@ -0,0 +1,282 @@
+(setq rcs-step-
+   "$Header: /usr/lib/lisp/step.l,v 1.1 83/01/29 18:39:46 jkf Exp $")
+
+; vi: set lisp :
+
+;;;                     LISP Stepping Package
+;;;
+;;; Adapted by Mitch Marcus for Franz Lisp from Chuck Rich's MACLISP
+;;; package.
+;;;
+;;;
+;;; Adapted 2/80 from the Maclisp version of 11/03/76
+;;; Further modified 5/80 by Don Cohen (DNC)
+;;;
+;;; modified by jkf 6/81 to handle funcallhook.
+;;;
+;;; User Interface Function
+;;;
+;;;             Valid Forms:                            
+;;; (step) or (step nil)       :: turn off stepping
+;;; (step t)                   :: turn on stepping right away.
+;;; (step e)                   :: turn on stepping of eval only
+;;; (step foo1 foo2 ...)       :: turn on stepping when one of fooi is
+;;;                            :: called
+;;;
+;------ implementation:
+; evalhook* is nil meaning no stepping, or t meaning always step
+;    or is a list of forms which will start continuous stepping.
+;
+; The hook functions are evalhook* and funcallhook*.
+;
+
+(declare (special 
+         evalhook-switch piport        
+         hookautolfcount funcallhook
+         evalhook evalhook* |evalhook#| prinlevel prinlength
+         fcn-evalhook fcn-funcallhook
+         Standard-Input)
+         (macros nil))
+
+;; First Some Macros
+
+(defun 7bit macro (s)
+       ;; (7BIT n c) tests if n is ascii for c
+       (list '= (list 'boole 1 127. (cadr s)) (caddr s)))
+
+;--- print* 
+; indent based on current evalhook recursion level then print the
+; arg in form
+;
+(defun print* macro (s)
+          ;; print with indentation
+         '(do ((i 1 (1+ i))
+               (indent (* 2 |evalhook#|))
+               (prinlevel 3)
+               (prinlength 5))
+              ((> i indent) 
+              (cond ((eq type 'funcall) (patom "f:")))
+              (print form))
+              (tyo 32.)))
+
+(defun step fexpr (arg)
+  (cond ((or (null arg) (car arg))
+        (setq evalhook-switch t) ; for fixit package
+        (setq |evalhook#| 0.)                  ;initialize depth count
+         (setq hookautolfcount 0)              ; count if auto lfs at break
+        (setq evalhook nil)                  ;for safety
+        (setq funcallhook nil)
+        ; (step e) means just step eval things, else step eval and funcal
+        (cond ((eq (car arg) 'e) 
+               (setq fcn-evalhook 'evalhook* fcn-funcallhook nil))
+              (t (setq fcn-evalhook 'evalhook* fcn-funcallhook 'funcallhook*)))
+        (setq evalhook*
+              (cond ((null arg) nil)
+                    ((or (eq (car arg) t) (eq (car arg) 'e)))
+                    (arg)))
+        (setq evalhook fcn-evalhook)      ;turn system hook to my function
+        (setq funcallhook fcn-funcallhook)
+        (sstatus translink nil)
+        (*rset t)                            ;must be on for hook to work
+        (sstatus evalhook t))           ;arm it
+       (t (setq evalhook* nil)
+          (setq evalhook nil)
+          (setq hookautolfcount 0)             ; count if auto lfs at break
+          (setq evalhook-switch nil)
+          (sstatus evalhook nil))))
+
+
+;---- funcall-evalhook*
+;
+; common function to handle evalhook's and funcallhook's.
+; the form to be evaluated is given as form and the type (eval or funcall)
+; is given as type.
+;
+
+(defun funcall-evalhook* (form type)
+  (cond (evalhook*
+        ;; see if selective feature kicks in here
+        (and (not (atom form))
+             (not (eq evalhook* t))
+             (memq (car form) evalhook*)
+             (setq evalhook* t))       ; yes, begin stepping always
+
+        (cond ((eq evalhook* t)
+               ;; print out form before evaluation
+               (print*)
+
+               (cond ((atom form)
+                      ;; since form is atom, we just eval it and print
+                      ;; out its value, no need to ask user what to do
+                      (cond ((not (or (numberp form)(null form)(eq form t)))
+                             (princ '" = ")
+                             ((lambda (prinlevel prinlength)
+                                      (setq form (evalhook form nil nil))
+                                      (print form))    
+                              3 5)))
+                      (terpri))
+                     (t ; s-expression
+                        (prog (cmd ehookfn fhookfcn)
+
+                          cmdlp  (cond ((greaterp hookautolfcount 0)
+                                        (setq hookautolfcount (sub1 hookautolfcount))
+                                        (terpr)
+                                        (setq cmd #\lf))
+                                       (t (setq cmd (let ((piport 
+                                                           Standard-Input))
+                                                         (drain piport)
+                                                         (tyi piport)))))
+
+                              ;; uppercase alphabetics
+                              ;; dispatch on command character
+                              (cond ((eq cmd #\lf)    
+                                     ; \n so continue
+                                     (setq ehookfn fcn-evalhook
+                                           fhookfcn fcn-funcallhook))
+
+                                    ((memq cmd '(#/p #/P))
+                                     ; "P" print in full
+                                     (print form)
+                                     (go cmdlp))
+
+                                    ; "G"
+                                    ((memq cmd '(#/g #/G))
+                                     (setq evalhook* nil  ;stop everything
+                                           ehookfn nil
+                                           fhookfcn nil))
+
+                                    ((memq cmd '(#/c #/C))
+                                     ;"C" no deeper
+                                     (setq ehookfn nil
+                                           fhookfcn nil))
+
+                                    ((memq cmd '(#/d #/D))
+                                     ;"D" call debug
+                                     (setq evalhook-switch nil)
+                                     (sstatus evalhook nil)
+                                     (debug)
+                                     (setq evalhook-switch t)
+                                     (sstatus evalhook t)
+                                     (go cmdlp))
+
+
+                                    ((memq cmd '(#/b #/B))
+                                     ; "B" give breakpoint
+                                     (break step)
+                                     (print*)
+                                     (go cmdlp))
+
+                                    ((memq cmd '(#/q #/Q))
+                                     ; "Q" stop stepping
+                                     (step nil)
+                                     (reset))
+
+                                    ((memq cmd '(#/n #/N))
+                                     (setq hookautolfcount 
+                                           (let ((piport Standard-Input))
+                                                (read)))
+                                     (cond ((not (numberp hookautolfcount))
+                                            (patom "arg to n should be number")
+                                            (terpr)
+                                            (setq hookautolfcount 0))))
+
+                                    ; "s" eval form
+                                    ((memq cmd '(#/s #/S))
+                                     (let ((piport Standard-Input)
+                                           (fcns nil))
+                                          (setq fcns (read))
+                                          (cond ((dtpr fcns) 
+                                                 (setq evalhook* fcns))
+                                                ((symbolp fcns)
+                                                 (setq evalhook* (list fcns))))))
+
+                                    ; "e" step eval only
+                                    ((memq cmd '(#/e #/E))
+                                     (setq fcn-funcallhook nil))
+
+                                    ; "?", "H" show the options
+                                    ((memq cmd '(72 104 63.))
+                                     #+cmu (ty /usr/lisp/doc/step\.ref)
+                                     #-cmu(stephelpform)
+                                     (terpri)
+                                     (go cmdlp))
+                                    ((eq cmd #\eof)
+                                     (patom "EOF typed")
+                                     (terpr))
+
+                                    (t (princ '"Try one of ?BCDGMPQ or <cr>")
+                                       (go cmdlp)))
+
+                              ;; evaluate form
+                              (clear-input-buffer)
+                              ((lambda (|evalhook#|)
+                                       (setq form (continue-evaluation 
+                                                   form 
+                                                   type 
+                                                   ehookfn 
+                                                   fhookfcn)))
+                               (1+ |evalhook#|))
+
+                              ;; print out evaluated form
+                              (cond ((and evalhook* 
+                                          (or (eq type 'funcall)
+                                              (not (zerop |evalhook#|))))
+                                     (let ((type nil))
+                                          (print*))
+                                     (terpri)
+                                     )))))
+               ;;return evaluated form
+               form)
+              (t ;  why was this here? (clear-input-buffer)
+                 (continue-evaluation form type fcn-evalhook fcn-funcallhook))))   
+       (t ;  why was this here? (clear-input-buffer)
+          (continue-evaluation form type fcn-evalhook fcn-funcallhook))))
+
+;--- stephelpform 
+;
+; print a summary of the functions of step
+;
+(defun stephelpform nil
+  (patom "<cr> - single step;  n <number> - step <number> times")(terpr)
+  (patom "b - break;  q - quit stepping;  d - call debug;") (terpri)
+  (patom "c - turn off step for deeper levels; e - stop at eval forms only")
+  (terpri)
+  (patom "h,? - print this") (terpr))
+
+;--- funcallhook* 
+;
+; automatically called when a funcall is done and funcallhook*'s 
+; value is the name of this function (funcallhook*).  When this is
+; called, a function with n-1 args is being funcalled, the args
+; to the function are (arg 1) through (arg (sub1 n)), the name of
+; the function is (arg n)
+;
+(defun funcallhook* n
+  (let ((name (arg n))
+       (args (listify (sub1 n))))
+       (funcall-evalhook* (cons name args) 'funcall)))
+
+;--- evalhook* 
+;
+; called whenever an eval is done and evalhook*'s value is the 
+; name of this function (evalhook*).  arg is the thing being
+; evaluated.
+;
+(defun evalhook* (arg)
+  (funcall-evalhook* arg 'eval))
+
+(defun continue-evaluation (form type evalhookfcn funcallhookfcn)
+  (cond ((eq type 'eval) (evalhook form evalhookfcn funcallhookfcn))
+       (t (funcallhook form funcallhookfcn evalhookfcn))))
+
+
+(or (boundp 'prinlength) (setq prinlength nil))
+
+(or (boundp 'prinlevel) (setq prinlevel nil))
+
+; Standard-Input is a variable bound to the initial stdin port. It is 
+; bound in the auxfns0 package, but older lisps may not have that new
+; package, so in case they don't we approximate Standard-Input with nil
+; which works in many cases, but drain's do not work.
+(or (boundp 'Standard-Input) (setq Standard-Input nil))
+(defun clear-input-buffer nil (drain Standard-Input))
diff --git a/usr/src/usr.bin/lisp/lisplib/syntax.l b/usr/src/usr.bin/lisp/lisplib/syntax.l
new file mode 100644 (file)
index 0000000..8047c4e
--- /dev/null
@@ -0,0 +1,165 @@
+(setq rcs-syntax-
+   "$Header: /usr/lib/lisp/syntax.l,v 1.1 83/01/29 18:40:24 jkf Exp $")
+
+;;
+;; syntax.l                            -[Sat Jan 29 18:28:58 1983 by jkf]-
+;;
+;; contains the user callable setsyntax function
+;;
+
+
+;--- setsyntax :: new version of setsyntax
+;  this version allows symbolic syntax codes.
+;
+(declare
+   (special syntax:symbolic-to-old-fixnum ;; for upward compatibility
+                                       ; use this to map from old
+                                       ; fixnums to symbolic names
+           syntax:symbolic-bits-to-fixnum ;; bit definitions of symbolic
+                                          ;bits.  see h/chars.h
+           syntax:code-to-bits         ;; used at runtime to
+                                       ; interpret symbolic names
+           readtable                   ;; current readtable
+   ))
+
+
+(def setsyntax
+   (lexpr (n)
+         (cond ((not (or (equal n 2) (equal n 3)))
+                (error "setsyntax: 2 or 3 args required, not " n)))
+         ; determine the correct code
+         (prog (given ch number)
+            (setq given (arg 2)
+                  ch    (arg 1))
+            (cond ((and (not (numberp ch))
+                        (not (symbolp ch)))
+                   (error "setsyntax: first arg must be a number or symbol: "
+                          ch)))
+            (cond ((numberp given)
+                   ; using the old fixnum values (we suppose)
+                   (cond ((setq number
+                                (rassq given syntax:symbolic-to-old-fixnum))
+                          (setq given (car number))) ; use symbolic name
+                         (t (error "setsyntax: fixnum code is not defined: "
+                                   given)))))
+            (cond ((symbolp given)
+                   ; convert from common names to our symbolic names
+                   (cond ((eq 'macro given)
+                          (setq given 'vmacro))
+                         ((eq 'splicing given)
+                          (setq given 'vsplicing-macro)))
+                   ; now see if the symbolic name is defined
+                   (cond ((setq number (assq given syntax:code-to-bits))
+                          (setq number (cdr number)))
+                         (t (error "setsyntax: unknown symbolic code: "
+                                   given))))
+                  (t (error "setsyntax: second arg not symbol or fixnum: "
+                            given)))
+            ; now call the low level code to set the value.
+            (int:setsyntax (arg 1) number)             ;;; change to *
+            ; the final argument is placed on the property list of the
+            ; first argument, with the indicator being the current readtable,
+            ; thus you can have more than one macro function for each
+            ; character for each readtable.
+            (cond ((equal n 3)
+                   (cond ((numberp ch) (setq ch (ascii ch))))   ; need symbol
+                   (putprop ch (arg 3) readtable))))
+   t))
+            
+
+(def getsyntax
+   (lambda (ch)
+      (let ((res (int:getsyntax ch))   ; this will be modified too
+           (symb))
+        (cond ((setq symb (rassq res syntax:code-to-bits))
+               (car symb))
+              (t (error "getsyntax: no symbolic code corresponds to: "
+                        res))))))
+
+
+;--- add-syntax-class : add a new symbolic syntax class
+; name is the name which we will use to refer to it.
+; bits are a list of symbolic bit names for it.
+; modifies global variable: syntax:code-to-bits
+;
+(def add-syntax-class
+   (lambda (name bits)
+      (cond ((not (symbolp name))
+            (error "add-syntax-class: illegal name: " name)))
+      (cond ((not (dtpr bits))
+            (error "add-syntax-class: illegal bits: " bits)))
+      (do ((xx bits (cdr xx))
+          (this 0)
+          (num 0))
+         ((null xx)
+          (cond ((setq this (assq name syntax:code-to-bits))
+                 (rplacd this num))    ; replace old value
+                (t (setq syntax:code-to-bits (cons (cons name num)
+                                                   syntax:code-to-bits)))))
+         (cond ((setq this (assq (car xx) syntax:symbolic-bits-to-fixnum))
+                ;(format t "num:~d, oth:~a, comb:~d~%"
+                       ; num (cdr this) (apply 'boole `(7 ,num ,(cdr this))))
+                (setq num (boole 7 num (cdr this)))
+                ;(format t "res: ~d~%" num)
+                )   ; logical or
+               (t (error "illegal syntax code " (car xx)))))
+      name))
+
+(setq syntax:symbolic-to-old-fixnum
+       '((vnumber . 0) (vsign . 1) (vcharacter . 2)
+        (vsingle-character-symbol . 66.)
+        (vleft-paren . 195.) (vright-paren . 196.)
+        (vperiod . 133.)
+        (vleft-bracket . 198.) (vright-bracket . 199.) (veof . 200.)
+        (vsingle-quote . 201.) (vsymbol-delimiter . 138.)
+        (vstring-delimiter . 137.)
+        (villegal . 203.) (vseparator . 204.)
+        (vsplicing-macro . 205.) (vmacro . 206.)
+        (vescape . 143.))
+   syntax:symbolic-bits-to-fixnum 
+       '(; character classes
+          (cnumber . 0) (csign . 1) (ccharacter . 2)
+          (cleft-paren . 3)
+          (cright-paren . 4) (cperiod . 5) (cleft-bracket . 6)
+          (cright-bracket . 7)
+          (csingle-quote . 9.) (csymbol-delimiter . 10.) (cillegal . 11.)
+          (cseparator . 12.) (csplicing-macro . 13.)
+          (cmacro . 14.) (cescape . 15.) (csingle-character-symbol . 16.)
+          (cstring-delimiter . 17.)
+          (csingle-macro . 18.) (csingle-splicing-macro . 19.)
+          (cinfix-macro . 20.)
+          (csingle-infix-macro . 21.)
+         ; escape bits
+          (escape-when-unique . 64.)
+          (escape-when-first . 128.)
+          (escape-always . 192.)
+         ; separator
+          (separator . 32.))
+   syntax:code-to-bits nil)
+       
+(add-syntax-class 'vnumber     '(cnumber))
+(add-syntax-class 'vsign       '(csign))
+(add-syntax-class 'vcharacter  '(ccharacter))
+(add-syntax-class 'vleft-paren         '(cleft-paren escape-always separator))
+(add-syntax-class 'vright-paren        '(cright-paren escape-always separator))
+(add-syntax-class 'vperiod     '(cperiod escape-when-unique))
+(add-syntax-class 'vleft-bracket '(cleft-bracket escape-always separator))
+(add-syntax-class 'vright-bracket '(cright-bracket escape-always separator))
+(add-syntax-class 'vsingle-quote '(csingle-quote escape-always separator))
+(add-syntax-class 'vsymbol-delimiter   '(csymbol-delimiter escape-always))
+(add-syntax-class 'villegal    '(cillegal escape-always separator))
+(add-syntax-class 'vseparator  '(cseparator escape-always separator))
+(add-syntax-class 'vsplicing-macro '(csplicing-macro escape-always separator))
+(add-syntax-class 'vmacro      '(cmacro escape-always separator))
+(add-syntax-class 'vescape     '(cescape escape-always))
+(add-syntax-class 'vsingle-character-symbol
+                 '(csingle-character-symbol separator))
+(add-syntax-class 'vstring-delimiter   '(cstring-delimiter escape-always))
+(add-syntax-class 'vsingle-macro '(csingle-macro escape-when-unique))
+(add-syntax-class 'vsingle-splicing-macro
+                '(csingle-splicing-macro escape-when-unique))
+(add-syntax-class 'vinfix-macro '(cinfix-macro escape-always separator))
+(add-syntax-class 'vsingle-infix-macro
+                  '(csingle-infix-macro escape-when-unique))
+
+
diff --git a/usr/src/usr.bin/lisp/lisplib/syscall.l b/usr/src/usr.bin/lisp/lisplib/syscall.l
new file mode 100644 (file)
index 0000000..131591b
--- /dev/null
@@ -0,0 +1,103 @@
+(setq rcs-syscall-
+   "$Header: /usr/lib/lisp/RCS/syscall.l,v 1.2 83/01/30 11:52:43 jkf Exp $")
+
+;
+;   syscall
+;
+; This file contains macro definitions of some of the Unix system calls.
+; The documentation for these system calls can be found in the Unix
+; manual.
+;
+; It is believed that all of these system calls can be executed by the
+; Unix emulator Eunice under VMS.
+;
+; Unix system calls which return values in registers other than r0 cannot
+; be called in this way.  An example of this is fork, for which there is
+; a seperate lisp function.
+
+(declare (macros t))
+
+(defmacro sys_access (name mode)
+  `(syscall 33 ,name ,mode))
+
+(defmacro sys_alarm (secs)
+  `(syscall 27 ,secs))
+
+(defmacro sys_brk (addr)
+  `(syscall 17 ,addr))
+
+(defmacro sys_chdir (dir)
+  `(syscall 12 ,dir))
+
+(defmacro sys_chmod (name mode)
+  `(syscall 15 ,name ,mode))
+
+(defmacro sys_chown (name ownerid groupid)
+  `(syscall 16 name ownerid groupid))
+
+(defmacro sys_close (filedes)
+  `(syscall 6 ,filedes))
+
+(defmacro sys_creat (name mode)
+  `(syscall 8 ,name ,mode))
+
+(defmacro sys_exit (status)
+  `(syscall 1 ,status))
+
+(defmacro sys_getpid nil
+  `(syscall 20))
+
+(defmacro sys_getuid nil
+  `(syscall 24))
+
+(defmacro sys_getgid nil
+  `(syscall 47))
+
+; sys_kill - need to get value into r0
+(defmacro sys_kill (pid)
+  `(syscall 37 ,pid))
+
+
+(defmacro sys_link (name newname)
+  `(syscall 9 ,name ,newname))
+
+(defmacro sys_nice (value)
+  `(syscall 34 ,value))
+
+; sys_lseek this may not be correct the explanation is given for a pdp-11
+; where certain values must be stored in two words.
+; also need to get value into r0
+
+(defmacro sys_open (name how)  
+  `(syscall 5 ,name ,how))
+
+(defmacro sys_pause nil
+  `(syscall 29))
+
+(defmacro sys_setuid (uid)
+  `(syscall 23 ,uid))
+
+
+(defmacro sys_setgid (gid)
+  `(syscall 46 ,gid))
+
+(defmacro sys_sync nil
+  `(syscall 36))
+
+(defmacro sys_time nil
+  `(syscall 13))
+
+(defmacro sys_umask (complementmode)
+  `(syscall 60 ,complementmode))
+
+(defmacro sys_unlink (name)
+  `(syscall 10 ,name))
+
+(defmacro sys_wait nil
+  `(syscall 7))
+
+(defmacro sys_ioctl (portnumber arg)
+  `(syscall 54 ,portnumber ,arg))
+
+
+(putprop 'syscall t 'version)  ; flag that this file has been loaded
diff --git a/usr/src/usr.bin/lisp/lisplib/ucifnc.l b/usr/src/usr.bin/lisp/lisplib/ucifnc.l
new file mode 100644 (file)
index 0000000..61edc4a
--- /dev/null
@@ -0,0 +1,603 @@
+(setq rcs-ucifnc-
+   "$Header: /usr/lib/lisp/ucifnc.l,v 1.1 83/01/29 18:41:16 jkf Exp $")
+
+;
+; There is problems with the ucilisp do being
+;      incompatible with maclisp/franz do,
+;      The problems with compiling do are gone, but
+;      due to these possible problems, the ucilisp do function
+;      is in a seperate file ucido.l and users of it
+;      should also load that file in at compile time before
+;      any call to do (since do is a macro) (and
+;      at runtime if do is to be interpreted).
+;
+; This file is meant to be fasl'd or used with liszt -u
+;      not to be read in interpretively (the syntax changes
+;      will not work in that case.
+;
+;      to compile this file do liszt ucifnc.l
+;
+;      one who wants to use these functions or compile and run
+;      a ucilisp program should do both
+;      liszt -u file.l         when compiling.
+;      and
+;      (fasl '/usr/lib/lisp/ucifnc)
+;              before loading in and running them
+;              programs in lisp.
+;      This is because some functions are macros and others are too
+;              complicated and need other functions around.
+;      Note this file will not load in directly and when fasl'd in will
+;              cause the syntax of lisp to change to ucilisp syntax.
+;
+(declare (macros t))
+
+;
+; ucilisp (de df dm) declare function macros.
+;
+; (de name args body) -> declare exprs and lexprs.
+;
+(defun de macro (l) 
+  `(defun ,@(cdr l)))
+  
+;
+; (df name args body) -> declare fexprs.
+;
+(defun df macro (l) 
+  `(defun ,(cadr l)
+         fexpr
+         ,@(cddr l)))
+
+;
+; macro's are not compiled except under the same
+;      conditions as in franz lisp.
+;      (usually just do (declare (macros t))
+;              to have macros also compiled).
+;
+;
+; (dm name args body) -> declare macros. same as (defun name 'macro body)
+;
+(defun dm macro (l) 
+  `(defun ,(cadr l)
+         macro
+         ,@(cddr l)))
+  
+;
+; ucilisp let macro.
+;
+(eval-when (compile load eval)
+  (defun let1 (l vars vals body)
+        (cond ((null l) 
+               (cons (cons 'lambda (cons vars body)) vals))
+              (t 
+               (let1 (cddr l) 
+                     (cons (car l) vars) 
+                     (cons (cadr l) vals) body)))))
+  
+(defun let macro (l)
+  (let1 (cadr l) nil nil (cddr l)))
+  
+(defun nconc1 macro (l) 
+  `(nconc ,(cadr l) (list ,(caddr l))))
+  
+(putd 'expandmacro (getd 'macroexpand))
+  
+;
+; ucilisp selectq function. (written by jkf)
+;
+(def selectq
+  (macro (form)
+        ((lambda (x)
+                 `((lambda (,x)
+                           (cond 
+                            ,@(maplist 
+                               '(lambda (ff)
+                                        (cond ((null (cdr ff))
+                                               `(t  ,(car ff)))
+                                              ((atom (caar ff))
+                                               `((eq ,x ',(caar ff))
+                                                 . ,(cdar ff)))
+                                              (t
+                                               `((memq ,x ',(caar ff))
+                                                 . ,(cdar ff)))))
+                               (cddr form))))
+                   ,(cadr form)))
+         (gensym 'Z))))
+
+;
+; ucilisp functions which declare read macros.
+;
+; dsm - declare splicing read macro.
+;
+(defun dsm macro (l) 
+  `(eval-when (compile load eval)
+             (setsyntax ',(cadr l) 'splicing ',(caddr l))))
+
+;
+; drm - declare read macro.
+;
+(defun drm macro (l) 
+  `(eval-when (compile load eval)
+             (setsyntax ',(cadr l) 'macro ',(caddr l))))
+
+;
+;(:= a b) -> ucilisp assignment macro.
+;
+(defun := macro (expression)
+      (let (lft (macroexpand (cadr expression)) rgt (caddr expression))
+          (cond ((atom lft) 
+                 `(setq ,lft ,(subst lft '*-* rgt)))
+                ((get (car lft) 'set-program)
+                 (cons (get (car lft) 'set-program)
+                       (append (cdr lft) (list (subst lft '*-* rgt))))))))
+  
+(defprop car rplaca set-program)
+(defprop cdr rplacd set-program)
+(defprop cadr rplacad set-program)
+(defprop cddr rplacdd set-program)
+(defprop caddr rplacadd set-program)
+(defprop cadddr rplacaddd set-program)
+(defprop get get-set-program set-program)
+
+(defun get-set-program (atm prop val) 
+  (putprop atm val prop))
+
+(defun rplacad (exp1 exp2) 
+  (rplaca (cdr exp1) exp2))
+
+(defun rplacdd (exp1 exp2) 
+  (rplacd (cdr exp1) exp2))
+
+(defun rplacadd (exp1 exp2) 
+  (rplaca (cddr exp1) exp2))
+
+(defun rplacaddd (exp1 exp2) 
+  (rplaca (cdddr exp1) exp2))
+
+;
+; ucilisp record-type package to declare records and field extraction
+;      macros.
+;
+
+(declare (special *type*))
+
+(defun record-type macro (l)
+  (let (*type* (cadr l) *flag* (caddr l) slots (car (last l)))
+       `(progn 'compile
+              (defun ,*type*
+                     ,(slot-funs-extract slots (and *flag* '(d)))
+                     ,(cond ((null *flag*) (struc-cons-form slots))
+                            (t (append `(cons ',*flag*)
+                                       (list (struc-cons-form slots))))))
+              ,(cond (*flag*
+                      (cond ((dtpr *flag*) (setq *flag* *type*)))
+                      `(defun ,(concat 'is- *type*)
+                              macro
+                              (l)
+                              (list 'and (list 'dtpr (cadr l))
+                                    (list 'eq (list 'car (cadr l))
+                                          '',*flag*))))))))
+  
+(defun slot-funs-extract (slots path)
+  (cond ((null slots) nil)
+       ((atom slots)
+        (eval `(defun ,(concat slots ': *type*)
+                      macro
+                      (l)
+                      (list ',(readlist `(c ,@path r))
+                            (cadr l))))
+        (list slots))
+       ((nconc (slot-funs-extract (car slots) (cons 'a path))
+               (slot-funs-extract (cdr slots) (cons 'd path))))))
+  
+(defun struc-cons-form (struc)
+  (cond ((null struc) nil)
+       ((atom struc) struc)
+       (t `(cons ,(struc-cons-form (car struc))
+                 ,(struc-cons-form (cdr struc))))))
+
+(defun some macro (l)
+  `((lambda (f a)
+           (prog ()
+                 loop
+                 (cond ((null a) (return nil))
+                       ((funcall f (car a))
+                        (return a))
+                       (t (setq a (cdr a))
+                          (go loop)))))
+    ,(cadr l)
+    ,(caddr l)))
+
+(declare (special vars))
+  
+(defun for macro (*l*)
+  (let (vars (vars:for *l*)
+            args (args:for *l*)
+            test (test:for *l*)
+            type (type:for *l*)
+            body (body:for *l*))
+       (cons (make-mapfn vars test type body)
+            (cons (list 'quote
+                        (make-lambda 
+                         vars (add-test test
+                                        (make-body vars test type body))))
+                  args))))
+  
+(defun type:for (*l*)
+  (let (item (item:for '(do save splice filter) *l*))
+       (cond (item (car item))
+            ((error '"No body in for loop")))))
+  
+(defun error (l &optional x)
+  (cond (x (terpri) (patom l) (terpri) (drain) (break) l)
+       (t l)))
+  
+(defun vars:for (*m*)
+  (mapcan '(lambda (x) (cond ((is-var-form x) (list (var:var-form x))))) *m*))
+
+(defun args:for (*n*)
+  (mapcan '(lambda (x) 
+                  (cond ((is-var-form x) (list (args:var-form x)))))
+         *n*))
+
+(defun is-var-form (x) (and (eq (length x) 3) (eq (cadr x) 'in)))
+  
+(defun var:var-form (x) (car x))
+(defun args:var-form (x) (caddr x))
+  
+(defun test:for (*o*)
+  (let (item (item:for '(when) *o*))
+       (cond (item (cadr item)))))
+  
+(defun body:for (*p*)
+  (let (item (item:for '(do save splice filter) *p*))
+       (cond ((not item) (error '"NO body in for loop"))
+            ((eq (length (cdr item)) 1) (cadr item))
+            ((cons 'progn (cdr item))))))
+
+(declare (special *l* item))
+
+(defun item:for (keywords *l*)
+  (let (item nil)
+       (some '(lambda (key) (setq item (assoc key (cdr *l*))))
+            keywords)
+       item))
+
+(defun make-mapfn (vars test type body)
+  (cond ((equal type 'do) 'mapc)
+       ((not (equal type 'save)) 'mapcan)
+       ((null test) 'mapcar)
+       ((subset-test vars body) 'subset)
+       ('mapcan)))
+  
+(defun subset-test (vars body)
+  (and (equal (length vars) 1) (equal (car vars) body)))
+  
+(defun make-body (vars test type body)
+  (cond ((equal type 'filter)
+        (list 'let (list 'x body) '(cond (x (list x)))))
+       ((or (not (equal type 'save)) (null test)) body)
+       ((subset-test vars body) nil)
+       ((list 'list body))))
+  
+(defun add-test (test body)
+  (cond ((null test) body)
+       ((null body) test)
+       (t (list 'cond (cond ((eq (car body) 'progn) (cons test (cdr body)))
+                            ((list test body)))))))
+  
+(defun make-lambda (var body)
+  (cond ((equal var (cdr body)) (car body))
+       ((eq (car body) 'progn) (cons 'lambda (cons vars (cdr body))))
+       ((list 'lambda vars body))))
+  
+(defun pop macro (q)
+  `(prog (*q*)
+        (setq *q* (car ,(cadr q)))
+        (setq ,(cadr q) (cdr ,(cadr q)))
+        (return *q*)))
+  
+(defun length (*u*)
+  (cond ((null *u*) 0)
+       ((atom *u*) 0)
+       ((add1 (length (cdr *u*))))))
+  
+(declare (special l))
+  
+(defun every macro (l)
+  `(prog ($$k $v)
+        (setq $$k ,(caddr l))
+        loop
+        (cond ((null $$k)
+               (return t))
+              ((apply ,(cadr l) (list (car $$k)))
+               (setq $$k (cdr $$k))
+               (go loop)))
+        (return nil)))
+
+(defun timer fexpr (request)
+  (prog (timein timeout result cpu garbage)
+       (setq timein (ptime))
+       (prog ()
+             loop (setq result (eval (car request)))
+             (setq request (cdr request))
+             (cond ((null request) (return result))
+                   ((go loop))))
+       (setq timeout (ptime))
+       (setq cpu (quotient (times 1000.0
+                                  (quotient (difference (car timeout) 
+                                                        (car timein))
+                                            60.0))
+                           1000.0))
+       (setq garbage (quotient (times 1000.0
+                                      (quotient (difference (cadr timeout) 
+                                                            (cadr timein)) 
+                                                60.0))
+                               1000.0))
+       (print (cons cpu garbage))
+       (terpri)
+       (return result)))
+  
+(defun addprop (id value prop)
+  (putprop id (enter value (get id prop)) prop))
+  
+(defun enter (v l)
+  (cond ((member v l) l)
+       (t (cons v l))))
+  
+(defmacro subset (fun lis)
+  `(mapcan '(lambda (ele)
+                   (cond ((funcall ,fun ele) (ncons ele))))
+          ,lis))
+  
+(defun push macro (varval)
+  `(setq ,(cadr varval)
+        (cons ,(caddr varval)
+              ,(cadr varval))))
+  
+(putd 'consp (getd 'dtpr))
+  
+(defun prelist (a b)
+  (cond ((null a) nil)
+       ((eq b 0) nil)
+       ((cons (car a) (prelist (cdr a) (sub1 b))))))
+  
+(defun suflist (a b)
+  (cond ((null a) nil)
+       ((eq b 0) a)
+       ((suflist (cdr a) (sub1 b)))))
+  
+(defun loop macro (l)
+  `(prog ,(var-list (get-keyword 'initial l))
+        ,@(subset (function caddr)
+                  (setq-steps (get-keyword 'initial l)))
+        loop
+        ,@(apply (function append) (mapcar (function do-clause) (cdr l)))
+        (go loop)
+        exit
+        (return ,@(get-keyword 'result l))))
+  
+(defun do-clause (clause)
+  (cond ((memq (car clause) '(initial result)) nil)
+       ((eq (car clause) 'while)
+        (list (list 'or (cadr clause) '(go exit))))
+       ((eq (car clause) 'do) (cdr clause))
+       ((eq (car clause) 'next) (setq-steps (cdr clause)))
+       ((eq (car clause) 'until)
+        (list (list 'and (cadr clause) '(go exit))))
+       (t (terpri) (patom '"unknown keyword clause")
+          (patom (car clause))
+          (terpri))))
+  
+(defun get-keyword (key l)
+  (cdr (assoc key (cdr l))))
+  
+(defun var-list (r)
+  (and r (cons (car r) (var-list (cddr r)))))
+  
+(defun setq-steps (s)
+  (and s (cons (list 'setq (car s) (cadr s))
+              (setq-steps (cddr s)))))
+
+(putd 'readch (getd 'readc))
+
+
+;
+; ucilisp msg function. (written by jkf)
+;
+(defmacro msg ( &rest body)
+  `(progn ,@(mapcar 
+            '(lambda (form)
+                     (cond ((eq form t) '(line-feed 1))
+                           ((numberp form)
+                            (cond ((greaterp form 0) 
+                                   `(msg-space ,form))
+                                  (t `(line-feed ,(minus form)))))
+                           ((atom form) `(patom ,form))
+                           ((eq (car form) t) '(patom '/       ))
+                           ((eq (car form) 'e) 
+                            `(patom ,(cadr form)))
+                           (t `(patom ,form))))
+            body)))
+  
+;
+; this must be fixed to not use do.
+;
+(defmacro msg-space (n)
+  (cond ((eq 1 n) '(patom '" "))
+       (t `(do i ,n (sub1 i) (lessp i 1) (patom '/ ))))) 
+
+(defmacro line-feed (n)
+  (cond ((eq 1 n) '(terpr))
+       (t `(do i ,n (sub1 i) (lessp i 1) (terpr)))))
+
+(defmacro prog1 ( first &rest rest &aux (foo (gensym)))
+  `((lambda (,foo) ,@rest ,foo) ,first))
+
+(defun append1 (l x) (append l (list x)))
+
+; compatability functions: functions required by uci lisp but not
+;      present in franz
+;
+; union uses the franz do loop (not the ucilisp one defined in this file).
+;
+
+(def union 
+  (lexpr (n)
+        (do ((res (arg n))
+             (i (sub1 n) (sub1 i)))
+            ((zerop i) res)
+            (mapc '(lambda (arg)
+                           (cond ((not (member arg res)) 
+                                  (setq res (cons arg res)))))
+                  (arg i)))))
+
+
+(putd 'newsym (getd 'gensym))  ; this is not exactly correct.
+                               ; it only uses the first letter of the arg.
+(putd 'remove (getd 'delete))
+
+; ignore column count
+(def sprint
+  (lambda (form column)
+         ($prpr form)))
+
+(def save  (lambda (f) (putprop f (getd f) 'olddef)))
+
+(def unsave 
+  (lambda (f) 
+         (putd f (get f 'olddef))))
+
+(putd 'atcat (getd 'concat))
+(putd 'consp (getd 'dtpr))
+
+(defun neq macro (x)
+  `(not (eq ,@(cdr x))))
+
+(putd 'gt (getd '>))
+(putd 'lt (getd '<))
+
+(defun le macro (x)
+  `(not (> ,@(cdr x))))
+
+(defun ge macro (x)
+  `(not (< ,@(cdr x))))
+
+(defun litatom macro (x)
+  `(and (atom ,@(cdr x))
+       (not (numberp ,@(cdr x)))))
+
+(putd 'apply\# (getd 'apply))
+
+(defun tconc (ptr x)
+  (cond ((null ptr)
+        (prog (temp)
+              (setq temp (list x))
+              (return (setq ptr (cons temp (last temp))))))
+       ((null (car ptr))
+        (rplaca ptr (list x))
+        (rplacd ptr (last (car ptr)))
+        ptr)
+       (t (prog (temp)
+                (setq temp (cdr ptr))
+                (rplacd (cdr ptr) (list x))
+                (rplacd ptr (cdr temp))
+                (return ptr)))))
+
+;
+;      unbound - (setq x (unbound)) will unbind x.
+; "this [code] is sick" - jkf.
+;
+(defun unbound macro (l)
+  `(fake -4))
+
+;
+;
+;      due to problems with franz do in the compiler, this
+;              has been commented out and is left in a seperate
+;              file called /usr/lib/lisp/ucido.l
+;
+;(defun do macro (l)
+;  ((lambda (dotype alist)
+;         (selectq dotype 
+;                  (while (dowhile (car alist) (cdr alist)))
+;                  (until (dowhile (list 'not (car alist))
+;                                  (cdr alist)))
+;                  (for (dofor (car alist) 
+;                              (cadr alist)
+;                              (caddr alist)
+;                              (cdddr alist)))
+;                  `((lambda ()
+;                            ,@alist))))
+;   (cadr l)
+;   (cddr l)))
+;
+;(defun dowhile (expr alist)
+;  `(prog (returnvar)
+;       loop
+;       (cond (,expr
+;              (setq returnvar ((lambda ()
+;                                       ,@alist)))
+;              (go loop))
+;             (t (return returnvar)))))
+;
+;(defun dofor (var fortype varlist stmlist)
+;  (selectq fortype 
+;         (in `(prog (returnvar l1 l2)
+;                    (setq l2 ',varlist)
+;                    loop
+;                    (setq l1 (car l2))
+;                    (setq l2 (cdr l2))
+;                    (cond ((null l1) 
+;                           (return returnvar)))
+;                    (setq returnvar
+;                          ((lambda (,var)
+;                                   ,@stmlist)
+;                           (l1)))
+;                    (go loop)))
+;         (on `(prog (returnvar l1 l2)
+;                    (setq l2 ',varlist)
+;                    loop
+;                    (cond ((null l2) 
+;                           (return returnvar)))
+;                    (setq returnvar
+;                          ((lambda (,var)
+;                                   ,@stmlist)
+;                           (l2)))
+;                    (setq l2 (cdr l2))
+;                    (go loop)))
+;         (rpt `(prog (returnvar ,var)
+;                     (setq ,var 1)
+;                     loop
+;                     (cond ((not (> ,var ,varlist))
+;                            (setq returnvar ((lambda ()
+;                                                     ,@stmlist)))
+;                            (setq ,var (1+ ,var))
+;                            (go loop))
+;                           (t (return returnvar)))))
+;         nil))
+;
+(putd 'dddd* (getd 'boundp))
+(defun boundp (l)
+  (cond ((arrayp l))
+       ((dddd* l))))
+
+;
+; now change to ucilisp syntax.
+;
+(sstatus uctolc t)
+;
+;      Leave backquote macro in for now.
+;              These characters should be declared as follows for real
+;              ucilisp syntax though.
+;(setsyntax '\` 2)
+;(setsyntax '\, 2)
+;(setsyntax '\@ 201)
+;(setsyntax '\@ 'macro '(lambda () (list 'quote (read))))
+; 
+; ~ as comment character, not ; and / instead of \ for escape
+(setsyntax '\~ 'splicing 'zapline)
+(setsyntax '\; 2)
+(setsyntax '\# 2)
+(setsyntax '\/ 143)
+(setsyntax '\\   2)
+(setsyntax '\! 2)