01: // Copyright (c) 2001 Per M.A. Bothner
02: // This is free software; for terms and warranty disclaimer see ./COPYING.
03:
04: package gnu.kawa.lispexpr;
05:
06: import gnu.text.*;
07: import gnu.mapping.InPort;
08:
09: /** Reader table entry for '<' to treat '[' and ']' as constituents.
10: * Lets us use (say) '<char[]>' as a token even if '[' and ']' are parens.
11: * @author Bruce R. Lewis.
12: */
13:
14: public class ReaderTypespec extends ReadTableEntry {
15: public int getKind() {
16: return ReadTable.NON_TERMINATING_MACRO;
17: }
18:
19: public Object read(Lexer in, int ch, int count)
20: throws java.io.IOException, SyntaxException {
21: int startPos = in.tokenBufferLength;
22: LineBufferedReader port = in.getPort();
23: ReadTable rtable = ReadTable.getCurrent();
24: ReadTableEntry entry;
25: char saveReadState = '\0';
26: in.tokenBufferAppend(ch);
27: int c = ch;
28: int prev;
29: if (port instanceof InPort) {
30: saveReadState = ((InPort) port).readState;
31: ((InPort) port).readState = (char) ch;
32: }
33: try {
34: boolean got_open_square = false;
35: for (;;) {
36: int next;
37:
38: prev = c;
39:
40: if (port.pos < port.limit && prev != '\n')
41: c = port.buffer[port.pos++];
42: else
43: c = port.read();
44: if (c == '\\') {
45: if (in instanceof LispReader)
46: c = ((LispReader) in).readEscape();
47: else
48: c = port.read();
49: } else {
50: if ((!got_open_square && c == '[' && true == (got_open_square = true))
51: || (got_open_square && c == ']' && false == (got_open_square = false))
52: || (null != (entry = rtable.lookup(c)) && entry
53: .getKind() == ReadTable.CONSTITUENT)) {
54: in.tokenBufferAppend(c);
55: continue;
56: } else {
57: in.unread(c);
58: break;
59: }
60: }
61: }
62: return (new java.lang.String(in.tokenBuffer, startPos,
63: in.tokenBufferLength - startPos)).intern();
64: } finally {
65: in.tokenBufferLength = startPos;
66: if (port instanceof InPort)
67: ((InPort) port).readState = saveReadState;
68: }
69: }
70: }
|