source: branches/0.19.x/abcl/src/org/armedbear/lisp/LispClass.java

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

Merge 'metaclass' branch, making STANDARD-CLASS have slots to

be inherited by deriving metaclasses.

Note: this does definitely *not* complete the metaclass work.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.6 KB
Line 
1/*
2 * LispClass.java
3 *
4 * Copyright (C) 2003-2005 Peter Graves
5 * $Id: LispClass.java 12481 2010-02-14 21:29:58Z ehuelsmann $
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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
38public abstract class LispClass extends StandardObject
39{
40  private static final EqHashTable map = new EqHashTable(256, NIL, NIL);
41
42  public static LispClass addClass(Symbol symbol, LispClass c)
43  {
44    synchronized (map)
45      {
46        map.put(symbol, c);
47      }
48    return c;
49  }
50
51  public static void removeClass(Symbol symbol)
52  {
53    synchronized (map)
54      {
55        map.remove(symbol);
56      }
57  }
58
59  public static LispClass findClass(Symbol symbol)
60  {
61    synchronized (map)
62      {
63        return (LispClass) map.get(symbol);
64      }
65  }
66
67  public static LispObject findClass(LispObject name, boolean errorp)
68
69  {
70    final Symbol symbol = checkSymbol(name);
71    final LispClass c;
72    synchronized (map)
73      {
74        c = (LispClass) map.get(symbol);
75      }
76    if (c != null)
77      return c;
78    if (errorp)
79      {
80        StringBuilder sb =
81          new StringBuilder("There is no class named ");
82        sb.append(name.writeToString());
83        sb.append('.');
84        return error(new LispError(sb.toString()));
85      }
86    return NIL;
87  }
88
89  private final int sxhash;
90
91  private LispObject name;
92  private LispObject propertyList;
93  private Layout classLayout;
94  private LispObject directSuperclasses = NIL;
95  private LispObject directSubclasses = NIL;
96  private LispObject classPrecedenceList = NIL;
97  private LispObject directMethods = NIL;
98  private LispObject documentation = NIL;
99  private boolean finalized;
100
101  protected LispClass(Layout layout)
102  {
103    super(layout, layout == null ? 0 : layout.getLength());
104    sxhash = hashCode() & 0x7fffffff;
105  }
106
107  protected LispClass(Symbol symbol)
108  {
109    this(null, symbol);
110  }
111
112  protected LispClass(Layout layout, Symbol symbol)
113  {
114    super(layout, layout == null ? 0 : layout.getLength());
115    setName(symbol);
116    sxhash = hashCode() & 0x7fffffff;
117  }
118
119  protected LispClass(Layout layout,
120                      Symbol symbol, LispObject directSuperclasses)
121  {
122    super(layout, layout == null ? 0 : layout.getLength());
123    sxhash = hashCode() & 0x7fffffff;
124    setName(symbol);
125    setDirectSuperclasses(directSuperclasses);
126  }
127
128  @Override
129  public LispObject getParts()
130  {
131    LispObject result = NIL;
132    result = result.push(new Cons("NAME", name != null ? name : NIL));
133    result = result.push(new Cons("LAYOUT",
134                                  getClassLayout() != null
135                                  ? getClassLayout() : NIL));
136    result = result.push(new Cons("DIRECT-SUPERCLASSES",
137                                  getDirectSuperclasses()));
138    result = result.push(new Cons("DIRECT-SUBCLASSES", getDirectSubclasses()));
139    result = result.push(new Cons("CLASS-PRECEDENCE-LIST", getCPL()));
140    result = result.push(new Cons("DIRECT-METHODS", getDirectMethods()));
141    result = result.push(new Cons("DOCUMENTATION", getDocumentation()));
142    return result.nreverse();
143  }
144
145  @Override
146  public final int sxhash()
147  {
148    return sxhash;
149  }
150
151  public LispObject getName()
152  {
153    return name;
154  }
155
156  public void setName(LispObject name)
157  {
158    this.name = name;
159  }
160
161  @Override
162  public final LispObject getPropertyList()
163  {
164    if (propertyList == null)
165      propertyList = NIL;
166    return propertyList;
167  }
168
169  @Override
170  public final void setPropertyList(LispObject obj)
171  {
172    if (obj == null)
173      throw new NullPointerException();
174    propertyList = obj;
175  }
176
177  public Layout getClassLayout()
178  {
179    return classLayout;
180  }
181
182  public void setClassLayout(Layout layout)
183  {
184    classLayout = layout;
185  }
186
187  public final int getLayoutLength()
188  {
189    if (layout == null)
190      return 0;
191    return layout.getLength();
192  }
193
194  public LispObject getDirectSuperclasses()
195  {
196    return directSuperclasses;
197  }
198
199  public void setDirectSuperclasses(LispObject directSuperclasses)
200  {
201    this.directSuperclasses = directSuperclasses;
202  }
203
204  public final boolean isFinalized()
205  {
206    return finalized;
207  }
208
209  public final void setFinalized(boolean b)
210  {
211    finalized = b;
212  }
213
214  // When there's only one direct superclass...
215  public final void setDirectSuperclass(LispObject superclass)
216  {
217    setDirectSuperclasses(new Cons(superclass));
218  }
219
220  public LispObject getDirectSubclasses()
221  {
222    return directSubclasses;
223  }
224
225  public void setDirectSubclasses(LispObject directSubclasses)
226  {
227    this.directSubclasses = directSubclasses;
228  }
229
230  public LispObject getCPL()
231  {
232    return classPrecedenceList;
233  }
234
235  public void setCPL(LispObject... cpl)
236  {
237    LispObject obj1 = cpl[0];
238    if (obj1 instanceof Cons && cpl.length == 1)
239      classPrecedenceList = obj1;
240    else
241      {
242        Debug.assertTrue(obj1 == this);
243        LispObject l = NIL;
244        for (int i = cpl.length; i-- > 0;)
245            l = new Cons(cpl[i], l);
246        classPrecedenceList = l;
247      }
248  }
249
250  public LispObject getDirectMethods()
251  {
252    return directMethods;
253  }
254
255  public void setDirectMethods(LispObject methods)
256  {
257    directMethods = methods;
258  }
259
260  public LispObject getDocumentation()
261  {
262    return documentation;
263  }
264
265  public void setDocumentation(LispObject doc)
266  {
267    documentation = doc;
268  }
269
270  @Override
271  public LispObject typeOf()
272  {
273    return Symbol.CLASS;
274  }
275
276  @Override
277  public LispObject classOf()
278  {
279    return StandardClass.CLASS;
280  }
281
282  @Override
283  public LispObject typep(LispObject type)
284  {
285    if (type == Symbol.CLASS)
286      return T;
287    if (type == StandardClass.CLASS)
288      return T;
289    return super.typep(type);
290  }
291
292  public boolean subclassp(LispObject obj)
293  {
294    LispObject cpl = getCPL();
295    while (cpl != NIL)
296      {
297        if (cpl.car() == obj)
298          return true;
299        cpl = ((Cons)cpl).cdr;
300      }
301    return false;
302  }
303
304  // ### find-class symbol &optional errorp environment => class
305  private static final Primitive FIND_CLASS =
306    new Primitive(Symbol.FIND_CLASS, "symbol &optional errorp environment")
307    {
308      @Override
309      public LispObject execute(LispObject arg)
310      {
311        return findClass(arg, true);
312      }
313      @Override
314      public LispObject execute(LispObject first, LispObject second)
315
316      {
317        return findClass(first, second != NIL);
318      }
319      @Override
320      public LispObject execute(LispObject first, LispObject second,
321                                LispObject third)
322
323      {
324        // FIXME Use environment!
325        return findClass(first, second != NIL);
326      }
327    };
328
329  // ### %set-find-class
330  private static final Primitive _SET_FIND_CLASS =
331    new Primitive("%set-find-class", PACKAGE_SYS, true)
332    {
333      @Override
334      public LispObject execute(LispObject first, LispObject second)
335
336      {
337        final Symbol name = checkSymbol(first);
338        if (second == NIL)
339          {
340            removeClass(name);
341            return second;
342          }
343        final LispClass c = checkClass(second);
344        addClass(name, c);
345        return second;
346      }
347    };
348
349  // ### subclassp
350  private static final Primitive SUBCLASSP =
351    new Primitive(Symbol.SUBCLASSP, "class")
352    {
353      @Override
354      public LispObject execute(LispObject first, LispObject second)
355
356      {
357        final LispClass c = checkClass(first);
358        return c.subclassp(second) ? T : NIL;
359      }
360    };
361}
Note: See TracBrowser for help on using the repository browser.