KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > kawa > lispexpr > LispPackage


1 package gnu.kawa.lispexpr;
2 import gnu.mapping.*;
3 import gnu.lists.*;
4
5 /** Implementa A Common Lisp "package" value.
6  * Far from complete. */

7
8 public class LispPackage extends Namespace
9 {
10   /** The set of exported symbols.
11    * This is on of the packages in importing.
12    */

13   Namespace exported;
14
15   LList shadowingSymbols = LList.Empty;
16
17   /** Namespaces that this Namespace imports or uses.
18    * These are the <code>imported</code> fields of the
19    * <code>NamespaceUse</code>, chained using <code>nextImported</code> fields.
20    * The CommonLisp "uses" list. */

21   NamespaceUse imported;
22   /** Namespaces that import/use this namespace.
23    * The CommonLisp "used-by" list. */

24   NamespaceUse importing;
25
26   /*
27   public static void use (Namespace importing, Namespace imported)
28   {
29     synchronized (masterLock)
30       {
31     // FIXME check conflicts.
32     NamespaceUse use = new NamespaceUse();
33     use.nextImporting = imported.importing;
34     imported.importing = use;
35     use.nextImported = importing.imported;
36     importing.imported = use;
37       }
38   }
39   */

40
41   public Symbol lookup(String JavaDoc name, int hash, boolean create)
42   {
43     Symbol sym = exported.lookup(name, hash, false);
44     if (sym != null)
45       return sym;
46     sym = lookupInternal(name, hash);
47     if (sym != null)
48       return sym;
49
50     // Do we need to synchronize on masterLock as well? FIXME
51
for (NamespaceUse used = imported; used != null;
52      used = used.nextImported)
53       {
54     sym = lookup(name, hash, false);
55     if (sym != null)
56       return sym;
57       }
58
59     if (create)
60       return add(new Symbol(this, name), hash);
61     else
62       return null;
63   }
64
65   public Symbol lookupPresent (String JavaDoc name, int hash, boolean intern)
66   {
67     Symbol sym = exported.lookup(name, hash, false);
68     if (sym == null)
69       sym = super.lookup(name, hash, intern);
70     return sym;
71   }
72
73   public boolean isPresent (String JavaDoc name)
74   {
75     return lookupPresent(name, name.hashCode(), false) != null;
76   }
77
78   public boolean unintern (Symbol symbol)
79   {
80     String JavaDoc name = symbol.getName();
81     int hash = name.hashCode();
82     if (exported.lookup(name, hash, false) == symbol)
83       exported.remove(symbol);
84     else if (super.lookup(name, hash, false) == symbol)
85       super.remove(symbol);
86     else
87       return false;
88     symbol.setNamespace(null);
89     if (removeFromShadowingSymbols(symbol))
90       {
91     // FIXME check use list: If thee are two or more different symbols
92
// named 'name' in used packages, then signal a conflict.
93
}
94     return true;
95   }
96
97   private void addToShadowingSymbols (Symbol sym)
98   {
99     for (Object JavaDoc s = shadowingSymbols; s != LList.Empty; )
100       {
101     Pair p = (Pair) s;
102     if (p.car == sym)
103       return;
104     s = p.cdr;
105       }
106     shadowingSymbols = new Pair(sym, shadowingSymbols);
107   }
108
109   private boolean removeFromShadowingSymbols (Symbol sym)
110   {
111     Pair prev = null;
112     for (Object JavaDoc s = shadowingSymbols; s != LList.Empty; )
113       {
114     Pair p = (Pair) s;
115     s = p.cdr;
116     if (p.car == sym)
117       {
118         if (prev == null)
119           shadowingSymbols = (LList) s;
120         else
121           prev.cdr = s;
122         return true;
123       }
124     prev = p;
125       }
126     return false;
127   }
128
129   /** The core of the Common Lisp shadow function. */
130   public void shadow (String JavaDoc name)
131   {
132     Symbol sym = lookupPresent(name, name.hashCode(), true);
133     addToShadowingSymbols(sym);
134   }
135
136   public void shadowingImport (Symbol symbol)
137   {
138     String JavaDoc name = symbol.getName();
139     int hash = name.hashCode();
140     Symbol old = lookupPresent(name, name.hashCode(), false);
141     if (old != null && old != symbol)
142       unintern(old);
143     addToShadowingSymbols(symbol);
144   }
145
146 }
147
148
149 /** This is used to implement two linked lists.
150  * For performance they're combined into one object. */

151 class NamespaceUse
152 {
153   Namespace imported;
154   NamespaceUse nextImported;
155
156   Namespace importing;
157   NamespaceUse nextImporting;
158 }
159
Popular Tags