001: /*
002: * Symbol.java
003: *
004: * Copyright (C) 2002-2003 Peter Graves
005: * $Id: Symbol.java,v 1.6 2003/11/15 11:03:32 beedlem Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.lisp;
023:
024: public class Symbol extends LispObject {
025: public static final Symbol AND_ALLOW_OTHER_KEYS = PACKAGE_CL
026: .addExternalSymbol("&ALLOW-OTHER-KEYS");
027: public static final Symbol AND_AUX = PACKAGE_CL
028: .addExternalSymbol("&AUX");
029: public static final Symbol AND_BODY = PACKAGE_CL
030: .addExternalSymbol("&BODY");
031: public static final Symbol AND_ENVIRONMENT = PACKAGE_CL
032: .addExternalSymbol("&ENVIRONMENT");
033: public static final Symbol AND_KEY = PACKAGE_CL
034: .addExternalSymbol("&KEY");
035: public static final Symbol AND_OPTIONAL = PACKAGE_CL
036: .addExternalSymbol("&OPTIONAL");
037: public static final Symbol AND_REST = PACKAGE_CL
038: .addExternalSymbol("&REST");
039: public static final Symbol AND_WHOLE = PACKAGE_CL
040: .addExternalSymbol("&WHOLE");
041: public static final Symbol APPLY = PACKAGE_CL
042: .addExternalSymbol("APPLY");
043: public static final Symbol BLOCK = PACKAGE_CL
044: .addExternalSymbol("BLOCK");
045: public static final Symbol CDR = PACKAGE_CL
046: .addExternalSymbol("CDR");
047: public static final Symbol DECLARE = PACKAGE_CL
048: .addExternalSymbol("DECLARE");
049: public static final Symbol DOCUMENTATION = PACKAGE_CL
050: .addExternalSymbol("DOCUMENTATION");
051: public static final Symbol EQ = PACKAGE_CL.addExternalSymbol("EQ");
052: public static final Symbol EQL = PACKAGE_CL
053: .addExternalSymbol("EQL");
054: public static final Symbol EQUAL = PACKAGE_CL
055: .addExternalSymbol("EQUAL");
056: public static final Symbol EQUALP = PACKAGE_CL
057: .addExternalSymbol("EQUALP");
058: public static final Symbol FLET = PACKAGE_CL
059: .addExternalSymbol("FLET");
060: public static final Symbol FORMAT = PACKAGE_CL
061: .addExternalSymbol("FORMAT");
062: public static final Symbol GO = PACKAGE_CL.addExternalSymbol("GO");
063: public static final Symbol LAMBDA = PACKAGE_CL
064: .addExternalSymbol("LAMBDA");
065: public static final Symbol LET = PACKAGE_CL
066: .addExternalSymbol("LET");
067: public static final Symbol LOAD = PACKAGE_CL
068: .addExternalSymbol("LOAD");
069: public static final Symbol OTHERWISE = PACKAGE_CL
070: .addExternalSymbol("OTHERWISE");
071: public static final Symbol QUOTE = PACKAGE_CL
072: .addExternalSymbol("QUOTE");
073: public static final Symbol SETF = PACKAGE_CL
074: .addExternalSymbol("SETF");
075:
076: // Type specifiers.
077: public static final Symbol AND = PACKAGE_CL
078: .addExternalSymbol("AND");
079: public static final Symbol ARRAY = PACKAGE_CL
080: .addExternalSymbol("ARRAY");
081: public static final Symbol ATOM = PACKAGE_CL
082: .addExternalSymbol("ATOM");
083: public static final Symbol BASE_CHAR = PACKAGE_CL
084: .addExternalSymbol("BASE-CHAR");
085: public static final Symbol BASE_STRING = PACKAGE_CL
086: .addExternalSymbol("BASE-STRING");
087: public static final Symbol BIGNUM = PACKAGE_CL
088: .addExternalSymbol("BIGNUM");
089: public static final Symbol BIT = PACKAGE_CL
090: .addExternalSymbol("BIT");
091: public static final Symbol BIT_VECTOR = PACKAGE_CL
092: .addExternalSymbol("BIT-VECTOR");
093: public static final Symbol BOOLEAN = PACKAGE_CL
094: .addExternalSymbol("BOOLEAN");
095: public static final Symbol BROADCAST_STREAM = PACKAGE_CL
096: .addExternalSymbol("BROADCAST-STREAM");
097: public static final Symbol BUILT_IN_CLASS = PACKAGE_CL
098: .addExternalSymbol("BUILT-IN-CLASS");
099: public static final Symbol CELL_ERROR = PACKAGE_CL
100: .addExternalSymbol("CELL-ERROR");
101: public static final Symbol CHARACTER = PACKAGE_CL
102: .addExternalSymbol("CHARACTER");
103: public static final Symbol CLASS = PACKAGE_CL
104: .addExternalSymbol("CLASS");
105: public static final Symbol COMPILED_FUNCTION = PACKAGE_CL
106: .addExternalSymbol("COMPILED-FUNCTION");
107: public static final Symbol COMPLEX = PACKAGE_CL
108: .addExternalSymbol("COMPLEX");
109: public static final Symbol CONCATENATED_STREAM = PACKAGE_CL
110: .addExternalSymbol("CONCATENATED-STREAM");
111: public static final Symbol CONS = PACKAGE_CL
112: .addExternalSymbol("CONS");
113: public static final Symbol DOUBLE_FLOAT = PACKAGE_CL
114: .addExternalSymbol("DOUBLE-FLOAT");
115: public static final Symbol ECHO_STREAM = PACKAGE_CL
116: .addExternalSymbol("ECHO-STREAM");
117: public static final Symbol EXTENDED_CHAR = PACKAGE_CL
118: .addExternalSymbol("EXTENDED-CHAR");
119: public static final Symbol FILE_STREAM = PACKAGE_CL
120: .addExternalSymbol("FILE-STREAM");
121: public static final Symbol FIXNUM = PACKAGE_CL
122: .addExternalSymbol("FIXNUM");
123: public static final Symbol FLOAT = PACKAGE_CL
124: .addExternalSymbol("FLOAT");
125: public static final Symbol FUNCTION = PACKAGE_CL
126: .addExternalSymbol("FUNCTION");
127: public static final Symbol GENERIC_FUNCTION = PACKAGE_CL
128: .addExternalSymbol("GENERIC-FUNCTION");
129: public static final Symbol HASH_TABLE = PACKAGE_CL
130: .addExternalSymbol("HASH-TABLE");
131: public static final Symbol INTEGER = PACKAGE_CL
132: .addExternalSymbol("INTEGER");
133: public static final Symbol KEYWORD = PACKAGE_CL
134: .addExternalSymbol("KEYWORD");
135: public static final Symbol LIST = PACKAGE_CL
136: .addExternalSymbol("LIST");
137: public static final Symbol LOGICAL_PATHNAME = PACKAGE_CL
138: .addExternalSymbol("LOGICAL-PATHNAME");
139: public static final Symbol LONG_FLOAT = PACKAGE_CL
140: .addExternalSymbol("LONG-FLOAT");
141: public static final Symbol MEMBER = PACKAGE_CL
142: .addExternalSymbol("MEMBER");
143: public static final Symbol METHOD = PACKAGE_CL
144: .addExternalSymbol("METHOD");
145: public static final Symbol METHOD_COMBINATION = PACKAGE_CL
146: .addExternalSymbol("METHOD-COMBINATION");
147: public static final Symbol NOT = PACKAGE_CL
148: .addExternalSymbol("NOT");
149: public static final Symbol NULL = PACKAGE_CL
150: .addExternalSymbol("NULL");
151: public static final Symbol NUMBER = PACKAGE_CL
152: .addExternalSymbol("NUMBER");
153: public static final Symbol OR = PACKAGE_CL.addExternalSymbol("OR");
154: public static final Symbol PACKAGE = PACKAGE_CL
155: .addExternalSymbol("PACKAGE");
156: public static final Symbol PATHNAME = PACKAGE_CL
157: .addExternalSymbol("PATHNAME");
158: public static final Symbol RANDOM_STATE = PACKAGE_CL
159: .addExternalSymbol("RANDOM-STATE");
160: public static final Symbol RATIO = PACKAGE_CL
161: .addExternalSymbol("RATIO");
162: public static final Symbol RATIONAL = PACKAGE_CL
163: .addExternalSymbol("RATIONAL");
164: public static final Symbol REAL = PACKAGE_CL
165: .addExternalSymbol("REAL");
166: public static final Symbol READTABLE = PACKAGE_CL
167: .addExternalSymbol("READTABLE");
168: public static final Symbol RESTART = PACKAGE_CL
169: .addExternalSymbol("RESTART");
170: public static final Symbol SEQUENCE = PACKAGE_CL
171: .addExternalSymbol("SEQUENCE");
172: public static final Symbol SHORT_FLOAT = PACKAGE_CL
173: .addExternalSymbol("SHORT-FLOAT");
174: public static final Symbol SIMPLE_ARRAY = PACKAGE_CL
175: .addExternalSymbol("SIMPLE-ARRAY");
176: public static final Symbol SIMPLE_BASE_STRING = PACKAGE_CL
177: .addExternalSymbol("SIMPLE-BASE-STRING");
178: public static final Symbol SIMPLE_BIT_VECTOR = PACKAGE_CL
179: .addExternalSymbol("SIMPLE-BIT-VECTOR");
180: public static final Symbol SIMPLE_STRING = PACKAGE_CL
181: .addExternalSymbol("SIMPLE-STRING");
182: public static final Symbol SIMPLE_VECTOR = PACKAGE_CL
183: .addExternalSymbol("SIMPLE-VECTOR");
184: public static final Symbol SINGLE_FLOAT = PACKAGE_CL
185: .addExternalSymbol("SINGLE-FLOAT");
186: public static final Symbol STANDARD_CHAR = PACKAGE_CL
187: .addExternalSymbol("STANDARD-CHAR");
188: public static final Symbol STANDARD_CLASS = PACKAGE_CL
189: .addExternalSymbol("STANDARD-CLASS");
190: public static final Symbol STANDARD_GENERIC_FUNCTION = PACKAGE_CL
191: .addExternalSymbol("STANDARD-GENERIC-FUNCTION");
192: public static final Symbol STANDARD_METHOD = PACKAGE_CL
193: .addExternalSymbol("STANDARD-METHOD");
194: public static final Symbol STANDARD_OBJECT = PACKAGE_CL
195: .addExternalSymbol("STANDARD-OBJECT");
196: public static final Symbol STREAM = PACKAGE_CL
197: .addExternalSymbol("STREAM");
198: public static final Symbol STRING = PACKAGE_CL
199: .addExternalSymbol("STRING");
200: public static final Symbol STRING_STREAM = PACKAGE_CL
201: .addExternalSymbol("STRING-STREAM");
202: public static final Symbol STRUCTURE_CLASS = PACKAGE_CL
203: .addExternalSymbol("STRUCTURE-CLASS");
204: public static final Symbol STRUCTURE_OBJECT = PACKAGE_CL
205: .addExternalSymbol("STRUCTURE-OBJECT");
206: public static final Symbol SYMBOL = PACKAGE_CL
207: .addExternalSymbol("SYMBOL");
208: public static final Symbol SYNONYM_STREAM = PACKAGE_CL
209: .addExternalSymbol("SYNONYM-STREAM");
210: public static final Symbol TWO_WAY_STREAM = PACKAGE_CL
211: .addExternalSymbol("TWO-WAY-STREAM");
212: public static final Symbol UNSIGNED_BYTE = PACKAGE_CL
213: .addExternalSymbol("UNSIGNED-BYTE");
214: public static final Symbol VECTOR = PACKAGE_CL
215: .addExternalSymbol("VECTOR");
216:
217: public static final Symbol UNSPECIFIED = PACKAGE_CL
218: .addExternalSymbol("*");
219:
220: // Condition types.
221: public static final Symbol ARITHMETIC_ERROR = PACKAGE_CL
222: .addExternalSymbol("ARITHMETIC-ERROR");
223: public static final Symbol CONDITION = PACKAGE_CL
224: .addExternalSymbol("CONDITION");
225: public static final Symbol CONTROL_ERROR = PACKAGE_CL
226: .addExternalSymbol("CONTROL-ERROR");
227: public static final Symbol DIVISION_BY_ZERO = PACKAGE_CL
228: .addExternalSymbol("DIVISION-BY-ZERO");
229: public static final Symbol END_OF_FILE = PACKAGE_CL
230: .addExternalSymbol("END-OF-FILE");
231: public static final Symbol ERROR = PACKAGE_CL
232: .addExternalSymbol("ERROR");
233: public static final Symbol FILE_ERROR = PACKAGE_CL
234: .addExternalSymbol("FILE-ERROR");
235: public static final Symbol FLOATING_POINT_INEXACT = PACKAGE_CL
236: .addExternalSymbol("FLOATING-POINT-INEXACT");
237: public static final Symbol FLOATING_POINT_INVALID_OPERATION = PACKAGE_CL
238: .addExternalSymbol("FLOATING-POINT-INVALID-OPERATION");
239: public static final Symbol FLOATING_POINT_OVERFLOW = PACKAGE_CL
240: .addExternalSymbol("FLOATING-POINT-OVERFLOW");
241: public static final Symbol FLOATING_POINT_UNDERFLOW = PACKAGE_CL
242: .addExternalSymbol("FLOATING-POINT-UNDERFLOW");
243: public static final Symbol PACKAGE_ERROR = PACKAGE_CL
244: .addExternalSymbol("PACKAGE-ERROR");
245: public static final Symbol PARSE_ERROR = PACKAGE_CL
246: .addExternalSymbol("PARSE-ERROR");
247: public static final Symbol PRINT_NOT_READABLE = PACKAGE_CL
248: .addExternalSymbol("PRINT-NOT-READABLE");
249: public static final Symbol PROGRAM_ERROR = PACKAGE_CL
250: .addExternalSymbol("PROGRAM-ERROR");
251: public static final Symbol READER_ERROR = PACKAGE_CL
252: .addExternalSymbol("READER-ERROR");
253: public static final Symbol SERIOUS_CONDITION = PACKAGE_CL
254: .addExternalSymbol("SERIOUS-CONDITION");
255: public static final Symbol SIMPLE_CONDITION = PACKAGE_CL
256: .addExternalSymbol("SIMPLE-CONDITION");
257: public static final Symbol SIMPLE_ERROR = PACKAGE_CL
258: .addExternalSymbol("SIMPLE-ERROR");
259: public static final Symbol SIMPLE_TYPE_ERROR = PACKAGE_CL
260: .addExternalSymbol("SIMPLE-TYPE-ERROR");
261: public static final Symbol SIMPLE_WARNING = PACKAGE_CL
262: .addExternalSymbol("SIMPLE-WARNING");
263: public static final Symbol STORAGE_CONDITION = PACKAGE_CL
264: .addExternalSymbol("STORAGE-CONDITION");
265: public static final Symbol STREAM_ERROR = PACKAGE_CL
266: .addExternalSymbol("STREAM-ERROR");
267: public static final Symbol STYLE_WARNING = PACKAGE_CL
268: .addExternalSymbol("STYLE-WARNING");
269: public static final Symbol TYPE_ERROR = PACKAGE_CL
270: .addExternalSymbol("TYPE-ERROR");
271: public static final Symbol UNBOUND_SLOT = PACKAGE_CL
272: .addExternalSymbol("UNBOUND-SLOT");
273: public static final Symbol UNBOUND_VARIABLE = PACKAGE_CL
274: .addExternalSymbol("UNBOUND-VARIABLE");
275: public static final Symbol UNDEFINED_FUNCTION = PACKAGE_CL
276: .addExternalSymbol("UNDEFINED-FUNCTION");
277: public static final Symbol WARNING = PACKAGE_CL
278: .addExternalSymbol("WARNING");
279:
280: // Internal symbols.
281: public static final Symbol BACKQUOTE = PACKAGE_CL
282: .addInternalSymbol("BACKQUOTE");
283: public static final Symbol COMMA = PACKAGE_CL
284: .addInternalSymbol("COMMA");
285: public static final Symbol COMMA_ATSIGN = PACKAGE_CL
286: .addInternalSymbol("COMMA-ATSIGN");
287: public static final Symbol COMMA_DOT = PACKAGE_CL
288: .addInternalSymbol("COMMA-DOT");
289: public static final Symbol MACROEXPAND_MACRO = PACKAGE_SYS
290: .addInternalSymbol("MACROEXPAND-MACRO");
291:
292: public static final Symbol ARRAY_DIMENSION_LIMIT = PACKAGE_CL
293: .addExternalSymbol("ARRAY-DIMENSION-LIMIT");
294: static {
295: ARRAY_DIMENSION_LIMIT.setSymbolValue(new Fixnum(0x1000000));
296: ARRAY_DIMENSION_LIMIT.setConstant(true);
297: }
298:
299: // Bit flags.
300: private static final int SPECIAL = 0x0001;
301: private static final int CONSTANT = 0x0002;
302:
303: public static final Symbol addFunction(String name, LispObject obj) {
304: Symbol symbol = PACKAGE_CL.intern(name);
305: try {
306: PACKAGE_CL.export(symbol); // FIXME Inefficient!
307: } catch (ConditionThrowable t) {
308: Debug.trace(t);
309: }
310: symbol.function = obj;
311: return symbol;
312: }
313:
314: private final String name;
315: private LispObject pkg;
316: private LispObject value;
317: private LispObject function;
318: private LispObject propertyList;
319: private int flags;
320:
321: // Construct an uninterned symbol.
322: public Symbol(String name) {
323: this .name = name;
324: }
325:
326: public Symbol(String name, Package pkg) {
327: this .name = name;
328: this .pkg = pkg;
329: }
330:
331: public LispObject typeOf() {
332: return Symbol.SYMBOL;
333: }
334:
335: public LispClass classOf() {
336: return BuiltInClass.SYMBOL;
337: }
338:
339: public LispObject typep(LispObject type) throws ConditionThrowable {
340: if (type == Symbol.SYMBOL)
341: return T;
342: if (type == BuiltInClass.SYMBOL)
343: return T;
344: if (type == Symbol.BOOLEAN)
345: return this == T ? T : NIL;
346: return super .typep(type);
347: }
348:
349: public final LispObject SYMBOLP() {
350: return T;
351: }
352:
353: public LispObject CONSTANTP() {
354: return (flags & CONSTANT) != 0 ? T : NIL;
355: }
356:
357: public LispObject getPackage() {
358: return pkg != null ? pkg : NIL;
359: }
360:
361: public void setPackage(LispObject obj) {
362: pkg = obj;
363: }
364:
365: public final boolean isSpecialVariable() {
366: return (flags & SPECIAL) != 0;
367: }
368:
369: public final void setSpecial(boolean b) {
370: if (b)
371: flags |= SPECIAL;
372: else
373: flags &= ~SPECIAL;
374: }
375:
376: public final boolean isConstant() {
377: return (flags & CONSTANT) != 0;
378: }
379:
380: public final void setConstant(boolean b) {
381: if (b)
382: flags |= CONSTANT;
383: else
384: flags &= ~CONSTANT;
385: }
386:
387: public final String getName() {
388: return name;
389: }
390:
391: public final String getQualifiedName() {
392: if (pkg == null)
393: return ("#:".concat(name));
394: if (pkg == PACKAGE_KEYWORD)
395: return ":".concat(name);
396: StringBuffer sb = new StringBuffer(pkg.getName());
397: if (((Package) pkg).findExternalSymbol(name) != null)
398: sb.append(':');
399: else
400: sb.append("::");
401: sb.append(name);
402: return sb.toString();
403: }
404:
405: // Raw accessor.
406: public LispObject getSymbolValue() {
407: return value;
408: }
409:
410: public final void setSymbolValue(LispObject value) {
411: this .value = value;
412: }
413:
414: // symbol-value
415: public final LispObject symbolValue() throws ConditionThrowable {
416: if ((flags & SPECIAL) != 0) {
417: LispObject val = LispThread.currentThread().lookupSpecial(
418: this );
419: if (val != null)
420: return val;
421: }
422: if (value != null)
423: return value;
424: throw new ConditionThrowable(new LispError(toString().concat(
425: " has no dynamic value")));
426: }
427:
428: public final LispObject symbolValueNoThrow() {
429: if ((flags & SPECIAL) != 0) {
430: LispObject val = LispThread.currentThread().lookupSpecial(
431: this );
432: if (val != null)
433: return val;
434: }
435: return value;
436: }
437:
438: public final LispObject symbolValueNoThrow(LispThread thread) {
439: if ((flags & SPECIAL) != 0) {
440: LispObject val = thread.lookupSpecial(this );
441: if (val != null)
442: return val;
443: }
444: return value;
445: }
446:
447: public LispObject getSymbolFunction() {
448: return function;
449: }
450:
451: public final LispObject getSymbolFunctionOrDie()
452: throws ConditionThrowable {
453: if (function == null)
454: throw new ConditionThrowable(new UndefinedFunction(this ));
455: return function;
456: }
457:
458: public final void setSymbolFunction(LispObject obj) {
459: this .function = obj;
460: }
461:
462: public final LispObject getPropertyList() {
463: return propertyList != null ? propertyList : NIL;
464: }
465:
466: public final void setPropertyList(LispObject obj) {
467: if (obj == null)
468: throw new NullPointerException();
469: propertyList = obj;
470: }
471:
472: private static final Symbol _FUNCTION_DOCUMENTATION = PACKAGE_SYS
473: .intern("%FUNCTION-DOCUMENTATION");
474:
475: private static final Symbol _VARIABLE_DOCUMENTATION = PACKAGE_SYS
476: .intern("%VARIABLE-DOCUMENTATION");
477:
478: // Returns null if there is no function documentation.
479: public final LispObject getFunctionDocumentation()
480: throws ConditionThrowable {
481: return get(this , _FUNCTION_DOCUMENTATION);
482: }
483:
484: public final void setFunctionDocumentation(String docstring)
485: throws ConditionThrowable {
486: put(this , _FUNCTION_DOCUMENTATION, new LispString(docstring));
487: }
488:
489: public final void setFunctionDocumentation(LispObject documentation)
490: throws ConditionThrowable {
491: put(this , _FUNCTION_DOCUMENTATION, documentation);
492: }
493:
494: public final void setVariableDocumentation(LispObject documentation)
495: throws ConditionThrowable {
496: put(this , _VARIABLE_DOCUMENTATION, documentation);
497: }
498:
499: public String toString() {
500: if (pkg == PACKAGE_KEYWORD)
501: return ":".concat(name);
502: if (_PRINT_ESCAPE_.symbolValueNoThrow() == NIL)
503: return name;
504: boolean escape = false;
505: for (int i = name.length(); i-- > 0;) {
506: char c = name.charAt(i);
507: if (c == '(' || c == ')') {
508: escape = true;
509: break;
510: }
511: if (Character.isWhitespace(c)) {
512: escape = true;
513: break;
514: }
515: if (Character.isLowerCase(c)) {
516: escape = true;
517: break;
518: }
519: }
520: final String s = escape ? ("|" + name + "|") : name;
521: if (pkg == null || pkg == NIL) {
522: if (_PRINT_GENSYM_.symbolValueNoThrow() != NIL)
523: return "#:".concat(s);
524: else
525: return s;
526: }
527: final Package currentPackage = (Package) _PACKAGE_
528: .getSymbolValue();
529: if (pkg == currentPackage)
530: return s;
531: if (currentPackage.uses(pkg)) {
532: if (((Package) pkg).findExternalSymbol(name) != null)
533: return s;
534: }
535: StringBuffer sb = new StringBuffer(pkg.getName());
536: if (((Package) pkg).findExternalSymbol(name) != null)
537: sb.append(':');
538: else
539: sb.append("::");
540: sb.append(s);
541: return sb.toString();
542: }
543:
544: public final int hashCode() {
545: return name.hashCode();
546: }
547:
548: public final boolean equals(Object obj) {
549: return this == obj;
550: }
551: }
|