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

Last change on this file was 11488, checked in by ehuelsmann, 17 years ago

Add @Override annotations.

Patch by: Douglas Miles

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 16.1 KB
Line 
1/*
2 * LispReader.java
3 *
4 * Copyright (C) 2004-2007 Peter Graves
5 * $Id: LispReader.java 11488 2008-12-27 10:50:33Z 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            throws ConditionThrowable
46        {
47            while (true) {
48                int n = stream._readChar();
49                if (n < 0)
50                    return null;
51                if (n == '\n')
52                    return null;
53            }
54        }
55    };
56
57    // ### read-string
58    public static final ReaderMacroFunction READ_STRING =
59        new ReaderMacroFunction("read-string", PACKAGE_SYS, false,
60                                "stream character")
61    {
62        @Override
63        public LispObject execute(Stream stream, char terminator)
64            throws ConditionThrowable
65        {
66            final LispThread thread = LispThread.currentThread();
67            final Readtable rt = (Readtable) Symbol.CURRENT_READTABLE.symbolValue(thread);
68            FastStringBuffer sb = new FastStringBuffer();
69            while (true) {
70                int n = stream._readChar();
71                if (n < 0) {
72                    error(new EndOfFile(stream));
73                    // Not reached.
74                    return null;
75                }
76                char c = (char) n;
77                if (rt.getSyntaxType(c) == Readtable.SYNTAX_TYPE_SINGLE_ESCAPE) {
78                    // Single escape.
79                    n = stream._readChar();
80                    if (n < 0) {
81                        error(new EndOfFile(stream));
82                        // Not reached.
83                        return null;
84                    }
85                    sb.append((char)n);
86                    continue;
87                }
88                if (Utilities.isPlatformWindows) {
89                    if (c == '\r') {
90                        n = stream._readChar();
91                        if (n < 0) {
92                            error(new EndOfFile(stream));
93                            // Not reached.
94                            return null;
95                        }
96                        if (n == '\n') {
97                            sb.append('\n');
98                        } else {
99                            // '\r' was not followed by '\n'.
100                            stream._unreadChar(n);
101                            sb.append('\r');
102                        }
103                        continue;
104                    }
105                }
106                if (c == terminator)
107                    break;
108                // Default.
109                sb.append(c);
110            }
111            return new SimpleString(sb);
112        }
113    };
114
115    // ### read-list
116    public static final ReaderMacroFunction READ_LIST =
117        new ReaderMacroFunction("read-list", PACKAGE_SYS, false,
118                                "stream character")
119    {
120        @Override
121        public LispObject execute(Stream stream, char ignored)
122            throws ConditionThrowable
123        {
124            return stream.readList(false, false);
125        }
126    };
127
128    // ### read-right-paren
129    public static final ReaderMacroFunction READ_RIGHT_PAREN =
130        new ReaderMacroFunction("read-right-paren", PACKAGE_SYS, false,
131                                "stream character")
132    {
133        @Override
134        public LispObject execute(Stream stream, char ignored)
135            throws ConditionThrowable
136        {
137            return error(new ReaderError("Unmatched right parenthesis.", stream));
138        }
139    };
140
141    // ### read-quote
142    public static final ReaderMacroFunction READ_QUOTE =
143        new ReaderMacroFunction("read-quote", PACKAGE_SYS, false,
144                                "stream character")
145    {
146        @Override
147        public LispObject execute(Stream stream, char ignored)
148            throws ConditionThrowable
149        {
150            return new Cons(Symbol.QUOTE,
151                            new Cons(stream.read(true, NIL, true,
152                                                 LispThread.currentThread())));
153        }
154    };
155
156    // ### read-dispatch-char
157    public static final ReaderMacroFunction READ_DISPATCH_CHAR =
158        new ReaderMacroFunction("read-dispatch-char", PACKAGE_SYS, false,
159                                "stream character")
160    {
161        @Override
162        public LispObject execute(Stream stream, char c)
163            throws ConditionThrowable
164        {
165            return stream.readDispatchChar(c, false);
166        }
167    };
168
169    // ### sharp-left-paren
170    public static final DispatchMacroFunction SHARP_LEFT_PAREN =
171        new DispatchMacroFunction("sharp-left-paren", PACKAGE_SYS, false,
172                                  "stream sub-char numarg")
173    {
174        @Override
175        public LispObject execute(Stream stream, char c, int n)
176            throws ConditionThrowable
177        {
178            final LispThread thread = LispThread.currentThread();
179            LispObject list = stream.readList(true, false);
180            if (_BACKQUOTE_COUNT_.symbolValue(thread).zerop()) {
181                if (n >= 0) {
182                    LispObject[] array = new LispObject[n];
183                    for (int i = 0; i < n; i++) {
184                        array[i] = list.car();
185                        if (list.cdr() != NIL)
186                            list = list.cdr();
187                    }
188                    return new SimpleVector(array);
189                } else
190                    return new SimpleVector(list);
191            }
192            return new Cons(_BQ_VECTOR_FLAG_.symbolValue(thread), list);
193        }
194    };
195
196    // ### sharp-star
197    public static final DispatchMacroFunction SHARP_STAR =
198        new DispatchMacroFunction("sharp-star", PACKAGE_SYS, false,
199                                  "stream sub-char numarg")
200    {
201        @Override
202        public LispObject execute(Stream stream, char ignored, int n)
203            throws ConditionThrowable
204        {
205            final LispThread thread = LispThread.currentThread();
206            final Readtable rt = (Readtable) Symbol.CURRENT_READTABLE.symbolValue(thread);
207            final boolean suppress = Symbol.READ_SUPPRESS.symbolValue(thread) != NIL;
208            FastStringBuffer sb = new FastStringBuffer();
209            while (true) {
210                int ch = stream._readChar();
211                if (ch < 0)
212                    break;
213                char c = (char) ch;
214                if (c == '0' || c == '1')
215                    sb.append(c);
216                else {
217                    int syntaxType = rt.getSyntaxType(c);
218                    if (syntaxType == Readtable.SYNTAX_TYPE_WHITESPACE ||
219                        syntaxType == Readtable.SYNTAX_TYPE_TERMINATING_MACRO) {
220                        stream._unreadChar(c);
221                        break;
222                    } else if (!suppress) {
223                        String name = LispCharacter.charToName(c);
224                        if (name == null)
225                            name = "#\\" + c;
226                        error(new ReaderError("Illegal element for bit-vector: " + name,
227                                               stream));
228                    }
229                }
230            }
231            if (suppress)
232                return NIL;
233            if (n >= 0) {
234                // n was supplied.
235                final int length = sb.length();
236                if (length == 0) {
237                    if (n > 0)
238                        return error(new ReaderError("No element specified for bit vector of length " +
239                                                      n + '.',
240                                                      stream));
241                }
242                if (n > length) {
243                    final char c = sb.charAt(length - 1);
244                    for (int i = length; i < n; i++)
245                        sb.append(c);
246                } else if (n < length) {
247                    return error(new ReaderError("Bit vector is longer than specified length: #" +
248                                                  n + '*' + sb.toString(),
249                                                  stream));
250                }
251            }
252            return new SimpleBitVector(sb.toString());
253        }
254    };
255
256    // ### sharp-dot
257    public static final DispatchMacroFunction SHARP_DOT =
258        new DispatchMacroFunction("sharp-dot", PACKAGE_SYS, false,
259                                  "stream sub-char numarg")
260    {
261        @Override
262        public LispObject execute(Stream stream, char c, int n)
263            throws ConditionThrowable
264        {
265            final LispThread thread = LispThread.currentThread();
266            if (Symbol.READ_EVAL.symbolValue(thread) == NIL)
267                return error(new ReaderError("Can't read #. when *READ-EVAL* is NIL.",
268                                              stream));
269            else
270                return eval(stream.read(true, NIL, true, thread),
271                            new Environment(), thread);
272        }
273    };
274
275    // ### sharp-colon
276    public static final DispatchMacroFunction SHARP_COLON =
277        new DispatchMacroFunction("sharp-colon", PACKAGE_SYS, false,
278                                  "stream sub-char numarg")
279    {
280        @Override
281        public LispObject execute(Stream stream, char c, int n)
282            throws ConditionThrowable
283        {
284            return stream.readSymbol();
285        }
286    };
287
288    // ### sharp-a
289    public static final DispatchMacroFunction SHARP_A =
290        new DispatchMacroFunction("sharp-a", PACKAGE_SYS, false,
291                                  "stream sub-char numarg")
292    {
293        @Override
294        public LispObject execute(Stream stream, char c, int n)
295            throws ConditionThrowable
296        {
297            return stream.readArray(n);
298        }
299    };
300
301    // ### sharp-b
302    public static final DispatchMacroFunction SHARP_B =
303        new DispatchMacroFunction("sharp-b", PACKAGE_SYS, false,
304                                  "stream sub-char numarg")
305    {
306        @Override
307        public LispObject execute(Stream stream, char c, int n)
308            throws ConditionThrowable
309        {
310            return stream.readRadix(2);
311        }
312    };
313
314    // ### sharp-c
315    public static final DispatchMacroFunction SHARP_C =
316        new DispatchMacroFunction("sharp-c", PACKAGE_SYS, false,
317                                  "stream sub-char numarg")
318    {
319        @Override
320        public LispObject execute(Stream stream, char c, int n)
321            throws ConditionThrowable
322        {
323            return stream.readComplex();
324        }
325    };
326
327    // ### sharp-o
328    public static final DispatchMacroFunction SHARP_O =
329        new DispatchMacroFunction("sharp-o", PACKAGE_SYS, false,
330                                  "stream sub-char numarg")
331    {
332        @Override
333        public LispObject execute(Stream stream, char c, int n)
334            throws ConditionThrowable
335        {
336            return stream.readRadix(8);
337        }
338    };
339
340    // ### sharp-p
341    public static final DispatchMacroFunction SHARP_P =
342        new DispatchMacroFunction("sharp-p", PACKAGE_SYS, false,
343                                  "stream sub-char numarg")
344    {
345        @Override
346        public LispObject execute(Stream stream, char c, int n)
347            throws ConditionThrowable
348        {
349            return stream.readPathname();
350        }
351    };
352
353    // ### sharp-r
354    public static final DispatchMacroFunction SHARP_R =
355        new DispatchMacroFunction("sharp-r", PACKAGE_SYS, false,
356                                  "stream sub-char numarg")
357    {
358        @Override
359        public LispObject execute(Stream stream, char c, int n)
360            throws ConditionThrowable
361        {
362            return stream.readRadix(n);
363        }
364    };
365
366    // ### sharp-s
367    public static final DispatchMacroFunction SHARP_S =
368        new DispatchMacroFunction("sharp-s", PACKAGE_SYS, false,
369                                  "stream sub-char numarg")
370    {
371        @Override
372        public LispObject execute(Stream stream, char c, int n)
373            throws ConditionThrowable
374        {
375            return stream.readStructure();
376        }
377    };
378
379    // ### sharp-x
380    public static final DispatchMacroFunction SHARP_X =
381        new DispatchMacroFunction("sharp-x", PACKAGE_SYS, false,
382                                  "stream sub-char numarg")
383    {
384        @Override
385        public LispObject execute(Stream stream, char c, int n)
386            throws ConditionThrowable
387        {
388            return stream.readRadix(16);
389        }
390    };
391
392    // ### sharp-quote
393    public static final DispatchMacroFunction SHARP_QUOTE =
394        new DispatchMacroFunction("sharp-quote", PACKAGE_SYS, false,
395                                  "stream sub-char numarg")
396    {
397        @Override
398        public LispObject execute(Stream stream, char c, int n)
399            throws ConditionThrowable
400        {
401            return new Cons(Symbol.FUNCTION,
402                            new Cons(stream.read(true, NIL, true,
403                                                 LispThread.currentThread())));
404        }
405    };
406
407    // ### sharp-backslash
408    public static final DispatchMacroFunction SHARP_BACKSLASH =
409        new DispatchMacroFunction("sharp-backslash", PACKAGE_SYS, false,
410                                  "stream sub-char numarg")
411    {
412        @Override
413        public LispObject execute(Stream stream, char c, int n)
414            throws ConditionThrowable
415        {
416            final LispThread thread = LispThread.currentThread();
417            final Readtable rt = (Readtable) Symbol.CURRENT_READTABLE.symbolValue(thread);
418            return stream.readCharacterLiteral(rt, thread);
419        }
420    };
421
422    // ### sharp-vertical-bar
423    public static final DispatchMacroFunction SHARP_VERTICAL_BAR =
424        new DispatchMacroFunction("sharp-vertical-bar", PACKAGE_SYS, false,
425                                  "stream sub-char numarg")
426    {
427        @Override
428        public LispObject execute(Stream stream, char c, int n)
429            throws ConditionThrowable
430        {
431            stream.skipBalancedComment();
432            return null;
433        }
434    };
435
436    // ### sharp-illegal
437    public static final DispatchMacroFunction SHARP_ILLEGAL =
438        new DispatchMacroFunction("sharp-illegal", PACKAGE_SYS, false,
439                                  "stream sub-char numarg")
440    {
441        @Override
442        public LispObject execute(Stream stream, char c, int n)
443            throws ConditionThrowable
444        {
445            FastStringBuffer sb = new FastStringBuffer("Illegal # macro character: #\\");
446            String s = LispCharacter.charToName(c);
447            if (s != null)
448                sb.append(s);
449            else
450                sb.append(c);
451            return error(new ReaderError(sb.toString(), stream));
452        }
453    };
454}
Note: See TracBrowser for help on using the repository browser.