1 4 package gnu.kawa.lispexpr; 5 import gnu.text.*; 6 import gnu.mapping.Values; 7 8 public class ReaderParens extends ReadTableEntry 9 { 10 char open; 11 char close; 12 int kind; 13 14 public int getKind() 15 { 16 return kind; 17 } 18 19 private static ReaderParens instance; 20 21 public static ReaderParens getInstance(char open, char close) 22 { 23 return getInstance(open, close, ReadTable.TERMINATING_MACRO); 24 } 25 26 public static ReaderParens getInstance(char open, char close, int kind) 27 { 28 if (open == '(' && close == ')' && kind == ReadTable.TERMINATING_MACRO) 29 { 30 if (instance == null) 31 instance = new ReaderParens(open, close, kind); 32 return instance; 33 } 34 else 35 { 36 return new ReaderParens(open, close, kind); 37 } 38 } 39 40 public ReaderParens(char open, char close, int kind) 41 { 42 this.open = open; 43 this.close = close; 44 this.kind = kind; 45 } 46 47 50 public Object read (Lexer in, int ch, int count) 51 throws java.io.IOException , SyntaxException 52 { 53 return readList((LispReader) in, ch, count, close); 54 } 55 56 public static Object readList (LispReader lexer, 57 int ch, int count, int close) 58 throws java.io.IOException , SyntaxException 59 { 60 LineBufferedReader port = lexer.getPort(); 61 char saveReadState = lexer.pushNesting(close == ']' ? '[' : '('); 62 int startLine = port.getLineNumber(); 63 int startColumn = port.getColumnNumber(); 64 try 65 { 66 Object last = null; 67 Object list = lexer.makeNil(); 68 boolean sawDot = false; 69 boolean sawDotCdr = false; 70 ReadTable readTable = ReadTable.getCurrent(); 71 for (;;) 72 { 73 int line = port.getLineNumber(); 74 int column = port.getColumnNumber(); 75 ch = port.read(); 76 if (ch == close) 77 break; 78 if (ch < 0) 79 lexer.eofError("unexpected EOF in list starting here", 80 startLine + 1, startColumn); 81 ReadTableEntry entry; 82 if (ch == '.') 83 { 84 ch = port.peek(); 85 entry = readTable.lookup(ch); 86 int kind = entry == null ? ReadTable.ILLEGAL : entry.getKind(); 87 if (kind == ReadTable.WHITESPACE 88 || kind == ReadTable.TERMINATING_MACRO 89 || kind == ReadTable.ILLEGAL) 90 { 91 port.skip(); 92 column++; 93 if (ch == close) 94 { 95 lexer.error("unexpected '" 96 + ((char) close) + "' after '.'"); 97 break; 98 } 99 if (ch < 0) 100 lexer.eofError("unexpected EOF in list starting here", 101 startLine + 1, startColumn); 102 if (sawDot) 103 { 104 lexer.error("multiple '.' in list"); 105 sawDotCdr = false; 106 list = lexer.makeNil(); 107 last = null; 108 } 109 sawDot = true; 110 } 111 else 112 { 113 ch = '.'; 115 entry = ReadTableEntry.getConstituentInstance(); 116 } 117 } 118 else 119 entry = readTable.lookup(ch); 120 Object value = lexer.readValues(ch, entry, readTable); 121 if (value == Values.empty) 122 continue; 123 value = lexer.handlePostfix(value, readTable, line, column); 124 125 130 if (sawDotCdr) 131 { 132 lexer.error("multiple values after '.'"); 133 last = null; 134 list = lexer.makeNil(); 135 sawDotCdr = false; 136 continue; 137 } 138 else if (sawDot) 139 { 140 sawDotCdr = true; 141 } 142 else 143 { 144 if (last == null) 145 { 146 line = startLine; 147 column = startColumn-1; 148 } 149 value = lexer.makePair(value, line, column); 150 } 151 if (last == null) 152 list = value; 153 else 154 lexer.setCdr(last, value); 155 last = value; 156 } 157 return list; 158 } 159 finally 160 { 161 lexer.popNesting(saveReadState); 162 } 163 164 } 165 } 166 | Popular Tags |