KickJava   Java API By Example, From Geeks To Geeks.

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


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.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  /** Read a list (possibly improper) of zero or more Scheme forms.
48    * Assumes '(' has been read.
49    */

50   public Object JavaDoc read (Lexer in, int ch, int count)
51     throws java.io.IOException JavaDoc, SyntaxException
52   {
53     return readList((LispReader) in, ch, count, close);
54   }
55
56   public static Object JavaDoc readList (LispReader lexer,
57                  int ch, int count, int close)
58     throws java.io.IOException JavaDoc, 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 JavaDoc last = null;
67     Object JavaDoc 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             // Treat '.' as start of token.
114
ch = '.';
115             entry = ReadTableEntry.getConstituentInstance();
116           }
117           }
118         else
119           entry = readTable.lookup(ch);
120         Object JavaDoc value = lexer.readValues(ch, entry, readTable);
121         if (value == Values.empty)
122           continue;
123             value = lexer.handlePostfix(value, readTable, line, column);
124
125         // ( a1 ... an . cdr) creates an n-element list ended by
126
// cdr. If n==0, a reasonable (and common) extension is to
127
// interpret this as a 0-element list ended by cdr - i.e.
128
// just cdr by itself.
129

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