KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > lisp > Symbol


1 /*
2  * Symbol.java
3  *
4  * Copyright (C) 2002-2004 Peter Graves
5  * $Id: Symbol.java,v 1.146 2004/09/20 18:43:02 piso Exp $
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
22 package org.armedbear.lisp;
23
24 public class Symbol extends LispObject
25 {
26     public static final Symbol AND_ALLOW_OTHER_KEYS = PACKAGE_CL.addExternalSymbol("&ALLOW-OTHER-KEYS");
27     public static final Symbol AND_AUX = PACKAGE_CL.addExternalSymbol("&AUX");
28     public static final Symbol AND_BODY = PACKAGE_CL.addExternalSymbol("&BODY");
29     public static final Symbol AND_ENVIRONMENT = PACKAGE_CL.addExternalSymbol("&ENVIRONMENT");
30     public static final Symbol AND_KEY = PACKAGE_CL.addExternalSymbol("&KEY");
31     public static final Symbol AND_OPTIONAL = PACKAGE_CL.addExternalSymbol("&OPTIONAL");
32     public static final Symbol AND_REST = PACKAGE_CL.addExternalSymbol("&REST");
33     public static final Symbol AND_WHOLE = PACKAGE_CL.addExternalSymbol("&WHOLE");
34     public static final Symbol APPLY = PACKAGE_CL.addExternalSymbol("APPLY");
35     public static final Symbol BLOCK = PACKAGE_CL.addExternalSymbol("BLOCK");
36     public static final Symbol BREAK = PACKAGE_CL.addExternalSymbol("BREAK");
37     public static final Symbol CDR = PACKAGE_CL.addExternalSymbol("CDR");
38     public static final Symbol DECLARE = PACKAGE_CL.addExternalSymbol("DECLARE");
39     public static final Symbol DOCUMENTATION = PACKAGE_CL.addExternalSymbol("DOCUMENTATION");
40     public static final Symbol EQ = PACKAGE_CL.addExternalSymbol("EQ");
41     public static final Symbol EQL = PACKAGE_CL.addExternalSymbol("EQL");
42     public static final Symbol EQUAL = PACKAGE_CL.addExternalSymbol("EQUAL");
43     public static final Symbol EQUALP = PACKAGE_CL.addExternalSymbol("EQUALP");
44     public static final Symbol EVAL = PACKAGE_CL.addExternalSymbol("EVAL");
45     public static final Symbol FLET = PACKAGE_CL.addExternalSymbol("FLET");
46     public static final Symbol FORMAT = PACKAGE_CL.addExternalSymbol("FORMAT");
47     public static final Symbol FUNCALL = PACKAGE_CL.addExternalSymbol("FUNCALL");
48     public static final Symbol GO = PACKAGE_CL.addExternalSymbol("GO");
49     public static final Symbol LAMBDA = PACKAGE_CL.addExternalSymbol("LAMBDA");
50     public static final Symbol LET = PACKAGE_CL.addExternalSymbol("LET");
51     public static final Symbol LOAD = PACKAGE_CL.addExternalSymbol("LOAD");
52     public static final Symbol OTHERWISE = PACKAGE_CL.addExternalSymbol("OTHERWISE");
53     public static final Symbol QUOTE = PACKAGE_CL.addExternalSymbol("QUOTE");
54     public static final Symbol SETF = PACKAGE_CL.addExternalSymbol("SETF");
55     public static final Symbol SIGNAL = PACKAGE_CL.addExternalSymbol("SIGNAL");
56     public static final Symbol SPECIAL = PACKAGE_CL.addExternalSymbol("SPECIAL");
57
58     // Type specifiers.
59
public static final Symbol AND = PACKAGE_CL.addExternalSymbol("AND");
60     public static final Symbol ARRAY = PACKAGE_CL.addExternalSymbol("ARRAY");
61     public static final Symbol ATOM = PACKAGE_CL.addExternalSymbol("ATOM");
62     public static final Symbol BASE_CHAR = PACKAGE_CL.addExternalSymbol("BASE-CHAR");
63     public static final Symbol BASE_STRING = PACKAGE_CL.addExternalSymbol("BASE-STRING");
64     public static final Symbol BIGNUM = PACKAGE_CL.addExternalSymbol("BIGNUM");
65     public static final Symbol BIT = PACKAGE_CL.addExternalSymbol("BIT");
66     public static final Symbol BIT_VECTOR = PACKAGE_CL.addExternalSymbol("BIT-VECTOR");
67     public static final Symbol BOOLEAN = PACKAGE_CL.addExternalSymbol("BOOLEAN");
68     public static final Symbol BROADCAST_STREAM = PACKAGE_CL.addExternalSymbol("BROADCAST-STREAM");
69     public static final Symbol BUILT_IN_CLASS = PACKAGE_CL.addExternalSymbol("BUILT-IN-CLASS");
70     public static final Symbol CELL_ERROR = PACKAGE_CL.addExternalSymbol("CELL-ERROR");
71     public static final Symbol CHARACTER = PACKAGE_CL.addExternalSymbol("CHARACTER");
72     public static final Symbol CLASS = PACKAGE_CL.addExternalSymbol("CLASS");
73     public static final Symbol COMPILED_FUNCTION = PACKAGE_CL.addExternalSymbol("COMPILED-FUNCTION");
74     public static final Symbol COMPLEX = PACKAGE_CL.addExternalSymbol("COMPLEX");
75     public static final Symbol CONCATENATED_STREAM = PACKAGE_CL.addExternalSymbol("CONCATENATED-STREAM");
76     public static final Symbol CONS = PACKAGE_CL.addExternalSymbol("CONS");
77     public static final Symbol DOUBLE_FLOAT = PACKAGE_CL.addExternalSymbol("DOUBLE-FLOAT");
78     public static final Symbol ECHO_STREAM = PACKAGE_CL.addExternalSymbol("ECHO-STREAM");
79     public static final Symbol EXTENDED_CHAR = PACKAGE_CL.addExternalSymbol("EXTENDED-CHAR");
80     public static final Symbol FILE_STREAM = PACKAGE_CL.addExternalSymbol("FILE-STREAM");
81     public static final Symbol FIXNUM = PACKAGE_CL.addExternalSymbol("FIXNUM");
82     public static final Symbol FLOAT = PACKAGE_CL.addExternalSymbol("FLOAT");
83     public static final Symbol FUNCTION = PACKAGE_CL.addExternalSymbol("FUNCTION");
84     public static final Symbol GENERIC_FUNCTION = PACKAGE_CL.addExternalSymbol("GENERIC-FUNCTION");
85     public static final Symbol HASH_TABLE = PACKAGE_CL.addExternalSymbol("HASH-TABLE");
86     public static final Symbol INTEGER = PACKAGE_CL.addExternalSymbol("INTEGER");
87     public static final Symbol KEYWORD = PACKAGE_CL.addExternalSymbol("KEYWORD");
88     public static final Symbol LIST = PACKAGE_CL.addExternalSymbol("LIST");
89     public static final Symbol LOGICAL_PATHNAME = PACKAGE_CL.addExternalSymbol("LOGICAL-PATHNAME");
90     public static final Symbol LONG_FLOAT = PACKAGE_CL.addExternalSymbol("LONG-FLOAT");
91     public static final Symbol MEMBER = PACKAGE_CL.addExternalSymbol("MEMBER");
92     public static final Symbol METHOD = PACKAGE_CL.addExternalSymbol("METHOD");
93     public static final Symbol METHOD_COMBINATION = PACKAGE_CL.addExternalSymbol("METHOD-COMBINATION");
94     public static final Symbol NOT = PACKAGE_CL.addExternalSymbol("NOT");
95     public static final Symbol NULL = PACKAGE_CL.addExternalSymbol("NULL");
96     public static final Symbol NUMBER = PACKAGE_CL.addExternalSymbol("NUMBER");
97     public static final Symbol OR = PACKAGE_CL.addExternalSymbol("OR");
98     public static final Symbol PACKAGE = PACKAGE_CL.addExternalSymbol("PACKAGE");
99     public static final Symbol PATHNAME = PACKAGE_CL.addExternalSymbol("PATHNAME");
100     public static final Symbol RANDOM_STATE = PACKAGE_CL.addExternalSymbol("RANDOM-STATE");
101     public static final Symbol RATIO = PACKAGE_CL.addExternalSymbol("RATIO");
102     public static final Symbol RATIONAL = PACKAGE_CL.addExternalSymbol("RATIONAL");
103     public static final Symbol REAL = PACKAGE_CL.addExternalSymbol("REAL");
104     public static final Symbol READTABLE = PACKAGE_CL.addExternalSymbol("READTABLE");
105     public static final Symbol RESTART = PACKAGE_CL.addExternalSymbol("RESTART");
106     public static final Symbol SEQUENCE = PACKAGE_CL.addExternalSymbol("SEQUENCE");
107     public static final Symbol SHORT_FLOAT = PACKAGE_CL.addExternalSymbol("SHORT-FLOAT");
108     public static final Symbol SIGNED_BYTE = PACKAGE_CL.addExternalSymbol("SIGNED-BYTE");
109     public static final Symbol SIMPLE_ARRAY = PACKAGE_CL.addExternalSymbol("SIMPLE-ARRAY");
110     public static final Symbol SIMPLE_BASE_STRING = PACKAGE_CL.addExternalSymbol("SIMPLE-BASE-STRING");
111     public static final Symbol SIMPLE_BIT_VECTOR = PACKAGE_CL.addExternalSymbol("SIMPLE-BIT-VECTOR");
112     public static final Symbol SIMPLE_STRING = PACKAGE_CL.addExternalSymbol("SIMPLE-STRING");
113     public static final Symbol SIMPLE_VECTOR = PACKAGE_CL.addExternalSymbol("SIMPLE-VECTOR");
114     public static final Symbol SINGLE_FLOAT = PACKAGE_CL.addExternalSymbol("SINGLE-FLOAT");
115     public static final Symbol STANDARD_CHAR = PACKAGE_CL.addExternalSymbol("STANDARD-CHAR");
116     public static final Symbol STANDARD_CLASS = PACKAGE_CL.addExternalSymbol("STANDARD-CLASS");
117     public static final Symbol STANDARD_GENERIC_FUNCTION = PACKAGE_CL.addExternalSymbol("STANDARD-GENERIC-FUNCTION");
118     public static final Symbol STANDARD_METHOD = PACKAGE_CL.addExternalSymbol("STANDARD-METHOD");
119     public static final Symbol STANDARD_OBJECT = PACKAGE_CL.addExternalSymbol("STANDARD-OBJECT");
120     public static final Symbol STREAM = PACKAGE_CL.addExternalSymbol("STREAM");
121     public static final Symbol STRING = PACKAGE_CL.addExternalSymbol("STRING");
122     public static final Symbol STRING_STREAM = PACKAGE_CL.addExternalSymbol("STRING-STREAM");
123     public static final Symbol STRUCTURE_CLASS = PACKAGE_CL.addExternalSymbol("STRUCTURE-CLASS");
124     public static final Symbol STRUCTURE_OBJECT = PACKAGE_CL.addExternalSymbol("STRUCTURE-OBJECT");
125     public static final Symbol SYMBOL = PACKAGE_CL.addExternalSymbol("SYMBOL");
126     public static final Symbol SYNONYM_STREAM = PACKAGE_CL.addExternalSymbol("SYNONYM-STREAM");
127     public static final Symbol TWO_WAY_STREAM = PACKAGE_CL.addExternalSymbol("TWO-WAY-STREAM");
128     public static final Symbol UNSIGNED_BYTE = PACKAGE_CL.addExternalSymbol("UNSIGNED-BYTE");
129     public static final Symbol VECTOR = PACKAGE_CL.addExternalSymbol("VECTOR");
130
131     public static final Symbol CASE_FROB_STREAM = PACKAGE_SYS.addInternalSymbol("CASE-FROB-STREAM");
132     public static final Symbol NIL_VECTOR = PACKAGE_SYS.addInternalSymbol("NIL-VECTOR");
133     public static final Symbol SOCKET_STREAM = PACKAGE_SYS.addInternalSymbol("SOCKET-STREAM");
134     public static final Symbol STRING_INPUT_STREAM = PACKAGE_SYS.addInternalSymbol("STRING-INPUT-STREAM");
135     public static final Symbol STRING_OUTPUT_STREAM = PACKAGE_SYS.addInternalSymbol("STRING-OUTPUT-STREAM");
136
137     public static final Symbol UNSPECIFIED = PACKAGE_CL.addExternalSymbol("*");
138
139     // Condition types.
140
public static final Symbol ARITHMETIC_ERROR = PACKAGE_CL.addExternalSymbol("ARITHMETIC-ERROR");
141     public static final Symbol CONDITION = PACKAGE_CL.addExternalSymbol("CONDITION");
142     public static final Symbol CONTROL_ERROR = PACKAGE_CL.addExternalSymbol("CONTROL-ERROR");
143     public static final Symbol DIVISION_BY_ZERO = PACKAGE_CL.addExternalSymbol("DIVISION-BY-ZERO");
144     public static final Symbol END_OF_FILE = PACKAGE_CL.addExternalSymbol("END-OF-FILE");
145     public static final Symbol ERROR = PACKAGE_CL.addExternalSymbol("ERROR");
146     public static final Symbol FILE_ERROR = PACKAGE_CL.addExternalSymbol("FILE-ERROR");
147     public static final Symbol FLOATING_POINT_INEXACT = PACKAGE_CL.addExternalSymbol("FLOATING-POINT-INEXACT");
148     public static final Symbol FLOATING_POINT_INVALID_OPERATION = PACKAGE_CL.addExternalSymbol("FLOATING-POINT-INVALID-OPERATION");
149     public static final Symbol FLOATING_POINT_OVERFLOW = PACKAGE_CL.addExternalSymbol("FLOATING-POINT-OVERFLOW");
150     public static final Symbol FLOATING_POINT_UNDERFLOW = PACKAGE_CL.addExternalSymbol("FLOATING-POINT-UNDERFLOW");
151     public static final Symbol PACKAGE_ERROR = PACKAGE_CL.addExternalSymbol("PACKAGE-ERROR");
152     public static final Symbol PARSE_ERROR = PACKAGE_CL.addExternalSymbol("PARSE-ERROR");
153     public static final Symbol PRINT_NOT_READABLE = PACKAGE_CL.addExternalSymbol("PRINT-NOT-READABLE");
154     public static final Symbol PROGRAM_ERROR = PACKAGE_CL.addExternalSymbol("PROGRAM-ERROR");
155     public static final Symbol READER_ERROR = PACKAGE_CL.addExternalSymbol("READER-ERROR");
156     public static final Symbol SERIOUS_CONDITION = PACKAGE_CL.addExternalSymbol("SERIOUS-CONDITION");
157     public static final Symbol SIMPLE_CONDITION = PACKAGE_CL.addExternalSymbol("SIMPLE-CONDITION");
158     public static final Symbol SIMPLE_ERROR = PACKAGE_CL.addExternalSymbol("SIMPLE-ERROR");
159     public static final Symbol SIMPLE_TYPE_ERROR = PACKAGE_CL.addExternalSymbol("SIMPLE-TYPE-ERROR");
160     public static final Symbol SIMPLE_WARNING = PACKAGE_CL.addExternalSymbol("SIMPLE-WARNING");
161     public static final Symbol STORAGE_CONDITION = PACKAGE_CL.addExternalSymbol("STORAGE-CONDITION");
162     public static final Symbol STREAM_ERROR = PACKAGE_CL.addExternalSymbol("STREAM-ERROR");
163     public static final Symbol STYLE_WARNING = PACKAGE_CL.addExternalSymbol("STYLE-WARNING");
164     public static final Symbol TYPE_ERROR = PACKAGE_CL.addExternalSymbol("TYPE-ERROR");
165     public static final Symbol UNBOUND_SLOT = PACKAGE_CL.addExternalSymbol("UNBOUND-SLOT");
166     public static final Symbol UNBOUND_VARIABLE = PACKAGE_CL.addExternalSymbol("UNBOUND-VARIABLE");
167     public static final Symbol UNDEFINED_FUNCTION = PACKAGE_CL.addExternalSymbol("UNDEFINED-FUNCTION");
168     public static final Symbol WARNING = PACKAGE_CL.addExternalSymbol("WARNING");
169
170     // Internal symbols.
171
public static final Symbol BACKQUOTE = PACKAGE_CL.addInternalSymbol("BACKQUOTE");
172     public static final Symbol COMMA = PACKAGE_CL.addInternalSymbol("COMMA");
173     public static final Symbol COMMA_ATSIGN = PACKAGE_CL.addInternalSymbol("COMMA-ATSIGN");
174     public static final Symbol COMMA_DOT = PACKAGE_CL.addInternalSymbol("COMMA-DOT");
175     public static final Symbol MACROEXPAND_MACRO = PACKAGE_SYS.addInternalSymbol("MACROEXPAND-MACRO");
176     public static final Symbol _SETF_FUNCTION = PACKAGE_SYS.addInternalSymbol("%SETF-FUNCTION");
177     public static final Symbol _SOURCE = PACKAGE_SYS.addInternalSymbol("%SOURCE");
178
179     public static final Symbol DOUBLE_FLOAT_POSITIVE_INFINITY = PACKAGE_EXT.addExternalSymbol("DOUBLE-FLOAT-POSITIVE-INFINITY");
180     public static final Symbol DOUBLE_FLOAT_NEGATIVE_INFINITY = PACKAGE_EXT.addExternalSymbol("DOUBLE-FLOAT-NEGATIVE-INFINITY");
181
182     // Bit flags.
183
private static final int FLAG_SPECIAL = 0x0001;
184     private static final int FLAG_CONSTANT = 0x0002;
185     private static final int FLAG_BUILT_IN_FUNCTION = 0x0004;
186
187     public static final Symbol addFunction(String JavaDoc name, LispObject obj)
188     {
189         Symbol symbol = PACKAGE_CL.intern(name);
190         try {
191             PACKAGE_CL.export(symbol); // FIXME Inefficient!
192
}
193         catch (ConditionThrowable t) {
194             Debug.trace(t);
195         }
196         symbol.function = obj;
197         return symbol;
198     }
199
200     private final String JavaDoc name;
201     private LispObject pkg;
202     private LispObject value;
203     private LispObject function;
204     private LispObject propertyList;
205     private int flags;
206
207     // Construct an uninterned symbol.
208
public Symbol(String JavaDoc name)
209     {
210         this.name = name;
211         pkg = NIL;
212     }
213
214     public Symbol(String JavaDoc name, Package JavaDoc pkg)
215     {
216         this.name = name;
217         this.pkg = pkg;
218     }
219
220     public LispObject typeOf()
221     {
222         if (pkg == PACKAGE_KEYWORD)
223             return Symbol.KEYWORD;
224         else
225             return Symbol.SYMBOL;
226     }
227
228     public LispClass classOf()
229     {
230         return BuiltInClass.SYMBOL;
231     }
232
233     public LispObject getDescription()
234     {
235         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("The symbol ");
236         sb.append(name);
237         return new SimpleString(sb);
238     }
239
240     public LispObject typep(LispObject type) throws ConditionThrowable
241     {
242         if (type == Symbol.SYMBOL)
243             return T;
244         if (type == BuiltInClass.SYMBOL)
245             return T;
246         if (type == Symbol.KEYWORD)
247             return pkg == PACKAGE_KEYWORD ? T : NIL;
248         if (type == Symbol.BOOLEAN)
249             return this == T ? T : NIL;
250         return super.typep(type);
251     }
252
253     public final LispObject SYMBOLP()
254     {
255         return T;
256     }
257
258     public boolean constantp()
259     {
260         return (flags & FLAG_CONSTANT) != 0;
261     }
262
263     public final LispObject STRING()
264     {
265         return new SimpleString(name);
266     }
267
268     public final LispObject getPackage()
269     {
270         return pkg;
271     }
272
273     public final void setPackage(LispObject obj)
274     {
275         pkg = obj;
276     }
277
278     public final boolean isSpecialVariable()
279     {
280         return (flags & FLAG_SPECIAL) != 0;
281     }
282
283     public final void setSpecial(boolean b)
284     {
285         if (b)
286             flags |= FLAG_SPECIAL;
287         else
288             flags &= ~FLAG_SPECIAL;
289     }
290
291     public final boolean isConstant()
292     {
293         return (flags & FLAG_CONSTANT) != 0;
294     }
295
296     public final void setConstant(boolean b)
297     {
298         if (b)
299             flags |= FLAG_CONSTANT;
300         else
301             flags &= ~FLAG_CONSTANT;
302     }
303
304     public final boolean isBuiltInFunction()
305     {
306         return (flags & FLAG_BUILT_IN_FUNCTION) != 0;
307     }
308
309     public final void setBuiltInFunction(boolean b)
310     {
311         if (b)
312             flags |= FLAG_BUILT_IN_FUNCTION;
313         else
314             flags &= ~FLAG_BUILT_IN_FUNCTION;
315     }
316
317     public final String JavaDoc getName()
318     {
319         return name;
320     }
321
322     public final String JavaDoc getQualifiedName()
323     {
324         if (pkg == NIL)
325             return("#:".concat(name));
326         if (pkg == PACKAGE_KEYWORD)
327             return ":".concat(name);
328         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(pkg.getName());
329         if (((Package JavaDoc)pkg).findExternalSymbol(name) != null)
330             sb.append(':');
331         else
332             sb.append("::");
333         sb.append(name);
334         return sb.toString();
335     }
336
337     // Raw accessor.
338
public LispObject getSymbolValue()
339     {
340         return value;
341     }
342
343     public final void setSymbolValue(LispObject value)
344     {
345         this.value = value;
346     }
347
348     public final LispObject symbolValue() throws ConditionThrowable
349     {
350         LispObject val = LispThread.currentThread().lookupSpecial(this);
351         if (val != null)
352             return val;
353         if (value != null)
354             return value;
355         return signal(new UnboundVariable(this));
356     }
357
358     public final LispObject symbolValue(LispThread thread) throws ConditionThrowable
359     {
360         LispObject val = thread.lookupSpecial(this);
361         if (val != null)
362             return val;
363         if (value != null)
364             return value;
365         return signal(new UnboundVariable(this));
366     }
367
368     public final LispObject symbolValueNoThrow()
369     {
370         if ((flags & FLAG_SPECIAL) != 0) {
371             LispObject val = LispThread.currentThread().lookupSpecial(this);
372             if (val != null)
373                 return val;
374         }
375         return value;
376     }
377
378     public final LispObject symbolValueNoThrow(LispThread thread)
379     {
380         if ((flags & FLAG_SPECIAL) != 0) {
381             LispObject val = thread.lookupSpecial(this);
382             if (val != null)
383                 return val;
384         }
385         return value;
386     }
387
388     public LispObject getSymbolFunction()
389     {
390         return function;
391     }
392
393     public final LispObject getSymbolFunctionOrDie() throws ConditionThrowable
394     {
395         if (function == null)
396             return signal(new UndefinedFunction(this));
397         if (function instanceof Autoload) {
398             Autoload autoload = (Autoload) function;
399             autoload.load();
400         }
401         return function;
402     }
403
404     public final LispObject getSymbolSetfFunctionOrDie() throws ConditionThrowable
405     {
406         LispObject obj = get(this, Symbol._SETF_FUNCTION);
407         if (obj == null)
408             return signal(new LispError("The function (SETF " + name +
409                                         ") is undefined."));
410         return obj;
411     }
412
413     public final void setSymbolFunction(LispObject obj)
414     {
415         this.function = obj;
416     }
417
418     public final LispObject getPropertyList()
419     {
420         return propertyList != null ? propertyList : NIL;
421     }
422
423     public final void setPropertyList(LispObject obj)
424     {
425         if (obj == null)
426             throw new NullPointerException JavaDoc();
427         propertyList = obj;
428     }
429
430     private static final Symbol _FUNCTION_DOCUMENTATION =
431         PACKAGE_SYS.intern("%FUNCTION-DOCUMENTATION");
432
433     private static final Symbol _VARIABLE_DOCUMENTATION =
434         PACKAGE_SYS.intern("%VARIABLE-DOCUMENTATION");
435
436     // Returns null if there is no function documentation.
437
public final LispObject getFunctionDocumentation() throws ConditionThrowable
438     {
439         return get(this, _FUNCTION_DOCUMENTATION);
440     }
441
442     public final void setFunctionDocumentation(String JavaDoc docstring)
443         throws ConditionThrowable
444     {
445         put(this, _FUNCTION_DOCUMENTATION, new SimpleString(docstring));
446     }
447
448     public final void setFunctionDocumentation(LispObject documentation)
449         throws ConditionThrowable
450     {
451         put(this, _FUNCTION_DOCUMENTATION, documentation);
452     }
453
454     public final void setVariableDocumentation(LispObject documentation)
455         throws ConditionThrowable
456     {
457         put(this, _VARIABLE_DOCUMENTATION, documentation);
458     }
459
460     public String JavaDoc writeToString() throws ConditionThrowable
461     {
462         final LispThread thread = LispThread.currentThread();
463         boolean printEscape = (_PRINT_ESCAPE_.symbolValue(thread) != NIL);
464         LispObject printCase = _PRINT_CASE_.symbolValue(thread);
465         LispObject readtableCase = currentReadtable().getReadtableCase();
466         boolean printReadably = (_PRINT_READABLY_.symbolValue(thread) != NIL);
467         if (printReadably) {
468             if (readtableCase != Keyword.UPCASE ||
469                 printCase != Keyword.UPCASE)
470             {
471                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
472                 if (pkg == PACKAGE_KEYWORD) {
473                     sb.append(':');
474                 } else if (pkg != NIL) {
475                     sb.append(multipleEscape(pkg.getName()));
476                     sb.append("::");
477                 } else {
478                     sb.append("#:");
479                 }
480                 sb.append(multipleEscape(name));
481                 return sb.toString();
482             } else
483                 printEscape = true;
484         }
485         if (!printEscape) {
486             if (pkg == PACKAGE_KEYWORD) {
487                 if (printCase == Keyword.DOWNCASE)
488                     return name.toLowerCase();
489                 if (printCase == Keyword.CAPITALIZE)
490                     return capitalize(name, readtableCase);
491                 return name;
492             }
493             // Printer escaping is disabled.
494
if (readtableCase == Keyword.UPCASE) {
495                 if (printCase == Keyword.DOWNCASE)
496                     return name.toLowerCase();
497                 if (printCase == Keyword.CAPITALIZE)
498                     return capitalize(name, readtableCase);
499                 return name;
500             } else if (readtableCase == Keyword.DOWNCASE) {
501                 // "When the readtable case is :DOWNCASE, uppercase characters
502
// are printed in their own case, and lowercase characters are
503
// printed in the case specified by *PRINT-CASE*." (22.1.3.3.2)
504
if (printCase == Keyword.DOWNCASE)
505                     return name;
506                 if (printCase == Keyword.UPCASE)
507                     return name.toUpperCase();
508                 if (printCase == Keyword.CAPITALIZE)
509                     return capitalize(name, readtableCase);
510                 return name;
511             } else if (readtableCase == Keyword.PRESERVE) {
512                 return name;
513             } else // INVERT
514
return invert(name);
515         }
516         // Printer escaping is enabled.
517
final boolean escape = needsEscape(name, readtableCase, thread);
518         String JavaDoc s = escape ? multipleEscape(name) : name;
519         if (!escape) {
520             if (readtableCase == Keyword.PRESERVE)
521                 ;
522             else if (readtableCase == Keyword.INVERT)
523                 s = invert(s);
524             else if (printCase == Keyword.DOWNCASE)
525                 s = s.toLowerCase();
526             else if (printCase == Keyword.UPCASE)
527                 s = s.toUpperCase();
528             else if (printCase == Keyword.CAPITALIZE)
529                 s = capitalize(s, readtableCase);
530         }
531         if (pkg == NIL) {
532             if (printReadably || _PRINT_GENSYM_.symbolValue(thread) != NIL)
533                 return "#:".concat(s);
534             else
535                 return s;
536         }
537         if (pkg == PACKAGE_KEYWORD)
538             return ":".concat(s);
539         // "Package prefixes are printed if necessary." (22.1.3.3.1)
540
final Package JavaDoc currentPackage = (Package JavaDoc) _PACKAGE_.symbolValue(thread);
541         if (pkg == currentPackage)
542             return s;
543         if (currentPackage != null && currentPackage.uses(pkg)) {
544             // Check for name conflict in current package.
545
if (currentPackage.findExternalSymbol(name) == null)
546                 if (currentPackage.findInternalSymbol(name) == null)
547                     if (((Package JavaDoc)pkg).findExternalSymbol(name) != null)
548                         return s;
549         }
550         // Has this symbol been imported into the current package?
551
if (currentPackage.findExternalSymbol(name) == this)
552             return s;
553         if (currentPackage.findInternalSymbol(name) == this)
554             return s;
555         // Package prefix is necessary.
556
String JavaDoc packageName = pkg.getName();
557         if (needsEscape(packageName, readtableCase, thread))
558             packageName = multipleEscape(packageName);
559         else if (printCase == Keyword.DOWNCASE)
560             packageName = packageName.toLowerCase();
561         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(packageName);
562         if (((Package JavaDoc)pkg).findExternalSymbol(name) != null)
563             sb.append(':');
564         else
565             sb.append("::");
566         sb.append(s);
567         return sb.toString();
568     }
569
570     private static final boolean needsEscape(String JavaDoc s,
571                                              LispObject readtableCase,
572                                              LispThread thread)
573         throws ConditionThrowable
574     {
575         boolean escape = false;
576         final int length = s.length();
577         if (length == 0)
578             return true;
579         if (s.charAt(0) == '#')
580             return true;
581         int radix;
582         try {
583             radix = ((Fixnum)_PRINT_BASE_.symbolValue(thread)).value;
584         }
585         catch (ClassCastException JavaDoc e) {
586             signal(new TypeError("The value of *PRINT-BASE* is not of type (INTEGER 2 36)."));
587             // Not reached.
588
return false;
589         }
590         if (radix < 2 || radix > 36) {
591             signal(new TypeError("The value of *PRINT-BASE* is not of type (INTEGER 2 36)."));
592             // Not reached.
593
return false;
594         }
595         boolean seenNonDigit = false;
596         for (int i = length; i-- > 0;) {
597             char c = s.charAt(i);
598             if ("(),|\\`'\";:".indexOf(c) >= 0)
599                 return true;
600             if (Character.isWhitespace(c))
601                 return true;
602             if (readtableCase == Keyword.UPCASE) {
603                 if (Character.isLowerCase(c))
604                     return true;
605             } else if (readtableCase == Keyword.DOWNCASE) {
606                 if (Character.isUpperCase(c))
607                     return true;
608             }
609             if (!escape && !seenNonDigit) {
610                 if (Character.digit(c, radix) < 0)
611                     seenNonDigit = true;
612             }
613         }
614         if (!seenNonDigit)
615                 return true;
616         if (s.length() > 0 && s.charAt(0) == '.') {
617             boolean allDots = true;
618             for (int i = s.length(); i-- > 1;) {
619                 if (s.charAt(i) != '.') {
620                     allDots = false;
621                     break;
622                 }
623             }
624             if (allDots)
625                 return true;
626         }
627         return false;
628     }
629
630     private static final String JavaDoc multipleEscape(String JavaDoc s)
631     {
632         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("|");
633         final int limit = s.length();
634         for (int i = 0; i < limit; i++) {
635             char c = s.charAt(i);
636             if (c == '|' || c == '\\')
637                 sb.append('\\');
638             sb.append(c);
639         }
640         sb.append('|');
641         return sb.toString();
642     }
643
644     private static final String JavaDoc capitalize(String JavaDoc s, LispObject readtableCase)
645     {
646         if (readtableCase == Keyword.INVERT || readtableCase == Keyword.PRESERVE)
647             return s;
648         final int limit = s.length();
649         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(limit);
650         boolean lastCharWasAlphanumeric = false;
651         for (int i = 0; i < limit; i++) {
652             char c = s.charAt(i);
653             if (Character.isLowerCase(c)) {
654                 if (readtableCase == Keyword.UPCASE)
655                     sb.append(c);
656                 else // DOWNCASE
657
sb.append(lastCharWasAlphanumeric ? c : Utilities.toUpperCase(c));
658                 lastCharWasAlphanumeric = true;
659             } else if (Character.isUpperCase(c)) {
660                 if (readtableCase == Keyword.UPCASE)
661                     sb.append(lastCharWasAlphanumeric ? Utilities.toLowerCase(c) : c);
662                 else // DOWNCASE
663
sb.append(c);
664                 lastCharWasAlphanumeric = true;
665             } else {
666                 sb.append(c);
667                 lastCharWasAlphanumeric = Character.isDigit(c);
668             }
669         }
670         return sb.toString();
671     }
672
673     public LispObject getParts() throws ConditionThrowable
674     {
675         LispObject result = NIL;
676         result = result.push(new Cons(new SimpleString("name"), new SimpleString(name)));
677         result = result.push(new Cons(new SimpleString("package"), pkg));
678         result = result.push(new Cons(new SimpleString("value"),
679                                       value != null ? value : UNBOUND));
680         result = result.push(new Cons(new SimpleString("function"),
681                                       function != null ? function : UNBOUND));
682         result = result.push(new Cons(new SimpleString("plist"), getPropertyList()));
683         return result.nreverse();
684     }
685
686     public final int hashCode()
687     {
688         return name.hashCode();
689     }
690
691     public final boolean equals(Object JavaDoc obj)
692     {
693         return this == obj;
694     }
695
696     // ### symbol-name
697
public static final Primitive1 SYMBOL_NAME = new Primitive1("symbol-name","symbol")
698     {
699         public LispObject execute(LispObject arg) throws ConditionThrowable
700         {
701             try {
702                 return new SimpleString(((Symbol)arg).name);
703             }
704             catch (ClassCastException JavaDoc e) {
705                 return signal(new TypeError(arg, Symbol.SYMBOL));
706             }
707         }
708     };
709
710     // ### symbol-package
711
public static final Primitive1 SYMBOL_PACKAGE = new Primitive1("symbol-package","symbol")
712     {
713         public LispObject execute(LispObject arg) throws ConditionThrowable
714         {
715             try {
716                 return ((Symbol)arg).pkg;
717             }
718             catch (ClassCastException JavaDoc e) {
719                 return signal(new TypeError(arg, Symbol.SYMBOL));
720             }
721         }
722     };
723
724     // ### symbol-function
725
public static final Primitive1 SYMBOL_FUNCTION =
726         new Primitive1("symbol-function", "symbol")
727     {
728         public LispObject execute(LispObject arg) throws ConditionThrowable
729         {
730             try {
731                 LispObject function = ((Symbol)arg).function;
732                 if (function != null)
733                     return function;
734                 return signal(new UndefinedFunction(arg));
735             }
736             catch (ClassCastException JavaDoc e) {
737                 return signal(new TypeError(arg, Symbol.SYMBOL));
738             }
739         }
740     };
741
742     // ### symbol-plist
743
public static final Primitive1 SYMBOL_PLIST = new Primitive1("symbol-plist", "symbol")
744     {
745         public LispObject execute(LispObject arg) throws ConditionThrowable
746         {
747             try {
748                 LispObject propertyList = ((Symbol)arg).propertyList;
749                 return propertyList != null ? propertyList : NIL;
750             }
751             catch (ClassCastException JavaDoc e) {
752                 return signal(new TypeError(arg, Symbol.SYMBOL));
753             }
754         }
755     };
756
757     // ### keywordp
758
public static final Primitive1 KEYWORDP = new Primitive1("keywordp", "object")
759     {
760         public LispObject execute(LispObject arg) throws ConditionThrowable
761         {
762             if (arg instanceof Symbol) {
763                 if (((Symbol)arg).pkg == PACKAGE_KEYWORD)
764                     return T;
765             }
766             return NIL;
767         }
768     };
769
770     // ### make-symbol
771
public static final Primitive1 MAKE_SYMBOL = new Primitive1("make-symbol", "name")
772     {
773         public LispObject execute(LispObject arg) throws ConditionThrowable
774         {
775             return new Symbol(arg.getStringValue());
776         }
777     };
778
779     // makunbound
780
public static final Primitive1 MAKUNBOUND = new Primitive1("makunbound", "symbol")
781     {
782         public LispObject execute(LispObject arg) throws ConditionThrowable
783         {
784             try {
785                 ((Symbol)arg).value = null;
786                 return arg;
787             }
788             catch (ClassCastException JavaDoc e) {
789                 return signal(new TypeError(arg, "symbol"));
790             }
791         }
792     };
793 }
794
Popular Tags