changelog shortlog graph tags branches changeset files file revisions raw help

Mercurial > core / annotate lisp/std/defpkg.lisp

changeset 413: 600e4fc73cb3
parent: d876b572b5b9
child: af486e0a40c9
author: Richard Westhaver <ellis@rwest.io>
date: Wed, 05 Jun 2024 22:27:33 -0400
permissions: -rw-r--r--
description: std fixes
216
97ad564cd68d gui stuff, music
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
1
 ;;; defpkg.lisp --- defpackage extension macro
97ad564cd68d gui stuff, music
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
2
 
97ad564cd68d gui stuff, music
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
3
 ;;; Commentary:
97ad564cd68d gui stuff, music
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
4
 
97ad564cd68d gui stuff, music
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
5
 ;;
97ad564cd68d gui stuff, music
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
6
 
97ad564cd68d gui stuff, music
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
7
 ;;; Code:
292
00d1c8afcdbb mostly done with std refactor, added sst-file-writer to rdb
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
8
 (defpackage :std/defpkg
00d1c8afcdbb mostly done with std refactor, added sst-file-writer to rdb
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
9
   (:use :cl)
00d1c8afcdbb mostly done with std refactor, added sst-file-writer to rdb
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
10
   (:nicknames :pkg)
00d1c8afcdbb mostly done with std refactor, added sst-file-writer to rdb
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
11
   (:export :defpkg
395
d876b572b5b9 updates
Richard Westhaver <ellis@rwest.io>
parents: 384
diff changeset
12
    :find-package* :find-symbol* :symbol-call :intern*
d876b572b5b9 updates
Richard Westhaver <ellis@rwest.io>
parents: 384
diff changeset
13
    :export* :import* :shadowing-import* :shadow* 
d876b572b5b9 updates
Richard Westhaver <ellis@rwest.io>
parents: 384
diff changeset
14
    :symbol-shadowing-p :home-package-p :make-symbol* :unintern*
292
00d1c8afcdbb mostly done with std refactor, added sst-file-writer to rdb
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
15
    :symbol-package-name :standard-common-lisp-symbol-p
00d1c8afcdbb mostly done with std refactor, added sst-file-writer to rdb
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
16
    :reify-package :unreify-package :reify-symbol :unreify-symbol
413
600e4fc73cb3 std fixes
Richard Westhaver <ellis@rwest.io>
parents: 395
diff changeset
17
    :nuke-symbol-in-package :nuke-symbol :rehome-symbol :ensure-package-unused
600e4fc73cb3 std fixes
Richard Westhaver <ellis@rwest.io>
parents: 395
diff changeset
18
    :delete-package* :package-names :packages-from-names :fresh-package-name 
600e4fc73cb3 std fixes
Richard Westhaver <ellis@rwest.io>
parents: 395
diff changeset
19
    :rename-package-away :package-definition-form :parse-defpkg-form :ensure-package
600e4fc73cb3 std fixes
Richard Westhaver <ellis@rwest.io>
parents: 395
diff changeset
20
    :with-package :define-lisp-package))
292
00d1c8afcdbb mostly done with std refactor, added sst-file-writer to rdb
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
21
 
291
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 276
diff changeset
22
 (in-package :std/defpkg)
216
97ad564cd68d gui stuff, music
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
23
 
223
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
24
 (eval-when (:load-toplevel :compile-toplevel :execute)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
25
   (defun find-package* (package-designator &optional (error t))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
26
     (let ((package (find-package package-designator)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
27
       (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
28
         (package package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
29
         (error (error "No package named ~S" (string package-designator)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
30
         (t nil))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
31
   (defun find-symbol* (name package-designator &optional (error t))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
32
     "Find a symbol in a package of given string'ified NAME;
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
33
 unlike CL:FIND-SYMBOL, work well with 'modern' case sensitive syntax
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
34
 by letting you supply a symbol or keyword for the name;
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
35
 also works well when the package is not present.
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
36
 If optional ERROR argument is NIL, return NIL instead of an error
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
37
 when the symbol is not found."
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
38
     (block nil
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
39
       (let ((package (find-package* package-designator error)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
40
         (when package ;; package error handled by find-package* already
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
41
           (multiple-value-bind (symbol status) (find-symbol (string name) package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
42
             (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
43
               (status (return (values symbol status)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
44
               (error (error "There is no symbol ~S in package ~S" name (package-name package))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
45
         (values nil nil))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
46
   (defun symbol-call (package name &rest args)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
47
     "Call a function associated with symbol of given name in given package,
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
48
 with given ARGS. Useful when the call is read before the package is loaded,
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
49
 or when loading the package is optional."
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
50
     (apply (find-symbol* name package) args))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
51
   (defun intern* (name package-designator &optional (error t))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
52
     (intern (string name) (find-package* package-designator error)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
53
   (defun export* (name package-designator)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
54
     (let* ((package (find-package* package-designator))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
55
            (symbol (intern* name package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
56
       (export (or symbol (list symbol)) package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
57
   (defun import* (symbol package-designator)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
58
     (import (or symbol (list symbol)) (find-package* package-designator)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
59
   (defun shadowing-import* (symbol package-designator)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
60
     (shadowing-import (or symbol (list symbol)) (find-package* package-designator)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
61
   (defun shadow* (name package-designator)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
62
     (shadow (list (string name)) (find-package* package-designator)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
63
   (defun make-symbol* (name)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
64
     (etypecase name
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
65
       (string (make-symbol name))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
66
       (symbol (copy-symbol name))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
67
   (defun unintern* (name package-designator &optional (error t))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
68
     (block nil
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
69
       (let ((package (find-package* package-designator error)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
70
         (when package
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
71
           (multiple-value-bind (symbol status) (find-symbol* name package error)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
72
             (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
73
               (status (unintern symbol package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
74
                       (return (values symbol status)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
75
               (error (error "symbol ~A not present in package ~A"
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
76
                             (string symbol) (package-name package))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
77
         (values nil nil))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
78
   (defun symbol-shadowing-p (symbol package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
79
     (and (member symbol (package-shadowing-symbols package)) t))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
80
   (defun home-package-p (symbol package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
81
     (and package (let ((sp (symbol-package symbol)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
82
                    (and sp (let ((pp (find-package* package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
83
                              (and pp (eq sp pp))))))))
216
97ad564cd68d gui stuff, music
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
84
 
223
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
85
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
86
 (eval-when (:load-toplevel :compile-toplevel :execute)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
87
   (defun symbol-package-name (symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
88
     (let ((package (symbol-package symbol)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
89
       (and package (package-name package))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
90
   (defun standard-common-lisp-symbol-p (symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
91
     (multiple-value-bind (sym status) (find-symbol* symbol :common-lisp nil)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
92
       (and (eq sym symbol) (eq status :external))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
93
   (defun reify-package (package &optional package-context)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
94
     (if (eq package package-context) t
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
95
         (etypecase package
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
96
           (null nil)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
97
           ((eql (find-package :cl)) :cl)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
98
           (package (package-name package)))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
99
   (defun unreify-package (package &optional package-context)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
100
     (etypecase package
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
101
       (null nil)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
102
       ((eql t) package-context)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
103
       ((or symbol string) (find-package package))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
104
   (defun reify-symbol (symbol &optional package-context)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
105
     (etypecase symbol
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
106
       ((or keyword (satisfies standard-common-lisp-symbol-p)) symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
107
       (symbol (vector (symbol-name symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
108
                       (reify-package (symbol-package symbol) package-context)))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
109
   (defun unreify-symbol (symbol &optional package-context)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
110
     (etypecase symbol
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
111
       (symbol symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
112
       ((simple-vector 2)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
113
        (let* ((symbol-name (svref symbol 0))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
114
               (package-foo (svref symbol 1))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
115
               (package (unreify-package package-foo package-context)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
116
          (if package (intern* symbol-name package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
117
              (make-symbol* symbol-name)))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
118
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
119
 (eval-when (:load-toplevel :compile-toplevel :execute)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
120
   (defvar *all-package-happiness* '())
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
121
   (defvar *all-package-fishiness* (list t))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
122
   (defun record-fishy (info)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
123
     ;;(format t "~&FISHY: ~S~%" info)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
124
     (push info *all-package-fishiness*))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
125
   (defmacro when-package-fishiness (&body body)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
126
     `(when *all-package-fishiness* ,@body))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
127
   (defmacro note-package-fishiness (&rest info)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
128
     `(when-package-fishiness (record-fishy (list ,@info)))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
129
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
130
 (eval-when (:load-toplevel :compile-toplevel :execute)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
131
   #+(or clisp clozure)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
132
   (defun get-setf-function-symbol (symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
133
     #+clisp (let ((sym (get symbol 'system::setf-function)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
134
               (if sym (values sym :setf-function)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
135
                   (let ((sym (get symbol 'system::setf-expander)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
136
                     (if sym (values sym :setf-expander)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
137
                         (values nil nil)))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
138
     #+clozure (gethash symbol ccl::%setf-function-names%))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
139
   #+(or clisp clozure)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
140
   (defun set-setf-function-symbol (new-setf-symbol symbol &optional kind)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
141
     #+clisp (assert (member kind '(:setf-function :setf-expander)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
142
     #+clozure (assert (eq kind t))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
143
     #+clisp
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
144
     (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
145
       ((null new-setf-symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
146
        (remprop symbol 'system::setf-function)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
147
        (remprop symbol 'system::setf-expander))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
148
       ((eq kind :setf-function)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
149
        (setf (get symbol 'system::setf-function) new-setf-symbol))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
150
       ((eq kind :setf-expander)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
151
        (setf (get symbol 'system::setf-expander) new-setf-symbol))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
152
       (t (error "invalid kind of setf-function ~S for ~S to be set to ~S"
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
153
                 kind symbol new-setf-symbol)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
154
     #+clozure
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
155
     (progn
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
156
       (gethash symbol ccl::%setf-function-names%) new-setf-symbol
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
157
       (gethash new-setf-symbol ccl::%setf-function-name-inverses%) symbol))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
158
   #+(or clisp clozure)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
159
   (defun create-setf-function-symbol (symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
160
     #+clisp (system::setf-symbol symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
161
     #+clozure (ccl::construct-setf-function-name symbol))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
162
   (defun set-dummy-symbol (symbol reason other-symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
163
     (setf (get symbol 'dummy-symbol) (cons reason other-symbol)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
164
   (defun make-dummy-symbol (symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
165
     (let ((dummy (copy-symbol symbol)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
166
       (set-dummy-symbol dummy 'replacing symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
167
       (set-dummy-symbol symbol 'replaced-by dummy)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
168
       dummy))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
169
   (defun dummy-symbol (symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
170
     (get symbol 'dummy-symbol))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
171
   (defun get-dummy-symbol (symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
172
     (let ((existing (dummy-symbol symbol)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
173
       (if existing (values (cdr existing) (car existing))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
174
           (make-dummy-symbol symbol))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
175
   (defun nuke-symbol-in-package (symbol package-designator)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
176
     (let ((package (find-package* package-designator))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
177
           (name (symbol-name symbol)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
178
       (multiple-value-bind (sym stat) (find-symbol name package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
179
         (when (and (member stat '(:internal :external)) (eq symbol sym))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
180
           (if (symbol-shadowing-p symbol package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
181
               (shadowing-import* (get-dummy-symbol symbol) package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
182
               (unintern* symbol package))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
183
   (defun nuke-symbol (symbol &optional (packages (list-all-packages)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
184
     #+(or clisp clozure)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
185
     (multiple-value-bind (setf-symbol kind)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
186
         (get-setf-function-symbol symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
187
       (when kind (nuke-symbol setf-symbol)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
188
     (loop :for p :in packages :do (nuke-symbol-in-package symbol p)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
189
   (defun rehome-symbol (symbol package-designator)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
190
     "Changes the home package of a symbol, also leaving it present in its old home if any"
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
191
     (let* ((name (symbol-name symbol))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
192
            (package (find-package* package-designator))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
193
            (old-package (symbol-package symbol))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
194
            (old-status (and old-package (nth-value 1 (find-symbol name old-package))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
195
            (shadowing (and old-package (symbol-shadowing-p symbol old-package) (make-symbol name))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
196
       (multiple-value-bind (overwritten-symbol overwritten-symbol-status) (find-symbol name package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
197
         (unless (eq package old-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
198
           (let ((overwritten-symbol-shadowing-p
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
199
                   (and overwritten-symbol-status
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
200
                        (symbol-shadowing-p overwritten-symbol package))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
201
             (note-package-fishiness
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
202
              :rehome-symbol name
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
203
              (when old-package (package-name old-package)) old-status (and shadowing t)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
204
              (package-name package) overwritten-symbol-status overwritten-symbol-shadowing-p)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
205
             (when old-package
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
206
               (if shadowing
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
207
                   (shadowing-import* shadowing old-package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
208
               (unintern* symbol old-package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
209
             (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
210
               (overwritten-symbol-shadowing-p
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
211
                (shadowing-import* symbol package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
212
               (t
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
213
                (when overwritten-symbol-status
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
214
                  (unintern* overwritten-symbol package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
215
                (import* symbol package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
216
             (if shadowing
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
217
                 (shadowing-import* symbol old-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
218
                 (import* symbol old-package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
219
             #+(or clisp clozure)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
220
             (multiple-value-bind (setf-symbol kind)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
221
                 (get-setf-function-symbol symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
222
               (when kind
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
223
                 (let* ((setf-function (fdefinition setf-symbol))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
224
                        (new-setf-symbol (create-setf-function-symbol symbol)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
225
                   (note-package-fishiness
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
226
                    :setf-function
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
227
                    name (package-name package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
228
                    (symbol-name setf-symbol) (symbol-package-name setf-symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
229
                    (symbol-name new-setf-symbol) (symbol-package-name new-setf-symbol))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
230
                   (when (symbol-package setf-symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
231
                     (unintern* setf-symbol (symbol-package setf-symbol)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
232
                   (setf (fdefinition new-setf-symbol) setf-function)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
233
                   (set-setf-function-symbol new-setf-symbol symbol kind))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
234
             #+(or clisp clozure)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
235
             (multiple-value-bind (overwritten-setf foundp)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
236
                 (get-setf-function-symbol overwritten-symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
237
               (when foundp
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
238
                 (unintern overwritten-setf)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
239
             (when (eq old-status :external)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
240
               (export* symbol old-package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
241
             (when (eq overwritten-symbol-status :external)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
242
               (export* symbol package))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
243
         (values overwritten-symbol overwritten-symbol-status))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
244
   (defun ensure-package-unused (package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
245
     (loop :for p :in (package-used-by-list package) :do
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
246
       (unuse-package package p)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
247
   (defun delete-package* (package &key nuke)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
248
     (let ((p (find-package package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
249
       (when p
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
250
         (when nuke (do-symbols (s p) (when (home-package-p s p) (nuke-symbol s))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
251
         (ensure-package-unused p)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
252
         (delete-package package))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
253
   (defun package-names (package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
254
     (cons (package-name package) (package-nicknames package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
255
   (defun packages-from-names (names)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
256
     (remove-duplicates (remove nil (mapcar #'find-package names)) :from-end t))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
257
   (defun fresh-package-name (&key (prefix :%TO-BE-DELETED)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
258
                                separator
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
259
                                (index (random most-positive-fixnum)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
260
     (loop :for i :from index
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
261
           :for n = (format nil "~A~@[~A~D~]" prefix (and (plusp i) (or separator "")) i)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
262
             :thereis (and (not (find-package n)) n)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
263
   (defun rename-package-away (p &rest keys &key prefix &allow-other-keys)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
264
     (let ((new-name
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
265
             (apply 'fresh-package-name
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
266
                    :prefix (or prefix (format nil "__~A__" (package-name p))) keys)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
267
       (record-fishy (list :rename-away (package-names p) new-name))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
268
       (rename-package p new-name))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
269
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
270
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
271
 ;;; Communicable representation of symbol and package information
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
272
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
273
 (eval-when (:load-toplevel :compile-toplevel :execute)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
274
   (defun package-definition-form (package-designator
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
275
                                   &key (nicknamesp t) (usep t)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
276
                                     (shadowp t) (shadowing-import-p t)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
277
                                     (exportp t) (importp t) internp (error t))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
278
     (let* ((package (or (find-package* package-designator error)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
279
                         (return-from package-definition-form nil)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
280
            (name (package-name package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
281
            (nicknames (package-nicknames package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
282
            (use (mapcar #'package-name (package-use-list package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
283
            (shadow ())
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
284
            (shadowing-import (make-hash-table :test 'equal))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
285
            (import (make-hash-table :test 'equal))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
286
            (export ())
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
287
            (intern ()))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
288
       (when package
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
289
         (loop :for sym :being :the :symbols :in package
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
290
               :for status = (nth-value 1 (find-symbol* sym package)) :do
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
291
                 (ecase status
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
292
                   ((nil :inherited))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
293
                   ((:internal :external)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
294
                    (let* ((name (symbol-name sym))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
295
                           (external (eq status :external))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
296
                           (home (symbol-package sym))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
297
                           (home-name (package-name home))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
298
                           (imported (not (eq home package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
299
                           (shadowing (symbol-shadowing-p sym package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
300
                      (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
301
                        ((and shadowing imported)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
302
                         (push name (gethash home-name shadowing-import)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
303
                        (shadowing
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
304
                         (push name shadow))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
305
                        (imported
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
306
                         (push name (gethash home-name import))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
307
                      (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
308
                        (external
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
309
                         (push name export))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
310
                        (imported)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
311
                        (t (push name intern)))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
312
         (labels ((sort-names (names)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
313
                    (sort (copy-list names) #'string<))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
314
                  (table-keys (table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
315
                    (loop :for k :being :the :hash-keys :of table :collect k))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
316
                  (when-relevant (key value)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
317
                    (when value (list (cons key value))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
318
                  (import-options (key table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
319
                    (loop :for i :in (sort-names (table-keys table))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
320
                          :collect `(,key ,i ,@(sort-names (gethash i table))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
321
           `(defpackage ,name
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
322
              ,@(when-relevant :nicknames (and nicknamesp (sort-names nicknames)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
323
              (:use ,@(and usep (sort-names use)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
324
              ,@(when-relevant :shadow (and shadowp (sort-names shadow)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
325
              ,@(import-options :shadowing-import-from (and shadowing-import-p shadowing-import))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
326
              ,@(import-options :import-from (and importp import))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
327
              ,@(when-relevant :export (and exportp (sort-names export)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
328
              ,@(when-relevant :intern (and internp (sort-names intern)))))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
329
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
330
 (eval-when (:load-toplevel :compile-toplevel :execute)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
331
   (defun ensure-shadowing-import (name to-package from-package shadowed imported)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
332
     (check-type name string)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
333
     (check-type to-package package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
334
     (check-type from-package package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
335
     (check-type shadowed hash-table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
336
     (check-type imported hash-table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
337
     (let ((import-me (find-symbol* name from-package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
338
       (multiple-value-bind (existing status) (find-symbol name to-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
339
         (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
340
           ((gethash name shadowed)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
341
            (unless (eq import-me existing)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
342
              (error "Conflicting shadowings for ~A" name)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
343
           (t
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
344
            (setf (gethash name shadowed) t)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
345
            (setf (gethash name imported) t)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
346
            (unless (or (null status)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
347
                        (and (member status '(:internal :external))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
348
                             (eq existing import-me)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
349
                             (symbol-shadowing-p existing to-package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
350
              (note-package-fishiness
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
351
               :shadowing-import name
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
352
               (package-name from-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
353
               (or (home-package-p import-me from-package) (symbol-package-name import-me))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
354
               (package-name to-package) status
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
355
               (and status (or (home-package-p existing to-package) (symbol-package-name existing)))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
356
            (shadowing-import* import-me to-package))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
357
   (defun ensure-imported (import-me into-package &optional from-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
358
     (check-type import-me symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
359
     (check-type into-package package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
360
     (check-type from-package (or null package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
361
     (let ((name (symbol-name import-me)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
362
       (multiple-value-bind (existing status) (find-symbol name into-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
363
         (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
364
           ((not status)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
365
            (import* import-me into-package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
366
           ((eq import-me existing))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
367
           (t
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
368
            (let ((shadowing-p (symbol-shadowing-p existing into-package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
369
              (note-package-fishiness
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
370
               :ensure-imported name
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
371
               (and from-package (package-name from-package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
372
               (or (home-package-p import-me from-package) (symbol-package-name import-me))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
373
               (package-name into-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
374
               status
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
375
               (and status (or (home-package-p existing into-package) (symbol-package-name existing)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
376
               shadowing-p)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
377
              (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
378
                ((or shadowing-p (eq status :inherited))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
379
                 (shadowing-import* import-me into-package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
380
                (t
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
381
                 (unintern* existing into-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
382
                 (import* import-me into-package))))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
383
     (values))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
384
   (defun ensure-import (name to-package from-package shadowed imported)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
385
     (check-type name string)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
386
     (check-type to-package package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
387
     (check-type from-package package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
388
     (check-type shadowed hash-table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
389
     (check-type imported hash-table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
390
     (multiple-value-bind (import-me import-status) (find-symbol name from-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
391
       (when (null import-status)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
392
         (note-package-fishiness
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
393
          :import-uninterned name (package-name from-package) (package-name to-package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
394
         (setf import-me (intern* name from-package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
395
       (multiple-value-bind (existing status) (find-symbol name to-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
396
         (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
397
           ((and imported (gethash name imported))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
398
            (unless (and status (eq import-me existing))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
399
              (error "Can't import ~S from both ~S and ~S"
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
400
                     name (package-name (symbol-package existing)) (package-name from-package))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
401
           ((gethash name shadowed)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
402
            (error "Can't both shadow ~S and import it from ~S" name (package-name from-package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
403
           (t
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
404
            (setf (gethash name imported) t))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
405
       (ensure-imported import-me to-package from-package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
406
   (defun ensure-inherited (name symbol to-package from-package mixp shadowed imported inherited)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
407
     (check-type name string)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
408
     (check-type symbol symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
409
     (check-type to-package package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
410
     (check-type from-package package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
411
     (check-type mixp (member nil t)) ; no cl:boolean on Genera
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
412
     (check-type shadowed hash-table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
413
     (check-type imported hash-table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
414
     (check-type inherited hash-table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
415
     (multiple-value-bind (existing status) (find-symbol name to-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
416
       (let* ((sp (symbol-package symbol))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
417
              (in (gethash name inherited))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
418
              (xp (and status (symbol-package existing))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
419
         (when (null sp)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
420
           (note-package-fishiness
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
421
            :import-uninterned name
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
422
            (package-name from-package) (package-name to-package) mixp)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
423
           (import* symbol from-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
424
           (setf sp (package-name from-package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
425
         (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
426
           ((gethash name shadowed))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
427
           (in
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
428
            (unless (equal sp (first in))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
429
              (if mixp
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
430
                  (ensure-shadowing-import name to-package (second in) shadowed imported)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
431
                  (error "Can't inherit ~S from ~S, it is inherited from ~S"
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
432
                         name (package-name sp) (package-name (first in))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
433
           ((gethash name imported)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
434
            (unless (eq symbol existing)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
435
              (error "Can't inherit ~S from ~S, it is imported from ~S"
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
436
                     name (package-name sp) (package-name xp))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
437
           (t
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
438
            (setf (gethash name inherited) (list sp from-package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
439
            (when (and status (not (eq sp xp)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
440
              (let ((shadowing (symbol-shadowing-p existing to-package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
441
                (note-package-fishiness
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
442
                 :inherited name
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
443
                 (package-name from-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
444
                 (or (home-package-p symbol from-package) (symbol-package-name symbol))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
445
                 (package-name to-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
446
                 (or (home-package-p existing to-package) (symbol-package-name existing)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
447
                (if shadowing (ensure-shadowing-import name to-package from-package shadowed imported)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
448
                    (unintern* existing to-package)))))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
449
   (defun ensure-mix (name symbol to-package from-package shadowed imported inherited)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
450
     (check-type name string)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
451
     (check-type symbol symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
452
     (check-type to-package package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
453
     (check-type from-package package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
454
     (check-type shadowed hash-table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
455
     (check-type imported hash-table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
456
     (check-type inherited hash-table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
457
     (unless (gethash name shadowed)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
458
       (multiple-value-bind (existing status) (find-symbol name to-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
459
         (let* ((sp (symbol-package symbol))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
460
                (im (gethash name imported))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
461
                (in (gethash name inherited)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
462
           (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
463
             ((or (null status)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
464
                  (and status (eq symbol existing))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
465
                  (and in (eq sp (first in))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
466
              (ensure-inherited name symbol to-package from-package t shadowed imported inherited))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
467
             (in
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
468
              (remhash name inherited)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
469
              (ensure-shadowing-import name to-package (second in) shadowed imported))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
470
             (im
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
471
              (error "Symbol ~S import from ~S~:[~; actually ~:[uninterned~;~:*from ~S~]~] conflicts with existing symbol in ~S~:[~; actually ~:[uninterned~;from ~:*~S~]~]"
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
472
                     name (package-name from-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
473
                     (home-package-p symbol from-package) (symbol-package-name symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
474
                     (package-name to-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
475
                     (home-package-p existing to-package) (symbol-package-name existing)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
476
             (t
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
477
              (ensure-inherited name symbol to-package from-package t shadowed imported inherited)))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
478
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
479
   (defun recycle-symbol (name recycle exported)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
480
     ;; Takes a symbol NAME (a string), a list of package designators for RECYCLE
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
481
     ;; packages, and a hash-table of names (strings) of symbols scheduled to be
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
482
     ;; EXPORTED from the package being defined. It returns two values, the
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
483
     ;; symbol found (if any, or else NIL), and a boolean flag indicating whether
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
484
     ;; a symbol was found. The caller (DEFPKG) will then do the
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
485
     ;; re-homing of the symbol, etc.
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
486
     (check-type name string)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
487
     (check-type recycle list)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
488
     (check-type exported hash-table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
489
     (when (gethash name exported) ;; don't bother recycling private symbols
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
490
       (let (recycled foundp)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
491
         (dolist (r recycle (values recycled foundp))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
492
           (multiple-value-bind (symbol status) (find-symbol name r)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
493
             (when (and status (home-package-p symbol r))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
494
               (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
495
                 (foundp
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
496
                  ;; (nuke-symbol symbol)) -- even simple variable names like O or C will do that.
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
497
                  (note-package-fishiness :recycled-duplicate name (package-name foundp) (package-name r)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
498
                 (t
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
499
                  (setf recycled symbol foundp r)))))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
500
   (defun symbol-recycled-p (sym recycle)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
501
     (check-type sym symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
502
     (check-type recycle list)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
503
     (and (member (symbol-package sym) recycle) t))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
504
   (defun ensure-symbol (name package intern recycle shadowed imported inherited exported)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
505
     (check-type name string)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
506
     (check-type package package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
507
     (check-type intern (member nil t)) ; no cl:boolean on Genera
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
508
     (check-type shadowed hash-table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
509
     (check-type imported hash-table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
510
     (check-type inherited hash-table)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
511
     (unless (or (gethash name shadowed)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
512
                 (gethash name imported)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
513
                 (gethash name inherited))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
514
       (multiple-value-bind (existing status)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
515
           (find-symbol name package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
516
         (multiple-value-bind (recycled previous) (recycle-symbol name recycle exported)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
517
           (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
518
             ((and status (eq existing recycled) (eq previous package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
519
             (previous
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
520
              (rehome-symbol recycled package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
521
             ((and status (eq package (symbol-package existing))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
522
             (t
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
523
              (when status
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
524
                (note-package-fishiness
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
525
                 :ensure-symbol name
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
526
                 (reify-package (symbol-package existing) package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
527
                 status intern)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
528
                (unintern existing))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
529
              (when intern
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
530
                (intern* name package))))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
531
   (declaim (ftype (function (t t t &optional t) t) ensure-exported))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
532
   (defun ensure-exported-to-user (name symbol to-package &optional recycle)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
533
     (check-type name string)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
534
     (check-type symbol symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
535
     (check-type to-package package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
536
     (check-type recycle list)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
537
     (assert (equal name (symbol-name symbol)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
538
     (multiple-value-bind (existing status) (find-symbol name to-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
539
       (unless (and status (eq symbol existing))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
540
         (let ((accessible
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
541
                 (or (null status)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
542
                     (let ((shadowing (symbol-shadowing-p existing to-package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
543
                           (recycled (symbol-recycled-p existing recycle)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
544
                       (unless (and shadowing (not recycled))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
545
                         (note-package-fishiness
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
546
                          :ensure-export name (symbol-package-name symbol)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
547
                          (package-name to-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
548
                          (or (home-package-p existing to-package) (symbol-package-name existing))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
549
                          status shadowing)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
550
                         (if (or (eq status :inherited) shadowing)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
551
                             (shadowing-import* symbol to-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
552
                             (unintern existing to-package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
553
                         t)))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
554
           (when (and accessible (eq status :external))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
555
             (ensure-exported name symbol to-package recycle))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
556
   (defun ensure-exported (name symbol from-package &optional recycle)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
557
     (dolist (to-package (package-used-by-list from-package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
558
       (ensure-exported-to-user name symbol to-package recycle))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
559
     (unless (eq from-package (symbol-package symbol))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
560
       (ensure-imported symbol from-package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
561
     (export* name from-package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
562
   (defun ensure-export (name from-package &optional recycle)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
563
     (multiple-value-bind (symbol status) (find-symbol* name from-package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
564
       (unless (eq status :external)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
565
         (ensure-exported name symbol from-package recycle))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
566
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
567
   (defun ensure-package (name &key
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
568
                                 nicknames documentation use
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
569
                                 shadow shadowing-import-from
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
570
                                 import-from export intern
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
571
                                 recycle mix reexport
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
572
                                 unintern)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
573
     #+genera (declare (ignore documentation))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
574
     (let* ((package-name (string name))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
575
            (nicknames (mapcar #'string nicknames))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
576
            (names (cons package-name nicknames))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
577
            (previous (packages-from-names names))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
578
            (discarded (cdr previous))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
579
            (to-delete ())
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
580
            (package (or (first previous) (make-package package-name :nicknames nicknames)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
581
            (recycle (packages-from-names recycle))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
582
            (use (mapcar 'find-package* use))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
583
            (mix (mapcar 'find-package* mix))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
584
            (reexport (mapcar 'find-package* reexport))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
585
            (shadow (mapcar 'string shadow))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
586
            (export (mapcar 'string export))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
587
            (intern (mapcar 'string intern))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
588
            (unintern (mapcar 'string unintern))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
589
            (shadowed (make-hash-table :test 'equal)) ; string to bool
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
590
            (imported (make-hash-table :test 'equal)) ; string to bool
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
591
            (exported (make-hash-table :test 'equal)) ; string to bool
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
592
            ;; string to list home package and use package:
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
593
            (inherited (make-hash-table :test 'equal)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
594
       (when-package-fishiness (record-fishy package-name))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
595
       #-genera
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
596
       (when documentation (setf (documentation package t) documentation))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
597
       (loop :for p :in (set-difference (package-use-list package) (append mix use))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
598
             :do (note-package-fishiness :over-use name (package-names p))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
599
                 (unuse-package p package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
600
       (loop :for p :in discarded
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
601
             :for n = (remove-if #'(lambda (x) (member x names :test 'equal))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
602
                                 (package-names p))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
603
             :do (note-package-fishiness :nickname name (package-names p))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
604
                 (cond (n (rename-package p (first n) (rest n)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
605
                       (t (rename-package-away p)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
606
                          (push p to-delete))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
607
       (rename-package package package-name nicknames)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
608
       (dolist (name unintern)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
609
         (multiple-value-bind (existing status) (find-symbol name package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
610
           (when status
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
611
             (unless (eq status :inherited)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
612
               (note-package-fishiness
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
613
                :unintern (package-name package) name (symbol-package-name existing) status)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
614
               (unintern* name package nil)))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
615
       (dolist (name export)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
616
         (setf (gethash name exported) t))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
617
       (dolist (p reexport)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
618
         (do-external-symbols (sym p)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
619
           (setf (gethash (string sym) exported) t)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
620
       (do-external-symbols (sym package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
621
         (let ((name (symbol-name sym)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
622
           (unless (gethash name exported)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
623
             (note-package-fishiness
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
624
              :over-export (package-name package) name
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
625
              (or (home-package-p sym package) (symbol-package-name sym)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
626
             (unexport sym package))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
627
       (dolist (name shadow)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
628
         (setf (gethash name shadowed) t)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
629
         (multiple-value-bind (existing status) (find-symbol name package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
630
           (multiple-value-bind (recycled previous) (recycle-symbol name recycle exported)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
631
             (let ((shadowing (and status (symbol-shadowing-p existing package))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
632
               (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
633
                 ((eq previous package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
634
                 (previous
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
635
                  (rehome-symbol recycled package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
636
                 ((or (member status '(nil :inherited))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
637
                      (home-package-p existing package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
638
                 (t
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
639
                  (let ((dummy (make-symbol name)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
640
                    (note-package-fishiness
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
641
                     :shadow-imported (package-name package) name
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
642
                     (symbol-package-name existing) status shadowing)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
643
                    (shadowing-import* dummy package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
644
                    (import* dummy package)))))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
645
         (shadow* name package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
646
       (loop :for (p . syms) :in shadowing-import-from
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
647
             :for pp = (find-package* p) :do
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
648
               (dolist (sym syms) (ensure-shadowing-import (string sym) package pp shadowed imported)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
649
       (loop :for p :in mix
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
650
             :for pp = (find-package* p) :do
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
651
               (do-external-symbols (sym pp) (ensure-mix (symbol-name sym) sym package pp shadowed imported inherited)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
652
       (loop :for (p . syms) :in import-from
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
653
             :for pp = (find-package p) :do
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
654
               (dolist (sym syms) (ensure-import (symbol-name sym) package pp shadowed imported)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
655
       (dolist (p (append use mix))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
656
         (do-external-symbols (sym p) (ensure-inherited (string sym) sym package p nil shadowed imported inherited))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
657
         (use-package p package))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
658
       (loop :for name :being :the :hash-keys :of exported :do
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
659
         (ensure-symbol name package t recycle shadowed imported inherited exported)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
660
         (ensure-export name package recycle))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
661
       (dolist (name intern)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
662
         (ensure-symbol name package t recycle shadowed imported inherited exported))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
663
       (do-symbols (sym package)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
664
         (ensure-symbol (symbol-name sym) package nil recycle shadowed imported inherited exported))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
665
       (map () 'delete-package* to-delete)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
666
       package)))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
667
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
668
 (eval-when (:load-toplevel :compile-toplevel :execute)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
669
   (defun parse-defpkg-form (package clauses)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
670
     (loop
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
671
       :with use-p = nil :with recycle-p = nil
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
672
       :with documentation = nil
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
673
       :for (kw . args) :in clauses
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
674
       :when (eq kw :nicknames) :append args :into nicknames :else
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
675
         :when (eq kw :documentation)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
676
           :do (cond
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
677
                 (documentation (error "defpkg: can't define documentation twice"))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
678
                 ((or (atom args) (cdr args)) (error "defpkg: bad documentation"))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
679
                 (t (setf documentation (car args)))) :else
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
680
       :when (eq kw :use) :append args :into use :and :do (setf use-p t) :else
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
681
         :when (eq kw :shadow) :append args :into shadow :else
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
682
           :when (eq kw :shadowing-import-from) :collect args :into shadowing-import-from :else
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
683
             :when (eq kw :import-from) :collect args :into import-from :else
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
684
               :when (eq kw :export) :append args :into export :else
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
685
                 :when (eq kw :intern) :append args :into intern :else
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
686
                   :when (eq kw :recycle) :append args :into recycle :and :do (setf recycle-p t) :else
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
687
                     :when (eq kw :mix) :append args :into mix :else
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
688
                       :when (eq kw :reexport) :append args :into reexport :else
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
689
                         :when (eq kw :use-reexport) :append args :into use :and :append args :into reexport
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
690
                         :and :do (setf use-p t) :else
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
691
       :when (eq kw :mix-reexport) :append args :into mix :and :append args :into reexport
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
692
       :and :do (setf use-p t) :else
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
693
       :when (eq kw :unintern) :append args :into unintern :else
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
694
         :do (error "unrecognized defpkg keyword ~S" kw)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
695
       :finally (return `(,package
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
696
                          :nicknames ,nicknames :documentation ,documentation
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
697
                          :use ,(if use-p use '(:common-lisp))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
698
                          :shadow ,shadow :shadowing-import-from ,shadowing-import-from
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
699
                          :import-from ,import-from :export ,export :intern ,intern
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
700
                          :recycle ,(if recycle-p recycle (cons package nicknames))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
701
                          :mix ,mix :reexport ,reexport :unintern ,unintern)))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
702
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
703
 (defmacro defpkg (package &rest clauses)
276
bcc180c6ed91 seems like fast-methods still wont compile
Richard Westhaver <ellis@rwest.io>
parents: 223
diff changeset
704
   "Richard's Robust DEFPACKAGE macro. Based on UIOP:DEFINE-PACKAGE ymmv.
223
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
705
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
706
 DEFPKG takes a PACKAGE and a number of CLAUSES, of the form (KEYWORD . ARGS).
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
707
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
708
 DEFPKG supports the following keywords:
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
709
 USE, SHADOW, SHADOWING-IMPORT-FROM, IMPORT-FROM, EXPORT, INTERN -- as per CL:DEFPACKAGE.
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
710
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
711
 DEFPKG also redefines the following extensions:
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
712
 RECYCLE, MIX, REEXPORT, UNINTERN -- as per UIOP/PACKAGE:DEFINE-PACKAGE
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
713
 
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
714
 REEXPORT -- Takes a list of package designators. For each package in
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
715
 the list, export symbols with the same name as those exported from
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
716
 that package. In the case of shadowing, etc. They may not be EQL."
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
717
   (let ((ensure-form
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
718
           `(apply 'ensure-package ',(parse-defpkg-form package clauses))))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
719
     `(progn
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
720
        #+(or clasp ecl gcl mkcl) (defpackage ,package (:use))
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
721
        (eval-when (:compile-toplevel :load-toplevel :execute)
b9ebec84fc18 log def macros
Richard Westhaver <ellis@rwest.io>
parents: 216
diff changeset
722
          ,ensure-form))))
384
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
723
 
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
724
 ;; This macro is courtesy of Paul Werkowski. A very nice idea. (From LISA)
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
725
 
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
726
 (defmacro define-lisp-package (pkg-name)
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
727
   (flet ((externals-of (pkg)
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
728
            (loop for s being each external-symbol in pkg collect s)))
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
729
     (let* ((pkg-externs (externals-of pkg-name))
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
730
            (pkg-shadows (intersection (package-shadowing-symbols pkg-name)
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
731
                                        pkg-externs))
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
732
            (cl-externs (externals-of "COMMON-LISP")))
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
733
       `(defpackage ,(sb-int:symbolicate pkg-name "-LISP")
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
734
          (:use "COMMON-LISP")
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
735
          (:shadowing-import-from ,pkg-name ,@pkg-shadows)
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
736
          (:import-from ,pkg-name ,@(set-difference pkg-externs pkg-shadows))
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
737
          (:export ,@cl-externs)
8fe057887c17 skel refactor1
Richard Westhaver <ellis@rwest.io>
parents: 292
diff changeset
738
          (:export ,@pkg-externs)))))
395
d876b572b5b9 updates
Richard Westhaver <ellis@rwest.io>
parents: 384
diff changeset
739
 
d876b572b5b9 updates
Richard Westhaver <ellis@rwest.io>
parents: 384
diff changeset
740
 
d876b572b5b9 updates
Richard Westhaver <ellis@rwest.io>
parents: 384
diff changeset
741
 (defmacro with-package ((pkg) &body body)
d876b572b5b9 updates
Richard Westhaver <ellis@rwest.io>
parents: 384
diff changeset
742
   "Execute BODY within the package PKG."
d876b572b5b9 updates
Richard Westhaver <ellis@rwest.io>
parents: 384
diff changeset
743
   `(let ((current (package-name *package*)))
d876b572b5b9 updates
Richard Westhaver <ellis@rwest.io>
parents: 384
diff changeset
744
      (unwind-protect (progn (in-package ,pkg) ,@body)
d876b572b5b9 updates
Richard Westhaver <ellis@rwest.io>
parents: 384
diff changeset
745
        (eval-when (:compile-toplevel :load-toplevel :execute)
d876b572b5b9 updates
Richard Westhaver <ellis@rwest.io>
parents: 384
diff changeset
746
          (setq *package* (find-package current))))))