1 4 package gnu.kawa.lispexpr; 5 import gnu.text.*; 6 import gnu.mapping.InPort; 7 import gnu.mapping.Values; 8 import gnu.mapping.Procedure; 9 import gnu.lists.*; 10 11 public class ReaderDispatchMisc extends ReadTableEntry 12 { 13 17 protected int code; 18 19 private static ReaderDispatchMisc instance = new ReaderDispatchMisc(); 20 21 public static ReaderDispatchMisc getInstance() { return instance; } 22 23 public ReaderDispatchMisc() 24 { 25 code = -1; 26 } 27 28 public ReaderDispatchMisc(int code) 29 { 30 this.code = code; 31 } 32 33 public Object read (Lexer in, int ch, int count) 34 throws java.io.IOException , SyntaxException 35 { 36 LispReader reader = (LispReader) in; 37 char saveReadState = '\0'; 38 LineBufferedReader port; 39 int length; 40 String name; 41 if (code >= 0) 42 ch = code; 43 switch (ch) 44 { 45 case ':': 46 int startPos = reader.tokenBufferLength; 49 reader.readToken(reader.read(), 'P', ReadTable.getCurrent()); 50 length = reader.tokenBufferLength - startPos; 51 name = new String (reader.tokenBuffer, startPos, length); 52 reader.tokenBufferLength = startPos; 53 return gnu.expr.Keyword.make(name.intern()); 54 case '\\': 55 return LispReader.readCharacter(reader); 56 case '!': 57 return LispReader.readSpecial(reader); 58 case 'T': 59 return Boolean.TRUE; 60 case 'F': 61 ch = in.peek(); 62 if (Character.isDigit((char) ch)) 63 return LispReader.readSimpleVector(reader, 'F'); 64 return Boolean.FALSE; 65 case 'S': 66 case 'U': 67 return LispReader.readSimpleVector(reader, (char) ch); 68 case 'R': 69 if (count > 36) 70 { 71 in.error("the radix "+count+" is too big (max is 36)"); 72 count = 36; 73 } 74 return LispReader.readNumberWithRadix(0, reader, count); 75 case 'X': 76 return LispReader.readNumberWithRadix(0, reader, 16); 77 case 'D': 78 return LispReader.readNumberWithRadix(0, reader, 10); 79 case 'O': 80 return LispReader.readNumberWithRadix(0, reader, 8); 81 case 'B': 82 return LispReader.readNumberWithRadix(0, reader, 2); 83 case 'I': 84 case 'E': 85 reader.tokenBufferAppend('#'); 86 reader.tokenBufferAppend(ch); 87 return LispReader.readNumberWithRadix(2, reader, 0); 88 case '|': 89 port = reader.getPort(); 90 if (port instanceof InPort) 91 { 92 saveReadState = ((InPort) port).readState; 93 ((InPort) port).readState = '|'; 94 } 95 try 96 { 97 reader.readNestedComment('#', '|'); 98 } 99 finally 100 { 101 if (port instanceof InPort) 102 ((InPort) port).readState = saveReadState; 103 } 104 return Values.empty; 105 case ',': 106 port = reader.getPort(); 107 Object list; 108 if (port.peek() == '(' 109 && ((length 110 = LList.listLength(list = reader.readObject(), false)) 111 > 0) 112 && ((Pair) list).car instanceof String ) 113 { 114 name = (String ) ((Pair) list).car; 115 Procedure proc = ReadTable.getCurrent().getReaderCtor(name); 116 if (proc == null) 117 in.error("unknown reader constructor "+name); 118 else 119 { 120 length--; Object [] args = new Object [length]; 122 Object argList = ((Pair) list).cdr; 123 for (int i = 0; i < length; i++) 124 { 125 Pair pair = (Pair) argList; 126 args[i] = pair.car; 127 argList = pair.cdr; 128 } 129 try 130 { 131 return proc.applyN(args); 132 } 133 catch (Throwable ex) 134 { 135 in.error("caught "+ex+" applying reader constructor "+name); 136 } 137 } 138 } 139 else 140 in.error("a non-empty list starting with a symbol must follow #,"); 141 return Boolean.FALSE; 142 default: 143 in.error("An invalid #-construct was read."); 144 return Values.empty; 145 } 146 } 147 } 148 | Popular Tags |