001: package gnu.expr;
002:
003: import gnu.mapping.*;
004: import java.io.*;
005: import gnu.text.Printable;
006: import gnu.lists.Consumer;
007:
008: public class Keyword extends Symbol implements Printable,
009: Externalizable {
010: public static final Namespace keywordNamespace = new Namespace();
011: static {
012: keywordNamespace.setName("(keywords)");
013: }
014:
015: public Keyword() {
016: }
017:
018: private Keyword(String name) {
019: super (keywordNamespace, name);
020: }
021:
022: /** Used for constructing literals (int gnu.expr.LitTable). */
023: public Keyword(Namespace namespace, String name) {
024: super (namespace, name);
025: }
026:
027: /** Get the corresponding non-keyword symbol.
028: * Informally, the symbol corresponding to dropping the ':'.
029: */
030: public Symbol asSymbol() {
031: return Namespace.EmptyNamespace.getSymbol(getName());
032: }
033:
034: /**
035: * Create or find a Keyword with a given name (without final ':').
036: * @param name the print-name of the desired Keyword
037: * @return a Keyword with the given name, newly created iff none such exist
038: */
039: static public Keyword make(String name) {
040: int hash = name.hashCode();
041: Keyword keyword = (Keyword) keywordNamespace.lookup(name, hash,
042: false);
043: if (keyword == null) {
044: keyword = new Keyword(name);
045: keywordNamespace.add(keyword, hash);
046: }
047: return keyword;
048: }
049:
050: /*
051: public FString toSchemeString()
052: {
053: return new FString(name);
054: }
055: */
056:
057: public static boolean isKeyword(Object obj) {
058: return obj instanceof Keyword;
059: }
060:
061: public final String toString() {
062: return getName() + ':';
063: }
064:
065: public void print(Consumer out) {
066: Symbols.print(getName(), out);
067: out.write(':');
068: }
069:
070: /**
071: * Search vals[0:offset-1] for a keyword.
072: * Each key at vals[i] is followed by a value at keys[i+1].
073: * (This is used to search for a keyword parameter in an argument list.)
074: * @param vals the list to search in
075: * @param offset the index in vals to start the search at
076: * @param keyword the keyword to search for
077: * @return vals[i+1] such that vals[i]==keyword (and (i-offset) is even
078: * and non-negative); if there is no such i, return Special.dfault.
079: */
080: public static Object searchForKeyword(Object[] vals, int offset,
081: Object keyword) {
082: for (int i = offset; i < vals.length; i += 2) {
083: if (vals[i] == keyword)
084: return vals[i + 1];
085: }
086: return Special.dfault;
087: }
088:
089: /**
090: * Search vals[0:offset-1] for a keyword.
091: * Each key at vals[i] is followed by a value at keys[i+1].
092: * (This is used to search for a keyword parameter in an argument list.)
093: * @param vals the list to search in
094: * @param offset the index in vals to start the search at
095: * @param keyword the keyword to search for
096: * @param dfault the value to return if there is no match
097: * @return vals[i+1] such that vals[i]==keyword (and (i-offset) is even
098: * and non-negative); if there is no such i, return dfault.
099: */
100: public static Object searchForKeyword(Object[] vals, int offset,
101: Object keyword, Object dfault) {
102: for (int i = offset; i < vals.length; i += 2) {
103: if (vals[i] == keyword)
104: return vals[i + 1];
105: }
106: return dfault;
107: }
108:
109: public void writeExternal(ObjectOutput out) throws IOException {
110: out.writeObject(getName());
111: }
112:
113: public void readExternal(ObjectInput in) throws IOException,
114: ClassNotFoundException {
115: name = (String) in.readObject();
116: }
117:
118: public Object readResolve() throws ObjectStreamException {
119: return make(keywordNamespace, getName());
120: }
121: }
|