/** * Enter a nested expression. This is used in interactive mode to control whether to continue past * end of line, depending on whether the expression is incomplete. * * @param promptChar Used in prompt string to indicate type of nesting. * @return The previous value of promptChar, to be passed to popNesting. */ public char pushNesting(char promptChar) { nesting++; InPort port = getPort(); char save = port.readState; port.readState = promptChar; return save; }
public Object read(Lexer in, int ch, int count) throws java.io.IOException, SyntaxException { if (!(in instanceof LispReader)) return super.read(in, ch, count); int endChar = ch == '<' ? '>' : -2; LispReader reader = (LispReader) in; int startPos = in.tokenBufferLength; InPort port = in.getPort(); ReadTable rtable = ReadTable.getCurrent(); char saveReadState = '\0'; in.tokenBufferAppend(ch); int c = ch; int prev; if (port instanceof InPort) { saveReadState = ((InPort) port).readState; ((InPort) port).readState = (char) ch; } try { boolean got_open_square = false; for (; ; ) { int next; prev = c; if (port.pos < port.limit && prev != '\n') c = port.buffer[port.pos++]; else c = port.read(); if (c == '\\') { in.tokenBufferAppend(LispReader.TOKEN_ESCAPE_CHAR); reader.seenEscapes = true; } else if (c == endChar && !got_open_square) { reader.readToken('>', rtable); break; } else { int kind; if ((!got_open_square && c == '[' && true == (got_open_square = true)) || (got_open_square && c == ']' && false == (got_open_square = false)) || ((kind = rtable.lookup(c).getKind()) == ReadTable.CONSTITUENT || kind == ReadTable.NON_TERMINATING_MACRO)) { in.tokenBufferAppend(c); continue; } else { in.unread(c); break; } } } return reader.handleToken(startPos, rtable); } finally { in.tokenBufferLength = startPos; if (port instanceof InPort) ((InPort) port).readState = saveReadState; } }
public static long readDigits(InPort port, int radix) throws IOException { long ival = -2; for (; ; ) { ival = readDigitsInBuffer(port, ival, radix); if (port.pos < port.limit || port.peek() < 0) break; } return ival; }
/** * Read digits, up to the first non-digit or the buffer limit * * @param ival previously-seen digits or -2 if no digits seen * @return the digits seen as a non-negative long, or -1 on overflow, or -2 if no digits seen */ public static long readDigitsInBuffer(InPort port, long ival, int radix) { int i = port.pos; if (i >= port.limit) return ival; for (; ; ) { char c = port.buffer[i]; int dval = Character.digit(c, radix); if (dval < 0) break; if (ival == -2) // initial digits ival = dval; else if (ival == -1) ; else if (ival > (Long.MAX_VALUE - dval) / radix) ival = -1; else ival = ival * radix + dval; if (++i >= port.limit) break; } port.pos = i; return ival; }
public int read(char[] buf, int offset, int length) throws java.io.IOException { return port.read(buf, offset, length); }
/** Read a Unicode character (codepoint) by checking for surrogates. */ public int readCodePoint() throws java.io.IOException { return port.readCodePoint(); }
public void close() throws java.io.IOException { port.close(); }
/** * Exit a nested expression, reversing pushNesting * * @param save Saved values return by prior pushNesting */ public void popNesting(char save) { InPort port = getPort(); port.readState = save; nesting--; }
/** Stop tentative parsing. Return to position where we called mark. */ public void reset() throws java.io.IOException { if (saveTokenBufferLength < 0) throw new Error("internal error: reset called without prior mark"); port.reset(); saveTokenBufferLength = -1; }
public void error(char severity, String message) { int line = port.getLineNumber(); int column = port.getColumnNumber(); error(severity, port.getName(), line + 1, column >= 0 ? column + 1 : 0, message); }
public void skip() throws java.io.IOException { port.skip(); }
/** Return the current (zero-based) column number. */ public int getColumnNumber() { return port.getColumnNumber(); }
/** Get the current line number. The "first" line is number number 0. */ public int getLineNumber() { return port.getLineNumber(); }
public String getName() { return port.getName(); }
public void eofError(String message, int startLine, int startColumn) throws SyntaxException { error('f', port.getName(), startLine, startColumn, message); throw new SyntaxException(messages); }
public void unread(int ch) throws java.io.IOException { if (ch >= 0) port.unread(); }
/** * Check if the next character matches a given character. * * @param ch The character to match against. * @return if the character read matches On a match, the position is advanced following that * character. */ public boolean checkNext(char ch) throws java.io.IOException { int r = port.read(); if (r == ch) return true; if (r >= 0) port.unread_quick(); return false; }
public int peek() throws java.io.IOException { return port.peek(); }
/** Start tentative parsing. Must be followed by a reset. */ public void mark() throws java.io.IOException { if (saveTokenBufferLength >= 0) throw new Error("internal error: recursive call to mark not allowed"); port.mark(Integer.MAX_VALUE); saveTokenBufferLength = tokenBufferLength; }
protected void unread() throws java.io.IOException { port.unread(); }
protected void skip_quick() throws java.io.IOException { port.skip_quick(); }