source: trunk/j/src/org/armedbear/lisp/defpackage.lisp @ 11299

Last change on this file since 11299 was 11299, checked in by ehuelsmann, 15 years ago

Fix DEFPACKAGE.24 and DEFPACKAGE.25 ansi-tests.

We're now at 58 failing tests.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.3 KB
Line 
1;;; defpackage.lisp
2;;;
3;;; Copyright (C) 2003-2007 Peter Graves
4;;; $Id: defpackage.lisp 11299 2008-08-31 20:19:05Z ehuelsmann $
5;;;
6;;; This program is free software; you can redistribute it and/or
7;;; modify it under the terms of the GNU General Public License
8;;; as published by the Free Software Foundation; either version 2
9;;; of the License, or (at your option) any later version.
10;;;
11;;; This program is distributed in the hope that it will be useful,
12;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with this program; if not, write to the Free Software
18;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19
20(in-package "SYSTEM")
21
22;;; Adapted from CMUCL.
23
24(defun designated-package-name (designator)
25  (cond ((packagep designator)
26         (package-name designator))
27        (t
28         (string designator))))
29
30(defun stringify-names (names)
31  (mapcar #'string names))
32
33(defun check-disjoint (&rest args)
34  (let ((rest-args args))
35    (dolist (arg1 args)
36      (let ((key1 (car arg1))
37            (set1 (cdr arg1)))
38        (setq rest-args (cdr rest-args))
39        (dolist (arg2 rest-args)
40          (let* ((key2 (car arg2))
41                 (set2 (cdr arg2))
42                 (common (remove-duplicates (intersection set1 set2 :test #'string=))))
43            (when common
44              (error 'program-error
45                     :format-control
46                     "Parameters ~S and ~S must be disjoint, but have common elements: ~S"
47                     :format-arguments
48                     (list key1 key2 common)))))))))
49
50(defun ensure-available-symbols (symbols)
51   symbols)
52
53(defmacro defpackage (package &rest options)
54  (let ((nicknames nil)
55  (size nil)
56  (shadows nil)
57  (shadowing-imports nil)
58  (use nil)
59  (use-p nil)
60  (imports nil)
61  (interns nil)
62  (exports nil)
63  (doc nil))
64    (dolist (option options)
65      (unless (consp option)
66  (error 'program-error "bad DEFPACKAGE option: ~S" option))
67      (case (car option)
68  (:nicknames
69   (setq nicknames (stringify-names (cdr option))))
70  (:size
71   (cond (size
72    (error 'program-error "can't specify :SIZE twice"))
73         ((and (consp (cdr option))
74         (typep (second option) 'unsigned-byte))
75    (setq size (second option)))
76         (t
77    (error 'program-error
78     "bad :SIZE, must be a positive integer: ~S"
79     (second option)))))
80  (:shadow
81   (let ((new (stringify-names (cdr option))))
82     (setq shadows (append shadows new))))
83  (:shadowing-import-from
84   (let ((package-name (designated-package-name (cadr option)))
85         (symbol-names (stringify-names (cddr option))))
86     (let ((assoc (assoc package-name shadowing-imports
87             :test #'string=)))
88       (if assoc
89     (setf (cdr assoc) (append (cdr assoc) symbol-names))
90     (setq shadowing-imports
91           (acons package-name symbol-names shadowing-imports))))))
92  (:use
93   (let ((new (mapcar #'designated-package-name (cdr option))))
94     (setq use (delete-duplicates (nconc use new) :test #'string=))
95     (setq use-p t)))
96  (:import-from
97   (let ((package-name (designated-package-name (cadr option)))
98         (symbol-names (stringify-names (cddr option))))
99     (let ((assoc (assoc package-name imports
100             :test #'string=)))
101       (if assoc
102     (setf (cdr assoc) (append (cdr assoc) symbol-names))
103     (setq imports (acons package-name symbol-names imports))))))
104  (:intern
105   (let ((new (stringify-names (cdr option))))
106     (setq interns (append interns new))))
107  (:export
108   (let ((new (stringify-names (cdr option))))
109     (setq exports (append exports new))))
110  (:documentation
111   (when doc
112     (error 'program-error "can't specify :DOCUMENTATION twice"))
113   (setq doc (coerce (cadr option) 'simple-string)))
114  (t
115   (error 'program-error "bad DEFPACKAGE option: ~S" option))))
116    (check-disjoint `(:intern ,@interns) `(:export  ,@exports))
117    (check-disjoint `(:intern ,@interns)
118        `(:import-from
119          ,@(apply #'append (mapcar #'rest imports)))
120        `(:shadow ,@shadows)
121        `(:shadowing-import-from
122          ,@(apply #'append (mapcar #'rest shadowing-imports))))
123    `(%defpackage ,(string package) ',nicknames ',size
124                  ',shadows (ensure-available-symbols ',shadowing-imports)
125                  ',(if use-p use nil)
126                  (ensure-available-symbols ',imports) ',interns ',exports ',doc)))
Note: See TracBrowser for help on using the repository browser.