001: package gnu.expr;
002:
003: import gnu.mapping.*;
004: import gnu.lists.Consumer;
005:
006: /** Utility class containing various routines to manipulate Scheme symbols.
007: * Note Scheme symbols are represented using java.lang.String objects,
008: * and there are no Symbol objects. */
009:
010: public class Symbols {
011: /** There are no instances of this class. */
012: private Symbols() {
013: }
014:
015: private static int gensym_counter;
016:
017: static synchronized int generateInt() {
018: return ++gensym_counter;
019: }
020:
021: /* DEBUGGING:
022: static java.util.Vector gensyms = new java.util.Vector();
023:
024: public static String show (String str)
025: {
026: StringBuffer buf = new StringBuffer(str);
027: if (str.intern() == str)
028: buf.append("<I>");
029: else
030: {
031: for (int i = gensyms.size(); ; )
032: {
033: if (--i < 0)
034: {
035: buf.append("<?>");
036: break;
037: }
038: else if (gensyms.elementAt(i) == str)
039: {
040: buf.append('<');
041: buf.append(i);
042: buf.append('>');
043: break;
044: }
045: }
046: }
047: return buf.toString();
048: }
049: */
050:
051: /**
052: * Generate a new (interned) symbol with a unique name.
053: * @return the new symbol
054: */
055: public static final String gentemp() {
056: return Symbols.make("GS." + Integer.toString(generateInt()));
057: }
058:
059: /**
060: * Create or find a Symbol with a given name.
061: * @param name the print-name of the desired Symbol
062: * @return a Symbol with the given name, newly created iff none such exist
063: */
064: static public String make(String name) {
065: return name.intern();
066: }
067:
068: static public final String intern(String name) {
069: return make(name);
070: }
071:
072: public static void print(String name, Consumer out) {
073: boolean readable = (out instanceof OutPort)
074: && ((OutPort) out).printReadable;
075: if (readable) {
076: int len = name.length();
077: for (int i = 0; i < len; i++) {
078: char ch = name.charAt(i);
079: if (!(Character.isLowerCase(ch)
080: || ch == '!'
081: || ch == '$'
082: || ch == '%'
083: || ch == '&'
084: || ch == '*'
085: || ch == '/'
086: || ch == ':'
087: || ch == '<'
088: || ch == '='
089: || ch == '>'
090: || ch == '?'
091: || ch == '~'
092: || ch == '_'
093: || ch == '^'
094: || ((ch == '+' || ch == '-') && (i > 0 || len == 1))
095: || (Character.isDigit(ch) && i > 0) || (ch == '.' && (i == 0 || name
096: .charAt(i - 1) == '.'))))
097: out.write('\\');
098: out.write(ch);
099: }
100: } else
101: out.write(name);
102: }
103:
104: }
|