@Override
	public void readInternal(Environment env) throws IOException, TypeException {
		
		readChar(env);
		if (!(env.peek() instanceof VChar))	{
			return;
		}
		
		int c = ((VChar)env.peek()).getChar();
		if (c == -1)	{
			env.pop();
			env.pushError("Unexpected EOF");
			return;
		}
		
		char ch = (char)c;
		IValue v = env.getBoundObject(Character.toString((char)ch));
		if (null != v && v instanceof VWhitespace)	{
			env.pushError("Unexpected Whitespace");
			return;
		}
		
		StringBuilder sb = new StringBuilder();
		while (true)	{
			readChar(env);
			if (!(env.peek() instanceof VChar))	{
				return;
			}
			c = ((VChar)env.peek()).getChar();
			
			if (c == -1)	{
				// It's up to upper level code to determine whether it's ok to 
				// have an EOF directly after a symbol
				env.pop();
				System.err.println("r(Symbol): " + sb.toString());
				VSymbol sym = new org.sugarlang.value.VSymbol(sb.toString());
				env.push(sym);
				env.pushReader("terminator");
				env.pushOp("read");
				return;
			}
			
			ch = (char)c;
			v = env.getBoundObject(Character.toString((char)ch));
			env.pop();
			
			if (null != v && v instanceof VWhitespace)	{
				break;
			}
			
			sb.append(ch);
				
		}
		
		System.err.println("r(Symbol): " + sb.toString());
		VSymbol sym = new org.sugarlang.value.VSymbol(sb.toString());
		env.push(sym);
	}