BSD 4_3_Tahoe development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Sun, 24 Mar 1985 04:16:23 +0000 (20:16 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Sun, 24 Mar 1985 04:16:23 +0000 (20:16 -0800)
Work on file usr/src/ucb/lisp/lisplib/lmhacks.l

Synthesized-from: CSRG/cd2/4.3tahoe

usr/src/ucb/lisp/lisplib/lmhacks.l [new file with mode: 0644]

diff --git a/usr/src/ucb/lisp/lisplib/lmhacks.l b/usr/src/ucb/lisp/lisplib/lmhacks.l
new file mode 100644 (file)
index 0000000..9f107a7
--- /dev/null
@@ -0,0 +1,371 @@
+(setq rcs-lmhacks-
+   "$Header: lmhacks.l,v 1.2 83/08/15 22:32:31 jkf Exp $")
+
+;;  This file contains miscellaneous functions and macros that 
+;;  ZetaLisp users often find useful
+
+
+;;;  (c) Copyright 1982 Massachusetts Institute of Technology 
+
+;; This is a simple multiple value scheme based on the one implemented
+;; in MACLISP.  It doesn't clean up after its self properly, so if
+;; you ask for multiple values, you will get them regardless of whether
+;; they are returned.
+
+(environment-maclisp (compile eval) (files struct flavorm))
+
+(declare (macros t))
+
+(defvar si:argn () "Number of arguments returned by last values")
+(defvar si:arg2 () "Second return value")
+(defvar si:arg3 () "Third return value")
+(defvar si:arg4 () "Fourth return value")
+(defvar si:arg5 () "Fifth return value")
+(defvar si:arg6 () "Sixth return value")
+(defvar si:arg7 () "Seventh return value")
+(defvar si:arg8 () "Eigth return value")
+(defvar si:arglist () "Additional return values after the eigth")
+
+(defvar si:return-registers
+  '(si:arg2 si:arg3 si:arg4 si:arg5 si:arg6 si:arg7 si:arg8))
+
+(defmacro values (&rest values)
+  `(prog2 (setq si:argn ,(length values))
+         ,(first values)
+         ,@(do ((vals (cdr values) (cdr vals))
+                (regs si:return-registers (cdr regs))
+                (forms))
+               (nil)
+             (cond ((null vals)
+                    (return (reverse forms)))
+                   ((null regs)
+                    (return
+                     `(,@(reverse forms)
+                       (setq si:arglist (list ,@vals)))))
+                   (t (push `(setq ,(car regs) ,(car vals))
+                            forms))))))
+
+(defun values-list (list)
+  (setq si:argn (length list))
+  (do ((vals (cdr list) (cdr vals))
+       (regs si:return-registers (cdr regs)))
+      ((null regs)
+       (if (not (null vals))
+          (setq si:arglist vals))
+       (car list))
+    (set (car regs) (car vals))))
+
+(defmacro multiple-value (vars form)
+  `(progn
+     ,@(if (not (null (car vars)))
+         `((setq ,(car vars) ,form)
+           (if (< si:argn 1) (setq ,(car vars) nil)))
+         `(,form))
+     ,@(do ((vs (cdr vars) (cdr vs))
+           (regs si:return-registers (cdr regs))
+           (i 2 (1+ i))
+           (forms))
+          (nil)
+        (cond ((null vars)
+               (return (reverse forms)))
+              ((null regs)
+               (return
+                (do ((vs vs (cdr vs)))
+                    ((null vs) (nreverse forms))
+                  (and (not (null (car vs)))
+                       (push
+                        `(setq ,(car vs)
+                               (prog1
+                                (if (not (> ,i si:argn))
+                                    (car si:arglist))
+                                (setq si:arglist (cdr si:arglist))))
+                        forms)))))
+              ((not (null (car vs)))
+               (push `(setq ,(car vs) (if (not (> ,i si:argn)) ,(car regs))
+                            ,(car regs) nil)
+                     forms))))))
+
+(defmacro multiple-value-bind (vars form &rest body)
+  `(let ,vars
+       (multiple-value ,vars ,form)
+       ,@body))
+
+(defmacro multiple-value-list (form)
+  `(multiple-value-list-1 ,form))
+
+(defun multiple-value-list-1 (si:arg1)
+  (cond ((= 0 si:argn) ())
+       ((= 1 si:argn)
+        (list si:arg1))
+       ((= 2 si:argn)
+        (list si:arg1 si:arg2))
+       ((= 3 si:argn)
+        (list si:arg1 si:arg2 si:arg3))
+       ((= 4 si:argn)
+        (list si:arg1 si:arg2 si:arg3 si:arg4))
+       ((= 5 si:argn)
+        (list si:arg1 si:arg2 si:arg3 si:arg4 si:arg5))
+       ((= 6 si:argn)
+        (list si:arg1 si:arg2 si:arg3 si:arg4 si:arg5 si:arg6))
+       ((= 7 si:argn)
+        (list si:arg1 si:arg2 si:arg3 si:arg4 si:arg5 si:arg6
+              si:arg7))
+       ((= 8 si:argn)
+        (list si:arg1 si:arg2 si:arg3 si:arg4 si:arg5 si:arg6
+              si:arg7 si:arg8))
+       ((> si:argn 8)
+        (rplacd (nthcdr (- si:argn 9) si:arglist) nil)
+        (list* si:arg1 si:arg2 si:arg3 si:arg4 si:arg5 si:arg6
+               si:arg7 si:arg8 si:arglist))
+       (t (ferror () "Internal error, si:argn = ~D" si:argn))))
+\f
+(defun union (set &rest others)
+  (loop for s in others
+       do (loop for elt in s
+                unless (memq elt set)
+                do (push elt set))
+       finally (return set)))
+
+(defun make-list (length &rest options &aux (iv))
+  (loop for (key val) on options by #'cddr
+       do (selectq key
+            (:initial-value
+               (setq iv val))
+            (:area)
+            (otherwise
+             (error "Illegal parameter to make-list" key))))
+  (loop for i from 1 to length collect iv))
+\f
+;; si:printing-random-object
+;; A macro for aiding in the printing of random objects.
+;; This macro generates a form which: (by default) includes the virtual 
+;; address in the printed representation.
+;; Options are :NO-POINTER to suppress the pointer
+;;             :TYPEP princs the typep of the object first.
+
+;; Example:
+;; (DEFSELECT ((:PROPERTY HACKER :NAMED-STRUCTURE-INVOKE))
+;;   (:PRINT-SELF (HACKER STREAM IGNORE IGNORE)
+;;     (SI:PRINTING-RANDOM-OBJECT (HACKER STREAM :TYPEP)
+;;       (PRIN1 (HACKER-NAME HACKER) STREAM))))
+;; ==> #<HACKER /"MMcM/" 6172536765>
+
+(defmacro si:printing-random-object ((object stream . options) &body body)
+  (let ((%pointer t)
+       (typep nil))
+    (do ((l options (cdr l)))
+       ((null l))
+      (selectq (car l)
+       (:no-pointer (setq %pointer nil))
+       (:typep (setq typep t))
+       (:fastp (setq l (cdr l)))               ; for compatibility sake
+       (otherwise
+        (ferror nil "~S is an unknown keyword in si:printing-random-object"
+                (car l)))))
+    `(progn
+       (patom "#<" ,stream)
+       ,@(and typep
+             `((patom (:typep ,object) ,stream)))
+       ,@(and typep body
+             `((patom " " ,stream)))
+       ,@body
+       ,@(and %pointer
+             `((patom " " ,stream)
+               (patom (maknum ,object) ,stream)))
+       (patom ">" ,stream)
+       ,object)))
+\f
+(defun named-structure-p (x &aux symbol)
+  (cond ((or (and (hunkp x) (atom (setq symbol (cxr 0 x))))
+            (and (vectorp x)
+                 (setq symbol (or (and (atom (vprop x)) (vprop x))
+                                  (and (dtpr (vprop x))
+                                       (atom (car (vprop x)))
+                                       (car (vprop x)))))))
+                                 
+        (if (get symbol 'defstruct-description)
+            symbol))))
+
+(defun named-structure-symbol (x)
+  (or (named-structure-p x)
+      (ferror () "~S was supposed to have been a named structure."
+             x)))
+
+(declare (localf named-structure-invoke-internal))
+
+(defun named-structure-invoke (operation struct &rest args)
+  (named-structure-invoke-internal operation struct args t))
+
+(defun named-structure-invoke-carefully (operation struct &rest args)
+  (named-structure-invoke-internal operation struct args nil))
+
+(defun named-structure-invoke-internal (operation struct args error-p)
+   (let (symbol fun)
+      (setq symbol (named-structure-symbol struct))
+      (if (setq fun (get symbol ':named-structure-invoke))
+        then (lexpr-funcall fun operation struct args)
+        else (and error-p
+                  (ferror ()
+                          "No named structure invoke function for ~S"
+                          struct)))))
+
+(defmacro defselect ((function-spec default-handler no-which-operations)
+                    &rest args)
+  (let ((name (intern (gensym)))
+       fun-name)
+    `(progn 'compile
+       (defun ,(if (eq (car function-spec) ':property)
+                  (cdr function-spec)
+                  (ferror () "Can't interpret ~S defselect function spec"
+                                 function-spec))
+             (operation &rest args &aux temp)
+        (if (setq temp (gethash operation (get ',name 'select-table)))
+            (lexpr-funcall temp args)
+            ,(if default-handler
+                 `(lexpr-funcall ,default-handler operation args)
+                 `(ferror () "No handler for the ~S method of ~S"
+                          operation ',function-spec))))
+       (setf (get ',name 'select-table) (make-hash-table))
+       ,@(do ((args args (cdr args))
+            (form)
+            (forms nil))
+           ((null args) (nreverse forms))
+         (setq form (car args))
+         (cond ((atom (cdr form))
+                (setq fun-name (cdr form)))
+               (t (setq fun-name
+                        (intern (concat name (if (atom (car form)) (car form)
+                                                 (caar form)))))
+                  (push `(defun ,fun-name ,@(cdr form)) forms)))
+         (if (atom (car form))
+             (push `(puthash ',(car form) ',fun-name
+                             (get ',name 'select-table))
+                   forms)
+             (mapc #'(lambda (q)
+                       (push `(puthash ',q ',fun-name
+                                       (get ',name 'select-table))
+                             forms))
+                   (car form))))
+       ,@(and (not no-which-operations)
+             `((defun ,(setq fun-name (intern
+                                       (concat name '-which-operations)))
+                      (&rest args)
+                 '(:which-operations ,@(loop for form in args
+                                             appending (if (atom (car form))
+                                                           (list (car form))
+                                                           (car form)))))
+               (puthash ':which-operations ',fun-name
+                        (get ',name 'select-table))))
+       ',function-spec)))
+\f
+(defun :typep (ob &optional (type nil) &aux temp)
+  (cond ((instancep ob)
+        (instance-typep ob type))
+       ((setq temp (named-structure-p ob))
+        (if (null type) temp
+            (if (eq type temp) t
+                (memq type (nth 11. (get temp 'defstruct-description))))))
+       ((hunkp ob)
+        (if (null type) 'hunk (eq type 'hunk)))
+       ((null type)
+        (funcall 'typep ob))
+       (t (eq type (funcall 'typep ob)))))
+
+(defun send-internal (object message &rest args)
+  (declare (special .own-flavor. self))
+  (lexpr-funcall (if (eq self object)
+                    (or (gethash message
+                                 (flavor-method-hash-table .own-flavor.))
+                        (flavor-default-handler .own-flavor.))
+                    object)
+                message args))
+\f
+;; New printer
+
+(declare (special poport prinlevel prinlength top-level-print))
+
+(defun zprint (x &optional (stream poport))
+       (zprin1 x stream)
+       't)
+
+(defun zprinc (x &optional (stream poport))
+       (zprin1a x stream () (or prinlevel -1)))
+
+(defun zprin1 (x &optional (stream poport))
+       (zprin1a x stream 't (or prinlevel -1)))
+
+(defun zprin1a (ob stream slashifyp level &aux temp)
+  (cond ((null ob) (patom "()" stream))
+       ((setq temp (named-structure-p ob))
+        (or (named-structure-invoke-carefully ':print-self ob stream
+                                               level slashifyp)
+            (si:printing-random-object (ob stream :typep))))
+       ((instancep ob)
+        (if (get-handler-for ob ':print-self)
+            (send ob ':print-self stream)
+            (si:printing-random-object (ob stream :typep))))
+        ((atom ob)
+        (if slashifyp (xxprint ob stream)
+            (patom ob stream)))
+       ((dtpr ob) (zprint-list ob stream slashifyp (1- level)))
+       ((hunkp ob) (zprint-hunk ob stream slashifyp (1- level)))
+       ((= level 0)
+        (patom "&" stream))
+       (t
+        (if slashifyp (xxprint ob stream)
+            (patom ob stream))))
+  't)
+
+(defun zprint-list (l stream slashifyp level)
+       (tyo #/( stream)
+       (do ((l l (cdr l))
+           (i (or prinlength -1) (1- i))
+           (first t nil))
+          ((not (dtpr l))
+           (cond ((not (null l))
+                  (patom " . " stream)
+                  (zprin1a l stream slashifyp level)))
+           't)
+           (cond ((= i 0)
+                 (patom " ..." stream)
+                 (return 't)))
+          (if (not first)
+              (tyo #/  stream))
+          (zprin1a (car l) stream slashifyp level))
+       (tyo #/) stream))
+
+(defun zprint-hunk (l stream slashifyp level)
+       (tyo #/{ stream)
+       (do ((i 0 (1+ i))
+           (lim (hunksize l))
+           (first t nil))
+          ((= i lim)
+           't)
+           (cond ((and (not (null prinlength)) (not (< i prinlength)))
+                 (patom " ..." stream)
+                 (return 't)))
+          (if (not first)
+              (tyo #/  stream))
+          (zprin1a (cxr i l) stream slashifyp level))
+       (tyo #/} stream))
+
+(eval-when (load eval)
+   (putd 'xxprint (getd 'print))
+   (putd 'xxprinc (getd 'princ)))
+
+(defun new-printer ()
+  (setq top-level-print 'zprint)
+  (putd 'print (getd 'zprint))
+  (putd 'prin1 (getd 'zprin1))
+  't)
+
+(defun old-printer ()
+  (setq top-level-print 'xxprint)
+  (putd 'print (getd 'xxprint))
+  (putd 'princ (getd 'xxprinc))
+  't)
+
+
+
+
+(putprop 'lmhacks t 'version)