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

1.1     ! root        1: (setq rcs-lmhacks-
        !             2:    "$Header: lmhacks.l,v 1.2 83/08/15 22:32:31 jkf Exp $")
        !             3: 
        !             4: ;;  This file contains miscellaneous functions and macros that 
        !             5: ;;  ZetaLisp users often find useful
        !             6: 
        !             7: 
        !             8: ;;;  (c) Copyright 1982 Massachusetts Institute of Technology 
        !             9: 
        !            10: ;; This is a simple multiple value scheme based on the one implemented
        !            11: ;; in MACLISP.  It doesn't clean up after its self properly, so if
        !            12: ;; you ask for multiple values, you will get them regardless of whether
        !            13: ;; they are returned.
        !            14: 
        !            15: (environment-maclisp (compile eval) (files struct flavorm))
        !            16: 
        !            17: (declare (macros t))
        !            18: 
        !            19: (defvar si:argn () "Number of arguments returned by last values")
        !            20: (defvar si:arg2 () "Second return value")
        !            21: (defvar si:arg3 () "Third return value")
        !            22: (defvar si:arg4 () "Fourth return value")
        !            23: (defvar si:arg5 () "Fifth return value")
        !            24: (defvar si:arg6 () "Sixth return value")
        !            25: (defvar si:arg7 () "Seventh return value")
        !            26: (defvar si:arg8 () "Eigth return value")
        !            27: (defvar si:arglist () "Additional return values after the eigth")
        !            28: 
        !            29: (defvar si:return-registers
        !            30:   '(si:arg2 si:arg3 si:arg4 si:arg5 si:arg6 si:arg7 si:arg8))
        !            31: 
        !            32: (defmacro values (&rest values)
        !            33:   `(prog2 (setq si:argn ,(length values))
        !            34:          ,(first values)
        !            35:          ,@(do ((vals (cdr values) (cdr vals))
        !            36:                 (regs si:return-registers (cdr regs))
        !            37:                 (forms))
        !            38:                (nil)
        !            39:              (cond ((null vals)
        !            40:                     (return (reverse forms)))
        !            41:                    ((null regs)
        !            42:                     (return
        !            43:                      `(,@(reverse forms)
        !            44:                        (setq si:arglist (list ,@vals)))))
        !            45:                    (t (push `(setq ,(car regs) ,(car vals))
        !            46:                             forms))))))
        !            47: 
        !            48: (defun values-list (list)
        !            49:   (setq si:argn (length list))
        !            50:   (do ((vals (cdr list) (cdr vals))
        !            51:        (regs si:return-registers (cdr regs)))
        !            52:       ((null regs)
        !            53:        (if (not (null vals))
        !            54:           (setq si:arglist vals))
        !            55:        (car list))
        !            56:     (set (car regs) (car vals))))
        !            57: 
        !            58: (defmacro multiple-value (vars form)
        !            59:   `(progn
        !            60:      ,@(if (not (null (car vars)))
        !            61:          `((setq ,(car vars) ,form)
        !            62:            (if (< si:argn 1) (setq ,(car vars) nil)))
        !            63:          `(,form))
        !            64:      ,@(do ((vs (cdr vars) (cdr vs))
        !            65:            (regs si:return-registers (cdr regs))
        !            66:            (i 2 (1+ i))
        !            67:            (forms))
        !            68:           (nil)
        !            69:         (cond ((null vars)
        !            70:                (return (reverse forms)))
        !            71:               ((null regs)
        !            72:                (return
        !            73:                 (do ((vs vs (cdr vs)))
        !            74:                     ((null vs) (nreverse forms))
        !            75:                   (and (not (null (car vs)))
        !            76:                        (push
        !            77:                         `(setq ,(car vs)
        !            78:                                (prog1
        !            79:                                 (if (not (> ,i si:argn))
        !            80:                                     (car si:arglist))
        !            81:                                 (setq si:arglist (cdr si:arglist))))
        !            82:                         forms)))))
        !            83:               ((not (null (car vs)))
        !            84:                (push `(setq ,(car vs) (if (not (> ,i si:argn)) ,(car regs))
        !            85:                             ,(car regs) nil)
        !            86:                      forms))))))
        !            87: 
        !            88: (defmacro multiple-value-bind (vars form &rest body)
        !            89:   `(let ,vars
        !            90:        (multiple-value ,vars ,form)
        !            91:        ,@body))
        !            92: 
        !            93: (defmacro multiple-value-list (form)
        !            94:   `(multiple-value-list-1 ,form))
        !            95: 
        !            96: (defun multiple-value-list-1 (si:arg1)
        !            97:   (cond ((= 0 si:argn) ())
        !            98:        ((= 1 si:argn)
        !            99:         (list si:arg1))
        !           100:        ((= 2 si:argn)
        !           101:         (list si:arg1 si:arg2))
        !           102:        ((= 3 si:argn)
        !           103:         (list si:arg1 si:arg2 si:arg3))
        !           104:        ((= 4 si:argn)
        !           105:         (list si:arg1 si:arg2 si:arg3 si:arg4))
        !           106:        ((= 5 si:argn)
        !           107:         (list si:arg1 si:arg2 si:arg3 si:arg4 si:arg5))
        !           108:        ((= 6 si:argn)
        !           109:         (list si:arg1 si:arg2 si:arg3 si:arg4 si:arg5 si:arg6))
        !           110:        ((= 7 si:argn)
        !           111:         (list si:arg1 si:arg2 si:arg3 si:arg4 si:arg5 si:arg6
        !           112:               si:arg7))
        !           113:        ((= 8 si:argn)
        !           114:         (list si:arg1 si:arg2 si:arg3 si:arg4 si:arg5 si:arg6
        !           115:               si:arg7 si:arg8))
        !           116:        ((> si:argn 8)
        !           117:         (rplacd (nthcdr (- si:argn 9) si:arglist) nil)
        !           118:         (list* si:arg1 si:arg2 si:arg3 si:arg4 si:arg5 si:arg6
        !           119:                si:arg7 si:arg8 si:arglist))
        !           120:        (t (ferror () "Internal error, si:argn = ~D" si:argn))))
        !           121: 
        !           122: (defun union (set &rest others)
        !           123:   (loop for s in others
        !           124:        do (loop for elt in s
        !           125:                 unless (memq elt set)
        !           126:                 do (push elt set))
        !           127:        finally (return set)))
        !           128: 
        !           129: (defun make-list (length &rest options &aux (iv))
        !           130:   (loop for (key val) on options by #'cddr
        !           131:        do (selectq key
        !           132:             (:initial-value
        !           133:                (setq iv val))
        !           134:             (:area)
        !           135:             (otherwise
        !           136:              (error "Illegal parameter to make-list" key))))
        !           137:   (loop for i from 1 to length collect iv))
        !           138: 
        !           139: ;; si:printing-random-object
        !           140: ;; A macro for aiding in the printing of random objects.
        !           141: ;; This macro generates a form which: (by default) includes the virtual 
        !           142: ;; address in the printed representation.
        !           143: ;; Options are :NO-POINTER to suppress the pointer
        !           144: ;;             :TYPEP princs the typep of the object first.
        !           145: 
        !           146: ;; Example:
        !           147: ;; (DEFSELECT ((:PROPERTY HACKER :NAMED-STRUCTURE-INVOKE))
        !           148: ;;   (:PRINT-SELF (HACKER STREAM IGNORE IGNORE)
        !           149: ;;     (SI:PRINTING-RANDOM-OBJECT (HACKER STREAM :TYPEP)
        !           150: ;;       (PRIN1 (HACKER-NAME HACKER) STREAM))))
        !           151: ;; ==> #<HACKER /"MMcM/" 6172536765>
        !           152: 
        !           153: (defmacro si:printing-random-object ((object stream . options) &body body)
        !           154:   (let ((%pointer t)
        !           155:        (typep nil))
        !           156:     (do ((l options (cdr l)))
        !           157:        ((null l))
        !           158:       (selectq (car l)
        !           159:        (:no-pointer (setq %pointer nil))
        !           160:        (:typep (setq typep t))
        !           161:        (:fastp (setq l (cdr l)))               ; for compatibility sake
        !           162:        (otherwise
        !           163:         (ferror nil "~S is an unknown keyword in si:printing-random-object"
        !           164:                 (car l)))))
        !           165:     `(progn
        !           166:        (patom "#<" ,stream)
        !           167:        ,@(and typep
        !           168:              `((patom (:typep ,object) ,stream)))
        !           169:        ,@(and typep body
        !           170:              `((patom " " ,stream)))
        !           171:        ,@body
        !           172:        ,@(and %pointer
        !           173:              `((patom " " ,stream)
        !           174:                (patom (maknum ,object) ,stream)))
        !           175:        (patom ">" ,stream)
        !           176:        ,object)))
        !           177: 
        !           178: (defun named-structure-p (x &aux symbol)
        !           179:   (cond ((or (and (hunkp x) (atom (setq symbol (cxr 0 x))))
        !           180:             (and (vectorp x)
        !           181:                  (setq symbol (or (and (atom (vprop x)) (vprop x))
        !           182:                                   (and (dtpr (vprop x))
        !           183:                                        (atom (car (vprop x)))
        !           184:                                        (car (vprop x)))))))
        !           185:                                  
        !           186:         (if (get symbol 'defstruct-description)
        !           187:             symbol))))
        !           188: 
        !           189: (defun named-structure-symbol (x)
        !           190:   (or (named-structure-p x)
        !           191:       (ferror () "~S was supposed to have been a named structure."
        !           192:              x)))
        !           193: 
        !           194: (declare (localf named-structure-invoke-internal))
        !           195: 
        !           196: (defun named-structure-invoke (operation struct &rest args)
        !           197:   (named-structure-invoke-internal operation struct args t))
        !           198: 
        !           199: (defun named-structure-invoke-carefully (operation struct &rest args)
        !           200:   (named-structure-invoke-internal operation struct args nil))
        !           201: 
        !           202: (defun named-structure-invoke-internal (operation struct args error-p)
        !           203:    (let (symbol fun)
        !           204:       (setq symbol (named-structure-symbol struct))
        !           205:       (if (setq fun (get symbol ':named-structure-invoke))
        !           206:         then (lexpr-funcall fun operation struct args)
        !           207:         else (and error-p
        !           208:                   (ferror ()
        !           209:                           "No named structure invoke function for ~S"
        !           210:                           struct)))))
        !           211: 
        !           212: (defmacro defselect ((function-spec default-handler no-which-operations)
        !           213:                     &rest args)
        !           214:   (let ((name (intern (gensym)))
        !           215:        fun-name)
        !           216:     `(progn 'compile
        !           217:        (defun ,(if (eq (car function-spec) ':property)
        !           218:                   (cdr function-spec)
        !           219:                   (ferror () "Can't interpret ~S defselect function spec"
        !           220:                                  function-spec))
        !           221:              (operation &rest args &aux temp)
        !           222:         (if (setq temp (gethash operation (get ',name 'select-table)))
        !           223:             (lexpr-funcall temp args)
        !           224:             ,(if default-handler
        !           225:                  `(lexpr-funcall ,default-handler operation args)
        !           226:                  `(ferror () "No handler for the ~S method of ~S"
        !           227:                           operation ',function-spec))))
        !           228:        (setf (get ',name 'select-table) (make-hash-table))
        !           229:        ,@(do ((args args (cdr args))
        !           230:             (form)
        !           231:             (forms nil))
        !           232:            ((null args) (nreverse forms))
        !           233:          (setq form (car args))
        !           234:          (cond ((atom (cdr form))
        !           235:                 (setq fun-name (cdr form)))
        !           236:                (t (setq fun-name
        !           237:                         (intern (concat name (if (atom (car form)) (car form)
        !           238:                                                  (caar form)))))
        !           239:                   (push `(defun ,fun-name ,@(cdr form)) forms)))
        !           240:          (if (atom (car form))
        !           241:              (push `(puthash ',(car form) ',fun-name
        !           242:                              (get ',name 'select-table))
        !           243:                    forms)
        !           244:              (mapc #'(lambda (q)
        !           245:                        (push `(puthash ',q ',fun-name
        !           246:                                        (get ',name 'select-table))
        !           247:                              forms))
        !           248:                    (car form))))
        !           249:        ,@(and (not no-which-operations)
        !           250:              `((defun ,(setq fun-name (intern
        !           251:                                        (concat name '-which-operations)))
        !           252:                       (&rest args)
        !           253:                  '(:which-operations ,@(loop for form in args
        !           254:                                              appending (if (atom (car form))
        !           255:                                                            (list (car form))
        !           256:                                                            (car form)))))
        !           257:                (puthash ':which-operations ',fun-name
        !           258:                         (get ',name 'select-table))))
        !           259:        ',function-spec)))
        !           260: 
        !           261: (defun :typep (ob &optional (type nil) &aux temp)
        !           262:   (cond ((instancep ob)
        !           263:         (instance-typep ob type))
        !           264:        ((setq temp (named-structure-p ob))
        !           265:         (if (null type) temp
        !           266:             (if (eq type temp) t
        !           267:                 (memq type (nth 11. (get temp 'defstruct-description))))))
        !           268:        ((hunkp ob)
        !           269:         (if (null type) 'hunk (eq type 'hunk)))
        !           270:        ((null type)
        !           271:         (funcall 'typep ob))
        !           272:        (t (eq type (funcall 'typep ob)))))
        !           273: 
        !           274: (defun send-internal (object message &rest args)
        !           275:   (declare (special .own-flavor. self))
        !           276:   (lexpr-funcall (if (eq self object)
        !           277:                     (or (gethash message
        !           278:                                  (flavor-method-hash-table .own-flavor.))
        !           279:                         (flavor-default-handler .own-flavor.))
        !           280:                     object)
        !           281:                 message args))
        !           282: 
        !           283: ;; New printer
        !           284: 
        !           285: (declare (special poport prinlevel prinlength top-level-print))
        !           286: 
        !           287: (defun zprint (x &optional (stream poport))
        !           288:        (zprin1 x stream)
        !           289:        't)
        !           290: 
        !           291: (defun zprinc (x &optional (stream poport))
        !           292:        (zprin1a x stream () (or prinlevel -1)))
        !           293: 
        !           294: (defun zprin1 (x &optional (stream poport))
        !           295:        (zprin1a x stream 't (or prinlevel -1)))
        !           296: 
        !           297: (defun zprin1a (ob stream slashifyp level &aux temp)
        !           298:   (cond ((null ob) (patom "()" stream))
        !           299:        ((setq temp (named-structure-p ob))
        !           300:         (or (named-structure-invoke-carefully ':print-self ob stream
        !           301:                                                level slashifyp)
        !           302:             (si:printing-random-object (ob stream :typep))))
        !           303:        ((instancep ob)
        !           304:         (if (get-handler-for ob ':print-self)
        !           305:             (send ob ':print-self stream)
        !           306:             (si:printing-random-object (ob stream :typep))))
        !           307:         ((atom ob)
        !           308:         (if slashifyp (xxprint ob stream)
        !           309:             (patom ob stream)))
        !           310:        ((dtpr ob) (zprint-list ob stream slashifyp (1- level)))
        !           311:        ((hunkp ob) (zprint-hunk ob stream slashifyp (1- level)))
        !           312:        ((= level 0)
        !           313:         (patom "&" stream))
        !           314:        (t
        !           315:         (if slashifyp (xxprint ob stream)
        !           316:             (patom ob stream))))
        !           317:   't)
        !           318: 
        !           319: (defun zprint-list (l stream slashifyp level)
        !           320:        (tyo #/( stream)
        !           321:        (do ((l l (cdr l))
        !           322:            (i (or prinlength -1) (1- i))
        !           323:            (first t nil))
        !           324:           ((not (dtpr l))
        !           325:            (cond ((not (null l))
        !           326:                   (patom " . " stream)
        !           327:                   (zprin1a l stream slashifyp level)))
        !           328:            't)
        !           329:            (cond ((= i 0)
        !           330:                  (patom " ..." stream)
        !           331:                  (return 't)))
        !           332:           (if (not first)
        !           333:               (tyo #/  stream))
        !           334:           (zprin1a (car l) stream slashifyp level))
        !           335:        (tyo #/) stream))
        !           336: 
        !           337: (defun zprint-hunk (l stream slashifyp level)
        !           338:        (tyo #/{ stream)
        !           339:        (do ((i 0 (1+ i))
        !           340:            (lim (hunksize l))
        !           341:            (first t nil))
        !           342:           ((= i lim)
        !           343:            't)
        !           344:            (cond ((and (not (null prinlength)) (not (< i prinlength)))
        !           345:                  (patom " ..." stream)
        !           346:                  (return 't)))
        !           347:           (if (not first)
        !           348:               (tyo #/  stream))
        !           349:           (zprin1a (cxr i l) stream slashifyp level))
        !           350:        (tyo #/} stream))
        !           351: 
        !           352: (eval-when (load eval)
        !           353:    (putd 'xxprint (getd 'print))
        !           354:    (putd 'xxprinc (getd 'princ)))
        !           355: 
        !           356: (defun new-printer ()
        !           357:   (setq top-level-print 'zprint)
        !           358:   (putd 'print (getd 'zprint))
        !           359:   (putd 'prin1 (getd 'zprin1))
        !           360:   't)
        !           361: 
        !           362: (defun old-printer ()
        !           363:   (setq top-level-print 'xxprint)
        !           364:   (putd 'print (getd 'xxprint))
        !           365:   (putd 'princ (getd 'xxprinc))
        !           366:   't)
        !           367: 
        !           368: 
        !           369: 
        !           370: 
        !           371: (putprop 'lmhacks t 'version)

unix.superglobalmegacorp.com

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