source: branches/0.22.x/abcl/src/org/armedbear/lisp/Package.java

Last change on this file was 12713, checked in by astalla, 15 years ago

Serialization support for some Lisp types.
For symbols and packages, only the "identity" is serialized, i.e. package name + symbol name.
For packages, it is expected that a package of the same name exists "at the other side".
For symbols, the deserialized symbol is interned in its home package.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 29.3 KB
Line 
1/*
2 * Package.java
3 *
4 * Copyright (C) 2002-2007 Peter Graves <peter@armedbear.org>
5 * $Id: Package.java 12713 2010-05-20 17:58:13Z astalla $
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36import static org.armedbear.lisp.Lisp.*;
37
38import java.util.ArrayList;
39import java.util.HashMap;
40import java.util.Iterator;
41import java.util.List;
42
43public final class Package extends LispObject implements java.io.Serializable
44{
45    private String name;
46    private transient SimpleString lispName;
47
48    private transient LispObject propertyList;
49
50    private transient final SymbolHashTable internalSymbols = new SymbolHashTable(16);
51    private transient final SymbolHashTable externalSymbols = new SymbolHashTable(16);
52
53    private transient HashMap<String,Symbol> shadowingSymbols;
54    private transient ArrayList<String> nicknames;
55    private transient LispObject useList = null;
56    private transient ArrayList<Package> usedByList = null;
57
58    // Anonymous package.
59    public Package()
60    {
61    }
62
63    public Package(String name)
64    {
65        this.name = name;
66        lispName = new SimpleString(name);
67    }
68
69    public Package(String name, int size)
70    {
71        this.name = name;
72        lispName = new SimpleString(name);
73    }
74
75    @Override
76    public LispObject typeOf()
77    {
78        return Symbol.PACKAGE;
79    }
80
81    @Override
82    public LispObject classOf()
83    {
84        return BuiltInClass.PACKAGE;
85    }
86
87    @Override
88    public LispObject getDescription()
89    {
90        if (name != null) {
91            StringBuilder sb = new StringBuilder("The ");
92            sb.append(name);
93            sb.append(" package");
94            return new SimpleString(sb);
95        }
96        return new SimpleString("PACKAGE");
97    }
98
99    @Override
100    public LispObject typep(LispObject type)
101    {
102        if (type == Symbol.PACKAGE)
103            return T;
104        if (type == BuiltInClass.PACKAGE)
105            return T;
106        return super.typep(type);
107    }
108
109    public final String getName()
110    {
111        return name;
112    }
113
114    public final LispObject NAME()
115    {
116        return lispName != null ? lispName : NIL;
117    }
118
119    @Override
120    public final LispObject getPropertyList()
121    {
122        if (propertyList == null)
123            propertyList = NIL;
124        return propertyList;
125    }
126
127    @Override
128    public final void setPropertyList(LispObject obj)
129    {
130        if (obj == null)
131            throw new NullPointerException();
132        propertyList = obj;
133    }
134
135    public final List getNicknames()
136    {
137        return nicknames;
138    }
139
140    public final synchronized boolean delete()
141    {
142        if (name != null) {
143            Packages.deletePackage(this);
144            List internals = internalSymbols.getSymbols();
145            for (int i = internals.size(); i-- > 0;) {
146                Symbol symbol = (Symbol) internals.get(i);
147                if (symbol.getPackage() == this)
148                    symbol.setPackage(NIL);
149                internalSymbols.remove(symbol);
150            }
151            List externals = externalSymbols.getSymbols();
152            for (int i = externals.size(); i-- > 0;) {
153                Symbol symbol = (Symbol) externals.get(i);
154                if (symbol.getPackage() == this)
155                    symbol.setPackage(NIL);
156                externalSymbols.remove(symbol);
157            }
158            name = null;
159            lispName = null;
160            nicknames = null;
161            return true;
162        }
163        return false;
164    }
165
166    public final synchronized void rename(String newName, LispObject newNicks)
167
168    {
169        ArrayList<String> arrayList = null;
170        while (newNicks != NIL) {
171            if (arrayList == null)
172                arrayList = new ArrayList<String>();
173            arrayList.add(javaString(newNicks.car()));
174            newNicks = newNicks.cdr();
175        }
176        // Remove old name and nicknames from Packages map.
177        Packages.deletePackage(this);
178        // Now change the names...
179        name = newName;
180        lispName = new SimpleString(newName);
181        nicknames = arrayList;
182        // And add the package back.
183        Packages.addPackage(this);
184    }
185
186    public synchronized Symbol findInternalSymbol(SimpleString name)
187    {
188        return internalSymbols.get(name);
189    }
190
191    public synchronized Symbol findExternalSymbol(SimpleString name)
192    {
193        return externalSymbols.get(name);
194    }
195
196    public synchronized Symbol findExternalSymbol(SimpleString name, int hash)
197    {
198        return externalSymbols.get(name, hash);
199    }
200
201    // Returns null if symbol is not accessible in this package.
202    public synchronized Symbol findAccessibleSymbol(String name)
203
204    {
205        return findAccessibleSymbol(new SimpleString(name));
206    }
207
208    // Returns null if symbol is not accessible in this package.
209    public synchronized Symbol findAccessibleSymbol(SimpleString name)
210
211    {
212        // Look in external and internal symbols of this package.
213        Symbol symbol = externalSymbols.get(name);
214        if (symbol != null)
215            return symbol;
216        symbol = internalSymbols.get(name);
217        if (symbol != null)
218            return symbol;
219        // Look in external symbols of used packages.
220        if (useList instanceof Cons) {
221            LispObject usedPackages = useList;
222            while (usedPackages != NIL) {
223                Package pkg = (Package) usedPackages.car();
224                symbol = pkg.findExternalSymbol(name);
225                if (symbol != null)
226                    return symbol;
227                usedPackages = usedPackages.cdr();
228            }
229        }
230        // Not found.
231        return null;
232    }
233
234    public synchronized LispObject findSymbol(String name)
235
236    {
237        final SimpleString s = new SimpleString(name);
238        final LispThread thread = LispThread.currentThread();
239        // Look in external and internal symbols of this package.
240        Symbol symbol = externalSymbols.get(s);
241        if (symbol != null)
242            return thread.setValues(symbol, Keyword.EXTERNAL);
243        symbol = internalSymbols.get(s);
244        if (symbol != null)
245            return thread.setValues(symbol, Keyword.INTERNAL);
246        // Look in external symbols of used packages.
247        if (useList instanceof Cons) {
248            LispObject usedPackages = useList;
249            while (usedPackages != NIL) {
250                Package pkg = (Package) usedPackages.car();
251                symbol = pkg.findExternalSymbol(s);
252                if (symbol != null)
253                    return thread.setValues(symbol, Keyword.INHERITED);
254                usedPackages = usedPackages.cdr();
255            }
256        }
257        // Not found.
258        return thread.setValues(NIL, NIL);
259    }
260
261    // Helper function to add NIL to PACKAGE_CL.
262    public synchronized void addSymbol(Symbol symbol)
263    {
264        Debug.assertTrue(symbol.getPackage() == this);
265        Debug.assertTrue(symbol.getName().equals("NIL"));
266        externalSymbols.put(symbol.name, symbol);
267    }
268
269    private synchronized Symbol addSymbol(SimpleString name, int hash)
270    {
271        Symbol symbol = new Symbol(name, hash, this);
272        if (this == PACKAGE_KEYWORD) {
273            symbol.initializeConstant(symbol);
274            externalSymbols.put(name, symbol);
275        } else
276            internalSymbols.put(name, symbol);
277       
278        return symbol;
279    }
280
281    public synchronized Symbol addInternalSymbol(String symbolName)
282    {
283        final Symbol symbol = new Symbol(symbolName, this);
284        internalSymbols.put(symbol);
285        return symbol;
286    }
287
288    public synchronized Symbol addExternalSymbol(String symbolName)
289    {
290        final Symbol symbol = new Symbol(symbolName, this);
291        externalSymbols.put(symbol);
292        return symbol;
293    }
294
295    public synchronized Symbol intern(String symbolName)
296    {
297        return intern(new SimpleString(symbolName));
298    }
299
300    public synchronized Symbol intern(SimpleString symbolName)
301    {
302        final int hash = symbolName.sxhash();
303        // Look in external and internal symbols of this package.
304        Symbol symbol = externalSymbols.get(symbolName, hash);
305        if (symbol != null)
306            return symbol;
307        symbol = internalSymbols.get(symbolName, hash);
308        if (symbol != null)
309            return symbol;
310        // Look in external symbols of used packages.
311        if (useList instanceof Cons) {
312            LispObject usedPackages = useList;
313            while (usedPackages != NIL) {
314                Package pkg = (Package) usedPackages.car();
315                symbol = pkg.findExternalSymbol(symbolName, hash);
316                if (symbol != null)
317                    return symbol;
318                usedPackages = usedPackages.cdr();
319            }
320        }
321        // Not found.
322        return addSymbol(symbolName, hash);
323    }
324
325    public synchronized Symbol intern(final SimpleString s,
326                                      final LispThread thread)
327    {
328        final int hash = s.sxhash();
329        // Look in external and internal symbols of this package.
330        Symbol symbol = externalSymbols.get(s, hash);
331        if (symbol != null)
332            return (Symbol) thread.setValues(symbol, Keyword.EXTERNAL);
333        symbol = internalSymbols.get(s, hash);
334        if (symbol != null)
335            return (Symbol) thread.setValues(symbol, Keyword.INTERNAL);
336        // Look in external symbols of used packages.
337        if (useList instanceof Cons) {
338            LispObject usedPackages = useList;
339            while (usedPackages != NIL) {
340                Package pkg = (Package) usedPackages.car();
341                symbol = pkg.findExternalSymbol(s, hash);
342                if (symbol != null)
343                    return (Symbol) thread.setValues(symbol, Keyword.INHERITED);
344                usedPackages = usedPackages.cdr();
345            }
346        }
347        // Not found.
348        return (Symbol) thread.setValues(addSymbol(s, hash), NIL);
349    }
350
351    public synchronized Symbol internAndExport(String symbolName)
352
353    {
354        final SimpleString s = new SimpleString(symbolName);
355        final int hash = s.sxhash();
356        // Look in external and internal symbols of this package.
357        Symbol symbol = externalSymbols.get(s, hash);
358        if (symbol != null)
359            return symbol;
360        symbol = internalSymbols.get(s, hash);
361        if (symbol != null) {
362            export(symbol);
363            return symbol;
364        }
365        if (useList instanceof Cons) {
366            // Look in external symbols of used packages.
367            LispObject usedPackages = useList;
368            while (usedPackages != NIL) {
369                Package pkg = (Package) usedPackages.car();
370                symbol = pkg.findExternalSymbol(s, hash);
371                if (symbol != null) {
372                    export(symbol);
373                    return symbol;
374                }
375                usedPackages = usedPackages.cdr();
376            }
377        }
378        // Not found.
379        symbol = new Symbol(s, hash, this);
380        if (this == PACKAGE_KEYWORD)
381            symbol.initializeConstant(symbol);
382        externalSymbols.put(s, symbol);
383        return symbol;
384    }
385
386    public synchronized LispObject unintern(final Symbol symbol)
387
388    {
389        final String symbolName = symbol.getName();
390        final boolean shadow;
391        if (shadowingSymbols != null && shadowingSymbols.get(symbolName) == symbol)
392            shadow = true;
393        else
394            shadow = false;
395        if (shadow) {
396            // Check for conflicts that might be exposed in used package list
397            // if we remove the shadowing symbol.
398            Symbol sym = null;
399            if (useList instanceof Cons) {
400                LispObject usedPackages = useList;
401                while (usedPackages != NIL) {
402                    Package pkg = (Package) usedPackages.car();
403                    Symbol s = pkg.findExternalSymbol(symbol.name);
404                    if (s != null) {
405                        if (sym == null)
406                            sym = s;
407                        else if (sym != s) {
408                            StringBuilder sb =
409                                new StringBuilder("Uninterning the symbol ");
410                            sb.append(symbol.getQualifiedName());
411                            sb.append(" causes a name conflict between ");
412                            sb.append(sym.getQualifiedName());
413                            sb.append(" and ");
414                            sb.append(s.getQualifiedName());
415                            return error(new PackageError(sb.toString()));
416                        }
417                    }
418                    usedPackages = usedPackages.cdr();
419                }
420            }
421        }
422        // Reaching here, it's OK to remove the symbol.
423        if (internalSymbols.get(symbol.name) == symbol)
424            internalSymbols.remove(symbol.name);
425        else if (externalSymbols.get(symbol.name) == symbol)
426            externalSymbols.remove(symbol.name);
427        else
428            // Not found.
429            return NIL;
430        if (shadow) {
431            Debug.assertTrue(shadowingSymbols != null);
432            shadowingSymbols.remove(symbolName);
433        }
434        if (symbol.getPackage() == this)
435            symbol.setPackage(NIL);
436        return T;
437    }
438
439    public synchronized void importSymbol(Symbol symbol)
440    {
441        if (symbol.getPackage() == this)
442            return; // Nothing to do.
443        Symbol sym = findAccessibleSymbol(symbol.name);
444        if (sym != null && sym != symbol) {
445            StringBuilder sb = new StringBuilder("The symbol ");
446            sb.append(sym.getQualifiedName());
447            sb.append(" is already accessible in package ");
448            sb.append(name);
449            sb.append('.');
450            error(new PackageError(sb.toString()));
451        }
452        internalSymbols.put(symbol.name, symbol);
453        if (symbol.getPackage() == NIL)
454            symbol.setPackage(this);
455    }
456
457    public synchronized void export(final Symbol symbol)
458    {
459        final String symbolName = symbol.getName();
460        boolean added = false;
461        if (symbol.getPackage() != this) {
462            Symbol sym = findAccessibleSymbol(symbol.name);
463            if (sym != symbol) {
464                StringBuilder sb = new StringBuilder("The symbol ");
465                sb.append(symbol.getQualifiedName());
466                sb.append(" is not accessible in package ");
467                sb.append(name);
468                sb.append('.');
469                error(new PackageError(sb.toString()));
470                return;
471            }
472            internalSymbols.put(symbol.name, symbol);
473            added = true;
474        }
475        if (added || internalSymbols.get(symbol.name) == symbol) {
476            if (usedByList != null) {
477                for (Iterator it = usedByList.iterator(); it.hasNext();) {
478                    Package pkg = (Package) it.next();
479                    Symbol sym = pkg.findAccessibleSymbol(symbol.name);
480                    if (sym != null && sym != symbol) {
481                        if (pkg.shadowingSymbols != null &&
482                            pkg.shadowingSymbols.get(symbolName) == sym) {
483                            // OK.
484                        } else {
485                            StringBuilder sb = new StringBuilder("The symbol ");
486                            sb.append(sym.getQualifiedName());
487                            sb.append(" is already accessible in package ");
488                            sb.append(pkg.getName());
489                            sb.append('.');
490                            error(new PackageError(sb.toString()));
491                            return;
492                        }
493                    }
494                }
495            }
496            // No conflicts.
497            internalSymbols.remove(symbol.name);
498            externalSymbols.put(symbol.name, symbol);
499            return;
500        }
501        if (externalSymbols.get(symbol.name) == symbol)
502            // Symbol is already exported; there's nothing to do.
503            return;
504        StringBuilder sb = new StringBuilder("The symbol ");
505        sb.append(symbol.getQualifiedName());
506        sb.append(" is not accessible in package ");
507        sb.append(name);
508        sb.append('.');
509        error(new PackageError(sb.toString()));
510    }
511
512    public synchronized void unexport(final Symbol symbol)
513
514    {
515        if (symbol.getPackage() == this) {
516            if (externalSymbols.get(symbol.name) == symbol) {
517                externalSymbols.remove(symbol.name);
518                internalSymbols.put(symbol.name, symbol);
519            }
520        } else {
521            // Signal an error if symbol is not accessible.
522            if (useList instanceof Cons) {
523                LispObject usedPackages = useList;
524                while (usedPackages != NIL) {
525                    Package pkg = (Package) usedPackages.car();
526                    if (pkg.findExternalSymbol(symbol.name) == symbol)
527                        return; // OK.
528                    usedPackages = usedPackages.cdr();
529                }
530            }
531            StringBuilder sb = new StringBuilder("The symbol ");
532            sb.append(symbol.getQualifiedName());
533            sb.append(" is not accessible in package ");
534            sb.append(name);
535            error(new PackageError(sb.toString()));
536        }
537    }
538
539    public synchronized void shadow(final String symbolName)
540
541    {
542        if (shadowingSymbols == null)
543            shadowingSymbols = new HashMap<String,Symbol>();
544        final SimpleString s = new SimpleString(symbolName);
545        Symbol symbol = externalSymbols.get(s);
546        if (symbol != null) {
547            shadowingSymbols.put(symbolName, symbol);
548            return;
549        }
550        symbol = internalSymbols.get(s);
551        if (symbol != null) {
552            shadowingSymbols.put(symbolName, symbol);
553            return;
554        }
555        if (shadowingSymbols.get(symbolName) != null)
556            return;
557        symbol = new Symbol(s, this);
558        internalSymbols.put(s, symbol);
559        shadowingSymbols.put(symbolName, symbol);
560    }
561
562    public synchronized void shadowingImport(Symbol symbol)
563    {
564        LispObject where = NIL;
565        final String symbolName = symbol.getName();
566        Symbol sym = externalSymbols.get(symbol.name);
567        if (sym != null) {
568            where = Keyword.EXTERNAL;
569        } else {
570            sym = internalSymbols.get(symbol.name);
571            if (sym != null) {
572                where = Keyword.INTERNAL;
573            } else {
574                // Look in external symbols of used packages.
575                if (useList instanceof Cons) {
576                    LispObject usedPackages = useList;
577                    while (usedPackages != NIL) {
578                        Package pkg = (Package) usedPackages.car();
579                        sym = pkg.findExternalSymbol(symbol.name);
580                        if (sym != null) {
581                            where = Keyword.INHERITED;
582                            break;
583                        }
584                        usedPackages = usedPackages.cdr();
585                    }
586                }
587            }
588        }
589        if (sym != null) {
590            if (where == Keyword.INTERNAL || where == Keyword.EXTERNAL) {
591                if (sym != symbol) {
592                    if (shadowingSymbols != null)
593                        shadowingSymbols.remove(symbolName);
594                    unintern(sym);
595                } else if (where == Keyword.INTERNAL) {
596                    // Assert rgument is already correctly a shadowing import
597                    Debug.assertTrue(shadowingSymbols != null);
598                    Debug.assertTrue(shadowingSymbols.get(symbolName) != null);
599                    return;
600                }
601            }
602        }
603        internalSymbols.put(symbol.name, symbol);
604        if (shadowingSymbols == null)
605            shadowingSymbols = new HashMap<String,Symbol>();
606        Debug.assertTrue(shadowingSymbols.get(symbolName) == null);
607        shadowingSymbols.put(symbolName, symbol);
608    }
609
610    // "USE-PACKAGE causes PACKAGE to inherit all the external symbols of
611    // PACKAGES-TO-USE. The inherited symbols become accessible as internal
612    // symbols of PACKAGE."
613    public void usePackage(Package pkg)
614    {
615        if (useList == null)
616            useList = NIL;
617        if (!memq(pkg, useList)) {
618            // "USE-PACKAGE checks for name conflicts between the newly
619            // imported symbols and those already accessible in package."
620            List symbols = pkg.getExternalSymbols();
621            for (int i = symbols.size(); i-- > 0;) {
622                Symbol symbol = (Symbol) symbols.get(i);
623                Symbol existing = findAccessibleSymbol(symbol.name);
624                if (existing != null && existing != symbol) {
625                    if (shadowingSymbols == null ||
626                        shadowingSymbols.get(symbol.getName()) == null)
627                    {
628                        error(new PackageError("A symbol named " + symbol.getName() +
629                                                " is already accessible in package " +
630                                                name + "."));
631                        return;
632                    }
633                }
634            }
635            useList = useList.push(pkg);
636            // Add this package to the used-by list of pkg.
637            if (pkg.usedByList != null)
638                Debug.assertTrue(!pkg.usedByList.contains(this));
639            if (pkg.usedByList == null)
640                pkg.usedByList = new ArrayList<Package>();
641            pkg.usedByList.add(this);
642        }
643    }
644
645    public void unusePackage(Package pkg)
646    {
647        if (useList instanceof Cons) {
648            if (memq(pkg, useList)) {
649                // FIXME Modify the original list instead of copying it!
650                LispObject newList = NIL;
651                while (useList != NIL) {
652                    if (useList.car() != pkg)
653                        newList = newList.push(useList.car());
654                    useList = useList.cdr();
655                }
656                useList = newList.nreverse();
657                Debug.assertTrue(!memq(pkg, useList));
658                Debug.assertTrue(pkg.usedByList != null);
659                Debug.assertTrue(pkg.usedByList.contains(this));
660                pkg.usedByList.remove(this);
661            }
662        }
663    }
664
665    public final void addNickname(String s)
666    {
667        // This call will signal an error if there's a naming conflict.
668        Packages.addNickname(this, s);
669
670        if (nicknames != null) {
671            if (nicknames.contains(s))
672                return; // Nothing to do.
673        } else
674            nicknames = new ArrayList<String>();
675
676        nicknames.add(s);
677    }
678
679    public String getNickname()
680    {
681        if (nicknames != null && nicknames.size() > 0)
682            return (String) nicknames.get(0);
683        return null;
684    }
685
686    public LispObject packageNicknames()
687    {
688        LispObject list = NIL;
689        if (nicknames != null) {
690            for (int i = nicknames.size(); i-- > 0;) {
691                String nickname = (String) nicknames.get(i);
692                list = new Cons(new SimpleString(nickname), list);
693            }
694        }
695        return list;
696    }
697
698    public LispObject getUseList()
699    {
700        if (useList == null)
701            useList = NIL;
702        return useList;
703    }
704
705    public boolean uses(LispObject pkg)
706    {
707        return (useList instanceof Cons) && memq(pkg, useList);
708    }
709
710    public LispObject getUsedByList()
711    {
712        LispObject list = NIL;
713        if (usedByList != null) {
714            for (Iterator it = usedByList.iterator(); it.hasNext();) {
715                Package pkg = (Package) it.next();
716                list = new Cons(pkg, list);
717            }
718        }
719        return list;
720    }
721
722    public LispObject getShadowingSymbols()
723    {
724        LispObject list = NIL;
725        if (shadowingSymbols != null) {
726            for (Iterator it = shadowingSymbols.values().iterator(); it.hasNext();) {
727                Symbol symbol = (Symbol) it.next();
728                list = new Cons(symbol, list);
729            }
730        }
731        return list;
732    }
733
734    public synchronized List getExternalSymbols()
735    {
736        return externalSymbols.getSymbols();
737    }
738
739    public synchronized List<Symbol> getAccessibleSymbols()
740    {
741        ArrayList<Symbol> list = new ArrayList<Symbol>();
742        list.addAll(internalSymbols.getSymbols());
743        list.addAll(externalSymbols.getSymbols());
744        if (useList instanceof Cons) {
745            LispObject usedPackages = useList;
746            while (usedPackages != NIL) {
747                Package pkg = (Package) usedPackages.car();
748                List<Symbol> symbols = pkg.externalSymbols.getSymbols();
749                for (int i = 0; i < symbols.size(); i++) {
750                    Symbol symbol = (Symbol) symbols.get(i);
751                    if (shadowingSymbols == null || shadowingSymbols.get(symbol.getName()) == null)
752                        list.add(symbol);
753                }
754                usedPackages = usedPackages.cdr();
755            }
756        }
757        return list;
758    }
759
760    public synchronized LispObject PACKAGE_INTERNAL_SYMBOLS()
761    {
762        LispObject list = NIL;
763        List symbols = internalSymbols.getSymbols();
764        for (int i = symbols.size(); i-- > 0;)
765            list = new Cons((Symbol)symbols.get(i), list);
766        return list;
767    }
768
769    public synchronized LispObject PACKAGE_EXTERNAL_SYMBOLS()
770    {
771        LispObject list = NIL;
772        List symbols = externalSymbols.getSymbols();
773        for (int i = symbols.size(); i-- > 0;)
774            list = new Cons((Symbol)symbols.get(i), list);
775        return list;
776    }
777
778    public synchronized LispObject PACKAGE_INHERITED_SYMBOLS()
779    {
780        LispObject list = NIL;
781        if (useList instanceof Cons) {
782            LispObject usedPackages = useList;
783            while (usedPackages != NIL) {
784                Package pkg = (Package) usedPackages.car();
785                List externals = pkg.getExternalSymbols();
786                for (int i = externals.size(); i-- > 0;) {
787                    Symbol symbol = (Symbol) externals.get(i);
788                    if (shadowingSymbols != null && shadowingSymbols.get(symbol.getName()) != null)
789                        continue;
790                    if (externalSymbols.get(symbol.name) == symbol)
791                        continue;
792                    list = new Cons(symbol, list);
793                }
794                usedPackages = usedPackages.cdr();
795            }
796        }
797        return list;
798    }
799
800    public synchronized LispObject getSymbols()
801    {
802        LispObject list = NIL;
803        List internals = internalSymbols.getSymbols();
804        for (int i = internals.size(); i-- > 0;)
805            list = new Cons((Symbol)internals.get(i), list);
806        List externals = externalSymbols.getSymbols();
807        for (int i = externals.size(); i-- > 0;)
808            list = new Cons((Symbol)externals.get(i), list);
809        return list;
810    }
811
812    public synchronized Symbol[] symbols()
813    {
814        List internals = internalSymbols.getSymbols();
815        List externals = externalSymbols.getSymbols();
816        Symbol[] array = new Symbol[internals.size() + externals.size()];
817        int i = 0;
818        for (Iterator it = internals.iterator(); it.hasNext();) {
819            Symbol symbol = (Symbol) it.next();
820            array[i++] = symbol;
821        }
822        for (Iterator it = externals.iterator(); it.hasNext();) {
823            Symbol symbol = (Symbol) it.next();
824            array[i++] = symbol;
825        }
826        return array;
827    }
828
829    @Override
830    public String writeToString()
831    {
832        if (_PRINT_FASL_.symbolValue() != NIL && name != null) {
833            StringBuilder sb = new StringBuilder("#.(FIND-PACKAGE \"");
834            sb.append(name);
835            sb.append("\")");
836            return sb.toString();
837        } else
838            return toString();
839    }
840   
841    @Override
842    public String toString() {
843         if (name != null) {
844            StringBuilder sb = new StringBuilder("#<PACKAGE \"");
845            sb.append(name);
846            sb.append("\">");
847            return sb.toString();
848        } else
849            return unreadableString("PACKAGE");
850    }
851
852    public Object readResolve() throws java.io.ObjectStreamException {
853  Package pkg = Packages.findPackage(name);
854  if(pkg != null) {
855      return pkg;
856  } else {
857      return error(new PackageError(name + " is not the name of a package."));
858  }
859    }
860}
Note: See TracBrowser for help on using the repository browser.