package st.gravel.core; import java.util.ArrayList; import java.util.HashSet; import java.util.WeakHashMap; import st.gravel.support.jvm.CharacterExtensions; public class Symbol { private final static WeakHashMap<String, Symbol> map = new WeakHashMap<String, Symbol>(); public static String getSmalltalkName() { return "Symbol"; } private final String value; private Symbol(String value) { super(); this.value = value; } public static Symbol value(String value) { if (value == null) return value(""); String intern = value.intern(); Symbol current = map.get(intern); if (current == null) return newSymbol(intern); return current; } private synchronized static Symbol newSymbol(String intern) { Symbol current = map.get(intern); if (current == null) { current = new Symbol(intern); map.put(intern, current); } return current; } public String asString() { return value; } public String toString() { return "#" + value; } public boolean isEmpty() { return value.isEmpty(); } public int numArgs() { if (value.length() == 0) return 0; if (!(CharacterExtensions.isLetter(value.charAt(0)) || value.charAt(0) == '_')) return 1; int tally = 0; for (int i = 0; i < value.length(); i++) { if (value.charAt(i) == ':') tally++; } return tally; } public String[] keywords() { if (numArgs() <= 1) return new String[] {asString()}; ArrayList<String> parts = new ArrayList<>(); int length = value.length(); int mark = 0; for (int i = 0; i < length; i++) { if (value.charAt(i) == ':') { parts.add(value.substring(mark, i+1)); mark = i + 1; } } return parts.toArray(new String[parts.size()]); } public static HashSet<String> allStrings() { return new HashSet(map.keySet()); } public boolean isUnary() { return numArgs() == 0; } public boolean isKeyword() { if( value.length() <= 1) return false; return value.charAt(value.length() -1 ) == ':'; } public boolean isBinary() { return !isUnary() && !isKeyword(); } public static Symbol forNumArgs(int numArgs) { if (numArgs == 0) return Symbol.value("value"); StringBuilder str = new StringBuilder(); for (int i = 0 ;i<numArgs ;i++) { str.append("value:"); } return Symbol.value(str.toString()); } }