;;;-*-Mode:LISP; Package:(PCL LISP 1000); Base:10; Syntax:Common-lisp -*- ;;; ;;; ************************************************************************* ;;; Copyright (c) 1985, 1986, 1987 Xerox Corporation. All rights reserved. ;;; ;;; Use and copying of this software and preparation of derivative works ;;; based upon this software are permitted. Any distribution of this ;;; software or derivative works must comply with all applicable United ;;; States export control laws. ;;; ;;; This software is made available AS IS, and Xerox Corporation makes no ;;; warranty about the software, its performance or its conformity to any ;;; specification. ;;; ;;; Any person obtaining a copy of this software is requested to send their ;;; name and post office or electronic mail address to: ;;; CommonLoops Coordinator ;;; Xerox Artifical Intelligence Systems ;;; 2400 Hanover St. ;;; Palo Alto, CA 94303 ;;; (or send Arpanet mail to CommonLoops-Coordinator.pa@Xerox.arpa) ;;; ;;; Suggestions, comments and requests for improvements are also welcome. ;;; ************************************************************************* ;;; ;;; Some support stuff for compiling and loading PCL. It would be nice if ;;; there was some portable make-system we could all agree to share for a ;;; while. At least until people really get databases and stuff. ;;; ;;; *** To install PCL at a new site, read the directions above the *** ;;; *** second and third defvars in this file (down about 10 lines). *** ;;; #| dcode doesn't use gensym function names flush :dynamic cpl should be in know slot # FSC should be smarter about function slot?? don't funcall closures (FIN's) in systems where it is slow?? get-slot--funcallable-standard-class FSC stuff compiles faster function-names, method-names congruent arglists macrolet in walk by hacking macroexpand-1?? no this won't work in general because there is no guarantee that the Lisp really call's macroexpand-1! |# (in-package 'pcl :use (list (or (find-package 'walker) (make-package 'walker :use '(lisp))) 'lisp)) (defvar *pcl-system-date* "8/27/87 August 27th, 1987") ;;; ;;; Various hacks to get people's *features* into better shape. ;;; (eval-when (compile load eval) #+Symbolics (si:inhibit-style-warnings (let ((major (sct:get-release-version))) (cond ((= major 6) (pushnew ':symbolics-release-6 *features*)) ((= major 7) (pushnew ':symbolics-release-7 *features*)) (t (error "don't know this system version"))))) (dolist (feature *features*) (when (and (symbolp feature) ;3600!! (equal (symbol-name feature) "CMU")) (pushnew :CMU *features*))) #+TI (if (eq (si:local-binary-file-type) :xld) (pushnew ':ti-release-3 *features*) (pushnew ':ti-release-2 *features*)) ) ;;; ;;; When installing PCL at your site, edit this defvar to give the directory ;;; in which the PCL files are stored. The values given below are EXAMPLES ;;; of correct values for *pcl-directory*. ;;; If the value specified for *pcl-directory* is a CONS, then the CAR is ;;; used as the source file directory and the CDR is used as the binary ;;; file directory. ;;; (defvar *pcl-directory* #+Symbolics (cons (pathname "BD:>pcl>") #+Symbolics-release-6 (pathname "BD:>pcl>rel6>") #+Symbolics-release-7 (pathname "BD:>pcl>")) #+Lucid (pathname "/usr/guest/gregor/pcl/") #+ExCL (pathname "/usr/guest/gregor/pcl/") #+KCL (pathname "/usr/guest/gregor/pcl/") #+(and DEC common vax VMS) (pathname "") #+:CMU (pathname "pcl:") #+HP (pathname "") #+Xerox (pathname "{phylum}<pcl>") #+:gclisp (pathname "/pcl/") #+pyramid (pathname "") ) ;;; ;;; *port* is a list of symbols (in the PCL package) which represent the ;;; Common Lisp in which PCL is now running. Many of the facilities in ;;; defsys use the value of *port* rather than #+ and #- to conditionalize ;;; the way they work. ;;; (defvar *port* '(#+Symbolics Symbolics #+Symbolics-Release-6 Rel-6 #+Symbolics-Release-7 Rel-7 #+Lucid Lucid #+Xerox Xerox #+TI TI #+(and dec vax common) Vaxlisp #+KCL KCL #+excl excl #+:CMU CMU #+HP HP #+:gclisp gclisp #+pyramid pyramid)) ;;; ;;; When you get a copy of PCL (by tape or by FTP), the sources files will ;;; have extensions of ".lisp" in particular, this file will be defsys.lisp. ;;; The preferred way to install pcl is to rename these files to have the ;;; extension which your lisp likes to use for its files. Alternately, it ;;; is possible not to rename the files. If the files are not renamed to ;;; the proper convention, the second line of the following defvar should ;;; be changed to: ;;; (let ((files-renamed-p nil) ;;; ;;; Note: Something people installing PCL on a machine running Unix ;;; might find useful. If you want to change the extensions ;;; of the source files from ".lisp" to ".lsp", *all* you have ;;; to do is the following: ;;; ;;; % foreach i (*.lisp) ;;; ? mv $i $i:r.lsp ;;; ? end ;;; % ;;; ;;; I am sure that a lot of people already know that, and some ;;; Unix hackers may say, "jeez who doesn't know that". Those ;;; same Unix hackers are invited to fix mv so that I can type ;;; "mv *.lisp *.lsp". ;;; (defvar *pathname-extensions* (let ((files-renamed-p t) (proper-extensions (car '(#+Symbolics ("lisp" . "bin") #+(and dec common vax (not ultrix)) ("LSP" . "FAS") #+(and dec common vax ultrix) ("lsp" . "fas") #+KCL ("lsp" . "o") #+Xerox ("lisp" . "dfasl") #+(and Lucid MC68000) ("lisp" . "lbin") #+(and Lucid VAX VMS) ("lisp" . "vbin") #+(and Lucid Prime) ("lisp" . "pbin") #+excl ("cl" . "fasl") #+:CMU ("slisp" . "sfasl") #+HP ("l" . "b") #+TI ("lisp" . #.(string (si::local-binary-file-type))) #+:gclisp ("LSP" . "F2S") #+pyramid ("clisp" . "o") )))) (cond ((null proper-extensions) '("l" . "lbin")) ((null files-renamed-p) (cons "lisp" (cdr proper-extensions))) (t proper-extensions)))) (defun make-source-pathname (name) (make-pathname-internal name :source)) (defun make-binary-pathname (name) (make-pathname-internal name :binary)) (defun make-pathname-internal (name type) (let* ((extension (ecase type (:source (car *pathname-extensions*)) (:binary (cdr *pathname-extensions*)))) (directory (etypecase *pcl-directory* (pathname *pcl-directory*) (cons (ecase type (:source (car *pcl-directory*)) (:binary (cdr *pcl-directory*)))))) (pathname (make-pathname :name #-VMS (string-downcase (string name)) #+VMS (string-downcase (substitute #\← #\- (string name))) :type extension :defaults directory))) #+Symbolics (setq pathname (zl:send pathname :new-raw-name (pathname-name pathname)) pathname (zl:send pathname :new-raw-type (pathname-type pathname))) pathname)) ;;; ;;; *PCL-FILES* is a kind of "defsystem" for pcl. A new port of pcl should ;;; add an entry for that port's xxx-low file. ;;; (defparameter *pcl-files* ;; file load compile files which port ;; environment environment force the of ;; recompilation ;; of this file `((rel-6-patches t t () rel-6) (rel-7-patches t t () rel-7) (7debug t t () rel-7) (ti-patches t t () ti) (pyr-patches t t () pyramid) (pkg t t ()) (walk (pkg) (pkg) ()) (macros (pkg walk) (pkg walk) ()) (low (pkg walk) (pkg macros) (macros)) (3600-low (low) (low) (low) Symbolics) (lucid-low (low) (low) (low) Lucid) (Xerox-low (low) (low) (low) Xerox) (ti-low (low) (low) (low) TI) (vaxl-low (low) (low) (low) vaxlisp) (kcl-low (low) (low) (low) KCL) (excl-low (low) (low) (low) excl) (cmu-low (low) (low) (low) CMU) (hp-low (low) (low) (low) HP) (gold-low (low) (low) (low) gclisp) (pyr-low (low) (low) (low) pyramid) (fin t t (low)) (defs t t (macros)) (boot t t (defs fin)) (slots t t (boot defs fin)) (defclass t t (boot defs fin)) (std-class t t (boot defs fin)) (braid1 t t (boot defs fin)) (fsc t t (boot defs fin)) (methods t t (boot defs fin)) (dcode t t (defs fin)) (dcode-pre1 t t (defs fin dcode)) (dcode-pre2 t t (defs fin dcode)) (fixup t t (boot defs fin)) (high t t (boot defs fin)) (compat t t ()) )) ;; ;;;;;; operate-on-system ;; ;;; Yet Another Sort Of General System Facility and friends. ;;; (defstruct (module (:constructor make-module (name)) (:print-function (lambda (m s d) (declare (ignore d)) (format s "#<Module ~A>" (module-name m))))) name load-env comp-env recomp-reasons) (defun make-modules (system-description) (let ((modules ())) (labels ((get-module (name) (or (find name modules :key #'module-name) (progn (setq modules (cons (make-module name) modules)) (car modules)))) (parse-spec (spec) (if (eq spec 't) (reverse (cdr modules)) (mapcar #'get-module spec)))) (dolist (file system-description) (let* ((name (car file)) (port (car (cddddr file))) (module nil)) (when (or (null port) (member port *port*)) (setq module (get-module name)) (setf (module-load-env module) (parse-spec (cadr file)) (module-comp-env module) (parse-spec (caddr file)) (module-recomp-reasons module) (parse-spec (cadddr file)))))) (reverse modules)))) (defun make-transformations (modules filter make-transform) (let ((transforms (list nil))) (dolist (m modules) (when (funcall filter m transforms) (funcall make-transform m transforms))) (reverse (cdr transforms)))) (defun make-compile-transformation (module transforms) (unless (dolist (trans transforms) (and (eq (car trans) ':compile) (eq (cadr trans) module) (return trans))) (dolist (c (module-comp-env module)) (make-load-transformation c transforms)) #+symbolics-release-6 (make-load-transformation module transforms) (push `(:compile ,module) (cdr transforms)))) (defun make-load-transformation (module transforms) (unless (dolist (trans transforms) (when (eq (cadr trans) module) (cond ((eq (car trans) ':compile) (return nil)) ((eq (car trans) ':load) (return trans))))) (dolist (l (module-load-env module)) (make-load-transformation l transforms)) (push `(:load ,module) (cdr transforms)))) (defun make-load-without-dependencies-transformation (module transforms) (unless (dolist (trans transforms) (and (eq (car trans) ':load) (eq (cadr trans) module) (return trans))) (push `(:load ,module) (cdr transforms)))) (defun compile-filter (module transforms) (or (dolist (r (module-recomp-reasons module)) (when (dolist (transform transforms) (when (and (eq (car transform) ':compile) (eq (cadr transform) r)) (return t))) (return t))) (null (probe-file (make-binary-pathname (module-name module)))) (> (file-write-date (make-source-pathname (module-name module))) (file-write-date (make-binary-pathname (module-name module)))))) (defun operate-on-system (system mode &optional arg print-only) (let ((modules (make-modules system)) (transformations ())) (flet ((load-module (m) (let ((name (module-name m)) (*load-verbose* nil)) (if (dolist (trans transformations) (and (eq (car trans) :compile) (eq (cadr trans) m) (return trans))) (progn (format t "~&Loading source of ~A..." name) (or print-only (load (make-source-pathname name)))) (progn (format t "~&Loading binary of ~A..." name) (or print-only (load (make-binary-pathname name))))))) (compile-module (m) (format t "~&Compiling ~A..." (module-name m)) (unless print-only (let ((name (module-name m))) (compile-file (make-source-pathname name) :output-file (make-binary-pathname name))))) (true (&rest ignore) (declare (ignore ignore)) 't)) (setq transformations (ecase mode (:compile (make-transformations modules #'compile-filter #'make-compile-transformation)) (:recompile (make-transformations modules #'true #'make-compile-transformation)) (:query-compile (make-transformations modules #'(lambda (m transforms) (or (compile-filter m transforms) (y-or-n-p "Compile ~A?" (module-name m)))) #'make-compile-transformation)) (:confirm-compile (make-transformations modules #'(lambda (m transforms) (and (compile-filter m transforms) (y-or-n-p "Compile ~A?" (module-name m)))) #'make-compile-transformation)) (:compile-from (make-transformations modules #'(lambda (m transforms) (or (member (module-name m) arg) (compile-filter m transforms))) #'make-compile-transformation)) (:load (make-transformations modules #'true #'make-load-transformation)) (:query-load (make-transformations modules #'(lambda (m transforms) (declare (ignore transforms)) (y-or-n-p "Load ~A?" (module-name m))) #'make-load-without-dependencies-transformation)))) (#+Symbolics compiler:compiler-warnings-context-bind #-Symbolics progn (loop (when (null transformations) (return t)) (let ((transform (pop transformations))) (ecase (car transform) (:compile (compile-module (cadr transform))) (:load (load-module (cadr transform)))))))))) (defun compile-pcl (&optional m) #+GCLisp (load "defsys.lsp") ;*** Don't ask (cond ((null m) (operate-on-system *pcl-files* :compile)) ((eq m 't) (operate-on-system *pcl-files* :recompile)) ((eq m :print) (operate-on-system *pcl-files* :compile () t)) ((eq m :query) (operate-on-system *pcl-files* :query-compile)) ((eq m :confirm) (operate-on-system *pcl-files* :confirm-compile)) ((symbolp m) (operate-on-system *pcl-files* :compile-from `(,m))) ((listp m) (operate-on-system *pcl-files* :compile-from m)))) (defun load-pcl (&optional m) #+GCLisp (load "defsys.lsp") ;*** Don't ask (cond ((null m) (operate-on-system *pcl-files* :load)) ((eq m :query) (operate-on-system *pcl-files* :query-load)))) ;;;; ;;; ;;; This stuff is not intended for external use. ;;; (defun rename-pcl () (dolist (f *pcl-files*) (let ((old nil) (new nil)) (let ((*pcl-directory* *default-pathname-defaults*)) (setq old (make-source-pathname (car f)))) (setq new (make-source-pathname (car f))) (rename-file old new)))) #+Symbolics (defun edit-pcl () (dolist (f *pcl-files*) (zwei:find-file (make-source-pathname (car f))))) #+Symbolics (defun hardcopy-pcl (&optional query-p) (let ((files (mapcar #'(lambda (f) (setq f (car f)) (and (or (not query-p) (y-or-n-p "~A? " f)) f)) *pcl-files*)) (b zwei:*interval*)) (unwind-protect (dolist (f files) (when f (multiple-value-bind (ignore b) (zwei:find-file (make-source-pathname f)) (zwei:hardcopy-buffer b)))) (zwei:make-buffer-current b)))) #+Symbolics (defun mail-pcl (to) (let* ((original-buffer zwei:*interval*) (files (cons 'defsys (mapcar #'car *pcl-files*))) (total-number (length files)) (file nil) (i 0) (mail-buffer nil)) (unwind-protect (loop (when (null files) (return)) (setq file (pop files)) (incf i) (multiple-value-bind (ignore b) (zwei:find-file (make-source-pathname file)) (zwei:com-mail-internal t to b nil nil nil (format nil "PCL file ~A (~A of ~A)" file i total-number)) (setq mail-buffer zwei:*interval*) (zwei:com-exit-com-mail) (format t "~&Just sent ~A (~A of ~A)." file i total-number) (zwei:kill-buffer mail-buffer))) (zwei:make-buffer-current original-buffer))))