KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > kawa > lispexpr > ReaderDispatchMisc


1 // Copyright (c) 2001 Per M.A. Bothner
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

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   /** A code which specifies which particular reader-action to perform.
14    * The code is one the CommonLisp or Scheme '#' reader characters.
15    * For example, if code=='x' then read a hexadecimal integer.
16    * If code==-1, perform the standard action for the character read. */

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 JavaDoc read (Lexer in, int ch, int count)
34     throws java.io.IOException JavaDoc, SyntaxException
35   {
36     LispReader reader = (LispReader) in;
37     char saveReadState = '\0';
38     LineBufferedReader port;
39     int length;
40     String JavaDoc name;
41     if (code >= 0)
42       ch = code;
43     switch (ch)
44       {
45       case ':':
46     // Handle Guile-style keyword syntax: '#:KEYWORD'
47
// Note this conflicts with Common Lisp uninterned symbols. FIXME
48
int startPos = reader.tokenBufferLength;
49     reader.readToken(reader.read(), 'P', ReadTable.getCurrent());
50     length = reader.tokenBufferLength - startPos;
51     name = new String JavaDoc(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 JavaDoc list;
108         if (port.peek() == '('
109             && ((length
110                  = LList.listLength(list = reader.readObject(), false))
111                 > 0)
112             && ((Pair) list).car instanceof String JavaDoc)
113           {
114             name = (String JavaDoc) ((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--; // Subtract 1 for the consrutcor name.
121
Object JavaDoc[] args = new Object JavaDoc[length];
122                 Object JavaDoc 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 JavaDoc 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