source: branches/0.17.x/abcl/src/org/armedbear/lisp/LispReader.java

Last change on this file was 12254, checked in by ehuelsmann, 16 years ago

Remove 'throws ConditionThrowable?' method annotations:

it's an unchecked exception now, so no need to declare it thrown.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 15.9 KB
Line 
1/*
2 * LispReader.java
3 *
4 * Copyright (C) 2004-2007 Peter Graves
5 * $Id: LispReader.java 12254 2009-11-06 20:07:54Z ehuelsmann $
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 *
21 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36public final class LispReader extends Lisp
37{
38    // ### read-comment
39    public static final ReaderMacroFunction READ_COMMENT =
40        new ReaderMacroFunction("read-comment", PACKAGE_SYS, false,
41                                "stream character")
42    {
43        @Override
44        public LispObject execute(Stream stream, char ignored)
45
46        {
47          try 
48            {
49              while (true) {
50                int n = stream._readChar();
51                if (n < 0)
52                  return null;
53                if (n == '\n')
54                  return null;
55              }
56            }
57          catch (java.io.IOException e)
58            {
59              return null;
60            }
61        }
62    };
63
64    // ### read-string
65    public static final ReaderMacroFunction READ_STRING =
66        new ReaderMacroFunction("read-string", PACKAGE_SYS, false,
67                                "stream character")
68    {
69        @Override
70        public LispObject execute(Stream stream, char terminator)
71
72        {
73            final LispThread thread = LispThread.currentThread();
74            final Readtable rt = (Readtable) Symbol.CURRENT_READTABLE.symbolValue(thread);
75            FastStringBuffer sb = new FastStringBuffer();
76            try 
77              {
78                while (true) {
79                  int n = stream._readChar();
80                  if (n < 0) {
81                    error(new EndOfFile(stream));
82                    // Not reached.
83                    return null;
84                  }
85                  char c = (char) n;
86                  if (rt.getSyntaxType(c) == Readtable.SYNTAX_TYPE_SINGLE_ESCAPE) {
87                    // Single escape.
88                    n = stream._readChar();
89                    if (n < 0) {
90                      error(new EndOfFile(stream));
91                      // Not reached.
92                      return null;
93                    }
94                    sb.append((char)n);
95                    continue;
96                  }
97                  if (Utilities.isPlatformWindows) {
98                    if (c == '\r') {
99                      n = stream._readChar();
100                      if (n < 0) {
101                        error(new EndOfFile(stream));
102                        // Not reached.
103                        return null;
104                      }
105                      if (n == '\n') {
106                        sb.append('\n');
107                      } else {
108                        // '\r' was not followed by '\n'.
109                        stream._unreadChar(n);
110                        sb.append('\r');
111                      }
112                      continue;
113                    }
114                  }
115                  if (c == terminator)
116                    break;
117                  // Default.
118                  sb.append(c);
119                }
120              }
121            catch (java.io.IOException e)
122              {
123                //error(new EndOfFile(stream));
124    return new SimpleString(sb);
125              }
126            return new SimpleString(sb);
127        }
128    };
129
130    // ### read-list
131    public static final ReaderMacroFunction READ_LIST =
132        new ReaderMacroFunction("read-list", PACKAGE_SYS, false,
133                                "stream character")
134    {
135        @Override
136        public LispObject execute(Stream stream, char ignored)
137
138        {
139            return stream.readList(false, false);
140        }
141    };
142
143    // ### read-right-paren
144    public static final ReaderMacroFunction READ_RIGHT_PAREN =
145        new ReaderMacroFunction("read-right-paren", PACKAGE_SYS, false,
146                                "stream character")
147    {
148        @Override
149        public LispObject execute(Stream stream, char ignored)
150
151        {
152            return error(new ReaderError("Unmatched right parenthesis.", stream));
153        }
154    };
155
156    // ### read-quote
157    public static final ReaderMacroFunction READ_QUOTE =
158        new ReaderMacroFunction("read-quote", PACKAGE_SYS, false,
159                                "stream character")
160    {
161        @Override
162        public LispObject execute(Stream stream, char ignored)
163
164        {
165            return new Cons(Symbol.QUOTE,
166                            new Cons(stream.read(true, NIL, true,
167                                                 LispThread.currentThread())));
168        }
169    };
170
171    // ### read-dispatch-char
172    public static final ReaderMacroFunction READ_DISPATCH_CHAR =
173        new ReaderMacroFunction("read-dispatch-char", PACKAGE_SYS, false,
174                                "stream character")
175    {
176        @Override
177        public LispObject execute(Stream stream, char c)
178
179        {
180            return stream.readDispatchChar(c, false);
181        }
182    };
183
184    // ### sharp-left-paren
185    public static final DispatchMacroFunction SHARP_LEFT_PAREN =
186        new DispatchMacroFunction("sharp-left-paren", PACKAGE_SYS, false,
187                                  "stream sub-char numarg")
188    {
189        @Override
190        public LispObject execute(Stream stream, char c, int n)
191
192        {
193            final LispThread thread = LispThread.currentThread();
194            LispObject list = stream.readList(true, false);
195            if (_BACKQUOTE_COUNT_.symbolValue(thread).zerop()) {
196                if (n >= 0) {
197                    LispObject[] array = new LispObject[n];
198                    for (int i = 0; i < n; i++) {
199                        array[i] = list.car();
200                        if (list.cdr() != NIL)
201                            list = list.cdr();
202                    }
203                    return new SimpleVector(array);
204                } else
205                    return new SimpleVector(list);
206            }
207            return new Cons(_BQ_VECTOR_FLAG_.symbolValue(thread), list);
208        }
209    };
210
211    // ### sharp-star
212    public static final DispatchMacroFunction SHARP_STAR =
213        new DispatchMacroFunction("sharp-star", PACKAGE_SYS, false,
214                                  "stream sub-char numarg")
215    {
216        @Override
217        public LispObject execute(Stream stream, char ignored, int n)
218
219        {
220            final LispThread thread = LispThread.currentThread();
221            final Readtable rt = (Readtable) Symbol.CURRENT_READTABLE.symbolValue(thread);
222            final boolean suppress = Symbol.READ_SUPPRESS.symbolValue(thread) != NIL;
223            FastStringBuffer sb = new FastStringBuffer();
224            try 
225              {
226                while (true) {
227                  int ch = stream._readChar();
228                  if (ch < 0)
229                    break;
230                  char c = (char) ch;
231                  if (c == '0' || c == '1')
232                    sb.append(c);
233                  else {
234                    int syntaxType = rt.getSyntaxType(c);
235                    if (syntaxType == Readtable.SYNTAX_TYPE_WHITESPACE ||
236                        syntaxType == Readtable.SYNTAX_TYPE_TERMINATING_MACRO) {
237                      stream._unreadChar(c);
238                      break;
239                    } else if (!suppress) {
240                      String name = LispCharacter.charToName(c);
241                      if (name == null)
242                        name = "#\\" + c;
243                      error(new ReaderError("Illegal element for bit-vector: " + name,
244                                            stream));
245                    }
246                  }
247                }
248              }
249            catch (java.io.IOException e)
250              {
251                error(new ReaderError("IO error-vector: ",
252                                      stream));
253              }
254            if (suppress)
255                return NIL;
256            if (n >= 0) {
257                // n was supplied.
258                final int length = sb.length();
259                if (length == 0) {
260                    if (n > 0)
261                        return error(new ReaderError("No element specified for bit vector of length " +
262                                                      n + '.',
263                                                      stream));
264                }
265                if (n > length) {
266                    final char c = sb.charAt(length - 1);
267                    for (int i = length; i < n; i++)
268                        sb.append(c);
269                } else if (n < length) {
270                    return error(new ReaderError("Bit vector is longer than specified length: #" +
271                                                  n + '*' + sb.toString(),
272                                                  stream));
273                }
274            }
275            return new SimpleBitVector(sb.toString());
276        }
277    };
278
279    // ### sharp-dot
280    public static final DispatchMacroFunction SHARP_DOT =
281        new DispatchMacroFunction("sharp-dot", PACKAGE_SYS, false,
282                                  "stream sub-char numarg")
283    {
284        @Override
285        public LispObject execute(Stream stream, char c, int n)
286
287        {
288            final LispThread thread = LispThread.currentThread();
289            if (Symbol.READ_EVAL.symbolValue(thread) == NIL)
290                return error(new ReaderError("Can't read #. when *READ-EVAL* is NIL.",
291                                              stream));
292            else
293                return eval(stream.read(true, NIL, true, thread),
294                            new Environment(), thread);
295        }
296    };
297
298    // ### sharp-colon
299    public static final DispatchMacroFunction SHARP_COLON =
300        new DispatchMacroFunction("sharp-colon", PACKAGE_SYS, false,
301                                  "stream sub-char numarg")
302    {
303        @Override
304        public LispObject execute(Stream stream, char c, int n)
305
306        {
307            return stream.readSymbol();
308        }
309    };
310
311    // ### sharp-a
312    public static final DispatchMacroFunction SHARP_A =
313        new DispatchMacroFunction("sharp-a", PACKAGE_SYS, false,
314                                  "stream sub-char numarg")
315    {
316        @Override
317        public LispObject execute(Stream stream, char c, int n)
318
319        {
320            return stream.readArray(n);
321        }
322    };
323
324    // ### sharp-b
325    public static final DispatchMacroFunction SHARP_B =
326        new DispatchMacroFunction("sharp-b", PACKAGE_SYS, false,
327                                  "stream sub-char numarg")
328    {
329        @Override
330        public LispObject execute(Stream stream, char c, int n)
331
332        {
333            return stream.readRadix(2);
334        }
335    };
336
337    // ### sharp-c
338    public static final DispatchMacroFunction SHARP_C =
339        new DispatchMacroFunction("sharp-c", PACKAGE_SYS, false,
340                                  "stream sub-char numarg")
341    {
342        @Override
343        public LispObject execute(Stream stream, char c, int n)
344
345        {
346            return stream.readComplex();
347        }
348    };
349
350    // ### sharp-o
351    public static final DispatchMacroFunction SHARP_O =
352        new DispatchMacroFunction("sharp-o", PACKAGE_SYS, false,
353                                  "stream sub-char numarg")
354    {
355        @Override
356        public LispObject execute(Stream stream, char c, int n)
357
358        {
359            return stream.readRadix(8);
360        }
361    };
362
363    // ### sharp-p
364    public static final DispatchMacroFunction SHARP_P =
365        new DispatchMacroFunction("sharp-p", PACKAGE_SYS, false,
366                                  "stream sub-char numarg")
367    {
368        @Override
369        public LispObject execute(Stream stream, char c, int n)
370
371        {
372            return stream.readPathname();
373        }
374    };
375
376    // ### sharp-r
377    public static final DispatchMacroFunction SHARP_R =
378        new DispatchMacroFunction("sharp-r", PACKAGE_SYS, false,
379                                  "stream sub-char numarg")
380    {
381        @Override
382        public LispObject execute(Stream stream, char c, int n)
383
384        {
385            return stream.readRadix(n);
386        }
387    };
388
389    // ### sharp-s
390    public static final DispatchMacroFunction SHARP_S =
391        new DispatchMacroFunction("sharp-s", PACKAGE_SYS, false,
392                                  "stream sub-char numarg")
393    {
394        @Override
395        public LispObject execute(Stream stream, char c, int n)
396
397        {
398            return stream.readStructure();
399        }
400    };
401
402    // ### sharp-x
403    public static final DispatchMacroFunction SHARP_X =
404        new DispatchMacroFunction("sharp-x", PACKAGE_SYS, false,
405                                  "stream sub-char numarg")
406    {
407        @Override
408        public LispObject execute(Stream stream, char c, int n)
409
410        {
411            return stream.readRadix(16);
412        }
413    };
414
415    // ### sharp-quote
416    public static final DispatchMacroFunction SHARP_QUOTE =
417        new DispatchMacroFunction("sharp-quote", PACKAGE_SYS, false,
418                                  "stream sub-char numarg")
419    {
420        @Override
421        public LispObject execute(Stream stream, char c, int n)
422
423        {
424            return new Cons(Symbol.FUNCTION,
425                            new Cons(stream.read(true, NIL, true,
426                                                 LispThread.currentThread())));
427        }
428    };
429
430    // ### sharp-backslash
431    public static final DispatchMacroFunction SHARP_BACKSLASH =
432        new DispatchMacroFunction("sharp-backslash", PACKAGE_SYS, false,
433                                  "stream sub-char numarg")
434    {
435        @Override
436        public LispObject execute(Stream stream, char c, int n)
437
438        {
439            final LispThread thread = LispThread.currentThread();
440            final Readtable rt = (Readtable) Symbol.CURRENT_READTABLE.symbolValue(thread);
441            return stream.readCharacterLiteral(rt, thread);
442        }
443    };
444
445    // ### sharp-vertical-bar
446    public static final DispatchMacroFunction SHARP_VERTICAL_BAR =
447        new DispatchMacroFunction("sharp-vertical-bar", PACKAGE_SYS, false,
448                                  "stream sub-char numarg")
449    {
450        @Override
451        public LispObject execute(Stream stream, char c, int n)
452
453        {
454            stream.skipBalancedComment();
455            return null;
456        }
457    };
458
459    // ### sharp-illegal
460    public static final DispatchMacroFunction SHARP_ILLEGAL =
461        new DispatchMacroFunction("sharp-illegal", PACKAGE_SYS, false,
462                                  "stream sub-char numarg")
463    {
464        @Override
465        public LispObject execute(Stream stream, char c, int n)
466
467        {
468            FastStringBuffer sb = new FastStringBuffer("Illegal # macro character: #\\");
469            String s = LispCharacter.charToName(c);
470            if (s != null)
471                sb.append(s);
472            else
473                sb.append(c);
474            return error(new ReaderError(sb.toString(), stream));
475        }
476    };
477}
Note: See TracBrowser for help on using the repository browser.