Annotation of 43BSD/ucb/lisp/lisplib/common1.l, revision 1.1

1.1     ! root        1: (setq rcs-common1-
        !             2:    "$Header: common1.l,v 1.9 84/01/06 14:21:46 sklower Exp $")
        !             3: 
        !             4: ;;
        !             5: ;; common1.l                           -[Sun Sep  4 14:04:15 1983 by jkf]-
        !             6: ;;
        !             7: ;;   common lisp functions.  These are the most common lisp functions
        !             8: ;; [which don't have to be defined in common0.l in order to support 
        !             9: ;;  the macros]
        !            10: ;;
        !            11: 
        !            12: (declare (macros t))           ;; compile macros in this file
        !            13: 
        !            14: ;--- Section 0 - variables
        !            15: (declare (special Standard-Input Standard-Output Standard-Error
        !            16:                  lisp-library-directory))
        !            17: 
        !            18: (or (boundp 'lisp-library-directory)
        !            19:    (setq lisp-library-directory '/usr/lib/lisp))
        !            20: 
        !            21: 
        !            22: ;--- Section 0 - equivalences
        !            23: ; 
        !            24: (defmacro make-equivalent (a b)
        !            25:    `(progn (putd ',a (getd ',b))
        !            26:           (putprop ',a (get ',b 'fcn-info) 'fcn-info)))
        !            27: 
        !            28: (make-equivalent abs absval)
        !            29: (make-equivalent add sum)
        !            30: (make-equivalent bcdcall funcall)
        !            31: (make-equivalent chrct charcnt)
        !            32: (make-equivalent diff difference)
        !            33: (make-equivalent numbp  numberp)
        !            34: (make-equivalent remainder mod)
        !            35: (make-equivalent terpri terpr)
        !            36: (make-equivalent typep type)
        !            37: (make-equivalent symeval eval)
        !            38: (make-equivalent < lessp)
        !            39: (make-equivalent <& lessp)     ; fixnum version
        !            40: (make-equivalent = equal)
        !            41: (make-equivalent =& equal)     ; fixnum version
        !            42: (make-equivalent > greaterp)
        !            43: (make-equivalent >& greaterp)  ; fixnum version
        !            44: (make-equivalent *dif difference)
        !            45: (make-equivalent \\ mod) 
        !            46: (make-equivalent \1+$ add1)
        !            47: (make-equivalent \1-$ sub1)
        !            48: (make-equivalent *$ times)
        !            49: (make-equivalent /$ quotient)
        !            50: (make-equivalent +$ add)
        !            51: (make-equivalent -$ difference)
        !            52: 
        !            53: ;--- Section I - functions and macros
        !            54: 
        !            55: 
        !            56: ;--- max - arg1 arg2 ... : sequence of numbe
        !            57: ;      returns the maximum
        !            58: ;
        !            59: (def max
        !            60:   (lexpr (nargs)
        !            61:         (do ((i nargs (1- i))
        !            62:              (max (arg 1)))
        !            63:             ((< i 2) max)
        !            64:             (cond ((greaterp (arg i) max) (setq max (arg i)))))))
        !            65: 
        !            66: 
        !            67: ;--- catch form [tag]  
        !            68: ;  catch is now a macro which translates to (*catch 'tag form)
        !            69: ;
        !            70: (def catch
        !            71:   (macro (l)
        !            72:         `(*catch ',(caddr l) ,(cadr l))))
        !            73: 
        !            74: ;--- throw form [tag]
        !            75: ;  throw isnow a macro
        !            76: ;
        !            77: (def throw
        !            78:   (macro (l)
        !            79:         `(*throw ',(caddr l) ,(cadr l))))
        !            80: 
        !            81: 
        !            82:       
        !            83: ;--- desetq
        !            84: ;      - pattern - pattern containing vrbl names
        !            85: ;      - expr    - expression to be evaluated
        !            86: ;
        !            87: (defmacro desetq (&rest forms &aux newgen destrs)
        !            88:   (do ((xx forms (cddr xx))
        !            89:        (res)
        !            90:        (patt)
        !            91:        (expr))
        !            92:       ((null xx) (cond ((null (cdr res)) (car res))
        !            93:                       (t (cons 'progn (nreverse res)))))
        !            94:       (setq patt (car xx) expr (cadr xx))
        !            95:       (setq res 
        !            96:            (cons (cond ((atom patt) `(setq ,patt ,expr))       ;trivial case
        !            97:                        (t (setq newgen (gensym)
        !            98:                                 destrs (de-compose patt '(r)))
        !            99:                           `((lambda (,newgen)
        !           100:                                     ,@(mapcar '(lambda (frm)
        !           101:                                                        `(setq  ,(cdr frm) 
        !           102:                                                                (,(car frm) ,newgen)))
        !           103:                                               destrs)
        !           104:                                     ,newgen)
        !           105:                             ,expr)))
        !           106:                  res))))
        !           107: 
        !           108: ;--- sassoc
        !           109: ;      - x : form
        !           110: ;      - y : assoc list
        !           111: ;      - fcn : function or lambda expression
        !           112: ; If (assoc x y) is non nil, then we apply the function fcn to nil.  
        !           113: ; This must be written as a macro if we expect to handle the case of
        !           114: ; a lambda expression as fcn in the compiler.  
        !           115: ;
        !           116: (defmacro sassoc (x y fcn)
        !           117:   (cond ((or (atom fcn) (not (eq 'quote (car fcn))))
        !           118:         `(or (assoc ,x ,y)
        !           119:              (funcall ,fcn)))
        !           120:        (t `(or (assoc ,x ,y)
        !           121:                (,(cadr fcn))))))
        !           122: 
        !           123: ;--- sassq
        !           124: ;      - x : form
        !           125: ;      - y : assoc list
        !           126: ;      - fcn : function or lambda expression
        !           127: ; like sassoc above except it uses assq instead of assoc.
        !           128: ;
        !           129: (defmacro sassq (x y fcn)
        !           130:   (cond ((or (atom fcn) (not (eq 'quote (car fcn))))
        !           131:         `(or (assq ,x ,y)
        !           132:              (funcall ,fcn)))
        !           133:        (t `(or (assq ,x ,y)
        !           134:                (,(cadr fcn))))))
        !           135: 
        !           136:                    
        !           137: 
        !           138: ;--- signp - test - unevaluated atom
        !           139: ;         - value - evaluated value
        !           140: ; test can be l, le, e, n, ge or g   with the obvious meaning
        !           141: ; we return t if value compares to 0 by test
        !           142: 
        !           143: (defmacro signp (tst val)
        !           144:   (setq tst  (cond ((eq 'l tst)  `(minusp signp-arg))
        !           145:                   ((eq 'le tst) `(not (greaterp signp-arg 0)))
        !           146:                   ((eq 'e tst)  `(zerop signp-arg))
        !           147:                   ((eq 'n tst)  `(not (zerop signp-arg)))
        !           148:                   ((eq 'ge tst) `(not (minusp signp-arg)))
        !           149:                   ((eq 'g tst)  `(greaterp signp-arg 0))
        !           150:                   (t (error "bad arg to signp " tst))))
        !           151:   (cond ((atom val) `(and (numberp ,val) ,(subst val 'signp-arg tst)))
        !           152:        (t `((lambda (signp-arg) (and (numberp signp-arg) ,tst))
        !           153:             ,val))))
        !           154: 
        !           155: 
        !           156: 
        !           157: ;--- unwind-protect
        !           158: ;  The form of a call to unwind-protect is
        !           159: ;   (unwind-protect pform
        !           160: ;                  form1 form2 ...)
        !           161: ; and it works as follows:
        !           162: ;  pform is evaluated, if nothing unusual happens, form1 form2 etc are
        !           163: ;      then evaluated and unwind-protect returns the value of pform.
        !           164: ;  if while evaluating pform, a throw or error caught by an errset which
        !           165: ;   would cause control to pass through the unwind-protect, then
        !           166: ;   form1 form2 etc are evaluated and then the error or throw continues.
        !           167: ; Thus, no matter what happens, form1, form2 etc will be evaluated.
        !           168: ;
        !           169: (defmacro unwind-protect (protected &rest conseq &aux (localv (gensym 'G)))
        !           170:   `((lambda (,localv)
        !           171:            (setq ,localv (*catch 'ER%unwind-protect ,protected))
        !           172:            ,@conseq
        !           173:            (cond ((and (dtpr ,localv) (eq 'ER%unwind-protect (car ,localv)))
        !           174:                   (I-throw-err (cdr ,localv)))
        !           175:                  (t ,localv)))
        !           176:     nil))
        !           177: 
        !           178: 
        !           179: ;----Section III -- Interrupt handlers 
        !           180: ; 
        !           181: 
        !           182: (def sys:fpeint-serv
        !           183:    (lambda (x$) (error "Floating Exception ")))
        !           184: 
        !           185: (def sys:int-serv
        !           186:    (lambda (dummy) (patom '"Interrupt:  ") (drain) (break)))
        !           187: 
        !           188: 
        !           189: (signal 8 'sys:fpeint-serv)
        !           190: (signal 2 'sys:int-serv)
        !           191: 
        !           192: 
        !           193: ;---- Section IV - interrupt handlers
        !           194: ;
        !           195: (cond ((null (boundp '$gcprint))
        !           196:        (setq $gcprint nil)))           ; dont print gc stats by default
        !           197: 
        !           198: (cond ((null (boundp '$gccount$))
        !           199:        (setq $gccount$ 0)))
        !           200: 
        !           201: ;--- prtpagesused - [arg] : type of page allocated last time.
        !           202: ;      prints a summary of pages used for certain selected types
        !           203: ;      of pages.  If arg is given we put a star beside that type
        !           204: ;      of page.  This is normally called after a gc.
        !           205: ;
        !           206: (def prtpagesused
        !           207:   (lambda (space tottime gctime)
        !           208:          (patom "[")
        !           209:          (do ((curtypl (cond ((memq space '(list fixnum ))
        !           210:                               '(list fixnum))
        !           211:                              (t (cons space '(list fixnum))))
        !           212:                        (cdr curtypl))
        !           213:               (temp))
        !           214:              ((null curtypl) (print 'ut:)
        !           215:               (print (max 0 (quotient (times 100 (difference tottime gctime))
        !           216:                                       tottime)))
        !           217:               (patom "%]") (terpr))
        !           218:              (setq temp (car curtypl))
        !           219:              (cond ((greaterp (cadr (opval temp)) 0)
        !           220:                     (cond ((eq space temp)
        !           221:                            (patom '*)))
        !           222:                     (patom temp)
        !           223:                     (patom '":")
        !           224:                     (print (cadr (opval temp)))
        !           225:                     (patom '"{")
        !           226:                     (print (fix (quotient 
        !           227:                                  (times 100.0
        !           228:                                         (car (opval temp)))
        !           229:                                  (* (cadr (opval temp))
        !           230:                                         (caddr (opval temp))))))
        !           231:                     (patom '"%}")
        !           232:                     (patom '"; "))))))
        !           233: 
        !           234: (declare (special gcafter-panic-mode $gccount$ $gc_midlim $gc_minalloc 
        !           235:                  $gc_pct $gc_lowlim $gcprint ptimeatlastgc))
        !           236: 
        !           237: (setq gcafter-panic-mode nil)
        !           238: (setq $gc_minalloc 10)
        !           239: (setq $gc_lowlim 60)
        !           240: (setq $gc_midlim 85)
        !           241: (setq $gc_pct    .10)
        !           242: (setq ptimeatlastgc (ptime))
        !           243: 
        !           244: ;--- gcafter - [s] : type of item which ran out forcing garbage collection.
        !           245: ;      This is called after each gc.
        !           246: ; the form of an opval element is  (number_of_items_in_use
        !           247: ;                                  number_of_pages_allocated
        !           248: ;                                  number_of_items_per_page)
        !           249: ;
        !           250: ;
        !           251: (def gcafter 
        !           252:   (nlambda (s)
        !           253:           (prog (x pct amt-to-allocate thisptime diffptime difftottime
        !           254:                    diffgctime)
        !           255:                 (cond ((null s) (return)))  
        !           256:                 (cond ((null (boundp '$gccount$)) (setq $gccount$ 0)))
        !           257:                 (setq $gccount$ (1+ $gccount$))
        !           258:                 (setq x (opval (car s)))
        !           259:                 (setq thisptime (ptime)
        !           260:                       difftottime (max  (difference (car thisptime)
        !           261:                                                     (car ptimeatlastgc))
        !           262:                                         1)
        !           263:                       diffgctime (difference (cadr thisptime)
        !           264:                                              (cadr ptimeatlastgc))
        !           265:                       ptimeatlastgc thisptime)
        !           266:                 ; pct is the percentage of space used
        !           267:                 (setq pct (quotient (times 100 (car x))
        !           268:                                     (max 1 (times (cadr x) (caddr x)))))
        !           269:                 (setq amt-to-allocate
        !           270:                       (cond (gcafter-panic-mode 
        !           271:                              (cond ((greaterp pct 95) 
        !           272:                                     (patom "[Storage space totally exhausted]")
        !           273:                                     (terpr)
        !           274:                                     (error "Space exhausted when allocating "
        !           275:                                            (car s)))
        !           276:                                    (t 0)))
        !           277:                             ((greaterp pct $gc_midlim)
        !           278:                              (max $gc_minalloc (fix (times $gc_pct (cadr x)))))
        !           279:                             ((greaterp pct $gc_lowlim)
        !           280:                              $gc_minalloc)
        !           281:                             ((lessp (cadr x) 100)
        !           282:                              $gc_minalloc)
        !           283:                             (t 0)))
        !           284:                 (cond ((and (null gcafter-panic-mode) (greaterp amt-to-allocate
        !           285:                                                                 0))
        !           286:                        (cond ((atom (errset (allocate (car s) amt-to-allocate)))
        !           287:                               (cond ($gcprint 
        !           288:                                        (patom "[Now in storage allocation panic mode]")
        !           289:                                        (terpr)))
        !           290:                               (setq gcafter-panic-mode t)))))
        !           291: 
        !           292:                 (cond ($gcprint (prtpagesused (car s) difftottime diffgctime)
        !           293:                                 (comment (cond ((and (getd 'gcstat)
        !           294:                                             (eq $gcprint '$all))
        !           295:                                        (print (gcstat))
        !           296:                                        (terpr)))))))))
        !           297: 
        !           298: ;----Section V - the functions
        !           299: ; 
        !           300: 
        !           301: 
        !           302: ;--- bigp - x : lispval
        !           303: ;      returns t if x is a bignum
        !           304: ;
        !           305: (def bigp (lambda (arg) (equal (type arg) 'bignum)))
        !           306: 
        !           307: ;--- comment - any
        !           308: ;      ignores the rest of the things in the list
        !           309: (def comment
        !           310:   (nlambda (x) 'comment))
        !           311: 
        !           312: 
        !           313: ;--- copy - l : list (will work if atom but will have no effect)
        !           314: ;      makes a copy of the list.
        !           315: ; will also copy vector and vectori's, if their property list
        !           316: ; doesn't have the 'unique' flag
        !           317: ;
        !           318: (def copy
        !           319:    (lambda (l)
        !           320:       (cond ((dtpr l) (cons (copy (car l)) (copy (cdr l))))
        !           321:            ((vectorp l)
        !           322:             (if (vget l 'unique)
        !           323:                then l
        !           324:                else (let ((size (vsize l)))
        !           325:                        (do ((newv (new-vector size))
        !           326:                             (i 0 (1+ i)))
        !           327:                            ((not (<& i size))
        !           328:                             (vsetprop newv (copy (vprop l)))
        !           329:                             newv)
        !           330:                            (vset newv i (copy (vref l i)))))))
        !           331:            ((vectorip l)
        !           332:             (if (vget l 'unique)
        !           333:                then l
        !           334:                else (let ((size (vsize-byte l)))
        !           335:                        (do ((newv (new-vectori-byte size))
        !           336:                             (i 0 (1+ i)))
        !           337:                            ((not (<& i size))
        !           338:                             (vsetprop newv (copy (vprop l)))
        !           339:                             newv)
        !           340:                            (vseti-byte newv i (vrefi-byte l i))))))
        !           341:            (t l))))
        !           342: 
        !           343: 
        !           344: ;--- copysymbol - sym : symbol to copy
        !           345: ;              - flag : t or nil
        !           346: ;  generates an uninterned symbol with the same name as sym.  If flag is t
        !           347: ; then the value, function binding and property list of sym are placed
        !           348: ; in the uninterned symbol.
        !           349: ;
        !           350: (def copysymbol 
        !           351:   (lambda (sym flag)
        !           352:          ((lambda (newsym)
        !           353:                   (cond (flag (cond ((boundp sym) (set newsym (eval sym))))
        !           354:                               (putd newsym (getd sym))
        !           355:                               (setplist newsym (plist sym))))
        !           356: 
        !           357:                   newsym)
        !           358:           (uconcat sym))))
        !           359: 
        !           360: 
        !           361: ;--- cvttointlisp -- convert reader syntax to conform to interlisp
        !           362: ;
        !           363: (def cvttointlisp
        !           364:   (lambda nil
        !           365:          (setsyntax '\% 'vescape)              ; escape character
        !           366:          (setsyntax '\\ 'vcharacter)           ; normal character
        !           367:          (setsyntax '\` 'vcharacter)           ; normal character
        !           368:          (setsyntax '\, 'vcharacter)           ; normal character
        !           369:          (sstatus uctolc t)                    ; one case
        !           370:          ))
        !           371: 
        !           372: 
        !           373: ;--- cvttomaclisp - converts the readtable to a maclisp character syntax
        !           374: ;
        !           375: (def cvttomaclisp
        !           376:   (lambda nil
        !           377:          (setsyntax '\/ 'vescape)              ; escape
        !           378:          (setsyntax '\\ 'vcharacter)           ; normal char
        !           379:          (setsyntax '\[ 'vcharacter)           ; normal char
        !           380:          (setsyntax '\] 'vcharacter)           ; normal char
        !           381:          (sstatus uctolc t)))
        !           382: 
        !           383: (declare (special readtable))
        !           384: ;--- cvttoucilisp - converts the readtable to a ucilisp character syntax
        !           385: ;
        !           386: (def cvttoucilisp
        !           387:   (lambda nil
        !           388:          (sstatus uctolc t)            ; upper case to lower case
        !           389:                                        ; change backquote character.
        !           390:                                        ; to ` and ! and !@ from ` , and ,@
        !           391:                                        ; undo comma.
        !           392:        (setsyntax '\! 'splicing (get '\, readtable))
        !           393:        (setsyntax '\, 'vcharacter)
        !           394:                ; 
        !           395:                ; ~ as comment character, not ; and / instead of \ for escape
        !           396:        (setsyntax '\~ 'splicing 'zapline)
        !           397:        (setsyntax '\; 'vcharacter)
        !           398:        (setsyntax '\/ 'vescape)
        !           399:        (setsyntax '\\   'vcharacter)))
        !           400: 
        !           401: 
        !           402: ;--- cvttofranzlisp - converts the readtable to the standard franz readtable
        !           403: ; this just does the obvious conversions, assuming that the user was
        !           404: ; in the maclisp syntax before.
        !           405: (def cvttofranzlisp
        !           406:    (lambda nil
        !           407:       (setsyntax '\/ 'vcharacter)
        !           408:       (setsyntax '\\ 'vescape)
        !           409:       (setsyntax '\[ 'vleft-bracket)
        !           410:       (setsyntax '\] 'vright-bracket)
        !           411:       (sstatus uctolc nil)))
        !           412: 
        !           413: ;--- defprop - like putprop except args are not evaled
        !           414: ;
        !           415: (def defprop 
        !           416:     (nlambda (argl)
        !           417:        (putprop (car argl) (cadr argl) (caddr argl) )))
        !           418: 
        !           419: ;--- delete
        !           420: ;      - val - lispval
        !           421: ;      - lst - list
        !           422: ;      - n   - Optional arg, number of occurances to delete
        !           423: ; removes up to n occurances of val from the top level of lst.
        !           424: ; if n is not given, all occurances will be removed.
        !           425: ;
        !           426: (def delete
        !           427:   (lexpr (nargs)
        !           428:         (prog (val lst cur ret nmb)
        !           429:               (cond ((= nargs 2)
        !           430:                      (setq nmb -1))
        !           431:                     ((= nargs 3) 
        !           432:                      (setq nmb (arg 3)))
        !           433:                     (t (error " wrong number of args to delete "
        !           434:                               (cons 'delete (listify nargs)))))
        !           435:               (setq val (arg 1) lst (arg 2))
        !           436:               (cond ((and (atom lst) (not (null lst)))         
        !           437:                      (error " non-list arg to delete " 
        !           438:                               (cons 'delete (listify nargs)))))
        !           439:               (setq cur (cons nil lst)
        !           440:                     ret cur)
        !           441:           loop
        !           442:               (cond ((or (atom lst) (zerop nmb))
        !           443:                      (return (cdr ret)))
        !           444:                     ((equal val (car lst))
        !           445:                      (rplacd cur (cdr lst))
        !           446:                      (setq nmb (1- nmb)))
        !           447:                     (t (setq cur (cdr cur))))
        !           448:               (setq lst (cdr lst))
        !           449:               (go loop))))
        !           450: 
        !           451: ;--- delq 
        !           452: ;  same as delete except eq is used for testing.
        !           453: ;
        !           454: (def delq
        !           455:   (lexpr (nargs)
        !           456:         (prog (val lst cur ret nmb)
        !           457:               (cond ((= nargs 2)
        !           458:                      (setq nmb -1))
        !           459:                     ((= nargs 3) 
        !           460:                      (setq nmb (arg 3)))
        !           461:                     (t (error " wrong number of args to delq "
        !           462:                               (cons 'delq (listify nargs)))))
        !           463:               (setq val (arg 1) lst (arg 2))
        !           464:               (cond ((and (atom lst) (not (null lst)))         
        !           465:                      (error " non-list arg to delq " 
        !           466:                               (cons 'delq (listify nargs)))))
        !           467:               (setq cur (cons nil lst)
        !           468:                     ret cur)
        !           469:           loop
        !           470:               (cond ((or (atom lst) (zerop nmb))
        !           471:                      (return (cdr ret)))
        !           472:                     ((eq val (car lst))
        !           473:                      (rplacd cur (cdr lst))
        !           474:                      (setq nmb (1- nmb)))
        !           475:                     (t (setq cur (cdr cur))))
        !           476:               (setq lst (cdr lst))
        !           477:               (go loop))))
        !           478: 
        !           479: ;--- evenp : num   -  return 
        !           480: ;
        !           481: ;
        !           482: (def evenp
        !           483:   (lambda (n)
        !           484:          (cond ((not (zerop (boole 4 1 n))) t))))
        !           485: 
        !           486: ;--- ex [name] : unevaluated name of file to edit.
        !           487: ;      the ex editor is forked to edit the given file, if no
        !           488: ;      name is given the previous name is used
        !           489: ;
        !           490: (def ex (nlambda (x) (exvi 'ex x nil)))
        !           491: 
        !           492: (declare (special edit_file))
        !           493: 
        !           494: (def exvi 
        !           495:   (lambda (cmd x doload) 
        !           496:           (prog (handy handyport bigname)
        !           497:                 (cond ((null x) (setq x (list edit_file)))
        !           498:                       (t (setq edit_file (car x))))             
        !           499:                 (setq bigname (concat (car x) ".l"))
        !           500:                 (cond ((setq handyport (car (errset (infile bigname) nil)))
        !           501:                        (close handyport)
        !           502:                        (setq handy bigname))
        !           503:                       (t (setq handy (car x))))
        !           504:                 (setq handy (concat cmd " '+set lisp' " handy))
        !           505:                 (setq handy (list 'process handy))
        !           506:                 (eval handy)
        !           507:                 (cond (doload (load edit_file))))))
        !           508: 
        !           509: ;--- exec - arg1 [arg2 [arg3 ...] ] unevaluated atoms
        !           510: ;      A string of all the args concatenated together seperated by 
        !           511: ;      blanks is forked as a process.
        !           512: ;
        !           513: (def exec
        !           514:  (nlambda (list)
        !           515:      (do ((xx list (cdr xx))
        !           516:          (res "" (concat res " " (car xx))))
        !           517:         ((null xx) (*process res)))))
        !           518: 
        !           519: ;--- exl - [name] : unevaluated name of file to edit and load.
        !           520: ;      If name is not given the last file edited will be used.
        !           521: ;      After the file is edited it will be `load'ed into lisp.
        !           522: ;
        !           523: (def exl (nlambda (x) (exvi 'ex x t)))
        !           524: 
        !           525: ;----- explode functions -------
        !           526: ; These functions, explode , explodec and exploden, implement the 
        !           527: ; maclisp explode functions completely.
        !           528: ; They have a similar structure and are written with efficiency, not
        !           529: ; beauty in mind (and as a result they are quite ugly)
        !           530: ; The basic idea in all of them is to keep a pointer to the last
        !           531: ; thing added to the list, and rplacd the last cons cell of it each time.
        !           532: ;
        !           533: ;--- explode - arg : lispval
        !           534: ;      explode returns a list of characters which print would use to
        !           535: ; print out arg.  Slashification is included.
        !           536: ;
        !           537: (def explode
        !           538:   (lambda (arg)
        !           539:          (cond ((atom arg) (aexplode arg))
        !           540:                ((vectorp arg)
        !           541:                 (aexplode (concat "vector[" (vsize arg) "]")))
        !           542:                ((vectorip arg)
        !           543:                 (aexplode (concat "vectori[" (vsize-byte arg) "]")))
        !           544:                (t (do ((ll (cdr arg) (cdr ll))
        !           545:                        (sofar (setq arg (cons '|(| (explode (car arg)))))
        !           546:                        (xx))
        !           547:                       ((cond ((null ll) (rplacd (last sofar) (ncons '|)| )) 
        !           548:                               t)
        !           549:                              ((atom ll) (rplacd (last sofar)
        !           550:                                                 `(| | |.| | | ,@(explode ll) 
        !           551:                                                     ,@(ncons '|)|)))
        !           552:                               t))
        !           553:                        arg)
        !           554:                       (setq xx (last sofar)
        !           555:                             sofar (cons '| | (explode (car ll))))
        !           556:                       (rplacd xx sofar))))))
        !           557: 
        !           558: ;--- explodec - arg : lispval
        !           559: ; returns the list of character which would be use to print arg assuming that
        !           560: ; patom were used to print all atoms.
        !           561: ; that is, no slashification would be used.
        !           562: ;
        !           563: (def explodec
        !           564:   (lambda (arg)
        !           565:          (cond ((atom arg) (aexplodec arg))
        !           566:                ((vectorp arg)
        !           567:                 (aexplodec (concat "vector[" (vsize arg) "]")))
        !           568:                ((vectorip arg)
        !           569:                 (aexplodec (concat "vectori[" (vsize-byte arg) "]")))
        !           570:                (t (do ((ll (cdr arg) (cdr ll))
        !           571:                        (sofar (setq arg (cons '|(| (explodec (car arg)))))
        !           572:                        (xx))
        !           573:                       ((cond ((null ll) (rplacd (last sofar) (ncons '|)| )) 
        !           574:                               t)
        !           575:                              ((atom ll) (rplacd (last sofar)
        !           576:                                                 `(| | |.| | | ,@(explodec ll) 
        !           577:                                                     ,@(ncons '|)|)))
        !           578:                               t))
        !           579:                        arg)
        !           580:                       (setq xx (last sofar)
        !           581:                             sofar (cons '| | (explodec (car ll))))
        !           582:                       (rplacd xx sofar))))))
        !           583: 
        !           584: ;--- exploden - arg : lispval
        !           585: ;      returns a list just like explodec, except we return fixnums instead
        !           586: ; of characters.
        !           587: ;
        !           588: (def exploden
        !           589:   (lambda (arg)
        !           590:          (cond ((atom arg) (aexploden arg))
        !           591:                ((vectorp arg)
        !           592:                 (aexploden (concat "vector[" (vsize arg) "]")))
        !           593:                ((vectorip arg)
        !           594:                 (aexploden (concat "vectori[" (vsize-byte arg) "]")))
        !           595:                (t (do ((ll (cdr arg) (cdr ll))
        !           596:                        (sofar (setq arg (cons 40. (exploden (car arg)))))
        !           597:                        (xx))
        !           598:                       ((cond ((null ll) (rplacd (last sofar) (ncons 41.)) 
        !           599:                               t)
        !           600:                              ((atom ll) (rplacd (last sofar)
        !           601:                                                 `(32. 46. 32. ,@(exploden ll) 
        !           602:                                                     ,@(ncons 41.)))
        !           603:                               t))
        !           604:                        arg)
        !           605:                       (setq xx (last sofar)
        !           606:                             sofar (cons 32. (exploden (car ll))))
        !           607:                       (rplacd xx sofar))))))
        !           608: 
        !           609: ;-- expt  - x
        !           610: ;        - y
        !           611: ;
        !           612: ;         y
        !           613: ; returns x
        !           614: ;
        !           615: (defun expt (x y)
        !           616:   (cond ((equal x 1) x)
        !           617:        ((zerop x) x)   ; Maclisp does this 
        !           618:        ((lessp y 0) (quotient 1.0 (expt x (times -1 y))))
        !           619:        ((floatp y) 
        !           620:         (exp (times y (log x)))) ; bomb out for (-3)^4 or (-3)^4.0 or 0^y.
        !           621:        ((bigp y)
        !           622:         (error "expt: Can't compute number to a bignum power" y))
        !           623:        (t ; y is integer, y>= 0
        !           624:           (prog (res)
        !           625:                 (setq res 1)
        !           626:                 loop
        !           627:                 (cond ((equal y 0) (return res))
        !           628:                       ((oddp y)(setq res (times  res x) y (1- y)))
        !           629:                       (t (setq x (times x x) y (/ y 2))))
        !           630:                 (go loop)))))
        !           631: 
        !           632: 
        !           633: 
        !           634: ;--- ffasl :: fasl in a fortran file
        !           635: ;  arg #
        !           636: ;   1  - fnam : file name
        !           637: ;   2  - entry : entry point name
        !           638: ;   3  - fcn  : entry name
        !           639: ;   4   - disc : optional discipline
        !           640: ;   5   - lib  ; optional library specifier
        !           641: ;
        !           642: (defun ffasl (fnam entry fcn &optional (disc 'subroutine) (lib " "))
        !           643:   (cfasl fnam entry fcn disc (concat lib " -lI77 -lF77 -lm")))
        !           644: 
        !           645: 
        !           646: ;
        !           647: ; filepos function (maclisp compatibility)
        !           648: ;
        !           649: (defun filepos n
        !           650:   (cond ((zerop n) nil)
        !           651:        ((onep n)
        !           652:         (fseek (arg 1) 0 1))
        !           653:        ((equal n 2)
        !           654:         (fseek (arg 1) (arg 2) 0))))
        !           655: 
        !           656: ;--- fixp - l : lispval
        !           657: ;      returns t if l is a fixnum or bignum
        !           658: ;
        !           659: (defun fixp (x) (or (equal (type x) 'fixnum)
        !           660:                    (equal (type x) 'bignum)))
        !           661: 
        !           662: 
        !           663: 
        !           664: ;--- flatsize - l : lispval
        !           665: ;           the second arg should be:
        !           666: ;            - n : limit for what we care about
        !           667: ;           but we dont care about this at present, since we have
        !           668: ;           to explode the whole thing anyway.
        !           669: ;      returns the number of characters which print would
        !           670: ;      use to print l
        !           671: ;
        !           672: (defun flatsize n
        !           673:   (length (explode (arg 1))))
        !           674: 
        !           675: 
        !           676: ;--- floatp - l : lispval
        !           677: ;      returns t if l is a flonum
        !           678: ;
        !           679: (defun floatp (x) (equal 'flonum (type x)))
        !           680: 
        !           681: 
        !           682: ;--- getchar,getcharn   - x : atom
        !           683: ;                      - n : fixnum
        !           684: ; returns the n'th character of x's pname (the first corresponds to n=1)
        !           685: ; if n is negative then it counts from the end of the pname
        !           686: ; if n is out of bounds, nil is returned
        !           687: 
        !           688: (def getchar
        !           689:   (lambda (x n)
        !           690:          (concat (substring x n 1))))
        !           691: 
        !           692: 
        !           693: (def getcharn
        !           694:   (lambda (x n)
        !           695:          (substringn x n 0)))
        !           696: 
        !           697: 
        !           698: (def getl 
        !           699:   (lambda (atm lis)
        !           700:          (do ((ll (cond ((atom atm) (plist atm))
        !           701:                         (t (cdr atm)))
        !           702:                   (cddr ll)))
        !           703:              ((null ll) nil)
        !           704:              (cond ((memq (car ll) lis) (return ll))))))
        !           705: 
        !           706: 
        !           707: ;--- help
        !           708: ; retrive selected portions of the Franz Lisp manual.
        !           709: ; There are four types of help offered:
        !           710: ; (help) prints a description of the other three options
        !           711: ; (help tc) prints a table of contents.
        !           712: ; (help n) {where n is a number or b or c} prints the whole chapter.
        !           713: ; (help fcn) prints info on function fcn
        !           714: ;
        !           715: ; An index to the functions is kept in the documentation directory.
        !           716: ; The index has entries like (append ch2.r).  
        !           717: ; When asked to print info on a function, it locates the chapter
        !           718: ; using the index then asks more to locate the definition.
        !           719: ;
        !           720: (declare (localf locatefunction))
        !           721: 
        !           722: (defun help fexpr (lis)
        !           723:   (cond ((null lis) 
        !           724:  (patom "type (help fnc) for info on function fnc")(terpr)
        !           725:  (patom "type (help n) to see chapter n")(terpr)
        !           726:  (patom "type (help tc) for a table of contents")(terpr))
        !           727:        (t (do ((ll lis (cdr ll))
        !           728:                (fcn))
        !           729:               ((null ll))
        !           730:               (cond ((not (atom (setq fcn (car ll))))
        !           731:                      (patom "Bad option to help ")(print fcn)(terpr))
        !           732:                     ((and (stringp fcn) (setq fcn (concat fcn)) nil))
        !           733:                     ((eq fcn 'tc)
        !           734:                      (patom "Table of contents")(terpr)
        !           735:  (patom "1 - intro; 2 - data structure; 3 - arithmetic; 4 - special")(terpr)
        !           736:  (patom "5 - i/o; 6 - system; 7 - reader; 8 - functions; 9 - arrays")(terpr)
        !           737:  (patom "10 - exceptions; 11 - trace package; 12 - Liszt;")(terpr)
        !           738:  (patom "14 - step package; 15 - fixit package") (terpr)
        !           739:  (patom "b - special symbols; c - gc & debugging & top level ")(terpr))
        !           740:                     ((or (and (numberp fcn) (lessp fcn 16) (greaterp fcn -1))
        !           741:                          (memq fcn '(b c)))
        !           742:                      (apply 'process 
        !           743:                         (ncons (concat "/usr/ucb/ul "
        !           744:                                        lisp-library-directory
        !           745:                                        "/manual/ch"
        !           746:                                       fcn ".r | /usr/ucb/more -f" ))))
        !           747:                     ((locatefunction fcn))
        !           748:                     (t (patom "Unknown function: ")(print fcn)(terpr)))))))
        !           749: 
        !           750: (declare (special readtable))
        !           751: 
        !           752: (defun locatefunction (fc)
        !           753:   (let (x inf )
        !           754:        (cond ((null (get 'append 'helplocation)) 
        !           755:              (patom "[Reading help index]")(drain)
        !           756:              (setq inf (infile (concat lisp-library-directory
        !           757:                                        "/manual/helpindex")))
        !           758:              (do ((readtable (makereadtable t))
        !           759:                   (x (read inf) (read inf)))
        !           760:                  ((null x) (close inf) (terpr))
        !           761:                  (cond ((null (cddr x))
        !           762:                         (putprop (car x) (cadr x) 'helplocation))
        !           763:                        (t (putprop (concat (car x) " " (cadr x))
        !           764:                                    (caddr x)
        !           765:                                    'helplocation))))))
        !           766:        (cond ((setq x (get fc 'helplocation))
        !           767:              (apply 'process (ncons (concat "/usr/ucb/ul "
        !           768:                                             lisp-library-directory
        !           769:                                             "/manual/"
        !           770:                                             x 
        !           771:                                             " | /usr/ucb/more -f \"+/(" 
        !           772:                                             fc 
        !           773:                                             "\"")))
        !           774:              t))))
        !           775: 
        !           776: ;
        !           777: ; (hunk 'g_arg1 [...'g_argn])
        !           778: ;
        !           779: ; This function makes a hunk. The hunk is preinitialized to the
        !           780: ; arguments present. The size of the hunk is determined by the
        !           781: ; number of arguments present.
        !           782: ;
        !           783: 
        !           784: (defun hunk n
        !           785:   (prog (size)
        !           786:        (setq size -1)
        !           787:        (cond ((> n 128) (error "hunk: size is too big" n))
        !           788:              ((eq n 1) (setq size 0))
        !           789:              ((eq n 0) (return nil))   ; hunk of zero length
        !           790:              (t (setq size (1- (haulong (1- n))))))
        !           791:        (setq size (*makhunk size))
        !           792:        (do
        !           793:         ((argnum 0 (1+ argnum)))
        !           794:         ((eq argnum n))
        !           795:         (*rplacx argnum size (arg (1+ argnum))))
        !           796:        (return size)))
        !           797: 
        !           798: 
        !           799: ;--- last - l : list
        !           800: ;      returns the last cons cell of the list, NOT the last element
        !           801: ;
        !           802: (def last 
        !           803:   (lambda (a)
        !           804:          (do ((ll a (cdr ll)))
        !           805:              ((null (cdr ll))  ll))))
        !           806: 
        !           807: ;---- load 
        !           808: ; load will either load (read-eval)  or fasl in the file.
        !           809: ; it is affected by these global flags
        !           810: ;  tilde-expansion :: expand filenames preceeded by ~ just like
        !           811: ;      csh does (we do the expansion here so each i/o function we call
        !           812: ;      doesn't have to do it).
        !           813: ;  load-most-recent :: if there is a choice between a .o and a .l file,
        !           814: ;      load the youngest one
        !           815: ;
        !           816: (declare (localf load-a-file))
        !           817: (declare (special gcdisable load-most-recent tilde-expansion))
        !           818: 
        !           819: (or (boundp 'load-most-recent) (setq load-most-recent nil))
        !           820: (or (boundp 'tilde-expansion) (setq tilde-expansion t))
        !           821: 
        !           822: (defun load (filename &rest fasl-args)
        !           823:   (cond ((not (or (symbolp filename) (stringp filename))) 
        !           824:         (error "load: illegal filename " filename)))
        !           825:   (let ( load-only fasl-only no-ext len search-path name pred shortname explf
        !           826:         faslfile loadfile)
        !           827: 
        !           828:        
        !           829:        (cond (tilde-expansion (setq filename (tilde-expand filename))))
        !           830:                
        !           831:        ; determine the length of the filename, ignoring the possible
        !           832:        ; list of directories.  set explf to the reversed exploded filename
        !           833:        (setq len (do ((xx (setq explf (nreverse (exploden filename))) (cdr xx))
        !           834:                      (i 0 (1+ i)))
        !           835:                     ((null xx) i)
        !           836:                     (cond ((eq #// (car xx)) (return i)))))
        !           837: 
        !           838:        (cond ((> len 2)
        !           839:              (cond ((eq (cadr explf) #/.)
        !           840:                     (cond ((eq (car explf) #/o)
        !           841:                            (setq fasl-only t))
        !           842:                           ((eq (car explf) #/l)
        !           843:                            (setq load-only t))
        !           844:                           (t (setq no-ext t))))
        !           845:                    (t (setq no-ext t))))
        !           846:             (t (setq no-ext t)))
        !           847: 
        !           848:        ; a short name is less or equal 12 characters.  If a name is not
        !           849:        ; short, then load will not try to append .l or .o
        !           850:        (cond ((or (< len 13) (status feature long-filenames))
        !           851:              (setq shortname t)))
        !           852: 
        !           853:        (cond ((and (> len 0) (eq (getchar filename 1) '/))
        !           854:              (setq search-path '(||)))
        !           855:             (t (setq search-path (status load-search-path))))
        !           856:        (do ((xx search-path (cdr xx)))
        !           857:           ((null xx) (error "load: file not found " filename))
        !           858:           (setq pred (cond ((memq (car xx) '(|| |.|)) '||)
        !           859:                            (t (concat (car xx) "/"))))
        !           860:           (cond (no-ext
        !           861:                  (cond ((and shortname
        !           862:                              load-most-recent
        !           863:                              (probef
        !           864:                                 (setq faslfile (concat pred filename ".o")))
        !           865:                              (probef
        !           866:                                 (setq loadfile (concat pred filename ".l"))))
        !           867:                         ; both an object and a source file exist.
        !           868:                         ; load the last modified one (fasl wins in ties)
        !           869:                         (let ((faslstat (filestat faslfile))
        !           870:                               (loadstat (filestat loadfile)))
        !           871:                            (cond ((< (filestat:mtime faslstat)
        !           872:                                      (filestat:mtime loadstat))
        !           873:                                   (return (load-a-file loadfile)))
        !           874:                                  (t (return
        !           875:                                        (fasl-a-file faslfile
        !           876:                                                     (car fasl-args)
        !           877:                                                     (cadr fasl-args)))))))
        !           878:                        ((and shortname
        !           879:                              (probef (setq name
        !           880:                                            (concat pred filename ".o"))))
        !           881:                         (return (fasl-a-file name (car fasl-args)
        !           882:                                              (cadr fasl-args))))
        !           883:                        ((and shortname
        !           884:                              (probef (setq name
        !           885:                                            (concat pred filename ".l"))))
        !           886:                         (return (load-a-file name)))
        !           887:                        ((probef (setq name (concat pred filename)))
        !           888:                         (cond (fasl-args (return
        !           889:                                             (fasl-a-file name
        !           890:                                                          (car fasl-args)
        !           891:                                                          (cadr fasl-args))))
        !           892:                               (t (return (load-a-file name)))))))
        !           893:                 (fasl-only
        !           894:                  (cond ((probef (setq name (concat  pred  filename)))
        !           895:                         (return (fasl-a-file name (car fasl-args)
        !           896:                                              (cadr fasl-args))))))
        !           897:                 (load-only
        !           898:                  (cond ((probef (setq name (concat pred filename)))
        !           899:                         (return (load-a-file name)))))))))
        !           900: 
        !           901: ;--- tilde-expand :: given a ~filename, expand it
        !           902: ;
        !           903: (defun tilde-expand (name)
        !           904:    (cond ((or (symbolp name) (stringp name))
        !           905:          (cond ((eq (getcharn name 1) #/~)
        !           906:                 (let ((form (exploden name)))
        !           907:                    (do ((xx (cdr form) (cdr xx))
        !           908:                         (res)
        !           909:                         (val))
        !           910:                        ((or (null xx) (eq (car xx) #//))
        !           911:                         ;; if this is the current user, just get value
        !           912:                         ;; from environment variable HOME
        !           913:                         (cond ((or (null res)
        !           914:                                    (equal (setq res (implode (nreverse res)))
        !           915:                                           (getenv 'USER)))
        !           916:                                (setq val (getenv 'HOME)))
        !           917:                               (t (setq val (username-to-dir res))))
        !           918:                         (cond ((null val)
        !           919:                                (error "tilde-expand: unknown user " res))
        !           920:                               (t (concat val (implode xx)))))
        !           921:                        (setq res (cons (car xx) res)))))
        !           922:                (t name)))
        !           923:         (t (error "tilde-expand: illegal argument " name))))
        !           924: 
        !           925:       
        !           926: 
        !           927: ;--- fasl-a-file
        !           928: ; The arguments are just like those to fasl.  This fasl's a file
        !           929: ; and if the translink's are set, it does the minimum work necessary to rebind
        !           930: ; the links (so that the new functions just fasl'ed in will be used).
        !           931: ; 
        !           932: (defun fasl-a-file (name map warnflag)
        !           933:    (let ((translinkarg (status translink)))
        !           934:       (prog1
        !           935:         (fasl name map warnflag)
        !           936:         (cond ((and translinkarg (setq translinkarg (status translink)))
        !           937:                ; if translink was set before and is still set
        !           938:                (cond ((eq translinkarg t)
        !           939:                       (sstatus translink nil)  ; clear all links
        !           940:                       (sstatus translink t))   ; set to make links
        !           941:                      (t ; must be 'on'
        !           942:                         (sstatus translink on) ; recompute all links
        !           943:                         ))))))) 
        !           944: 
        !           945: (declare (special $ldprint))   ; print message before loading
        !           946: (declare (special prinlevel prinlength))
        !           947: 
        !           948: (defun load-a-file (fname)
        !           949:    (cond ($ldprint (patom "[load ")(patom fname)(patom "]")(terpr)))
        !           950:    (let ((translinkarg (status translink)))
        !           951:       (prog1
        !           952:         (let ((Piport (infile fname))
        !           953:               ; (gcdisable t)  ; too dangerous: removed for now
        !           954:               ; don't gc when loading, it slows things down
        !           955:               (eof (list nil)))
        !           956:            (do ((form (errset (read Piport eof)) (errset (read Piport eof)))
        !           957:                 (lastform "<no form read successfully>"))
        !           958:                ((eq eof (car form)) (close Piport) t)
        !           959:                (cond ((null form)
        !           960:                       (error "load aborted due to read error after form "
        !           961:                              lastform))
        !           962:                      (t (setq lastform (car form))
        !           963:                         (eval (car form))))))
        !           964:         (cond ((and translinkarg (setq translinkarg (status translink)))
        !           965:                ; if translink was set before and is still set
        !           966:                (cond ((eq translinkarg t)
        !           967:                       (sstatus translink nil)  ; clear all links
        !           968:                       (sstatus translink t))   ; set to make links
        !           969:                      (t ; must be 'on'
        !           970:                         (sstatus translink on) ; recompute all links
        !           971:                         )))))))
        !           972: 
        !           973: (funcall 'sstatus (list 'load-search-path (list '|.| lisp-library-directory)))
        !           974: ;--- include - read in the file name given, the name not evaluated
        !           975: ;
        !           976: (def include (nlambda (l) (load (car l))))
        !           977: 
        !           978: ;--- includef - read in the file name given and eval the first arg
        !           979: ;
        !           980: (def includef (lambda (l) (load l)))
        !           981: 
        !           982: 
        !           983: ;--- list-to-bignum
        !           984: ;  convert a list of fixnums to a bignum.
        !           985: ; there is a function bignum-to-list but it is written in C
        !           986: ;
        !           987: ;(author: kls)
        !           988: ;
        !           989: (def list-to-bignum
        !           990:  (lambda (x) (cond (x (scons (car x) (list-to-bignum (cdr x))))
        !           991:                   (t nil))))
        !           992: 
        !           993: 
        !           994: 
        !           995: ;--- macroexpand - form 
        !           996: ;      expands out all macros it can
        !           997: ;
        !           998: (def macroexpand
        !           999:   (lambda (form)
        !          1000:     (prog nil
        !          1001:   top (cond ((atom form) (return form))
        !          1002:            ((atom (car form))
        !          1003:             (return
        !          1004:              (let ((nam (car form)) def disc)
        !          1005:                   (setq def (getd nam))
        !          1006:                   (setq disc (cond ((bcdp def) (getdisc def))
        !          1007:                                    ((arrayp def) 'array)
        !          1008:                                    ((dtpr def) (car def))))
        !          1009:                   (cond ((and (null def)
        !          1010:                               (get nam 'macro-autoload))
        !          1011:                          (setq disc 'macro)))
        !          1012:                   (cond ((memq disc '(array lambda lexpr nil))
        !          1013:                          (cons nam (mapcar 'macroexpand (cdr form))))
        !          1014:                         ((eq disc 'macro)
        !          1015:                          (setq form (apply nam form))
        !          1016:                          (go top))
        !          1017:                         ((eq nam 'prog)
        !          1018:                          (cons nam
        !          1019:                                (cons (cadr form)
        !          1020:                                      (mapcar 'macroexpand (cddr form)))))
        !          1021:                         (t form)))))
        !          1022:            (t (return (cons (macroexpand (car form))
        !          1023:                             (mapcar 'macroexpand (cdr form)))))))))
        !          1024: 
        !          1025: 
        !          1026: 
        !          1027: 
        !          1028: ;
        !          1029: ; (makhunk 'n)
        !          1030: ;
        !          1031: ; This function is similar to hunk, except that:
        !          1032: ;
        !          1033: ; n can be a fixnum, which specifies the length of the hunk.
        !          1034: ;      The hunk is preinitialized to nil's
        !          1035: ; n can be a list which is used to preinitialize the hunk.
        !          1036: ;
        !          1037: (defun makhunk (n)
        !          1038:   (prog (size Hunk)
        !          1039:        (setq size -1)
        !          1040:        (cond ((numberp n)
        !          1041: ;
        !          1042: ; If n is a number then build a nil hunk of the right size
        !          1043: ;
        !          1044:               (cond ((greaterp n 128) (error "makhunk: size is too big" n))
        !          1045:                     ((= n 1) (setq size 0))
        !          1046:                     (t (setq size (1- (haulong (1- n))))))
        !          1047:               (cond ((minusp size) (return nil)))
        !          1048:               (setq Hunk (*makhunk size))
        !          1049:               (do ((i 0 (1+ i)))
        !          1050:                   ((=& i n))
        !          1051:                   (*rplacx i Hunk nil))
        !          1052:               (return Hunk))
        !          1053: ;
        !          1054: ; If it isn't a number, then try hunk on it
        !          1055: ;
        !          1056:              (t (return (apply 'hunk n))))))
        !          1057: 
        !          1058: ;--- member - VAL : lispval
        !          1059: ;          - LIS : list
        !          1060: ;      returns that portion of LIS beginning with the first occurance
        !          1061: ;      of VAL  if  VAL is found at the top level of list LIS.
        !          1062: ;      uses equal for comparisons.
        !          1063: ;
        !          1064: (def member 
        !          1065:   (lambda ($a$ $l$)
        !          1066:          (do ((ll $l$ (cdr ll)))
        !          1067:              ((null ll) nil)
        !          1068:              (cond ((equal $a$ (car ll)) (return ll))))))
        !          1069: 
        !          1070: ;--- memq - arg : (probably a symbol)
        !          1071: ;        - lis : list
        !          1072: ; returns part of lis beginning with arg if arg is in lis
        !          1073: ;      
        !          1074: ; [ defintion moved to top of file to allow backquote macro to work ]
        !          1075: 
        !          1076: ;--- min - arg1 ... numbers 
        !          1077: ;
        !          1078: ;      returns minimum of n numbers. 
        !          1079: ;
        !          1080: 
        !          1081: (def min
        !          1082:   (lexpr (nargs)
        !          1083:         (do ((i nargs (1- i))
        !          1084:              (min (arg 1)))
        !          1085:             ((lessp i 2) min)
        !          1086:             (cond ((lessp (arg i) min) (setq min (arg i)))))))
        !          1087: 
        !          1088: 
        !          1089: ;
        !          1090: (def oddp
        !          1091:   (lambda (n)
        !          1092:          (cond ((not (zerop (boole 1 1 n))) t))))
        !          1093: 
        !          1094: ;--- plusp : x - number
        !          1095: ; returns t iff x is greater than zero
        !          1096: 
        !          1097: (def plusp
        !          1098:   (lambda (x)
        !          1099:          (greaterp x 0)))
        !          1100: 
        !          1101: 
        !          1102: ;--- princ : l - any s-expression
        !          1103: ;          [p] - port to write to
        !          1104: ; prints using patom for atoms (unslashified)
        !          1105: ;
        !          1106: (def princ
        !          1107:   (lexpr (n)
        !          1108:         (prog (port val)
        !          1109:               (cond ((eq n 2) (setq port (arg 2))))
        !          1110:               (cond ((dtpr (setq val (arg 1)))
        !          1111:                      (cond ((and (eq 'quote (car val))
        !          1112:                                  (dtpr (cdr val))
        !          1113:                                  (null (cddr val)))
        !          1114:                             (patom "'" port)
        !          1115:                             (princ (cadr val) port))
        !          1116:                            (t 
        !          1117:                             (patom "(" port)
        !          1118:                             (do ((xx val))
        !          1119:                                 ((null xx) (patom ")" port))
        !          1120:                                 (princ (car xx) port)
        !          1121:                                 (cond ((null (setq xx (cdr xx))))
        !          1122:                                       ((not (dtpr xx))
        !          1123:                                        (patom " . " port)
        !          1124:                                        (princ xx port)
        !          1125:                                        (setq xx nil))
        !          1126:                                       (t (patom " " port)))))))
        !          1127:                     (t (patom val port)))
        !          1128:               (return t))))
        !          1129: 
        !          1130: ;--- prog1 : return the first value computed in a list of forms
        !          1131: ;
        !          1132: (def prog1
        !          1133:   (lexpr (n)
        !          1134:         (arg 1)))
        !          1135: 
        !          1136: ;--- reverse : l - list
        !          1137: ;      returns the list reversed using cons to create new list cells.
        !          1138: ;
        !          1139: (def reverse 
        !          1140:   (lambda (x)
        !          1141:          (cond ((null x) nil)
        !          1142:                (t (do ((cur (cons (car x) nil) 
        !          1143:                             (cons (car res) cur))
        !          1144:                        (res (cdr x) (cdr res)))
        !          1145:                       ((null res) cur))))))
        !          1146: 
        !          1147: 
        !          1148: ;--- shell - invoke a new c shell
        !          1149: ;
        !          1150: (def shell 
        !          1151:   (lambda nil 
        !          1152:          ((lambda (shellname)
        !          1153:                   (cond ((lessp (flatc shellname) 1) (setq shellname 'csh)))
        !          1154:                   (apply 'process (ncons shellname)))
        !          1155:           (getenv 'SHELL))))
        !          1156: 
        !          1157: 
        !          1158: 
        !          1159: ; S L O A D  stuff
        !          1160: ;
        !          1161: (defvar $sldprint t)
        !          1162: (declare (special sload-print))
        !          1163: (setq sload-print nil)
        !          1164: 
        !          1165: (defmacro sl-print (&rest args)
        !          1166:    `(cond ((and sload-print
        !          1167:                (getd sload-print))
        !          1168:           (funcall sload-print . ,args))
        !          1169:          (t (print . ,args))))
        !          1170: 
        !          1171: ;--- sload : fn - file name (must include the .l)
        !          1172: ;      loads in the file printing each result as it is seen
        !          1173: ;
        !          1174: (defun sload (&rest files)
        !          1175:    (mapc '(lambda (fn)
        !          1176:             (prog (por eof argnum result)
        !          1177:                (cond ((setq por (infile fn))
        !          1178:                       (and $sldprint
        !          1179:                            (progn (princ "[sload ")
        !          1180:                                   (princ fn)
        !          1181:                                   (princ "]")
        !          1182:                                   (terpr))))
        !          1183:                      (t (patom "bad file name: ")
        !          1184:                         (patom fn)
        !          1185:                         (terpr)
        !          1186:                         (return nil)))
        !          1187:                (setq eof (gensym))
        !          1188:                (do ((input (read por eof) (read por eof)))
        !          1189:                    ((eq eof input) (close por))
        !          1190:                    (and $sldprint
        !          1191:                         (cond ((and (dtpr input)
        !          1192:                                     (setq argnum
        !          1193:                                           (get (car input) 'sloadprintarg)))
        !          1194:                                (print (nth argnum input)))
        !          1195:                               (t (print input))))
        !          1196:                    (setq result (eval input))
        !          1197:                    (and (eq 'value $sldprint)
        !          1198:                         (progn (princ ": ")
        !          1199:                                (sl-print result)))
        !          1200:                    (and $sldprint
        !          1201:                         (terpr)))
        !          1202:                (return t)))
        !          1203:         files))
        !          1204: 
        !          1205: (defprop def 1 sloadprintarg)
        !          1206: (defprop defun 1 sloadprintarg)
        !          1207: 
        !          1208: (defprop setq 1 sloadprintarg)
        !          1209: (defprop declare 1 sloadprintarg)
        !          1210: 
        !          1211: 
        !          1212: 
        !          1213: 
        !          1214: 
        !          1215: ;---- bubble merge sort 
        !          1216: ; it recursively splits the list to sort until the list is small.  At that
        !          1217: ; point it uses a bubble sort.  Finally the sorted lists are merged.
        !          1218: 
        !          1219: (declare (special sort-function))
        !          1220: 
        !          1221: ;--- sort :: sort a lisp list
        !          1222: ; args: lst - list of items
        !          1223: ;       fcn - function to compare two items.
        !          1224: ; returns: the list with such that for each pair of adjacent elements,
        !          1225: ;         either the elements are equal, or fcn applied to the two 
        !          1226: ;         args returns a non nil value.
        !          1227: ;
        !          1228: (defun sort (lst fcn)
        !          1229:   (setq sort-function (cond (fcn)   ; store function name in global cell
        !          1230:                            (t 'alphalessp)))
        !          1231:   ; (setq sort-compares 0)             ; count number of comparisons
        !          1232:   (sortmerge lst (length lst)))
        !          1233: 
        !          1234: 
        !          1235: ;--- sortmerge :: utility routine to sort
        !          1236: ; args: lst - list of items to sort
        !          1237: ;      nitems - a rough idea of how many items are in the list
        !          1238: ;
        !          1239: ; result - sorted list (see the result of sort above)
        !          1240: ;
        !          1241: (defun sortmerge (lst nitems)
        !          1242:   (prog (tmp tmp2)
        !          1243:        (cond ((greaterp nitems 7)
        !          1244:               ; do a split and merge
        !          1245:               (setq tmp (splitlist lst (setq tmp2 (quotient nitems 2))))
        !          1246:               (return (mergelists (sortmerge (car tmp) tmp2)
        !          1247:                              (sortmerge (cdr tmp) tmp2))))
        !          1248:              (t ; do a bubble sort
        !          1249:                 (do ((l lst (cdr l))
        !          1250:                      (fin))
        !          1251:                     ((null l))
        !          1252:                     (do ((ll lst (cdr ll)))
        !          1253:                         ((eq fin (cdr ll)) (setq fin ll))
        !          1254:                         ;(setq sort-compares (1+ sort-compares))
        !          1255:                         (cond ((not (funcall sort-function (car ll) (cadr ll)))
        !          1256:                                (rplaca ll (prog1 (cadr ll)
        !          1257:                                                 (rplaca (cdr ll)
        !          1258:                                                         (car ll))))))))
        !          1259:                 (return lst)))))
        !          1260: 
        !          1261: ;--- splitlist :: utility routine to split a list
        !          1262: ; args : lst - list to split
        !          1263: ;        spliton - number of items to put in the first list
        !          1264: ;
        !          1265: ; returns: a cons cell whose car is the first part of the list
        !          1266: ;         and whose cdr is the second part.
        !          1267: ;
        !          1268: (defun splitlist (lst spliton)
        !          1269:   (prog (second)
        !          1270:        (do ((i spliton (sub1 i))
        !          1271:             (l lst))
        !          1272:            ((or (null (cdr l)) (zerop i))
        !          1273:             (setq second (cdr l))
        !          1274:             (rplacd l nil))
        !          1275:            (setq l (cdr l)))
        !          1276:        (return (cons lst second))))
        !          1277: 
        !          1278: 
        !          1279: ;--- mergelists ::utility routine to merge two lists based on predicate function
        !          1280: ; args: ls1 - lisp list
        !          1281: ;      ls2 - lisp list
        !          1282: ;      sort-function (global) - compares items of the lists
        !          1283: ;
        !          1284: ; returns: a sorted list containing the elements of the two lists.
        !          1285: ; 
        !          1286: (defun mergelists  (ls1 ls2)
        !          1287:   (prog (result current)
        !          1288:        ; initialize
        !          1289:        (setq current (setq result (cons nil nil)))
        !          1290: loop   (cond ((null ls1)
        !          1291:               (rplacd current ls2)
        !          1292:               (return (cdr result)))
        !          1293:              ((null ls2)
        !          1294:               (rplacd current ls1)
        !          1295:               (return (cdr result)))
        !          1296:              ((funcall sort-function (car ls1) (car ls2))
        !          1297:               ;(setq sort-compares (1+ sort-compares))
        !          1298:               (rplacd current ls1)
        !          1299:               (setq current ls1
        !          1300:                     ls1 (cdr ls1)))
        !          1301:              (t ;(setq sort-compares (1+ sort-compares))
        !          1302:                 (rplacd current ls2)
        !          1303:                 (setq current ls2
        !          1304:                       ls2 (cdr ls2))))
        !          1305:        (go loop)))
        !          1306: 
        !          1307: ;--- end bubble merge sort
        !          1308: (declare (localf exchange2))
        !          1309: 
        !          1310: (defun sortcar (a fun)
        !          1311:    (prog (n)
        !          1312:        (if (null fun) then (setq fun 'alphalessp))
        !          1313:        (cond ((null a) (return nil)) ;no elements
        !          1314:             (t (setq n (length a))
        !          1315:                (do i 1 (1+ i) (greaterp i n) (sortcarhelp a fun))
        !          1316:                (return a)))))
        !          1317: 
        !          1318: (defun sortcarhelp (a fun)
        !          1319:   (cond ((null (cdr a)) a)
        !          1320:         ((funcall fun (caadr a) (caar a))  
        !          1321:         (exchange2 a)
        !          1322:         (sortcarhelp (cdr a) fun))
        !          1323:        (t (sortcarhelp (cdr a) fun))))
        !          1324: 
        !          1325: 
        !          1326: (defun exchange2 (a)
        !          1327:   (prog (temp)
        !          1328:        (setq temp (cadr a))
        !          1329:        (rplaca (cdr a) (car a))
        !          1330:        (rplaca a temp)))
        !          1331: 
        !          1332: ;--- sublis: alst - assoc list ((a . val) (b . val2) ...)
        !          1333: ;           exp  - s-expression
        !          1334: ; for each atom in exp which corresponds to a key in alst, the associated
        !          1335: ; value from alst is substituted.  The substitution is done by adding
        !          1336: ; list cells, no struture mangling is done.  Only the minimum number
        !          1337: ; of list cells will be created.
        !          1338: ;
        !          1339: (def sublis
        !          1340:   (lambda (alst exp)
        !          1341:      (let (tmp)
        !          1342:          (cond ((atom exp) 
        !          1343:                 (cond ((setq tmp (assoc exp alst))
        !          1344:                        (cdr tmp))
        !          1345:                       (t exp)))
        !          1346:                ((setq tmp (sublishelp alst exp))
        !          1347:                 (car tmp))
        !          1348:                (t exp)))))
        !          1349: 
        !          1350: ;--- sublishelp : alst - assoc list
        !          1351: ;                exp  - s-expression
        !          1352: ; this function helps sublis work.  it is different from sublis in that
        !          1353: ; it return nil if no change need be made to exp, or returns a list of
        !          1354: ; one element which is the changed exp.
        !          1355: ;
        !          1356: (def sublishelp
        !          1357:   (lambda (alst exp)
        !          1358:      (let (carp cdrp)
        !          1359:          (cond ((atom exp)
        !          1360:                 (cond ((setq carp (assoc exp alst))
        !          1361:                        (list (cdr carp)))
        !          1362:                       (t nil)))
        !          1363:                (t (setq carp (sublishelp alst (car exp))
        !          1364:                         cdrp (sublishelp alst (cdr exp)))
        !          1365:                   (cond ((not (or carp cdrp)) nil)             ; no change
        !          1366:                         ((and carp (not cdrp))                 ; car change
        !          1367:                          (list (cons (car carp) (cdr exp))))   
        !          1368:                         ((and (not carp) cdrp)                 ; cdr change
        !          1369:                          (list (cons (car exp) (car cdrp))))   
        !          1370:                         (t                                     ; both change 
        !          1371:                          (list (cons (car carp) (car cdrp))))))))))
        !          1372: 
        !          1373: 
        !          1374: ;--- subst : new - sexp
        !          1375: ;           old - sexp
        !          1376: ;           pat - sexp
        !          1377: ; substitutes in patrn all occurrences equal to old with new and returns the
        !          1378: ; result
        !          1379: ; MUST be put in the manual
        !          1380: 
        !          1381: (declare (special new old))
        !          1382: 
        !          1383: (def subst 
        !          1384:   (lambda (new old pat)
        !          1385:          (cond ((symbolp old) (substeq pat))
        !          1386:                (t (substequal pat)))))
        !          1387: 
        !          1388: ;use this function for substituting for symbols
        !          1389: (def substeq
        !          1390:   (lambda (pat)
        !          1391:          (cond ((eq old pat) new)
        !          1392:                ((atom pat) pat)
        !          1393:                (t (cons (substeq (car pat))(substeq (cdr pat)))))))
        !          1394: 
        !          1395: (def substequal
        !          1396:   (lambda (pat)
        !          1397:          (cond ((equal old pat) new)
        !          1398:                ((atom pat) pat)
        !          1399:                (t (cons (substequal (car pat))
        !          1400:                         ; in interlisp, the next line would be
        !          1401:                         ;(substeq (cdr pat))
        !          1402:                         ; for maclisp compatibility, we do this.
        !          1403:                         (substequal (cdr pat)))))))
        !          1404: 
        !          1405: (declare (unspecial new old))
        !          1406: ;--- vi: arg is unevaluated name of function to run vi on
        !          1407: ;
        !          1408: (def vi (nlambda (x) (exvi 'vi x nil)))
        !          1409: 
        !          1410: ;--- vil : arg is unevaluated, edits file and then loads it
        !          1411: ;
        !          1412: (def vil (nlambda (x) (exvi 'vi x t)))
        !          1413: 
        !          1414: ;--- *quo : returns integer part of x/y
        !          1415: ; x and y must be fixnums.
        !          1416: ;
        !          1417: (putd '*quo (getd 'quotient))
        !          1418: 
        !          1419: ;--- xcons : a - sexp
        !          1420: ;           b - sexp
        !          1421: ; returns (b . a)   that is, it is an exchanged cons
        !          1422: ;
        !          1423: (def xcons  (lambda (a b) (cons b a)))
        !          1424: 
        !          1425: 
        !          1426: 
        !          1427: 
        !          1428: 
        !          1429: 
        !          1430: ;--- mode lines, must be last lines of the file
        !          1431: ; vi: set lisp :
        !          1432: ;

unix.superglobalmegacorp.com

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