X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2Fchr%2FCharInput.java;h=10150d57b66e58aef1c4c18823736dfdce8ad6b9;hp=15f128953d149f99617ac13d7c96efec390478b1;hb=972303162555284f8066047d3caead8df139afd4;hpb=c042bb0dcce5d64f09b2788b2dfb722145162d2b diff --git a/src/edu/berkeley/sbp/chr/CharInput.java b/src/edu/berkeley/sbp/chr/CharInput.java index 15f1289..10150d5 100644 --- a/src/edu/berkeley/sbp/chr/CharInput.java +++ b/src/edu/berkeley/sbp/chr/CharInput.java @@ -11,15 +11,67 @@ import edu.berkeley.sbp.misc.*; import edu.berkeley.sbp.Input.Location; public class CharInput extends Cartesian.Input { - private final Reader r; + + private static class RollbackReader extends Reader { + private final Reader r; + public RollbackReader(Reader r) { this.r = r; } + + private char[] queue = new char[1024]; + private int head = 0; + private int tail = 0; + + private void unread(char c) { + if (tail >= queue.length) { + if (tail - head > queue.length/2) { + char[] queue2 = new char[queue.length * 2]; + System.arraycopy(queue, head, queue2, 0, tail-head); + } else { + System.arraycopy(queue, head, queue, 0, tail-head); + } + tail = tail-head; + head = 0; + } + queue[tail++] = c; + } + + public void close() throws IOException { r.close(); } + public int read() throws IOException { + if (tail>head) + return queue[head++]; + return r.read(); + } + public int read(char cbuf[]) throws IOException { return read(cbuf, 0, cbuf.length); } + public int read(char cbuf[], int off, int len) throws IOException { + if (tail>head) { + int count = Math.min(len, tail-head); + System.arraycopy(queue, head, cbuf, off, count); + head += count; + return count; + } + return r.read(cbuf, off, len); + } + public long skip(long n) throws IOException { return r.skip(n); } + public boolean ready() throws IOException { return true; } + public boolean markSupported() { return false; } + public void mark(int readAheadLimit) throws IOException { throw new IOException("not supported"); } + public void reset() throws IOException { throw new IOException("not supported"); } + } + + private final RollbackReader r; public CharInput(String s) { this(new StringReader(s)); } public CharInput(Reader r) { this(r, null); } - public CharInput(Reader r, String s) { this.r = new BufferedReader(r); } + public CharInput(Reader r, String s) { this.r = new RollbackReader(new BufferedReader(r)); } public CharInput(InputStream i) { this(i, null); } public CharInput(InputStream i, String s) { this(new InputStreamReader(i), s); } - + + public CharInput(InputStream i, String s, boolean indent) { + this(new InputStreamReader(i), s); + this.indent = indent; + } + boolean cr = false; + boolean indent = false; private int count = 0; private StringBuilder cache = new StringBuilder(); @@ -28,21 +80,87 @@ public class CharInput extends Cartesian.Input { else if (cache == null) cache = new StringBuilder(); } + int indentation = -1; + int lastIndentation = 0; + int queuedIndentation = 0; + char queuedCharacter = ' '; + int delta = 0; + public boolean isCR() { return cr; } public Character _next() throws IOException { + Character ret = __next(); + if (ret==null) return null; + char c = ret.charValue(); + if (indent) { + if (ret==CharAtom.left) System.out.print("\033[31m{\033[0m"); + else if (ret==CharAtom.right) System.out.print("\033[31m}\033[0m"); + else System.out.print(c+""); + } + return ret; + } + public Character __next() throws IOException { + cr = false; + + if (queuedIndentation < 0) { + queuedIndentation++; + return CharAtom.right; + } + if (queuedSpaces > 0) { + queuedSpaces--; + return ' '; + } + if (queuedIndentation > 0) { + queuedIndentation--; + return CharAtom.left; + } + + if (queuedCharacter != ' ') { + char ret = queuedCharacter; + queuedCharacter = ' '; + return ret; + } + int i = r.read(); - if (i==-1) { /*System.err.print("\r...done \r"); */return null; } + if (i==-1) { + /*System.err.print("\r...done \r"); */ + if (indent && indentation >= 0) { + redent(indentation - lastIndentation); + //System.err.println("\r \rindent: " + (indentation - lastIndentation)); + lastIndentation = indentation; + indentation = -1; + return __next(); + } + return null; + } char c = (char)i; if (cache != null) cache.append(c); cr = c=='\n'; - /* - if ((count++) % 100 == 0) - System.err.print(" " + count + "\r"); - */ + + if (indent) + if (cr) { + indentation = 0; + } else if (c==' ' && indentation >= 0) { + indentation++; + } else if (indentation >= 0) { + //System.err.println("\r \rindent: " + (indentation - lastIndentation)); + redent(indentation - lastIndentation); + r.unread(c); + lastIndentation = indentation; + indentation = -1; + return __next(); + } + return c; } + private void redent(int i) { + if (i<0) { r.unread(CharAtom.right); redent(i+1); return; } + if (i>0) { r.unread(CharAtom.left); redent(i-1); return; } + } + + int queuedSpaces = 0; + public String showRegion(Region rc) { if (cache == null) return null; Cartesian.Region r = (Cartesian.Region)rc;