001: package gnu.expr;
002:
003: import gnu.mapping.*;
004: import java.io.*;
005: import gnu.lists.*;
006:
007: public class Keyword extends CpsProcedure implements Printable,
008: Externalizable {
009: // Does not include final ':'.
010: private String name;
011:
012: public Keyword() {
013: }
014:
015: private Keyword(String name) {
016: this .name = name;
017: }
018:
019: private static java.util.Hashtable keywordTable = new java.util.Hashtable();
020:
021: public int hashCode() {
022: return name.hashCode();
023: }
024:
025: /**
026: * Create or find a Keyword with a given name (without final ':').
027: * @param name the print-name of the desired Keyword
028: * @return a Keyword with the given name, newly created iff none such exist
029: */
030: static public Keyword make(String name) {
031: Keyword keyword = (Keyword) keywordTable.get(name);
032: if (keyword == null) {
033: keyword = new Keyword(name);
034: keywordTable.put(name, keyword);
035: }
036: return keyword;
037: }
038:
039: /*
040: public FString toSchemeString()
041: {
042: return new FString(name);
043: }
044: */
045:
046: public static boolean isKeyword(Object obj) {
047: return obj instanceof Keyword;
048: }
049:
050: public final String toString() {
051: return name + ':';
052: }
053:
054: public void print(java.io.PrintWriter ps) {
055: Symbol.print(name, ps);
056: ps.print(':');
057: }
058:
059: /**
060: * Search vals[0:offset-1] for a keyword.
061: * Each key at vals[i] is followed by a value at vals[i+1].
062: * (This is used to search for a keyword parameter in an argument list.)
063: * @param vals the list to search in
064: * @param offset the index in vals to start the search at
065: * @param keyword the keyword to search for
066: * @return vals[i+1] such that vals[i]==keyword (and (i-offset) is even
067: * and non-negative); if there is no such i, return Special.dfault.
068: */
069: public static Object searchForKeyword(Object[] vals, int offset,
070: Object keyword) {
071: for (int i = offset; i < vals.length; i += 2) {
072: if (vals[i] == keyword)
073: return vals[i + 1];
074: }
075: return Special.dfault;
076: }
077:
078: /**
079: * Search vals[0:offset-1] for a keyword.
080: * Each key at vals[i] is followed by a value at keys[i+1].
081: * (This is used to search for a keyword parameter in an argument list.)
082: * @param vals the list to search in
083: * @param offset the index in vals to start the search at
084: * @param keyword the keyword to search for
085: * @param dfault the value to return if there is no match
086: * @return vals[i+1] such that vals[i]==keyword (and (i-offset) is even
087: * and non-negative); if there is no such i, return dfault.
088: */
089: public static Object searchForKeyword(Object[] vals, int offset,
090: Object keyword, Object dfault) {
091: for (int i = offset; i < vals.length; i += 2) {
092: if (vals[i] == keyword)
093: return vals[i + 1];
094: }
095: return dfault;
096: }
097:
098: public final String getName() {
099: return name;
100: }
101:
102: /**
103: * @serialData Write the keyword name (without colons) using writeUTF.
104: */
105:
106: public void writeExternal(ObjectOutput out) throws IOException {
107: out.writeUTF(name);
108: }
109:
110: public void readExternal(ObjectInput in) throws IOException,
111: ClassNotFoundException {
112: name = in.readUTF();
113: }
114:
115: public Object readResolve() throws ObjectStreamException {
116: return make(name);
117: }
118:
119: public void apply(CallContext ctx) {
120: Consumer out = ctx.consumer;
121: String tag = getName();
122: int nargs = ctx.count;
123: out.beginGroup(tag, this );
124: for (int i = 0; i < nargs; i++) {
125: Object arg = ctx.getArgAsObject(i);
126: if (arg instanceof Keyword && i + 1 < nargs) {
127: Keyword attr = (Keyword) arg;
128: arg = ctx.getArgAsObject(++i);
129: out.beginAttribute(attr.getName(), attr);
130: out.writeObject(arg);
131: out.endAttribute();
132: } else {
133: /*
134: if (arg instanceof Consumable)
135: ((Consumable) arg).consume(out);
136: else
137: */
138: out.writeObject(arg);
139: }
140: }
141: out.endGroup(tag);
142: }
143:
144: }
|