001: /*
002: * describe.java
003: *
004: * Copyright (C) 2003-2004 Peter Graves
005: * $Id: describe.java,v 1.15 2004/04/24 12:37:04 piso 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 final class describe extends Lisp {
025: // ### describe
026: // Need to support optional second argument specifying output stream.
027: private static final Primitive DESCRIBE = new Primitive("describe",
028: "object &optional stream") {
029: public LispObject execute(LispObject[] args)
030: throws ConditionThrowable {
031: if (args.length != 1)
032: return signal(new WrongNumberOfArgumentsException(this ));
033: LispObject obj = args[0];
034: StringBuffer sb = new StringBuffer(obj.writeToString());
035: if (obj instanceof Symbol) {
036: Symbol symbol = (Symbol) obj;
037: LispObject pkg = symbol.getPackage();
038: sb.append(" is an ");
039: if (pkg == NIL)
040: sb.append("uninterned");
041: else if (((Package) pkg).findExternalSymbol(symbol
042: .getName()) == symbol)
043: sb.append("external");
044: else
045: sb.append("internal");
046: sb.append(" symbol");
047: if (pkg != NIL) {
048: sb.append(" in the ");
049: sb.append(pkg.getName());
050: sb.append(" package");
051: }
052: sb.append(".\n");
053: LispObject value = symbol.getSymbolValue();
054: if (symbol.isSpecialVariable()) {
055: sb.append("It is a ");
056: sb.append(symbol.isConstant() ? "constant"
057: : "special variable");
058: sb.append("; ");
059: if (value != null) {
060: sb.append("its value is ");
061: sb.append(value.writeToString());
062: } else
063: sb.append("it is unbound");
064: sb.append(".\n");
065: } else if (value != null) {
066: sb
067: .append("It is an undefined variable; its value is ");
068: sb.append(value.writeToString());
069: sb.append(".\n");
070: }
071: LispObject function = symbol.getSymbolFunction();
072: if (function != null) {
073: sb.append("Its function binding is ");
074: sb.append(function.writeToString());
075: sb.append(".\n");
076: if (function instanceof Function) {
077: LispObject arglist = ((Function) function)
078: .getArglist();
079: if (arglist != null) {
080: LispThread thread = LispThread
081: .currentThread();
082: Environment oldDynEnv = thread
083: .getDynamicEnvironment();
084: thread.bindSpecial(_PRINT_ESCAPE_, NIL);
085: sb.append("Function argument list:\n ");
086: if (arglist instanceof AbstractString)
087: sb.append(arglist.getStringValue());
088: else
089: sb.append(arglist.writeToString());
090: sb.append('\n');
091: thread.setDynamicEnvironment(oldDynEnv);
092: }
093: }
094: LispObject documentation = symbol
095: .getFunctionDocumentation();
096: if (documentation instanceof AbstractString) {
097: sb.append("Function documentation:\n ");
098: sb.append(documentation.getStringValue());
099: sb.append('\n');
100: }
101: }
102: LispObject plist = symbol.getPropertyList();
103: if (plist != NIL) {
104: sb
105: .append("Its property list has these indicator/value pairs:\n");
106: LispObject[] array = plist.copyToArray();
107: for (int i = 0; i < array.length; i += 2) {
108: sb.append(" ");
109: sb.append(array[i].writeToString());
110: sb.append(' ');
111: sb.append(array[i + 1].writeToString());
112: sb.append('\n');
113: }
114: }
115: }
116: Stream out = getStandardOutput();
117: out.freshLine();
118: out._writeString(sb.toString());
119: out.freshLine();
120: return LispThread.currentThread().nothing();
121: }
122: };
123: }
|