Index: src/org/armedbear/lisp/FaslReader.java
===================================================================
--- src/org/armedbear/lisp/FaslReader.java	(revision 12602)
+++ src/org/armedbear/lisp/FaslReader.java	(working copy)
@@ -101,21 +101,7 @@
         public LispObject execute(Stream stream, char c, int n)
 
         {
-            final LispThread thread = LispThread.currentThread();
-            LispObject list = stream.readList(true, Stream.faslReadtable);
-            if (_BACKQUOTE_COUNT_.symbolValue(thread).zerop()) {
-                if (n >= 0) {
-                    LispObject[] array = new LispObject[n];
-                    for (int i = 0; i < n; i++) {
-                        array[i] = list.car();
-                        if (list.cdr() != NIL)
-                            list = list.cdr();
-                    }
-                    return new SimpleVector(array);
-                } else
-                    return new SimpleVector(list);
-            }
-            return new Cons(_BQ_VECTOR_FLAG_.symbolValue(thread), list);
+          return stream.readSharpLeftParen(c, n, Stream.faslReadtable);
         }
     };
 
@@ -128,65 +114,7 @@
         public LispObject execute(Stream stream, char ignored, int n)
 
         {
-            final LispThread thread = LispThread.currentThread();
-            final Readtable rt = FaslReadtable.getInstance();
-            final boolean suppress =
-                (Symbol.READ_SUPPRESS.symbolValue(thread) != NIL);
-            StringBuilder sb = new StringBuilder();
-	    try 
-	      {
-		while (true) {
-		  int ch = stream._readChar();
-		  if (ch < 0)
-                    break;
-		  char c = (char) ch;
-		  if (c == '0' || c == '1')
-                    sb.append(c);
-		  else {
-                    int syntaxType = rt.getSyntaxType(c);
-                    if (syntaxType == Readtable.SYNTAX_TYPE_WHITESPACE ||
-                        syntaxType == Readtable.SYNTAX_TYPE_TERMINATING_MACRO) {
-		      stream._unreadChar(c);
-		      break;
-                    } else if (!suppress) {
-		      String name = LispCharacter.charToName(c);
-		      if (name == null)
-			name = "#\\" + c;
-		      error(new ReaderError("Illegal element for bit-vector: " + name,
-					    stream));
-                    }
-		  }
-		}
-	      }
-	    catch (java.io.IOException e)
-	      {
-		error(new ReaderError("IO error: ",
-				      stream));
-		return NIL;
-	      }
-
-            if (suppress)
-                return NIL;
-            if (n >= 0) {
-                // n was supplied.
-                final int length = sb.length();
-                if (length == 0) {
-                    if (n > 0)
-                        return error(new ReaderError("No element specified for bit vector of length " +
-                                                      n + '.',
-                                                      stream));
-                }
-                if (n > length) {
-                    final char c = sb.charAt(length - 1);
-                    for (int i = length; i < n; i++)
-                        sb.append(c);
-                } else if (n < length) {
-                    return error(new ReaderError("Bit vector is longer than specified length: #" +
-                                                  n + '*' + sb.toString(),
-                                                  stream));
-                }
-            }
-            return new SimpleBitVector(sb.toString());
+          return stream.readSharpStar(ignored, n, Stream.faslReadtable);
         }
     };
 
@@ -199,14 +127,7 @@
         public LispObject execute(Stream stream, char c, int n)
 
         {
-            final LispThread thread = LispThread.currentThread();
-            if (Symbol.READ_EVAL.symbolValue(thread) == NIL)
-                return error(new ReaderError("Can't read #. when *READ-EVAL* is NIL.",
-                                              stream));
-            else
-                return eval(stream.read(true, NIL, true, thread,
-                                        Stream.faslReadtable),
-                            new Environment(), thread);
+          return stream.readSharpDot(c, n, Stream.faslReadtable);
         }
     };
 
Index: src/org/armedbear/lisp/LispReader.java
===================================================================
--- src/org/armedbear/lisp/LispReader.java	(revision 12602)
+++ src/org/armedbear/lisp/LispReader.java	(working copy)
@@ -140,21 +140,7 @@
         public LispObject execute(Stream stream, char c, int n)
 
         {
-            final LispThread thread = LispThread.currentThread();
-            LispObject list = stream.readList(true, Stream.currentReadtable);
-            if (_BACKQUOTE_COUNT_.symbolValue(thread).zerop()) {
-                if (n >= 0) {
-                    LispObject[] array = new LispObject[n];
-                    for (int i = 0; i < n; i++) {
-                        array[i] = list.car();
-                        if (list.cdr() != NIL)
-                            list = list.cdr();
-                    }
-                    return new SimpleVector(array);
-                } else
-                    return new SimpleVector(list);
-            }
-            return new Cons(_BQ_VECTOR_FLAG_.symbolValue(thread), list);
+          return stream.readSharpLeftParen(c, n, Stream.currentReadtable);
         }
     };
 
@@ -167,62 +153,7 @@
         public LispObject execute(Stream stream, char ignored, int n)
 
         {
-            final LispThread thread = LispThread.currentThread();
-            final Readtable rt = (Readtable) Symbol.CURRENT_READTABLE.symbolValue(thread);
-            final boolean suppress = Symbol.READ_SUPPRESS.symbolValue(thread) != NIL;
-            StringBuilder sb = new StringBuilder();
-            try 
-              {
-                while (true) {
-                  int ch = stream._readChar();
-                  if (ch < 0)
-                    break;
-                  char c = (char) ch; // ### BUG: Codepoint conversion
-                  if (c == '0' || c == '1')
-                    sb.append(c);
-                  else {
-                    int syntaxType = rt.getSyntaxType(c);
-                    if (syntaxType == Readtable.SYNTAX_TYPE_WHITESPACE ||
-                        syntaxType == Readtable.SYNTAX_TYPE_TERMINATING_MACRO) {
-                      stream._unreadChar(c);
-                      break;
-                    } else if (!suppress) {
-                      String name = LispCharacter.charToName(c);
-                      if (name == null)
-                        name = "#\\" + c;
-                      error(new ReaderError("Illegal element for bit-vector: " + name,
-                                            stream));
-                    }
-                  }
-                }
-              }
-            catch (java.io.IOException e)
-              {
-                error(new ReaderError("IO error-vector: ",
-                                      stream));
-              }
-            if (suppress)
-                return NIL;
-            if (n >= 0) {
-                // n was supplied.
-                final int length = sb.length();
-                if (length == 0) {
-                    if (n > 0)
-                        return error(new ReaderError("No element specified for bit vector of length " +
-                                                      n + '.',
-                                                      stream));
-                }
-                if (n > length) {
-                    final char c = sb.charAt(length - 1);
-                    for (int i = length; i < n; i++)
-                        sb.append(c);
-                } else if (n < length) {
-                    return error(new ReaderError("Bit vector is longer than specified length: #" +
-                                                  n + '*' + sb.toString(),
-                                                  stream));
-                }
-            }
-            return new SimpleBitVector(sb.toString());
+          return stream.readSharpStar(ignored, n, Stream.currentReadtable);
         }
     };
 
@@ -235,14 +166,7 @@
         public LispObject execute(Stream stream, char c, int n)
 
         {
-            final LispThread thread = LispThread.currentThread();
-            if (Symbol.READ_EVAL.symbolValue(thread) == NIL)
-                return error(new ReaderError("Can't read #. when *READ-EVAL* is NIL.",
-                                              stream));
-            else
-                return eval(stream.read(true, NIL, true,
-                                        thread, Stream.currentReadtable),
-                            new Environment(), thread);
+          return stream.readSharpDot(c, n, Stream.currentReadtable);
         }
     };
 
Index: src/org/armedbear/lisp/Stream.java
===================================================================
--- src/org/armedbear/lisp/Stream.java	(revision 12602)
+++ src/org/armedbear/lisp/Stream.java	(working copy)
@@ -735,6 +735,105 @@
                                      this));
     }
 
+    public LispObject readSharpLeftParen(char c, int n, 
+                                         ReadtableAccessor rta) 
+    {
+        final LispThread thread = LispThread.currentThread();
+        LispObject list = readList(true, rta);
+        if (_BACKQUOTE_COUNT_.symbolValue(thread).zerop()) {
+            if (n >= 0) {
+                LispObject[] array = new LispObject[n];
+                for (int i = 0; i < n; i++) {
+                    array[i] = list.car();
+                    if (list.cdr() != NIL)
+                        list = list.cdr();
+                }
+                return new SimpleVector(array);
+            } else
+                return new SimpleVector(list);
+        }
+        return new Cons(_BQ_VECTOR_FLAG_.symbolValue(thread), list);
+    }
+
+    public LispObject readSharpStar(char ignored, int n, 
+                                    ReadtableAccessor rta) 
+    {
+        final LispThread thread = LispThread.currentThread();
+        final Readtable rt = rta.rt(thread);
+
+        final boolean suppress =
+            (Symbol.READ_SUPPRESS.symbolValue(thread) != NIL);
+        StringBuilder sb = new StringBuilder();
+        try 
+            {
+		while (true) {
+                    int ch = _readChar();
+                    if (ch < 0)
+                        break;
+                    char c = (char) ch;
+                    if (c == '0' || c == '1')
+                        sb.append(c);
+                    else {
+                        int syntaxType = rt.getSyntaxType(c);
+                        if (syntaxType == Readtable.SYNTAX_TYPE_WHITESPACE ||
+                            syntaxType == Readtable.SYNTAX_TYPE_TERMINATING_MACRO) {
+                            _unreadChar(c);
+                            break;
+                        } else if (!suppress) {
+                            String name = LispCharacter.charToName(c);
+                            if (name == null)
+                                name = "#\\" + c;
+                            error(new ReaderError("Illegal element for bit-vector: " + name,
+                                                  this));
+                        }
+                    }
+		}
+            }
+        catch (java.io.IOException e)
+            {
+		error(new ReaderError("IO error: ",
+				      this));
+		return NIL;
+            }
+        
+        if (suppress)
+            return NIL;
+        if (n >= 0) {
+            // n was supplied.
+            final int length = sb.length();
+            if (length == 0) {
+                if (n > 0)
+                    return error(new ReaderError("No element specified for bit vector of length " +
+                                                 n + '.',
+                                                 this));
+            }
+            if (n > length) {
+                final char c = sb.charAt(length - 1);
+                for (int i = length; i < n; i++)
+                    sb.append(c);
+            } else if (n < length) {
+                return error(new ReaderError("Bit vector is longer than specified length: #" +
+                                             n + '*' + sb.toString(),
+                                             this));
+            }
+        }
+        return new SimpleBitVector(sb.toString());
+    }
+
+
+    public LispObject readSharpDot(char c, int n, 
+                                   ReadtableAccessor rta) 
+    {
+        final LispThread thread = LispThread.currentThread();
+        if (Symbol.READ_EVAL.symbolValue(thread) == NIL)
+            return error(new ReaderError("Can't read #. when *READ-EVAL* is NIL.",
+                                         this));
+        else
+            return eval(read(true, NIL, true, thread,
+                             rta),
+                        new Environment(), thread);
+    }
+
     public LispObject readCharacterLiteral(Readtable rt, LispThread thread)
 
     {
