
Index: src/jvm/clojure/lang/LispReader.java
===================================================================
--- src/jvm/clojure/lang/LispReader.java	(revision 1207)
+++ src/jvm/clojure/lang/LispReader.java	(working copy)
@@ -76,7 +76,7 @@
 	macros[']'] = new UnmatchedDelimiterReader();
 	macros['{'] = new MapReader();
 	macros['}'] = new UnmatchedDelimiterReader();
-//	macros['|'] = new ArgVectorReader();
+	macros['|'] = new SymbolReader();
 	macros['\\'] = new CharacterReader();
 	macros['%'] = new ArgReader();
 	macros['#'] = new DispatchReader();
@@ -284,6 +284,34 @@
 	throw new Exception("Invalid token: " + s);
 }
 
+public static class SymbolReader extends AFn{
+	public Object invoke(Object reader, Object pipeCharacter) throws Exception{
+		StringBuilder sb = new StringBuilder();
+		Reader r = (Reader) reader;
+		for(int ch = r.read(); ch != '|'; ch = r.read())
+			{
+			if(ch == -1)
+				throw new Exception("EOF while reading Symbol");
+			if(ch == '\\')	//escape
+				{
+				ch = r.read();
+				if(ch == -1)
+					throw new Exception("EOF while reading Symbol");
+				switch(ch)
+					{
+					case '\\':
+						break;
+                    case '|':
+						break;
+					default:
+						throw new Exception("Unsupported escape character in Symbol: \\" + (char) ch);
+					}
+				}
+			sb.append((char) ch);
+			}
+		return Symbol.intern(sb.toString());
+    }
+}
 
 private static Object matchSymbol(String s){
 	Matcher m = symbolPat.matcher(s);
Index: src/jvm/clojure/lang/Symbol.java
===================================================================
--- src/jvm/clojure/lang/Symbol.java	(revision 1207)
+++ src/jvm/clojure/lang/Symbol.java	(working copy)
@@ -23,11 +23,47 @@
 final int hash;
 
 public String toString(){
-	if(ns != null)
-		return ns + "/" + name;
-	return name;
+	String unescaped;
+	
+	if(ns != null)        
+		unescaped = ns + "/" + name;
+	else
+		unescaped = name;
+	
+	if(unescaped.equals(""))
+		return "||";
+	
+	if(unescaped.equals("false"))
+		return "|false|";
+	
+	if(unescaped.equals("true"))
+		return "|true|";
+	
+	//escape if the Symbol looks a number or Keyword
+	if(Character.isDigit(unescaped.charAt(0))
+			||(unescaped.length() > 1
+				&& (unescaped.startsWith("+") || unescaped.startsWith("-")) 
+				&& Character.isDigit(unescaped.charAt(1)))
+			||unescaped.startsWith(":"))
+		return escape(unescaped);
+	
+	//escape the Symbol if it contains clojure syntax
+	char[] specialChars = {'"',';','\'','@','^','`','~','(',')','[',']','{',
+		                   '}','|','\\','%',' ',',','\t','\r','\n'};
+	
+	for(char c : specialChars)
+		if(unescaped.indexOf(c) >= 0) 
+			return escape(unescaped);
+	
+	return unescaped;
 }
 
+private static String escape(String unescaped){
+	return "|" + unescaped.replaceAll("\\\\", "\\\\\\\\")                
+		.replaceAll("\\|", "\\\\\\|") + "|";
+
+}
+
 public String getNamespace(){
 	return ns;
 }
