001: /*
002: * LispReader.java
003: *
004: * Copyright (C) 2004 Peter Graves
005: * $Id: LispReader.java,v 1.24 2004/04/17 10:54:24 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.lisp;
023:
024: public final class LispReader extends Lisp {
025: // ### read-comment
026: public static final ReaderMacroFunction READ_COMMENT = new ReaderMacroFunction(
027: "read-comment", PACKAGE_SYS, false, "stream character") {
028: public LispObject execute(Stream stream, char ignored)
029: throws ConditionThrowable {
030: while (true) {
031: int n = stream._readChar();
032: if (n < 0)
033: return null;
034: if (n == '\n')
035: return null;
036: }
037: }
038: };
039:
040: // ### read-string
041: public static final ReaderMacroFunction READ_STRING = new ReaderMacroFunction(
042: "read-string", PACKAGE_SYS, false, "stream character") {
043: public LispObject execute(Stream stream, char terminator)
044: throws ConditionThrowable {
045: StringBuffer sb = new StringBuffer();
046: while (true) {
047: int n = stream._readChar();
048: if (n < 0) {
049: signal(new EndOfFile(stream));
050: // Not reached.
051: return null;
052: }
053: char c = (char) n;
054: if (c == '\\') {
055: // Single escape.
056: n = stream._readChar();
057: if (n < 0) {
058: signal(new EndOfFile(stream));
059: // Not reached.
060: return null;
061: }
062: sb.append((char) n);
063: continue;
064: }
065: if (c == terminator)
066: break;
067: // Default.
068: sb.append(c);
069: }
070: return new SimpleString(sb);
071: }
072: };
073:
074: // ### read-list
075: public static final ReaderMacroFunction READ_LIST = new ReaderMacroFunction(
076: "read-list", PACKAGE_SYS, false, "stream character") {
077: public LispObject execute(Stream stream, char ignored)
078: throws ConditionThrowable {
079: return stream.readList();
080: }
081: };
082:
083: // ### read-right-paren
084: public static final ReaderMacroFunction READ_RIGHT_PAREN = new ReaderMacroFunction(
085: "read-right-paren", PACKAGE_SYS, false, "stream character") {
086: public LispObject execute(Stream stream, char ignored)
087: throws ConditionThrowable {
088: return signal(new ReaderError(
089: "Unmatched right parenthesis."));
090: }
091: };
092:
093: // ### read-quote
094: public static final ReaderMacroFunction READ_QUOTE = new ReaderMacroFunction(
095: "read-quote", PACKAGE_SYS, false, "stream character") {
096: public LispObject execute(Stream stream, char ignored)
097: throws ConditionThrowable {
098: return new Cons(Symbol.QUOTE, new Cons(stream.read(true,
099: NIL, true)));
100: }
101: };
102:
103: // ### read-dispatch-char
104: public static final ReaderMacroFunction READ_DISPATCH_CHAR = new ReaderMacroFunction(
105: "read-dispatch-char", PACKAGE_SYS, false,
106: "stream character") {
107: public LispObject execute(Stream stream, char c)
108: throws ConditionThrowable {
109: return stream.readDispatchChar(c);
110: }
111: };
112:
113: // ### backquote-macro
114: public static final ReaderMacroFunction BACKQUOTE_MACRO = new ReaderMacroFunction(
115: "backquote-macro", PACKAGE_SYS, false, "stream character") {
116: public LispObject execute(Stream stream, char ignored)
117: throws ConditionThrowable {
118: return new Cons(Symbol.BACKQUOTE, new Cons(stream.read(
119: true, NIL, true)));
120: }
121: };
122:
123: // ### comma-macro
124: public static final ReaderMacroFunction COMMA_MACRO = new ReaderMacroFunction(
125: "comma-macro", PACKAGE_SYS, false, "stream character") {
126: public LispObject execute(Stream stream, char ignored)
127: throws ConditionThrowable {
128: return stream.readComma();
129: }
130: };
131:
132: // ### sharp-left-paren
133: public static final DispatchMacroFunction SHARP_LEFT_PAREN = new DispatchMacroFunction(
134: "sharp-left-paren", PACKAGE_SYS, false,
135: "stream sub-char numarg") {
136: public LispObject execute(Stream stream, char c, int n)
137: throws ConditionThrowable {
138: return new SimpleVector(stream.readList());
139: }
140: };
141:
142: // ### sharp-star
143: public static final DispatchMacroFunction SHARP_STAR = new DispatchMacroFunction(
144: "sharp-star", PACKAGE_SYS, false, "stream sub-char numarg") {
145: public LispObject execute(Stream stream, char c, int n)
146: throws ConditionThrowable {
147: return stream.readBitVector();
148: }
149: };
150:
151: // ### sharp-dot
152: public static final DispatchMacroFunction SHARP_DOT = new DispatchMacroFunction(
153: "sharp-dot", PACKAGE_SYS, false, "stream sub-char numarg") {
154: public LispObject execute(Stream stream, char c, int n)
155: throws ConditionThrowable {
156: if (_READ_EVAL_.symbolValueNoThrow() == NIL)
157: return signal(new ReaderError(
158: "Can't read #. when *READ-EVAL* is NIL."));
159: else
160: return eval(stream.read(true, NIL, true),
161: new Environment(), LispThread.currentThread());
162: }
163: };
164:
165: // ### sharp-colon
166: public static final DispatchMacroFunction SHARP_COLON = new DispatchMacroFunction(
167: "sharp-colon", PACKAGE_SYS, false, "stream sub-char numarg") {
168: public LispObject execute(Stream stream, char c, int n)
169: throws ConditionThrowable {
170: return stream.readSymbol();
171: }
172: };
173:
174: // ### sharp-a
175: public static final DispatchMacroFunction SHARP_A = new DispatchMacroFunction(
176: "sharp-a", PACKAGE_SYS, false, "stream sub-char numarg") {
177: public LispObject execute(Stream stream, char c, int n)
178: throws ConditionThrowable {
179: return stream.readArray(n);
180: }
181: };
182:
183: // ### sharp-b
184: public static final DispatchMacroFunction SHARP_B = new DispatchMacroFunction(
185: "sharp-b", PACKAGE_SYS, false, "stream sub-char numarg") {
186: public LispObject execute(Stream stream, char c, int n)
187: throws ConditionThrowable {
188: return stream.readRadix(2);
189: }
190: };
191:
192: // ### sharp-c
193: public static final DispatchMacroFunction SHARP_C = new DispatchMacroFunction(
194: "sharp-c", PACKAGE_SYS, false, "stream sub-char numarg") {
195: public LispObject execute(Stream stream, char c, int n)
196: throws ConditionThrowable {
197: return stream.readComplex();
198: }
199: };
200:
201: // ### sharp-o
202: public static final DispatchMacroFunction SHARP_O = new DispatchMacroFunction(
203: "sharp-o", PACKAGE_SYS, false, "stream sub-char numarg") {
204: public LispObject execute(Stream stream, char c, int n)
205: throws ConditionThrowable {
206: return stream.readRadix(8);
207: }
208: };
209:
210: // ### sharp-p
211: public static final DispatchMacroFunction SHARP_P = new DispatchMacroFunction(
212: "sharp-p", PACKAGE_SYS, false, "stream sub-char numarg") {
213: public LispObject execute(Stream stream, char c, int n)
214: throws ConditionThrowable {
215: return stream.readPathname();
216: }
217: };
218:
219: // ### sharp-r
220: public static final DispatchMacroFunction SHARP_R = new DispatchMacroFunction(
221: "sharp-r", PACKAGE_SYS, false, "stream sub-char numarg") {
222: public LispObject execute(Stream stream, char c, int n)
223: throws ConditionThrowable {
224: return stream.readRadix(n);
225: }
226: };
227:
228: // ### sharp-s
229: public static final DispatchMacroFunction SHARP_S = new DispatchMacroFunction(
230: "sharp-s", PACKAGE_SYS, false, "stream sub-char numarg") {
231: public LispObject execute(Stream stream, char c, int n)
232: throws ConditionThrowable {
233: return stream.readStructure();
234: }
235: };
236:
237: // ### sharp-x
238: public static final DispatchMacroFunction SHARP_X = new DispatchMacroFunction(
239: "sharp-x", PACKAGE_SYS, false, "stream sub-char numarg") {
240: public LispObject execute(Stream stream, char c, int n)
241: throws ConditionThrowable {
242: return stream.readRadix(16);
243: }
244: };
245:
246: // ### sharp-quote
247: public static final DispatchMacroFunction SHARP_QUOTE = new DispatchMacroFunction(
248: "sharp-quote", PACKAGE_SYS, false, "stream sub-char numarg") {
249: public LispObject execute(Stream stream, char c, int n)
250: throws ConditionThrowable {
251: return new Cons(Symbol.FUNCTION, new Cons(stream.read(true,
252: NIL, true)));
253: }
254: };
255:
256: // ### sharp-backslash
257: public static final DispatchMacroFunction SHARP_BACKSLASH = new DispatchMacroFunction(
258: "sharp-backslash", PACKAGE_SYS, false,
259: "stream sub-char numarg") {
260: public LispObject execute(Stream stream, char c, int n)
261: throws ConditionThrowable {
262: return stream.readCharacterLiteral();
263: }
264: };
265:
266: // ### sharp-vertical-bar
267: public static final DispatchMacroFunction SHARP_VERTICAL_BAR = new DispatchMacroFunction(
268: "sharp-vertical-bar", PACKAGE_SYS, false,
269: "stream sub-char numarg") {
270: public LispObject execute(Stream stream, char c, int n)
271: throws ConditionThrowable {
272: stream.skipBalancedComment();
273: return null;
274: }
275: };
276:
277: // ### sharp-illegal
278: public static final DispatchMacroFunction SHARP_ILLEGAL = new DispatchMacroFunction(
279: "sharp-illegal", PACKAGE_SYS, false,
280: "stream sub-char numarg") {
281: public LispObject execute(Stream stream, char c, int n)
282: throws ConditionThrowable {
283: StringBuffer sb = new StringBuffer(
284: "Illegal # macro character: #\\");
285: String s = LispCharacter.charToName(c);
286: if (s != null)
287: sb.append(s);
288: else
289: sb.append(c);
290: return signal(new ReaderError(sb.toString()));
291: }
292: };
293: }
|