source: trunk/abcl/src/org/armedbear/lisp/LispClass.java @ 12381

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

Make LispClass?.addClass return the added class, for convenience.

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