KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > q2 > lang > Q2Read


1 package gnu.q2.lang;
2 import gnu.kawa.lispexpr.*;
3 import gnu.expr.QuoteExp;
4 import gnu.text.*;
5 import gnu.mapping.*;
6 import gnu.lists.*;
7 import gnu.expr.Keyword;
8 import gnu.kawa.xml.MakeAttribute;
9
10 /** A class to read Scheme forms (S-expressions). */
11
12 public class Q2Read extends LispReader
13 {
14   void init()
15   {
16     initialColonIsKeyword = false;
17     ((InPort) port).readState = ' ';
18   }
19
20   public Q2Read(InPort port)
21   {
22     super(port);
23     init();
24   }
25   
26   public Q2Read(InPort port, SourceMessages messages)
27   {
28     super(port, messages);
29     init();
30   }
31   
32   int skipIndentation ()
33       throws java.io.IOException JavaDoc, SyntaxException
34   {
35     int numTabs = 0, numSpaces = 0;
36     int ch = port.read();
37     while (ch == '\t')
38       {
39     numTabs++;
40     ch = port.read();
41       }
42     while (ch == ' ')
43       {
44     numSpaces++;
45     ch = port.read();
46       }
47     if (ch < 0)
48       return -1;
49     port.unread();
50     return (numTabs << 16) + numSpaces;
51   }
52
53   boolean singleLine()
54   {
55     return interactive && nesting == 0;
56   }
57
58   public Object JavaDoc readCommand ()
59       throws java.io.IOException JavaDoc, SyntaxException
60   {
61     return readCommand(false);
62   }
63
64   public Object JavaDoc readCommand (boolean forceList)
65       throws java.io.IOException JavaDoc, SyntaxException
66   {
67     int line = port.getLineNumber();
68     int startColumn = port.getColumnNumber();
69     int lastColumn = startColumn;
70     Object JavaDoc obj = LList.Empty;
71     PairWithPosition pair = null, last = null;
72     for (;;)
73       {
74     int ch = read();
75     if (ch < 0)
76       break;
77     if (ch == ' ' || ch == '\t')
78       continue;
79     unread();
80     if (ch == ')')
81       break;
82     line = port.getLineNumber();
83     int column = port.getColumnNumber();
84     while (ch == '\r' || ch == '\n')
85       {
86         if (singleLine())
87           return obj;
88         ch = read();
89         skipIndentation(); // skipHorSpace.
90
column = port.getColumnNumber();
91         ch = peek();
92         if (column <= startColumn)
93           break;
94       }
95     if (column <= startColumn && last != null)
96       break;
97     Object JavaDoc next;
98     if (column == lastColumn && last != null)
99       next = readCommand();
100     else if (column < lastColumn && last != null)
101       {
102         PairWithPosition p = pair;
103         for (;;)
104           {
105         Object JavaDoc n = p.cdr;
106         if (n == LList.Empty)
107           break;
108         PairWithPosition np = (PairWithPosition) n;
109         int pColumn = np.getColumnNumber()-1;
110         if (pColumn >= column)
111           {
112             if (pColumn > column)
113               error('e', "some tokens on previous line indented more than current line");
114             n = np.cdr;
115             if (n != LList.Empty)
116               {
117             if (((PairWithPosition) n).getColumnNumber()-1==column)
118               {
119                 p = (PairWithPosition) n;
120                 continue;
121               }
122             last = (PairWithPosition)
123               makePair(np, port.getLineNumber(), column);
124             p.cdr = last;
125               }
126             break;
127           }
128         p = np;
129           }
130         next = readCommand();
131       }
132     else
133       next = readObject();
134     if (next == Sequence.eofValue)
135       break;
136     lastColumn = column;
137     String JavaDoc filename = port.getName();
138     PairWithPosition cur = PairWithPosition.make(next, LList.Empty,
139                              filename, line+1, column+1);
140     if (last == null)
141       {
142         pair = cur;
143         obj = cur;
144       }
145     else if (last.car instanceof Keyword)
146       {
147         Object JavaDoc name = new QuoteExp(((Keyword) last.car).getName());
148         last.car
149           = new PairWithPosition(last, MakeAttribute.makeAttribute,
150                      new PairWithPosition(last, name, cur));
151         continue;
152       }
153     else
154       last.cdr = cur;
155     last = cur;
156       }
157     if (! forceList)
158       {
159     if (obj == last)
160       obj = last.car;
161     else if (last == null)
162       obj = QuoteExp.voidExp;
163       }
164     return obj;
165   }
166
167   public static Object JavaDoc readObject(InPort port)
168       throws java.io.IOException JavaDoc, SyntaxException
169   {
170     return (new Q2Read(port)).readObject();
171   }
172
173   /** Record '[' location for error messages. */
174   String JavaDoc expressionStartFile;
175   int expressionStartLine;
176   int expressionStartColumn;
177
178   void saveExpressionStartPosition()
179   {
180     expressionStartFile = port.getName();
181     expressionStartLine = port.getLineNumber();
182     expressionStartColumn = port.getColumnNumber();
183   }
184 }
185
186 class Q2ReaderParens extends ReaderDispatchMisc
187 {
188   public Object JavaDoc read (Lexer in, int ch, int count)
189     throws java.io.IOException JavaDoc, SyntaxException
190   {
191     Q2Read reader = (Q2Read) in;
192     char saveReadState = reader.pushNesting('(');
193     try
194       {
195     Object JavaDoc result = reader.readCommand(true);
196
197     LineBufferedReader port = reader.getPort();
198     if (port.read() != ')')
199       reader.error("missing ')'");
200     return result;
201       }
202     finally
203       {
204     reader.popNesting(saveReadState);
205       }
206   }
207
208 }
209
Popular Tags