Source Code Cross Referenced for InputPort.java in  » Scripting » jscheme » jsint » 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
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » jscheme » jsint 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package jsint;
002:
003:        import java.io.*;
004:
005:        /** InputPort is to Scheme as InputStream is to Java. 
006:
007:         * @author Peter Norvig, Copyright 1998, peter@norvig.com, <a href="license.txt">license</a>
008:         * subsequently modified by Jscheme project members
009:         * licensed under zlib licence (see license.txt)
010:         **/
011:
012:        public class InputPort implements  java.util.Enumeration {
013:
014:            /** The distinguished end of file marking object. **/
015:            // public static final Symbol EOF = Symbol.intern("#!eof");
016:            public static final Object EOF = token("!eof");
017:            public static final boolean defaultBrlsMode = true;
018:            public boolean brlsMode = defaultBrlsMode;
019:            private boolean keepComments = false;
020:
021:            /** These tokens must be distinguishable from anything else returned
022:                by readToken().
023:             **/
024:            private static class Token {
025:                String name;
026:
027:                Token(String name) {
028:                    this .name = name;
029:                }
030:
031:                public String toString() {
032:                    return "#" + name + "#";
033:                }
034:            }
035:
036:            private static final Object BACKQUOTE = token("`");
037:            private static final Object CLOSE = token(")");
038:            private static final Object COMMA = token(",");
039:            private static final Object COMMA_AT = token(",@");
040:            private static final Object DOT = token(".");
041:            private static final Object OPEN = token("(");
042:            private static final Object QUOTE = token("'");
043:            private static final Object HASH_ESCAPE_CLOSE = token("#]");
044:            private static final Object HASH_ESCAPE_OPEN = token("#[");
045:            private static final Object HASH_CLOSE = token("#}");
046:
047:            /* These are used when reading the #\s,#\space,#\n,#\newline
048:               character literals */
049:            private static final Symbol CHAR_s = Symbol.intern("s");
050:            private static final Symbol CHAR_S = Symbol.intern("S");
051:            private static final Symbol CHAR_n = Symbol.intern("n");
052:            private static final Symbol CHAR_N = Symbol.intern("N");
053:            private static final Symbol NEWLINE_UC = Symbol.intern("NEWLINE");
054:            private static final Symbol NEWLINE_LC = Symbol.intern("newline");
055:            private static final Symbol SPACE_UC = Symbol.intern("SPACE");
056:            private static final Symbol SPACE_LC = Symbol.intern("space");
057:            private static final Symbol CURLY = Symbol.intern("!{}");
058:            private static final Symbol HASH_CURLY = Symbol.intern("!#{}");
059:
060:            /* This stack is used to keep track of the current state viz-a-viz
061:               quasi-strings. The states are listed below the stack declaration */
062:            private java.util.Stack quasiStack = new java.util.Stack();
063:
064:            private static final Integer TOP = new Integer(0);
065:            private static final Integer STR = new Integer(1); // inside a "...." string
066:            private static final Integer QSTR = new Integer(2); // inside a {....} quasi-string
067:            private static final Integer HQSTR = new Integer(3); // inside a #{....#} quasi-string
068:            private static final Integer QSTRESC = new Integer(4); // inside a [...] escape of a {...} quasi-string
069:            private static final Integer HQSTRESC = new Integer(5); // inside a #[...#] escape of a #{...#} quasi-string
070:
071:            private static Object token(String x) {
072:                return new Token(x);
073:            }
074:
075:            boolean isPushedChar = false;
076:            int pushedChar = -1;
077:            int radix = 10;
078:            LineNumberReader in;
079:            StringBuffer buff = new StringBuffer(8);
080:
081:            public InputPort(Reader in, boolean keepComments) {
082:                quasiStack.push(InputPort.TOP);
083:                if (in instanceof  LineNumberReader)
084:                    this .in = (LineNumberReader) in;
085:                else
086:                    this .in = new LineNumberReader(in);
087:                this .keepComments = keepComments;
088:            }
089:
090:            /** Construct an InputPort from an InputStream. **/
091:            public InputPort(InputStream in) {
092:                this (new InputStreamReader(in), false);
093:            }
094:
095:            /** Construct an InputPort from a Reader. **/
096:            public InputPort(Reader in) {
097:                this (in, false);
098:            }
099:
100:            /** Read and return a Scheme character or EOF. **/
101:            public synchronized Object readChar() {
102:                try {
103:                    if (isPushedChar) {
104:                        isPushedChar = false;
105:                        if (pushedChar == -1)
106:                            return EOF;
107:                        else
108:                            return U.toChar((char) pushedChar);
109:                    } else {
110:                        int ch = in.read();
111:                        if (ch == -1)
112:                            return EOF;
113:                        else
114:                            return U.toChar((char) ch);
115:                    }
116:                } catch (IOException e) {
117:                    E.warn("On input, exception A: " + e);
118:                    return EOF;
119:                }
120:            }
121:
122:            /** Peek at and return the next Scheme character (or EOF).
123:             * However, don't consume the character. **/
124:            public synchronized Object peekChar() {
125:                int p = peekCh();
126:                if (p == -1)
127:                    return EOF;
128:                else
129:                    return U.toChar((char) p);
130:            }
131:
132:            private Pair pushedTokens = Pair.EMPTY;
133:
134:            private boolean isPushedToken() {
135:                return (pushedTokens != Pair.EMPTY);
136:            }
137:
138:            /** Push a token back to be re-used later. **/
139:            private Object pushToken(Object token) {
140:                pushedTokens = new Pair(token, pushedTokens);
141:                return token;
142:            }
143:
144:            /** Pop off the previously pushed token. **/
145:            private Object popToken() {
146:                Object token = pushedTokens.first;
147:                pushedTokens = (Pair) (pushedTokens.rest);
148:                return token;
149:            }
150:
151:            /** Push a character back to be re-used later. **/
152:            private int pushChar(int ch) {
153:                isPushedChar = true;
154:                return pushedChar = ch;
155:            }
156:
157:            /** Pop off the previously pushed character. **/
158:            private int popChar() {
159:                isPushedChar = false;
160:                return pushedChar;
161:            }
162:
163:            /** Peek at and return the next Scheme character as an int, -1 for EOF.
164:             * However, don't consume the character. **/
165:            private int peekCh() {
166:                try {
167:                    return isPushedChar ? pushedChar : pushChar(in.read());
168:                } catch (IOException e) {
169:                    E.warn("On input, exception B: " + e);
170:                    return -1;
171:                }
172:            }
173:
174:            public int getLineNumber() {
175:                return in.getLineNumber();
176:            }
177:
178:            public Object nextElement() {
179:                return read();
180:            }
181:
182:            public boolean hasMoreElements() {
183:                try {
184:                    Object token = readToken();
185:                    pushToken(token);
186:                    return (token != EOF);
187:                } catch (IOException e) {
188:                    E.warn("On input, exception C: " + e);
189:                    return false;
190:                }
191:            }
192:
193:            public synchronized Object read() {
194:                try {
195:                    Object token = readToken();
196:                    if (token instanceof  Symbol)
197:                        return token; // return lookupGlobal((Symbol) token);
198:                    else if (token instanceof  Token) {
199:                        // if (token == OPEN)  return readTail(false);
200:                        if (token == OPEN)
201:                            return readList();
202:                        else if (token == QUOTE)
203:                            return U.list(Symbol.QUOTE, read());
204:                        else if (token == COMMA)
205:                            return U.list(Symbol.UNQUOTE, read());
206:                        else if (token == BACKQUOTE)
207:                            return U.list(Symbol.QUASIQUOTE, read());
208:                        else if (token == COMMA_AT)
209:                            return U.list(Symbol.UNQUOTE_SPLICING, read());
210:                        else if (token == CLOSE) {
211:                            E.warn("Extra ) ignored -- line number "
212:                                    + in.getLineNumber());
213:                            return read();
214:                        } else if (token == DOT) {
215:                            E.warn("Extra . ignored -- line number "
216:                                    + in.getLineNumber());
217:                            return read();
218:                        } else
219:                            return token;
220:                    } else
221:                        return token;
222:                } catch (IOException e) {
223:                    E.warn("On input, exception D: " + e);
224:                    return EOF;
225:                }
226:            }
227:
228:            /** Close the port.  Return TRUE if ok. **/
229:            public Object close() {
230:                try {
231:                    this .in.close();
232:                    return U.TRUE;
233:                } catch (IOException e) {
234:                    return E.error("On input, IOException E: " + e);
235:                }
236:            }
237:
238:            private Object readList() throws IOException { // Saw "("
239:                Object token = readToken();
240:                if (token instanceof  Token)
241:                    return readListToken((Token) token);
242:                return readListRest(new Queue(token));
243:            }
244:
245:            private Object readListToken(Token token) throws IOException {
246:                if (token == CLOSE)
247:                    return Pair.EMPTY; //  "()"
248:                else if (token == DOT)
249:                    return E.error("'.' not allowed immediately after '('");
250:                else if (token == EOF)
251:                    return E.error("EOF during read.");
252:                else {
253:                    pushToken(token);
254:                    return readListRest(new Queue(read()));
255:                }
256:            }
257:
258:            private Object readListRest(Queue queue) throws IOException {
259:                int lineNum = getLineNumber();
260:                // Saw "( x ..."
261:                while (true) {
262:                    if (Scheme.isInterruptable())
263:                        Scheme.interruptCheck();
264:                    Object token = readToken();
265:                    if (token instanceof  Token) {
266:                        if (token == CLOSE)
267:                            return queue.getContent();
268:                        if (token == DOT) {
269:                            Object result = read();
270:                            token = readToken();
271:                            if (token != CLOSE)
272:                                return E.error("Where's the ')'? Got " + token
273:                                        + " after .");
274:                            queue.getLast().rest = result;
275:                            return queue.getContent();
276:                        }
277:                        if (token == EOF)
278:                            return E
279:                                    .error("EOF during read: open paren on line "
280:                                            + lineNum + " not closed.");
281:                        pushToken(token);
282:                        queue.add(read());
283:                    } else
284:                        queue.add(token);
285:                }
286:            }
287:
288:            /** Returns either a Token or a primitive Scheme type. **/
289:            private Object readToken() throws IOException {
290:                Integer qstate = (Integer) quasiStack.peek();
291:
292:                if (isPushedToken()) {
293:                    Object t = popToken();
294:                    // handle case where a #] was pushed in readSymbolOrNumber
295:                    if (HASH_ESCAPE_CLOSE.equals(t)) {
296:                        quasiStack.pop();
297:                        return readString();
298:                    } else
299:                        return t;
300:                }
301:
302:                int ch = (isPushedChar) ? popChar() : in.read();
303:                while (Character.isWhitespace((char) ch))
304:                    ch = in.read();
305:                // See what kind of non-white character we got
306:                switch (ch) {
307:                case '(':
308:                    return OPEN;
309:                case ')':
310:                    return CLOSE;
311:                case '\'':
312:                    return QUOTE;
313:                case '`':
314:                    return BACKQUOTE;
315:                case '#':
316:                    return readHashToken();
317:                case '"':
318:                    return readString();
319:                case ',':
320:                    ch = in.read();
321:                    if (ch == '@')
322:                        return COMMA_AT;
323:                    else {
324:                        pushChar(ch);
325:                        return COMMA;
326:                    }
327:                case ';':
328:                    return readComment(ch);
329:                case -1:
330:                    return EOF;
331:                case '{':
332:                    if (brlsMode) {
333:                        quasiStack.push(InputPort.QSTR);
334:                        pushToken(CURLY);
335:                        isPushedChar = true;
336:                        pushedChar = '"';
337:                        return OPEN;
338:                    }
339:                case ']':
340:                    if (brlsMode) {
341:                        if (QSTRESC == qstate) {
342:                            quasiStack.pop();
343:                            return readString();
344:                        } else if (HQSTRESC == qstate) {
345:                            ch = in.read();
346:                            if (ch == '#') {
347:                                quasiStack.pop();
348:                                return readString();
349:                            }
350:                        }
351:                    }
352:
353:                default:
354:                    return readNumberOrSymbol(ch);
355:                }
356:            }
357:
358:            // Comment: skip to end of line and then read next token
359:            private Object readComment(int ch) throws IOException {
360:                if (keepComments)
361:                    return readCommentKeeping(ch);
362:                else {
363:                    while (ch != -1 && ch != '\n' && ch != '\r')
364:                        ch = in.read();
365:                    return readToken();
366:                }
367:            }
368:
369:            private Object readCommentKeeping(int ch) throws IOException {
370:                buff.setLength(0);
371:                int count = 0;
372:                while (ch == ';') {
373:                    count = count + 1;
374:                    ch = in.read();
375:                }
376:                while (ch != -1 && ch != '\n' && ch != '\r') {
377:                    buff.append((char) ch);
378:                    ch = in.read();
379:                }
380:                return jscheme.JS.list(Symbol.intern("comment"), new Integer(
381:                        count), buff.toString());
382:            }
383:
384:            /*
385:              Here we read a string or quasi-string or hash-quasi-string
386:              A string is terminated by a '"' which is not itself quoted.
387:              A quasi-string is terminated by a '[' or a '}'
388:              A hash-quasi-string is terminated by a #[ or }#, so we need to check
389:              whether the [ is preceded by a hash or the } is followed by a hash. The proper way to
390:              escape such a string is #\[ or }/# ...
391:             */
392:            private String readString() {
393:                Integer qstate = (Integer) quasiStack.peek();
394:                int ch = 0;
395:                int lastchar = -1;
396:                buff.setLength(0);
397:
398:                if (qstate == QSTR)
399:                    try {
400:                        while (((ch = in.read()) != '}') && (ch != '[')
401:                                && (ch != -1)) {
402:                            lastchar = ch;
403:                            buff
404:                                    .append((char) ((ch == '\\') ? (U.useJavaSyntax ? escapechar(in
405:                                            .read())
406:                                            : in.read())
407:                                            : ch));
408:                        }
409:                        if (ch == -1)
410:                            E.warn("EOF inside of a string.");
411:                        if (ch == '}') {
412:                            quasiStack.pop();
413:                            pushToken(CLOSE);
414:                        }
415:                        if (ch == '[') {
416:                            quasiStack.push(QSTRESC);
417:                        }
418:                        return internStringBuffer(buff);
419:                    } catch (IOException e) {
420:                        E.warn("On input, IOException G:", e);
421:                        return "";
422:                    }
423:
424:                else if (qstate == HQSTR)
425:                    try {
426:                        while ((!(((ch = in.read()) == '#') && (lastchar == '}')))
427:                                && (!((ch == '[') && (lastchar == '#')))
428:                                && (ch != -1)) {
429:                            lastchar = ch;
430:                            buff
431:                                    .append((char) ((ch == '\\') ? (U.useJavaSyntax ? escapechar(in
432:                                            .read())
433:                                            : in.read())
434:                                            : ch));
435:                        }
436:                        if (ch == -1)
437:                            E.warn("EOF inside of a string.");
438:                        if (ch == '#') {
439:                            quasiStack.pop();
440:                            pushToken(CLOSE);
441:                        }
442:                        if (ch == '[') {
443:                            quasiStack.push(HQSTRESC);
444:                        }
445:                        buff.deleteCharAt(buff.length() - 1); // get rid of the extra #
446:                        return internStringBuffer(buff);
447:                    } catch (IOException e) {
448:                        E.warn("On input, IOException H1:", e);
449:                        return "";
450:                    }
451:                else
452:                    try {
453:                        while (((ch = in.read()) != '"') && (ch != -1)) {
454:                            buff
455:                                    .append((char) ((ch == '\\') ? (U.useJavaSyntax ? escapechar(in
456:                                            .read())
457:                                            : in.read())
458:                                            : ch));
459:                        }
460:                        if (ch == -1)
461:                            E.warn("EOF inside of a string.");
462:                        return internStringBuffer(buff);
463:                    } catch (IOException e) {
464:                        E.warn("On input, IOException F:", e);
465:                        return "";
466:                    }
467:            }
468:
469:            private String internStringBuffer(StringBuffer b) {
470:                return b.toString().intern();
471:            }
472:
473:            private String moveBufToString(StringBuffer b) {
474:                int L = b.length();
475:                char[] chars = new char[L];
476:                if (L > 0) {
477:                    b.getChars(0, L, chars, 0);
478:                    b.setLength(0);
479:                }
480:                return new String(chars);
481:            }
482:
483:            /*
484:              KRA 31MAR01: 4.3% of loading elf/basic.scm was spent thowing
485:              NumberFormatException i think because + and - are commonly used
486:              symbols.  So added length test.
487:
488:              KRA 06APR03: This did not work for #xff. so add tests for each
489:              radix.
490:             */
491:            private boolean maybeNumber(int c, String buff, int radix) {
492:                return (radix == 10 && (c >= '0' && c <= '9' || ((c == '.'
493:                        || c == '+' || c == '-') && buff.length() > 1)))
494:                        || (radix == 16 && ((c >= '0' && c <= '9')
495:                                || (c >= 'a' && c <= 'f') || (c >= 'a' && c <= 'A')))
496:                        || (radix == 8 && (c >= '0' && c <= '7'))
497:                        || (radix == 2 && (c >= '0' && c <= '1'));
498:            }
499:
500:            /*
501:              read a number or a symbol
502:              if in quasi-string-escape mode, then a ] delimits a number or symbol
503:              if in hash-quasi-string-escape mode, then a #] delimits a number or symbol
504:             */
505:            private Object readNumberOrSymbol(int ch) throws IOException {
506:                Integer qstate = (Integer) quasiStack.peek();
507:                buff.setLength(0);
508:                int c = ch; // save the first character
509:                boolean foundDelimiter = false;
510:
511:                do { // accumulate characters up to the next delimiter
512:                    buff.append((char) ch);
513:                    ch = in.read();
514:                    foundDelimiter = isDelimiter(ch);
515:
516:                    /* check for a ]# delimiting a number or symbol */
517:                    if ((ch == ']') && (qstate == HQSTRESC)) {
518:                        ch = in.read();
519:                        if (ch == '#') {
520:                            foundDelimiter = true;
521:                            pushToken(HASH_ESCAPE_CLOSE);
522:                            ch = ' ';
523:                            continue;
524:                        } else {
525:                            buff.append(']');
526:                        }
527:                    }
528:
529:                    if ((ch == ']') && (qstate == QSTRESC)) {
530:                        foundDelimiter = true;
531:                    }
532:
533:                    /* this next if expression handles the quasi-string exception
534:                       which allows [] to appear within Symbols in quasi-string escapes */
535:                    if ((ch == '[') && (qstate == QSTRESC)) {
536:                        buff.append((char) ch);
537:                        ch = in.read();
538:                        foundDelimiter = isDelimiter(ch) && (ch != ']');
539:                    }
540:
541:                } while (!foundDelimiter);
542:                pushChar(ch);
543:                if (c == '.' && buff.length() == 1)
544:                    return DOT;
545:                String tok = moveBufToString(buff);
546:                // Try potential numbers, but catch any format errors.
547:                try {
548:                    if (maybeNumber(c, tok, radix)) {
549:                        Object it = stringToNumber(tok, radix);
550:                        if (it instanceof  Number)
551:                            return it;
552:                    }
553:                } catch (NumberFormatException e) {
554:                    return Symbol.intern(tok);
555:                }
556:                return Symbol.intern(tok);
557:            }
558:
559:            public static Object schemeStringToNumber(String tok, int rdx) {
560:                try {
561:                    return U.toNum(Long.parseLong(tok, rdx));
562:                } catch (NumberFormatException e) {
563:                    try {
564:                        if (rdx != 10)
565:                            return U.FALSE;
566:                        else
567:                            return new Double(tok);
568:                    } catch (NumberFormatException e2) {
569:                        return U.FALSE;
570:                    }
571:                }
572:            }
573:
574:            public static Object stringToNumber(String tok, int rdx) {
575:                if (rdx == 10) {
576:                    if (U.useJavaSyntax) {
577:                        try {
578:                            return readWholeNumber(tok);
579:                        } catch (NumberFormatException e1) {
580:                            try {
581:                                return readFloatingPoint(tok);
582:                            } catch (NumberFormatException e3) {
583:                                return U.FALSE;
584:                            }
585:                        }
586:                    } else {
587:                        try {
588:                            return U.toNum(Long.parseLong(tok, rdx));
589:                        } catch (NumberFormatException e) {
590:                            try {
591:                                return new Double(tok);
592:                            } catch (NumberFormatException e2) {
593:                                return U.FALSE;
594:                            }
595:                        }
596:                    }
597:                } else
598:                    return U
599:                            .toNum(Long.parseLong(U.stringify(tok, false), rdx));
600:            }
601:
602:            /* attempt to parse a long or an int in Java syntax
603:               this currently accepts +---+013LLBSBSL --> -11L
604:               we may want to disallow multiple signs and multiple type characters
605:             */
606:            public static Number readWholeNumber(String s)
607:                    throws NumberFormatException {
608:                long n;
609:                if (s.endsWith("l") || s.endsWith("L"))
610:                    return new Long(readWholeNumber(
611:                            s.substring(0, s.length() - 1)).longValue());
612:                if (s.endsWith("b") || s.endsWith("B"))
613:                    return new Byte(readWholeNumber(
614:                            s.substring(0, s.length() - 1)).byteValue());
615:                if (s.endsWith("s") || s.endsWith("S"))
616:                    return new Short(readWholeNumber(
617:                            s.substring(0, s.length() - 1)).shortValue());
618:                else if (s.startsWith("+") && (s.length() > 1))
619:                    return readWholeNumber(s.substring(1, s.length()));
620:                else if (s.startsWith("-") && (s.length() > 1))
621:                    return negate(readWholeNumber(s.substring(1, s.length())));
622:                //     else if (s.startsWith("0x")) 
623:                //       n = Long.parseLong(s.substring(2,s.length()),16);
624:                //     else if ((s.startsWith("0")) && (s.length()>1))
625:                //       n = Long.parseLong(s.substring(1,s.length()),8);
626:                else
627:                    n = Long.parseLong(s, 10);
628:                return U.toNum(n);
629:            }
630:
631:            public static Number negate(Number n) {
632:                if (n instanceof  Integer)
633:                    return U.toNum(-n.intValue());
634:                else if (n instanceof  Long)
635:                    return new Long(-n.longValue());
636:                else if (n instanceof  Float)
637:                    return new Float(-n.floatValue());
638:                else if (n instanceof  Double)
639:                    return new Double(-n.doubleValue());
640:                else { // this should never happen!
641:                    E.warn("ERROR in Inputport.negate called with "
642:                            + n.getClass() + " returning " + n);
643:                    return n;
644:                }
645:            }
646:
647:            /* attempt to read a float or double in Java syntax */
648:            public static Number readFloatingPoint(String s)
649:                    throws NumberFormatException {
650:                if (s.endsWith("f") || s.endsWith("F"))
651:                    return new Float(readFloatingPoint(
652:                            s.substring(0, s.length() - 1)).floatValue());
653:                else if (s.endsWith("d") || s.endsWith("D"))
654:                    return new Double(readFloatingPoint(
655:                            s.substring(0, s.length() - 1)).doubleValue());
656:                else if (s.startsWith("+") && (s.length() > 1))
657:                    return readFloatingPoint(s.substring(1, s.length()));
658:                else if (s.startsWith("-") && (s.length() > 1))
659:                    return negate(readFloatingPoint(s.substring(1, s.length())));
660:                else if (s.startsWith("0") && (s.length() > 1)
661:                        && (Character.isDigit(s.charAt(1))))
662:                    throw (new NumberFormatException(
663:                            "floating point starting with 0 is either an octal or 0.ddd"));
664:                else
665:                    return new Double(s);
666:            }
667:
668:            private Object readHashToken() throws IOException {
669:                int ch;
670:                Object token = null;
671:                switch (ch = in.read()) {
672:                case 't':
673:                case 'T':
674:                    return U.TRUE;
675:                case 'f':
676:                case 'F':
677:                    return U.FALSE;
678:                case 'n': { // #null
679:                    pushChar(ch);
680:                    token = readToken();
681:                    if (token == Symbol.NULL)
682:                        return null;
683:                    else
684:                        E.warn("illegal syntax #" + token + " ignored");
685:                    return readToken();
686:                }
687:                case '(': //  #(...) vector.
688:                    pushChar('(');
689:                    return U.listToVector(read());
690:                case '\\': // #\...
691:                    ch = in.read();
692:                    if (ch == 's' || ch == 'S' || ch == 'n' || ch == 'N') {
693:                        pushChar(ch);
694:                        token = readToken();
695:                        /* at this point token must be one of 
696:                        SPACE, space, NEWLINE, newline, s, S, n, or N
697:                           or we have an error, and we warn the user and ignore the token
698:                         */
699:                        if ((token == SPACE_UC) || (token == SPACE_LC))
700:                            return U.toChar(' ');
701:                        else if ((token == NEWLINE_UC) || (token == NEWLINE_LC))
702:                            return U.toChar('\n');
703:                        else if (token == CHAR_s)
704:                            return U.toChar('s');
705:                        else if (token == CHAR_S)
706:                            return U.toChar('S');
707:                        else if (token == CHAR_n)
708:                            return U.toChar('n');
709:                        else if (token == CHAR_N)
710:                            return U.toChar('N');
711:                        else {
712:                            E.warn("illegal syntax #" + token + " ignored");
713:                            return readToken();
714:                        }
715:                    } else
716:                        return U.toChar((char) ch);
717:                case '\'':
718:                    if (U.useJavaSyntax) {
719:                        ch = in.read();
720:                        Character x;
721:                        if (ch != '\\')
722:                            x = new Character((char) ch);
723:                        else
724:                            x = new Character(escapechar(in.read()));
725:                        ch = in.read();
726:                        if (ch != '\'')
727:                            E.warn("character syntax is #'C', or #\\C, not #'C"
728:                                    + ((char) ch));
729:                        return x;
730:                    }
731:
732:                    // start of hashQuasiString #{ .... #} with hash escapes #[...#]
733:                    // implement by converting to (!#{} A B ... Z)
734:                case '{':
735:                    if (brlsMode) {
736:                        quasiStack.push(InputPort.HQSTR);
737:                        pushToken(HASH_CURLY);
738:                        isPushedChar = true;
739:                        pushedChar = '"';
740:                        return OPEN;
741:                    }
742:                    // Unix #! treated as comment.
743:                case '!':
744:                    return readComment(ch);
745:
746:                    // else fall through to the default
747:                default:
748:                    if (U.useJavaSyntax) {
749:                        E.warn("#" + ((char) ch) + " not recognized, ignored.");
750:                        return readToken();
751:                    } else
752:                        switch (ch) {
753:                        case 'e':
754:                            return U.toNum(U.toInt(readToken()));
755:                        case 'i':
756:                            return U.toNum(U.toReal(readToken()));
757:                        case 'd':
758:                            return readToken();
759:                        case 'b':
760:                        case 'o':
761:                        case 'x':
762:                            return readHashNumber(ch == 'b' ? 2 : ch == 'o' ? 8
763:                                    : 16);
764:                        default:
765:                            E.warn("#" + ((char) ch)
766:                                    + " not recognized, ignored.");
767:                            return readToken();
768:                        }
769:                }
770:            }
771:
772:            private Object readHashNumber(int radix) throws IOException {
773:                synchronized (this ) { // synchonize to potect radix
774:                    this .radix = radix;
775:                    Object token = readToken(); // should be readNumberOrSymbol(...);
776:                    this .radix = 10;
777:                    return token;
778:                }
779:            }
780:
781:            private char escapechar(int c) throws IOException {
782:                switch (c) {
783:                case 'b':
784:                    return '\b';
785:                case 't':
786:                    return '\t';
787:                case 'n':
788:                    return '\n';
789:                case 'f':
790:                    return '\f';
791:                case 'r':
792:                    return '\r';
793:                case '"':
794:                    return '"';
795:                case '\'':
796:                    return '\'';
797:                case '\\':
798:                    return '\\';
799:                case '0':
800:                    return new Character((char) Integer.parseInt((""
801:                            + (char) in.read() + (char) in.read()), 8))
802:                            .charValue();
803:                case 'u':
804:                    return new Character((char) Integer.parseInt((""
805:                            + (char) in.read() + (char) in.read()
806:                            + (char) in.read() + (char) in.read()), 16))
807:                            .charValue();
808:                case '[':
809:                case ']':
810:                case '{':
811:                case '}':
812:                    return (char) c;
813:
814:                default: {
815:                    E
816:                            .warn("Expected a Java escape sequence for a character, found "
817:                                    + ((char) c) + " with ascii code " + c);
818:                    return (char) c;
819:                }
820:                }
821:            }
822:
823:            private boolean isDelimiter(int ch) {
824:                switch (ch) {
825:                case -1:
826:                case '(':
827:                case ')':
828:                case '\'':
829:                case ';':
830:                case ',':
831:                case '"':
832:                case '`':
833:                case ' ':
834:                case '\t':
835:                case '\n':
836:                    return true;
837:                default:
838:                    return Character.isWhitespace((char) ch);
839:                }
840:            }
841:
842:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.