Source Code Cross Referenced for Stream.java in  » IDE » J » org » armedbear » lisp » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » J » org.armedbear.lisp 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Stream.java
0003:         *
0004:         * Copyright (C) 2003-2004 Peter Graves
0005:         * $Id: Stream.java,v 1.82 2004/09/18 20:27:28 piso Exp $
0006:         *
0007:         * This program is free software; you can redistribute it and/or
0008:         * modify it under the terms of the GNU General Public License
0009:         * as published by the Free Software Foundation; either version 2
0010:         * of the License, or (at your option) any later version.
0011:         *
0012:         * This program is distributed in the hope that it will be useful,
0013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015:         * GNU General Public License for more details.
0016:         *
0017:         * You should have received a copy of the GNU General Public License
0018:         * along with this program; if not, write to the Free Software
0019:         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
0020:         */
0021:
0022:        package org.armedbear.lisp;
0023:
0024:        import java.io.BufferedInputStream;
0025:        import java.io.BufferedOutputStream;
0026:        import java.io.BufferedReader;
0027:        import java.io.IOException;
0028:        import java.io.InputStream;
0029:        import java.io.InputStreamReader;
0030:        import java.io.OutputStream;
0031:        import java.io.OutputStreamWriter;
0032:        import java.io.PrintWriter;
0033:        import java.io.PushbackReader;
0034:        import java.io.StringWriter;
0035:        import java.io.Writer;
0036:        import java.math.BigInteger;
0037:        import java.util.BitSet;
0038:
0039:        public class Stream extends LispObject {
0040:            protected LispObject elementType;
0041:            protected boolean isInputStream;
0042:            protected boolean isOutputStream;
0043:            protected boolean isCharacterStream;
0044:            protected boolean isBinaryStream;
0045:
0046:            private boolean interactive;
0047:            private boolean open = true;
0048:
0049:            // Character input.
0050:            private PushbackReader reader;
0051:            protected int offset;
0052:            protected int lineNumber;
0053:
0054:            // Character output.
0055:            private Writer writer;
0056:
0057:            // The number of characters on the current line of output (-1 if unknown).
0058:            protected int charPos;
0059:
0060:            // Binary input.
0061:            private BufferedInputStream in;
0062:
0063:            // Binary output.
0064:            private BufferedOutputStream out;
0065:
0066:            protected Stream() {
0067:            }
0068:
0069:            // Input stream constructors.
0070:            public Stream(InputStream inputStream, LispObject elementType) {
0071:                this .elementType = elementType;
0072:                if (elementType == Symbol.CHARACTER
0073:                        || elementType == Symbol.BASE_CHAR) {
0074:                    isCharacterStream = true;
0075:                    InputStreamReader inputStreamReader;
0076:                    try {
0077:                        inputStreamReader = new InputStreamReader(inputStream,
0078:                                "ISO-8859-1");
0079:                    } catch (java.io.UnsupportedEncodingException e) {
0080:                        Debug.trace(e);
0081:                        inputStreamReader = new InputStreamReader(inputStream);
0082:                    }
0083:                    reader = new PushbackReader(new BufferedReader(
0084:                            inputStreamReader), 2);
0085:                } else {
0086:                    isBinaryStream = true;
0087:                    in = new BufferedInputStream(inputStream);
0088:                }
0089:                isInputStream = true;
0090:                isOutputStream = false;
0091:            }
0092:
0093:            public Stream(InputStream inputStream, LispObject elementType,
0094:                    boolean interactive) {
0095:                this (inputStream, elementType);
0096:                setInteractive(interactive);
0097:            }
0098:
0099:            // Output stream constructors.
0100:            public Stream(OutputStream outputStream, LispObject elementType) {
0101:                this .elementType = elementType;
0102:                if (elementType == Symbol.CHARACTER
0103:                        || elementType == Symbol.BASE_CHAR) {
0104:                    isCharacterStream = true;
0105:                    try {
0106:                        writer = new OutputStreamWriter(outputStream,
0107:                                "ISO-8859-1");
0108:                    } catch (java.io.UnsupportedEncodingException e) {
0109:                        Debug.trace(e);
0110:                        writer = new OutputStreamWriter(outputStream);
0111:                    }
0112:                } else {
0113:                    isBinaryStream = true;
0114:                    out = new BufferedOutputStream(outputStream);
0115:                }
0116:                isInputStream = false;
0117:                isOutputStream = true;
0118:            }
0119:
0120:            public Stream(OutputStream outputStream, LispObject elementType,
0121:                    boolean interactive) {
0122:                this (outputStream, elementType);
0123:                setInteractive(interactive);
0124:            }
0125:
0126:            public boolean isInputStream() throws ConditionThrowable {
0127:                return isInputStream;
0128:            }
0129:
0130:            public boolean isOutputStream() throws ConditionThrowable {
0131:                return isOutputStream;
0132:            }
0133:
0134:            public boolean isCharacterInputStream() throws ConditionThrowable {
0135:                return isCharacterStream && isInputStream;
0136:            }
0137:
0138:            public boolean isBinaryInputStream() throws ConditionThrowable {
0139:                return isBinaryStream && isInputStream;
0140:            }
0141:
0142:            public boolean isCharacterOutputStream() throws ConditionThrowable {
0143:                return isCharacterStream && isOutputStream;
0144:            }
0145:
0146:            public boolean isBinaryOutputStream() throws ConditionThrowable {
0147:                return isBinaryStream && isOutputStream;
0148:            }
0149:
0150:            public boolean isInteractive() {
0151:                return interactive;
0152:            }
0153:
0154:            public void setInteractive(boolean b) {
0155:                interactive = b;
0156:            }
0157:
0158:            public boolean isOpen() {
0159:                return open;
0160:            }
0161:
0162:            public void setOpen(boolean b) {
0163:                open = b;
0164:            }
0165:
0166:            public LispObject typeOf() {
0167:                return Symbol.STREAM;
0168:            }
0169:
0170:            public LispClass classOf() {
0171:                return BuiltInClass.STREAM;
0172:            }
0173:
0174:            public LispObject typep(LispObject typeSpecifier)
0175:                    throws ConditionThrowable {
0176:                if (typeSpecifier == Symbol.STREAM)
0177:                    return T;
0178:                if (typeSpecifier == BuiltInClass.STREAM)
0179:                    return T;
0180:                return super .typep(typeSpecifier);
0181:            }
0182:
0183:            public LispObject getElementType() throws ConditionThrowable {
0184:                return elementType;
0185:            }
0186:
0187:            // Character input.
0188:            public int getOffset() {
0189:                return offset;
0190:            }
0191:
0192:            // Character input.
0193:            public int getLineNumber() {
0194:                return lineNumber;
0195:            }
0196:
0197:            protected void setWriter(Writer writer) {
0198:                this .writer = writer;
0199:            }
0200:
0201:            // Character output.
0202:            public int getCharPos() {
0203:                return charPos;
0204:            }
0205:
0206:            // Character output.
0207:            public void setCharPos(int n) {
0208:                charPos = n;
0209:            }
0210:
0211:            public LispObject read(boolean eofError, LispObject eofValue,
0212:                    boolean recursive) throws ConditionThrowable {
0213:                LispObject result = readPreservingWhitespace(eofError,
0214:                        eofValue, recursive);
0215:                if (result != eofValue && !recursive) {
0216:                    if (_charReady()) {
0217:                        int n = _readChar();
0218:                        if (n >= 0) {
0219:                            char c = (char) n;
0220:                            if (!currentReadtable().isWhitespace(c))
0221:                                _unreadChar(c);
0222:                        }
0223:                    }
0224:                }
0225:                if (_READ_SUPPRESS_.symbolValueNoThrow() != NIL)
0226:                    return NIL;
0227:                else
0228:                    return result;
0229:            }
0230:
0231:            public LispObject readPreservingWhitespace(boolean eofError,
0232:                    LispObject eofValue, boolean recursive)
0233:                    throws ConditionThrowable {
0234:                final Readtable rt = currentReadtable();
0235:                while (true) {
0236:                    int n = _readChar();
0237:                    if (n < 0) {
0238:                        if (eofError)
0239:                            return signal(new EndOfFile(this ));
0240:                        else
0241:                            return eofValue;
0242:                    }
0243:                    char c = (char) n;
0244:                    if (rt.isWhitespace(c))
0245:                        continue;
0246:                    LispObject result = processChar(c);
0247:                    if (result != null)
0248:                        return result;
0249:                }
0250:            }
0251:
0252:            private LispObject processChar(char c) throws ConditionThrowable {
0253:                LispObject handler = currentReadtable().getReaderMacroFunction(
0254:                        c);
0255:                if (handler instanceof  ReaderMacroFunction)
0256:                    return ((ReaderMacroFunction) handler).execute(this , c);
0257:                if (handler != null && handler != NIL)
0258:                    return handler.execute(this , LispCharacter.getInstance(c));
0259:                return readToken(c);
0260:            }
0261:
0262:            public LispObject readPathname() throws ConditionThrowable {
0263:                LispObject obj = read(true, NIL, false);
0264:                if (obj instanceof  AbstractString)
0265:                    return new Pathname(obj.getStringValue());
0266:                if (obj.listp())
0267:                    return Pathname.makePathname(obj);
0268:                return signal(new TypeError(
0269:                        "#p requires a string or list argument."));
0270:            }
0271:
0272:            public LispObject readSymbol() throws ConditionThrowable {
0273:                StringBuffer sb = new StringBuffer();
0274:                _readToken(sb, LispThread.currentThread());
0275:                return new Symbol(sb.toString());
0276:            }
0277:
0278:            public LispObject readStructure() throws ConditionThrowable {
0279:                LispObject obj = read(true, NIL, false);
0280:                if (_READ_SUPPRESS_.symbolValueNoThrow() != NIL)
0281:                    return NIL;
0282:                if (obj.listp()) {
0283:                    Symbol structure = checkSymbol(obj.car());
0284:                    LispClass c = LispClass.findClass(structure);
0285:                    if (!(c instanceof  StructureClass)) {
0286:                        return signal(new ReaderError(structure.getName()
0287:                                + " is not a defined structure type."));
0288:                    }
0289:                    LispObject args = obj.cdr();
0290:                    Package pkg = checkPackage(structure.getPackage());
0291:                    Symbol constructor = pkg.intern("MAKE-"
0292:                            + structure.getName());
0293:                    return funcall(constructor.getSymbolFunctionOrDie(), args
0294:                            .copyToArray(), LispThread.currentThread());
0295:                }
0296:                return signal(new ReaderError("Non-list following #S: " + obj));
0297:            }
0298:
0299:            public LispObject readList() throws ConditionThrowable {
0300:                Cons first = null;
0301:                Cons last = null;
0302:                while (true) {
0303:                    char c = flushWhitespace();
0304:                    if (c == ')') {
0305:                        return first == null ? NIL : first;
0306:                    }
0307:                    if (c == '.') {
0308:                        int n = _readChar();
0309:                        if (n < 0)
0310:                            return signal(new EndOfFile(this ));
0311:                        char nextChar = (char) n;
0312:                        if (nextChar == ',') {
0313:                            LispObject obj = readComma();
0314:                            last.setCdr(obj);
0315:                            continue;
0316:                        } else if (isTokenDelimiter(nextChar)) {
0317:                            if (last == null)
0318:                                return signal(new ReaderError(
0319:                                        "Nothing appears before . in list."));
0320:                            LispObject obj = read(true, NIL, true);
0321:                            last.setCdr(obj);
0322:                            continue;
0323:                        } else {
0324:                            // normal token beginning with '.'
0325:                            _unreadChar(nextChar);
0326:                        }
0327:                    }
0328:                    LispObject obj = processChar(c);
0329:                    if (obj == null) {
0330:                        // A comment.
0331:                        continue;
0332:                    }
0333:                    if (first == null) {
0334:                        first = new Cons(obj);
0335:                        last = first;
0336:                    } else {
0337:                        Cons newCons = new Cons(obj);
0338:                        last.setCdr(newCons);
0339:                        last = newCons;
0340:                    }
0341:                }
0342:            }
0343:
0344:            private static final boolean isTokenDelimiter(char c)
0345:                    throws ConditionThrowable {
0346:                switch (c) {
0347:                case '"':
0348:                case '\'':
0349:                case '(':
0350:                case ')':
0351:                case ',':
0352:                case ';':
0353:                case '`':
0354:                    return true;
0355:                default:
0356:                    return currentReadtable().isWhitespace(c);
0357:                }
0358:            }
0359:
0360:            public LispObject readComma() throws ConditionThrowable {
0361:                int n = _readChar();
0362:                if (n < 0)
0363:                    return signal(new EndOfFile(this ));
0364:                char c = (char) n;
0365:                switch (c) {
0366:                case '@':
0367:                    return new Cons(Symbol.COMMA_ATSIGN, new Cons(read(true,
0368:                            NIL, true), NIL));
0369:                case '.':
0370:                    return new Cons(Symbol.COMMA_DOT, new Cons(read(true, NIL,
0371:                            true), NIL));
0372:                default:
0373:                    _unreadChar(c);
0374:                    return new Cons(Symbol.COMMA, new Cons(
0375:                            read(true, NIL, true), NIL));
0376:                }
0377:            }
0378:
0379:            public LispObject readDispatchChar(char ignored)
0380:                    throws ConditionThrowable {
0381:                int numArg = -1;
0382:                char c;
0383:                while (true) {
0384:                    int n = _readChar();
0385:                    if (n < 0)
0386:                        return signal(new EndOfFile(this ));
0387:                    c = (char) n;
0388:                    if (c < '0' || c > '9')
0389:                        break;
0390:                    if (numArg < 0)
0391:                        numArg = 0;
0392:                    numArg = numArg * 10 + c - '0';
0393:                }
0394:                LispObject fun = currentReadtable().getDispatchMacroCharacter(
0395:                        '#', c);
0396:                if (fun instanceof  DispatchMacroFunction)
0397:                    return ((DispatchMacroFunction) fun).execute(this , c,
0398:                            numArg);
0399:                if (fun != NIL) {
0400:                    final LispThread thread = LispThread.currentThread();
0401:                    LispObject result = funcall3(fun, this , LispCharacter
0402:                            .getInstance(c), (numArg < 0) ? NIL : new Fixnum(
0403:                            numArg), thread);
0404:                    LispObject[] values = thread.getValues();
0405:                    if (values != null && values.length == 0)
0406:                        result = null;
0407:                    thread.clearValues();
0408:                    return result;
0409:                }
0410:                return null;
0411:            }
0412:
0413:            public LispObject readCharacterLiteral() throws ConditionThrowable {
0414:                int n = _readChar();
0415:                if (n < 0)
0416:                    return signal(new EndOfFile(this ));
0417:                char c = (char) n;
0418:                StringBuffer sb = new StringBuffer();
0419:                sb.append(c);
0420:                Readtable rt = currentReadtable();
0421:                while (true) {
0422:                    n = _readChar();
0423:                    if (n < 0)
0424:                        break;
0425:                    c = (char) n;
0426:                    if (rt.isWhitespace(c))
0427:                        break;
0428:                    if (c == '(' || c == ')') {
0429:                        _unreadChar(c);
0430:                        break;
0431:                    }
0432:                    sb.append(c);
0433:                }
0434:                if (_READ_SUPPRESS_.symbolValueNoThrow() != NIL)
0435:                    return NIL;
0436:                String token = sb.toString();
0437:                if (token.length() == 1)
0438:                    return LispCharacter.getInstance(token.charAt(0));
0439:                n = LispCharacter.nameToChar(token);
0440:                if (n >= 0)
0441:                    return LispCharacter.getInstance((char) n);
0442:                return signal(new LispError("Unrecognized character name: \""
0443:                        + token + '"'));
0444:            }
0445:
0446:            public void skipBalancedComment() throws ConditionThrowable {
0447:                while (true) {
0448:                    int n = _readChar();
0449:                    if (n < 0)
0450:                        return;
0451:                    if (n == '|') {
0452:                        n = _readChar();
0453:                        if (n == '#')
0454:                            return;
0455:                        else
0456:                            _unreadChar(n);
0457:                    } else if (n == '#') {
0458:                        n = _readChar();
0459:                        if (n == '|')
0460:                            skipBalancedComment(); // Nested comment. Recurse!
0461:                        else
0462:                            _unreadChar(n);
0463:                    }
0464:                }
0465:            }
0466:
0467:            public LispObject readBitVector() throws ConditionThrowable {
0468:                StringBuffer sb = new StringBuffer();
0469:                while (true) {
0470:                    int n = _readChar();
0471:                    if (n < 0)
0472:                        break;
0473:                    char c = (char) n;
0474:                    if (c == '0' || c == '1')
0475:                        sb.append(c);
0476:                    else {
0477:                        _unreadChar(c);
0478:                        break;
0479:                    }
0480:                }
0481:                return new SimpleBitVector(sb.toString());
0482:            }
0483:
0484:            public LispObject readArray(int rank) throws ConditionThrowable {
0485:                LispObject obj = read(true, NIL, true);
0486:                switch (rank) {
0487:                case -1:
0488:                    return signal(new ReaderError(
0489:                            "No dimensions argument to #A."));
0490:                case 0:
0491:                    return new ZeroRankArray(T, obj, false);
0492:                case 1:
0493:                    return new SimpleVector(obj);
0494:                default:
0495:                    return new SimpleArray(rank, obj);
0496:                }
0497:            }
0498:
0499:            public LispObject readComplex() throws ConditionThrowable {
0500:                LispObject obj = read(true, NIL, true);
0501:                if (_READ_SUPPRESS_.symbolValue() != NIL)
0502:                    return NIL;
0503:                if (obj instanceof  Cons && obj.length() == 2)
0504:                    return Complex.getInstance(obj.car(), obj.cadr());
0505:                // Error.
0506:                StringBuffer sb = new StringBuffer(
0507:                        "Invalid complex number format");
0508:                if (this  instanceof  FileStream) {
0509:                    Pathname p = ((FileStream) this ).getPathname();
0510:                    if (p != null) {
0511:                        String namestring = p.getNamestring();
0512:                        if (namestring != null) {
0513:                            sb.append(" in #P\"");
0514:                            sb.append(namestring);
0515:                            sb.append('"');
0516:                        }
0517:                    }
0518:                    sb.append(" at offset ");
0519:                    sb.append(_getFilePosition());
0520:                }
0521:                sb.append(": #C");
0522:                sb.append(obj.writeToString());
0523:                return signal(new ReaderError(sb.toString()));
0524:            }
0525:
0526:            private String readMultipleEscape() throws ConditionThrowable {
0527:                StringBuffer sb = new StringBuffer();
0528:                while (true) {
0529:                    int n = _readChar();
0530:                    if (n < 0)
0531:                        break;
0532:                    char c = (char) n;
0533:                    if (c == '\\') {
0534:                        n = _readChar();
0535:                        if (n < 0) {
0536:                            signal(new EndOfFile(this ));
0537:                            // Not reached.
0538:                            return null;
0539:                        }
0540:                        sb.append((char) n);
0541:                        continue;
0542:                    }
0543:                    if (c == '|')
0544:                        break;
0545:                    sb.append(c);
0546:                }
0547:                return sb.toString();
0548:            }
0549:
0550:            private static final int findUnescapedSingleColon(String s,
0551:                    BitSet flags) {
0552:                if (flags == null)
0553:                    return s.indexOf(':');
0554:                final int limit = s.length();
0555:                for (int i = 0; i < limit; i++) {
0556:                    if (s.charAt(i) == ':' && !flags.get(i)) {
0557:                        return i;
0558:                    }
0559:                }
0560:                return -1;
0561:            }
0562:
0563:            private static final int findUnescapedDoubleColon(String s,
0564:                    BitSet flags) {
0565:                if (flags == null)
0566:                    return s.indexOf("::");
0567:                final int limit = s.length() - 1;
0568:                for (int i = 0; i < limit; i++) {
0569:                    if (s.charAt(i) == ':' && !flags.get(i)) {
0570:                        if (s.charAt(i + 1) == ':' && !flags.get(i + 1)) {
0571:                            return i;
0572:                        }
0573:                    }
0574:                }
0575:                return -1;
0576:            }
0577:
0578:            private final LispObject readToken(char c)
0579:                    throws ConditionThrowable {
0580:                StringBuffer sb = new StringBuffer();
0581:                sb.append(c);
0582:                final LispThread thread = LispThread.currentThread();
0583:                BitSet flags = _readToken(sb, thread);
0584:                boolean escaped = (flags != null);
0585:                if (_READ_SUPPRESS_.symbolValue(thread) != NIL)
0586:                    return NIL;
0587:                final String token = sb.toString();
0588:                final int length = token.length();
0589:                if (length > 0) {
0590:                    final char firstChar = token.charAt(0);
0591:                    if (flags == null) {
0592:                        if (firstChar == '.') {
0593:                            // Section 2.3.3: "If a token consists solely of dots (with
0594:                            // no escape characters), then an error of type READER-
0595:                            // ERROR is signaled, except in one circumstance: if the
0596:                            // token is a single dot and appears in a situation where
0597:                            // dotted pair notation permits a dot, then it is accepted
0598:                            // as part of such syntax and no error is signaled."
0599:                            boolean ok = false;
0600:                            for (int i = length; i-- > 1;) {
0601:                                if (token.charAt(i) != '.') {
0602:                                    ok = true;
0603:                                    break;
0604:                                }
0605:                            }
0606:                            if (!ok) {
0607:                                final String message;
0608:                                if (length > 1)
0609:                                    message = "Too many dots.";
0610:                                else
0611:                                    message = "Dot context error.";
0612:                                return signal(new ReaderError(message));
0613:                            }
0614:                        }
0615:                        final int radix = getReadBase(thread);
0616:                        if ("-+0123456789".indexOf(firstChar) >= 0) {
0617:                            LispObject number = makeNumber(token, length, radix);
0618:                            if (number != null)
0619:                                return number;
0620:                        } else if (Character.digit(firstChar, radix) >= 0) {
0621:                            LispObject number = makeNumber(token, length, radix);
0622:                            if (number != null)
0623:                                return number;
0624:                        }
0625:                    }
0626:                    if (firstChar == ':')
0627:                        return PACKAGE_KEYWORD.intern(token.substring(1));
0628:                    int index = findUnescapedDoubleColon(token, flags);
0629:                    if (index > 0) {
0630:                        String packageName = token.substring(0, index);
0631:                        String symbolName = token.substring(index + 2);
0632:                        Package pkg = Packages.findPackage(packageName);
0633:                        if (pkg == null)
0634:                            return signal(new LispError("Package \""
0635:                                    + packageName + "\" not found."));
0636:                        return pkg.intern(symbolName);
0637:                    }
0638:                    index = findUnescapedSingleColon(token, flags);
0639:                    if (index > 0) {
0640:                        String packageName = token.substring(0, index);
0641:                        String symbolName = token.substring(index + 1);
0642:                        Package pkg = Packages.findPackage(packageName);
0643:                        if (pkg == null)
0644:                            return signal(new PackageError("Package \""
0645:                                    + packageName + "\" not found."));
0646:                        Symbol symbol = pkg.findExternalSymbol(symbolName);
0647:                        if (symbol != null)
0648:                            return symbol;
0649:                        // Error!
0650:                        if (pkg.findInternalSymbol(symbolName) != null)
0651:                            return signal(new LispError("The symbol \""
0652:                                    + symbolName
0653:                                    + "\" is not external in package "
0654:                                    + packageName + '.'));
0655:                        else
0656:                            return signal(new LispError("The symbol \""
0657:                                    + symbolName
0658:                                    + "\" was not found in package "
0659:                                    + packageName + '.'));
0660:                    }
0661:                }
0662:                // Intern token in current package.
0663:                return ((Package) _PACKAGE_.symbolValue(thread)).intern(token);
0664:            }
0665:
0666:            private final BitSet _readToken(StringBuffer sb, LispThread thread)
0667:                    throws ConditionThrowable {
0668:                BitSet flags = null;
0669:                final Readtable rt = currentReadtable(thread);
0670:                final LispObject readtableCase = rt.getReadtableCase();
0671:                if (sb.length() > 0) {
0672:                    Debug.assertTrue(sb.length() == 1);
0673:                    char c = sb.charAt(0);
0674:                    if (c == '|') {
0675:                        sb.setLength(0);
0676:                        sb.append(readMultipleEscape());
0677:                        flags = new BitSet(sb.length());
0678:                        for (int i = sb.length(); i-- > 0;)
0679:                            flags.set(i);
0680:                    } else if (c == '\\') {
0681:                        int n = _readChar();
0682:                        if (n < 0) {
0683:                            signal(new EndOfFile(this ));
0684:                            // Not reached.
0685:                            return flags;
0686:                        }
0687:                        sb.setCharAt(0, (char) n);
0688:                        flags = new BitSet(1);
0689:                        flags.set(0);
0690:                    } else if (readtableCase == Keyword.UPCASE) {
0691:                        sb.setCharAt(0, Utilities.toUpperCase(c));
0692:                    } else if (readtableCase == Keyword.DOWNCASE) {
0693:                        sb.setCharAt(0, Utilities.toLowerCase(c));
0694:                    }
0695:                }
0696:                loop: while (true) {
0697:                    int n = _readChar();
0698:                    if (n < 0)
0699:                        break;
0700:                    char c = (char) n;
0701:                    if (rt.isWhitespace(c))
0702:                        break;
0703:                    if (rt.getAttribute(c) == Readtable.ATTR_TERMINATING_MACRO) {
0704:                        _unreadChar(c);
0705:                        break;
0706:                    }
0707:                    switch (c) {
0708:                    case '\\':
0709:                        n = _readChar();
0710:                        if (n < 0)
0711:                            break loop;
0712:                        sb.append((char) n);
0713:                        if (flags == null)
0714:                            flags = new BitSet(sb.length());
0715:                        flags.set(sb.length() - 1);
0716:                        break;
0717:                    case '|': {
0718:                        int begin = sb.length();
0719:                        sb.append(readMultipleEscape());
0720:                        int end = sb.length();
0721:                        if (flags == null)
0722:                            flags = new BitSet(sb.length());
0723:                        for (int i = begin; i < end; i++)
0724:                            flags.set(i);
0725:                        break;
0726:                    }
0727:                    default:
0728:                        if (readtableCase == Keyword.UPCASE)
0729:                            c = Utilities.toUpperCase(c);
0730:                        else if (readtableCase == Keyword.DOWNCASE)
0731:                            c = Utilities.toLowerCase(c);
0732:                        sb.append(c);
0733:                    }
0734:                }
0735:                if (readtableCase == Keyword.INVERT) {
0736:                    // FIXME Preserve case of escaped characters!
0737:                    String s = invert(sb.toString());
0738:                    sb.setLength(0);
0739:                    sb.append(s);
0740:                }
0741:                return flags;
0742:            }
0743:
0744:            private static final int getReadBase(LispThread thread)
0745:                    throws ConditionThrowable {
0746:                final int readBase;
0747:                try {
0748:                    readBase = ((Fixnum) _READ_BASE_.symbolValue(thread)).value;
0749:                } catch (ClassCastException e) {
0750:                    // The value of *READ-BASE* is not a Fixnum.
0751:                    signal(new LispError(
0752:                            "The value of *READ-BASE* is not of type '(INTEGER 2 36)."));
0753:                    // Not reached.
0754:                    return 10;
0755:                }
0756:                if (readBase < 2 || readBase > 36) {
0757:                    signal(new LispError(
0758:                            "The value of *READ-BASE* is not of type '(INTEGER 2 36)."));
0759:                    // Not reached.
0760:                    return 10;
0761:                }
0762:                return readBase;
0763:            }
0764:
0765:            private static final LispObject makeNumber(String token,
0766:                    int length, int radix) throws ConditionThrowable {
0767:                if (length == 0)
0768:                    return null;
0769:                if (token.indexOf('/') >= 0)
0770:                    return makeRatio(token, radix);
0771:                if (token.charAt(length - 1) == '.') {
0772:                    radix = 10;
0773:                    token = token.substring(0, --length);
0774:                }
0775:                boolean numeric = true;
0776:                if (radix == 10) {
0777:                    for (int i = length; i-- > 0;) {
0778:                        char c = token.charAt(i);
0779:                        if (c < '0' || c > '9') {
0780:                            if (i > 0 || (c != '-' && c != '+')) {
0781:                                numeric = false;
0782:                                break;
0783:                            }
0784:                        }
0785:                    }
0786:                } else {
0787:                    for (int i = length; i-- > 0;) {
0788:                        char c = token.charAt(i);
0789:                        if (Character.digit(c, radix) < 0) {
0790:                            if (i > 0 || (c != '-' && c != '+')) {
0791:                                numeric = false;
0792:                                break;
0793:                            }
0794:                        }
0795:                    }
0796:                }
0797:                if (!numeric) // Can't be an integer.
0798:                    return makeFloat(token, length);
0799:                if (token.charAt(0) == '+')
0800:                    token = token.substring(1);
0801:                try {
0802:                    return new Fixnum(Integer.parseInt(token, radix));
0803:                } catch (NumberFormatException e) {
0804:                }
0805:                // parseInt() failed.
0806:                try {
0807:                    return new Bignum(new BigInteger(token, radix));
0808:                } catch (NumberFormatException e) {
0809:                }
0810:                // Not a number.
0811:                return null;
0812:            }
0813:
0814:            private static final LispObject makeRatio(String token, int radix)
0815:                    throws ConditionThrowable {
0816:                final int index = token.indexOf('/');
0817:                if (index < 0)
0818:                    return null;
0819:                try {
0820:                    BigInteger numerator = new BigInteger(token.substring(0,
0821:                            index), radix);
0822:                    BigInteger denominator = new BigInteger(token
0823:                            .substring(index + 1), radix);
0824:                    return number(numerator, denominator);
0825:                } catch (NumberFormatException e) {
0826:                }
0827:                return null;
0828:            }
0829:
0830:            private static final LispObject makeFloat(final String token,
0831:                    final int length) throws ConditionThrowable {
0832:                if (length == 0)
0833:                    return null;
0834:                StringBuffer sb = new StringBuffer();
0835:                int i = 0;
0836:                boolean maybe = false;
0837:                char c = token.charAt(i);
0838:                if (c == '-' || c == '+') {
0839:                    sb.append(c);
0840:                    ++i;
0841:                }
0842:                while (i < length) {
0843:                    c = token.charAt(i);
0844:                    if (c == '.' || (c >= '0' && c <= '9')) {
0845:                        if (c == '.')
0846:                            maybe = true;
0847:                        sb.append(c);
0848:                        ++i;
0849:                    } else
0850:                        break;
0851:                }
0852:                if (i < length) {
0853:                    if ("esfdlESFDL".indexOf(token.charAt(i)) >= 0) {
0854:                        // Exponent marker.
0855:                        maybe = true;
0856:                        sb.append('E');
0857:                        ++i;
0858:                    }
0859:                }
0860:                if (!maybe)
0861:                    return null;
0862:                // Append rest of token.
0863:                sb.append(token.substring(i));
0864:                try {
0865:                    return new LispFloat(Double.parseDouble(sb.toString()));
0866:                } catch (NumberFormatException e) {
0867:                    return null;
0868:                }
0869:            }
0870:
0871:            public LispObject readRadix(int radix) throws ConditionThrowable {
0872:                StringBuffer sb = new StringBuffer();
0873:                boolean escaped = (_readToken(sb, LispThread.currentThread()) != null);
0874:                if (escaped)
0875:                    return signal(new ReaderError("Illegal syntax for number."));
0876:                String s = sb.toString();
0877:                if (s.indexOf('/') >= 0)
0878:                    return makeRatio(s, radix);
0879:                try {
0880:                    return new Fixnum(Integer.parseInt(s, radix));
0881:                } catch (NumberFormatException e) {
0882:                }
0883:                // parseInt() failed.
0884:                try {
0885:                    return new Bignum(new BigInteger(s, radix));
0886:                } catch (NumberFormatException e) {
0887:                }
0888:                // Not a number.
0889:                return signal(new LispError());
0890:            }
0891:
0892:            private char flushWhitespace() throws ConditionThrowable {
0893:                final Readtable rt = currentReadtable();
0894:                while (true) {
0895:                    int n = _readChar();
0896:                    if (n < 0) {
0897:                        signal(new EndOfFile(this ));
0898:                        // Not reached.
0899:                        return 0;
0900:                    }
0901:                    char c = (char) n;
0902:                    if (!rt.isWhitespace(c))
0903:                        return c;
0904:                }
0905:            }
0906:
0907:            public LispObject readDelimitedList(char delimiter)
0908:                    throws ConditionThrowable {
0909:                LispObject result = NIL;
0910:                while (true) {
0911:                    char c = flushWhitespace();
0912:                    if (c == delimiter)
0913:                        break;
0914:                    LispObject obj = processChar(c);
0915:                    if (obj != null)
0916:                        result = new Cons(obj, result);
0917:                }
0918:                return result.nreverse();
0919:            }
0920:
0921:            // read-line &optional stream eof-error-p eof-value recursive-p
0922:            // => line, missing-newline-p
0923:            // recursive-p is ignored
0924:            public LispObject readLine(boolean eofError, LispObject eofValue)
0925:                    throws ConditionThrowable {
0926:                final LispThread thread = LispThread.currentThread();
0927:                StringBuffer sb = new StringBuffer();
0928:                while (true) {
0929:                    int n = _readChar();
0930:                    if (n < 0) {
0931:                        if (sb.length() == 0) {
0932:                            if (eofError)
0933:                                return signal(new EndOfFile(this ));
0934:                            return thread.setValues(eofValue, T);
0935:                        }
0936:                        return thread.setValues(new SimpleString(sb), T);
0937:                    }
0938:                    if (n == '\n')
0939:                        return thread.setValues(new SimpleString(sb), NIL);
0940:                    else
0941:                        sb.append((char) n);
0942:                }
0943:            }
0944:
0945:            // read-char &optional stream eof-error-p eof-value recursive-p => char
0946:            // recursive-p is ignored
0947:            public LispObject readChar(boolean eofError, LispObject eofValue)
0948:                    throws ConditionThrowable {
0949:                int n = _readChar();
0950:                if (n < 0) {
0951:                    if (eofError)
0952:                        return signal(new EndOfFile(this ));
0953:                    else
0954:                        return eofValue;
0955:                }
0956:                return LispCharacter.getInstance((char) n);
0957:            }
0958:
0959:            // read-char-no-hang &optional stream eof-error-p eof-value recursive-p => char
0960:            // recursive-p is ignored
0961:            public LispObject readCharNoHang(boolean eofError,
0962:                    LispObject eofValue) throws ConditionThrowable {
0963:                return _charReady() ? readChar(eofError, eofValue) : NIL;
0964:            }
0965:
0966:            // unread-char character &optional input-stream => nil
0967:            public LispObject unreadChar(LispCharacter c)
0968:                    throws ConditionThrowable {
0969:                _unreadChar(c.getValue());
0970:                return NIL;
0971:            }
0972:
0973:            public LispObject finishOutput() throws ConditionThrowable {
0974:                _finishOutput();
0975:                return NIL;
0976:            }
0977:
0978:            // clear-input &optional input-stream => nil
0979:            public LispObject clearInput() throws ConditionThrowable {
0980:                _clearInput();
0981:                return NIL;
0982:            }
0983:
0984:            public LispObject getFilePosition() throws ConditionThrowable {
0985:                long pos = _getFilePosition();
0986:                return pos >= 0 ? number(pos) : NIL;
0987:            }
0988:
0989:            public LispObject setFilePosition(LispObject arg)
0990:                    throws ConditionThrowable {
0991:                return _setFilePosition(arg) ? T : NIL;
0992:            }
0993:
0994:            // close stream &key abort => result
0995:            // Must return true if stream was open, otherwise implementation-dependent.
0996:            public LispObject close(LispObject abort) throws ConditionThrowable {
0997:                _close();
0998:                return T;
0999:            }
1000:
1001:            public String toString() {
1002:                return unreadableString("STREAM");
1003:            }
1004:
1005:            // read-byte stream &optional eof-error-p eof-value => byte
1006:            // Reads an 8-bit byte.
1007:            public LispObject readByte(boolean eofError, LispObject eofValue)
1008:                    throws ConditionThrowable {
1009:                int n = _readByte();
1010:                if (n < 0) {
1011:                    if (eofError)
1012:                        return signal(new EndOfFile(this ));
1013:                    else
1014:                        return eofValue;
1015:                }
1016:                return new Fixnum(n);
1017:            }
1018:
1019:            public LispObject terpri() throws ConditionThrowable {
1020:                _writeChar('\n');
1021:                return NIL;
1022:            }
1023:
1024:            public LispObject freshLine() throws ConditionThrowable {
1025:                if (charPos == 0)
1026:                    return NIL;
1027:                _writeChar('\n');
1028:                return T;
1029:            }
1030:
1031:            public void print(char c) throws ConditionThrowable {
1032:                _writeChar(c);
1033:            }
1034:
1035:            // PRIN1 produces output suitable for input to READ.
1036:            // Binds *PRINT-ESCAPE* to true.
1037:            public void prin1(LispObject obj) throws ConditionThrowable {
1038:                LispThread thread = LispThread.currentThread();
1039:                Environment oldDynEnv = thread.getDynamicEnvironment();
1040:                thread.bindSpecial(_PRINT_ESCAPE_, T);
1041:                String s = obj.writeToString();
1042:                thread.setDynamicEnvironment(oldDynEnv);
1043:                _writeString(s);
1044:            }
1045:
1046:            public LispObject listen() throws ConditionThrowable {
1047:                return _charReady() ? T : NIL;
1048:            }
1049:
1050:            public LispObject fileLength() throws ConditionThrowable {
1051:                return signal(new TypeError(
1052:                        "Stream is not associated with a file."));
1053:            }
1054:
1055:            public LispObject fileStringLength(LispObject arg)
1056:                    throws ConditionThrowable {
1057:                if (arg instanceof  LispCharacter)
1058:                    return Fixnum.ONE;
1059:                else if (arg instanceof  AbstractString)
1060:                    return number(arg.length());
1061:                else
1062:                    return signal(new TypeError(String.valueOf(arg)
1063:                            + " is neither a string nor a character."));
1064:            }
1065:
1066:            // Returns -1 at end of file.
1067:            protected int _readChar() throws ConditionThrowable {
1068:                try {
1069:                    int n = reader.read();
1070:                    ++offset;
1071:                    if (n == '\r') {
1072:                        if (interactive && Utilities.isPlatformWindows())
1073:                            return _readChar();
1074:                    }
1075:                    if (n == '\n')
1076:                        ++lineNumber;
1077:                    return n;
1078:                } catch (IOException e) {
1079:                    signal(new StreamError(this , e));
1080:                    // Not reached.
1081:                    return -1;
1082:                }
1083:            }
1084:
1085:            protected void _unreadChar(int n) throws ConditionThrowable {
1086:                try {
1087:                    reader.unread(n);
1088:                    --offset;
1089:                    if (n == '\n')
1090:                        --lineNumber;
1091:                } catch (IOException e) {
1092:                    signal(new StreamError(this , e));
1093:                }
1094:            }
1095:
1096:            protected boolean _charReady() throws ConditionThrowable {
1097:                try {
1098:                    return reader.ready();
1099:                } catch (IOException e) {
1100:                    signal(new StreamError(this , e));
1101:                    // Not reached.
1102:                    return false;
1103:                }
1104:            }
1105:
1106:            public void _writeChar(char c) throws ConditionThrowable {
1107:                try {
1108:                    writer.write(c);
1109:                    if (c == '\n') {
1110:                        writer.flush();
1111:                        charPos = 0;
1112:                    } else
1113:                        ++charPos;
1114:                } catch (IOException e) {
1115:                    signal(new StreamError(this , e));
1116:                }
1117:            }
1118:
1119:            public void _writeChars(char[] chars, int start, int end)
1120:                    throws ConditionThrowable {
1121:                try {
1122:                    writer.write(chars, start, end - start);
1123:                    int index = -1;
1124:                    for (int i = end; i-- > start;) {
1125:                        if (chars[i] == '\n') {
1126:                            index = i;
1127:                            break;
1128:                        }
1129:                    }
1130:                    if (index < 0) {
1131:                        // No newline.
1132:                        charPos += (end - start);
1133:                    } else {
1134:                        charPos = end - (index + 1);
1135:                        writer.flush();
1136:                    }
1137:                } catch (IOException e) {
1138:                    signal(new StreamError(this , e));
1139:                }
1140:            }
1141:
1142:            public void _writeString(String s) throws ConditionThrowable {
1143:                try {
1144:                    writer.write(s);
1145:                    int index = s.lastIndexOf('\n');
1146:                    if (index < 0)
1147:                        charPos += s.length();
1148:                    else {
1149:                        charPos = s.length() - (index + 1);
1150:                        writer.flush();
1151:                    }
1152:                } catch (IOException e) {
1153:                    signal(new StreamError(this , e));
1154:                }
1155:            }
1156:
1157:            public void _writeLine(String s) throws ConditionThrowable {
1158:                try {
1159:                    writer.write(s);
1160:                    writer.write('\n');
1161:                    writer.flush();
1162:                    charPos = 0;
1163:                } catch (IOException e) {
1164:                    signal(new StreamError(this , e));
1165:                }
1166:            }
1167:
1168:            // Reads an 8-bit byte.
1169:            public int _readByte() throws ConditionThrowable {
1170:                try {
1171:                    return in.read(); // Reads an 8-bit byte.
1172:                } catch (IOException e) {
1173:                    signal(new StreamError(this , e));
1174:                    // Not reached.
1175:                    return -1;
1176:                }
1177:            }
1178:
1179:            // Writes an 8-bit byte.
1180:            public void _writeByte(int n) throws ConditionThrowable {
1181:                try {
1182:                    out.write(n); // Writes an 8-bit byte.
1183:                } catch (IOException e) {
1184:                    signal(new StreamError(this , e));
1185:                }
1186:            }
1187:
1188:            public void _finishOutput() throws ConditionThrowable {
1189:                try {
1190:                    if (writer != null)
1191:                        writer.flush();
1192:                    if (out != null)
1193:                        out.flush();
1194:                } catch (IOException e) {
1195:                    signal(new StreamError(this , e));
1196:                }
1197:            }
1198:
1199:            public void _clearInput() throws ConditionThrowable {
1200:                if (reader != null) {
1201:                    while (_charReady())
1202:                        _readChar();
1203:                } else if (in != null) {
1204:                    try {
1205:                        while (in.available() > 0)
1206:                            in.read();
1207:                    } catch (IOException e) {
1208:                        signal(new StreamError(this , e));
1209:                    }
1210:                }
1211:            }
1212:
1213:            protected long _getFilePosition() throws ConditionThrowable {
1214:                return -1;
1215:            }
1216:
1217:            protected boolean _setFilePosition(LispObject arg)
1218:                    throws ConditionThrowable {
1219:                return false;
1220:            }
1221:
1222:            public void _close() throws ConditionThrowable {
1223:                try {
1224:                    if (reader != null)
1225:                        reader.close();
1226:                    if (in != null)
1227:                        in.close();
1228:                    if (writer != null)
1229:                        writer.close();
1230:                    if (out != null)
1231:                        out.close();
1232:                    setOpen(false);
1233:                } catch (IOException e) {
1234:                    signal(new StreamError(this , e));
1235:                }
1236:            }
1237:
1238:            public void printStackTrace(Throwable t) throws ConditionThrowable {
1239:                StringWriter sw = new StringWriter();
1240:                PrintWriter pw = new PrintWriter(sw);
1241:                t.printStackTrace(pw);
1242:                try {
1243:                    writer.write(sw.toString());
1244:                    writer.write('\n');
1245:                    writer.flush();
1246:                    charPos = 0;
1247:                } catch (IOException e) {
1248:                    signal(new StreamError(this , e));
1249:                }
1250:            }
1251:
1252:            // ### file-position
1253:            private static final Primitive FILE_POSITION = new Primitive(
1254:                    "file-position", "stream &optional position-spec") {
1255:                public LispObject execute(LispObject arg)
1256:                        throws ConditionThrowable {
1257:                    return checkStream(arg).getFilePosition();
1258:                }
1259:
1260:                public LispObject execute(LispObject first, LispObject second)
1261:                        throws ConditionThrowable {
1262:                    return checkStream(first).setFilePosition(second);
1263:                }
1264:            };
1265:
1266:            // ### stream-line-number
1267:            private static final Primitive1 STREAM_LINE_NUMBER = new Primitive1(
1268:                    "stream-line-number", PACKAGE_SYS, false, "stream") {
1269:                public LispObject execute(LispObject arg)
1270:                        throws ConditionThrowable {
1271:                    Stream stream = checkStream(arg);
1272:                    return number(stream.getLineNumber() + 1);
1273:                }
1274:            };
1275:
1276:            // ### stream-offset
1277:            private static final Primitive1 STREAM_OFFSET = new Primitive1(
1278:                    "stream-offset", PACKAGE_SYS, false, "stream") {
1279:                public LispObject execute(LispObject arg)
1280:                        throws ConditionThrowable {
1281:                    Stream stream = checkStream(arg);
1282:                    return number(stream.getOffset());
1283:                }
1284:            };
1285:        }
www.java2java.com | Contact Us
Copyright 2010 - 2030 Java Source and Support. All rights reserved.
All other trademarks are property of their respective owners.