source: trunk/abcl/src/org/armedbear/lisp/FaslReader.java @ 12484

Last change on this file since 12484 was 12431, checked in by Mark Evenson, 15 years ago

Replace FastStringBuffer? with java.lang.StringBuilder?.

Phil Hudson suggested in Feburary 2009 that "[FastStringBuffer?] should
be removed with all references to it replaced with
java.lang.StringBuilder? once enough confidence in this change has been
gained." After almost a year of using FastStringBuffer? as a delagate
for StringBuilder?, that confidence has indeed been gained.

One subtlety for use of StringBuilder?: there is no

StringBuilder?(char)

constructor, so use

StringBuilder?(String.valueOf(c))

to construct a new StringBuilder? containing a single char. Otherwise
that char will get promoted to an int, and you will invoke

StringBuilder?(int capacity)

which will "swallow" the first character that you thought you were adding.

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