Source Code Cross Referenced for U.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) 


0001:        package jsint;
0002:
0003:        import java.io.*;
0004:        import java.lang.reflect.Array;
0005:
0006:        /**
0007:         A class to hold static utility methods; the name "U" stands for
0008:         "Utility", but is short because it will be used a lot.
0009:         @author Peter Norvig, Copyright 1998, peter@norvig.com, <a href="license.txt">license</a>
0010:         subsequently modified by Jscheme project members
0011:         licensed under zlib licence (see license.txt)
0012:         **/
0013:
0014:        public abstract class U {
0015:
0016:            /** a flag which specifies whether Java (or Scheme) syntax
0017:             * should be used when printing Scheme terms 
0018:             **/
0019:            public static boolean useJavaSyntax = true;
0020:
0021:            //////////////// Constants ////////////////
0022:
0023:            /** Same as Boolean.TRUE. **/
0024:            public static final Boolean TRUE = Boolean.TRUE;
0025:
0026:            /** Same as Boolean.FALSE. **/
0027:            public static final Boolean FALSE = Boolean.FALSE;
0028:
0029:            /** The value to return when a variable is not defined. **/
0030:            public static final Symbol UNDEFINED = Symbol.intern("#!undefined");
0031:
0032:            /** The value to use when a parameter is not supplied to a procedure. **/
0033:            // public static final Pair MISSING = Pair.EMPTY;
0034:            public static final Symbol MISSING = Symbol.intern("#!missing");
0035:            /** An argument list with zero arguments. **/
0036:            public static final Object[] NO_ARGS = new Object[0];
0037:            public static final Object[] EMPTY_ARGS = new Object[] { Pair.EMPTY };
0038:
0039:            //////////////// Conversion Routines ////////////////
0040:
0041:            // The following convert or coerce objects to the right type.
0042:
0043:            /** #f and #null are treated as false **/
0044:            public static boolean isFalse(Object x) {
0045:                return x == null || FALSE.equals(x);
0046:            }
0047:
0048:            /** One argument and used by (and) macro. **/
0049:            public static Object and1(Object x) {
0050:                return isFalse(x) ? FALSE : x;
0051:            }
0052:
0053:            /** Convert Scheme object to boolean. **/
0054:            public static boolean to_bool(Object x) {
0055:                return !(isFalse(x));
0056:            }
0057:
0058:            /** Convert boolean to Boolean. **/
0059:            public static Boolean toBool(boolean x) {
0060:                return x ? TRUE : FALSE;
0061:            }
0062:
0063:            /** Convert Scheme object to Boolean.  **/
0064:            public static Boolean toBool(Object x) {
0065:                return isFalse(x) ? FALSE : TRUE;
0066:            }
0067:
0068:            /** Returns TRUE if x is FALSE or null. **/
0069:            public static Boolean not(Object x) {
0070:                return isFalse(x) ? TRUE : FALSE;
0071:            }
0072:
0073:            /** Converts a Character to a char, or calls error for non-Characters. **/
0074:            public static char to_char(Object x) {
0075:                if (x instanceof  Character)
0076:                    return ((Character) x).charValue();
0077:                else
0078:                    return to_char(E.typeError("char", x));
0079:            }
0080:
0081:            /** Converts a Character to a lowercase char, or calls error for non-Characters. **/
0082:            public static char to_lc_char(Object x) {
0083:                if (x instanceof  Character)
0084:                    return Character.toLowerCase(((Character) x).charValue());
0085:                else
0086:                    return to_lc_char(E.typeError("char", x));
0087:            }
0088:
0089:            /** Number of chars, positive, negative ints to cache. **/
0090:            private final static int NUM_CACHED = 128;
0091:            private final static Character[] cachedCharacters = new Character[128];
0092:
0093:            /** Converts a char to a Character. Caches low-numbered chars. **/
0094:            public static Character toChar(char ch) {
0095:                if (ch < NUM_CACHED) {
0096:                    Character c = cachedCharacters[ch];
0097:                    return (c != null) ? c
0098:                            : (cachedCharacters[ch] = new Character(ch));
0099:                } else
0100:                    return new Character(ch);
0101:            }
0102:
0103:            public static Class toClass(Object c) {
0104:                if (c instanceof  Class)
0105:                    return (Class) c;
0106:                else
0107:                    return Import.classNamed(stringify(c, false));
0108:            }
0109:
0110:            public static Class maybeToClass(Object c) {
0111:                if (c instanceof  Class)
0112:                    return (Class) c;
0113:                else
0114:                    return Import.maybeClassNamed(stringify(c, false));
0115:            }
0116:
0117:            private final static Integer[] cachedPosInts = new Integer[NUM_CACHED];
0118:            private final static Integer[] cachedNegInts = new Integer[NUM_CACHED];
0119:
0120:            /** Convert int to Integer. Caches small ints so that we only ever
0121:             * make one copy of new Integer(0), new Integer(1), etc. **/
0122:            public static Integer toNum(int i) {
0123:                if (i >= 0) {
0124:                    if (i < NUM_CACHED) {
0125:                        Integer in = cachedPosInts[i];
0126:                        return (in != null) ? in
0127:                                : (cachedPosInts[i] = new Integer(i));
0128:                    } else
0129:                        return new Integer(i);
0130:                } else if (i > -NUM_CACHED) {
0131:                    Integer in = cachedNegInts[-i];
0132:                    return (in != null) ? in
0133:                            : (cachedNegInts[-i] = new Integer(i));
0134:                }
0135:                return new Integer(i);
0136:            }
0137:
0138:            /** Convert long to Number, either Integer or Long. **/
0139:            public static Number toNum(long i) {
0140:                if (i <= Integer.MAX_VALUE && i >= Integer.MIN_VALUE)
0141:                    return toNum((int) i);
0142:                else
0143:                    return new Long(i);
0144:            }
0145:
0146:            /** A Double with value 0.0. Defined here so that we need only one. **/
0147:            public static final Double ZERO = new Double(0.0);
0148:
0149:            /** A Double with value 1.0. Defined here so that we need only one. **/
0150:            public static final Double ONE = new Double(1.0);
0151:
0152:            /** Convert double to Double. Caches 0 and 1; makes new for others. **/
0153:            public static Double toNum(double x) {
0154:                return (x == 0.0) ? ZERO : (x == 1.0) ? ONE : new Double(x);
0155:            }
0156:
0157:            /** Converts a Scheme object to a double, or calls error. **/
0158:            public static double toReal(Object x) {
0159:                if (x instanceof  Number)
0160:                    return ((Number) x).doubleValue();
0161:                else
0162:                    return toReal(E.typeError("real number", x));
0163:            }
0164:
0165:            /** Converts a Scheme object to an int, or calls error. **/
0166:            public static int toInt(Object x) {
0167:                try {
0168:                    return ((Number) x).intValue();
0169:                } catch (ClassCastException e) {
0170:                    return toInt(E.typeError("integer", x));
0171:                }
0172:            }
0173:
0174:            /** Converts a Scheme object to an int, return the default
0175:             * if it is not possible to convert the object to an int. **/
0176:            public static int toInt(Object x, int defaultVal) {
0177:                if (x instanceof  Number)
0178:                    return ((Number) x).intValue();
0179:                else
0180:                    return defaultVal;
0181:            }
0182:
0183:            /** Cast a Scheme object to a String, or call error. **/
0184:            public static String toStr(Object x) {
0185:                return (x instanceof  String) ? (String) x : toStr(E.typeError(
0186:                        "string", x));
0187:            }
0188:
0189:            /** Cast a Scheme object to a Scheme symbol, or call error. **/
0190:            public static Symbol toSym(Object x) {
0191:                if (x instanceof  Symbol)
0192:                    return (Symbol) x;
0193:                else
0194:                    return toSym(E.typeError("symbol", x));
0195:            }
0196:
0197:            /** Cast a Scheme object to a procedure, or call error. **/
0198:            public static Procedure toProc(Object x) {
0199:                try {
0200:                    return (Procedure) x;
0201:                } catch (ClassCastException e) {
0202:                    return toProc(E.typeError("procedure", x));
0203:                }
0204:            }
0205:
0206:            /** Check if the argument is a non-empty list. **/
0207:            public static boolean isPair(Object x) {
0208:                return x instanceof  Pair && x != Pair.EMPTY;
0209:            }
0210:
0211:            /** Cast a Scheme object to a Pair (can't be the empty list). **/
0212:            public static Pair toPair(Object x) {
0213:                try {
0214:                    if (x != Pair.EMPTY)
0215:                        return (Pair) x;
0216:                    else
0217:                        return toPair(E.typeError("pair(i.e. non-empty list)",
0218:                                x));
0219:                } catch (ClassCastException e) {
0220:                    return toPair(E.typeError("pair(i.e. non-empty list)", x));
0221:                }
0222:                /*
0223:                if (x != Pair.EMPTY && x instanceof Pair) return (Pair) x;
0224:                else return toPair(E.typeError("pair(i.e. non-empty list)", x));
0225:                 */
0226:            }
0227:
0228:            /** Cast a Scheme object to a Pair or the empty list. **/
0229:            public static Pair toList(Object x) {
0230:                try {
0231:                    return (Pair) x;
0232:                } catch (ClassCastException e) {
0233:                    return toPair(E.typeError("list (i.e. pair or empty)", x));
0234:                }
0235:            }
0236:
0237:            /** Cast a Scheme object to a Scheme input port, which is an InputPort.
0238:             * If the argument is missing, returns Scheme.getInput(). **/
0239:            public static InputPort toInPort(Object x) {
0240:                if (x == MISSING)
0241:                    return Scheme.currentEvaluator().getInput();
0242:                else if (x instanceof  InputPort)
0243:                    return (InputPort) x;
0244:                else
0245:                    return toInPort(E.typeError("input port", x));
0246:            }
0247:
0248:            /** Cast a Scheme object to a Scheme input port, which is a PrintWriter.
0249:             * If the argument is missing, returns Scheme.getOutput(). **/
0250:            public static PrintWriter toOutPort(Object x) {
0251:                if (x == MISSING)
0252:                    return Scheme.currentEvaluator().getOutput();
0253:                else if (x instanceof  PrintWriter)
0254:                    return (PrintWriter) x;
0255:                else
0256:                    return toOutPort(E.typeError("output port", x));
0257:            }
0258:
0259:            //////////////// Basic manipulation Routines ////////////////
0260:
0261:            /** Return the first element of a Pair, or error. **/
0262:            public static Object first(Object x) {
0263:                return toPair(x).first;
0264:            }
0265:
0266:            /** Return the rest of a Pair, or error. **/
0267:            public static Object rest(Object x) {
0268:                return toPair(x).rest;
0269:            }
0270:
0271:            /** Return the second element of a list. **/
0272:            public static Object second(Object x) {
0273:                return toPair(x).second();
0274:            }
0275:
0276:            /** Creates a three element list. **/
0277:            public static Pair list(Object a, Object b, Object c) {
0278:                return new Pair(a, new Pair(b, new Pair(c, Pair.EMPTY)));
0279:            }
0280:
0281:            /** Creates a two element list. **/
0282:            public static Pair list(Object a, Object b) {
0283:                return new Pair(a, new Pair(b, Pair.EMPTY));
0284:            }
0285:
0286:            /** Creates a one element list. **/
0287:            public static Pair list(Object a) {
0288:                return new Pair(a, Pair.EMPTY);
0289:            }
0290:
0291:            /**  Structural equality. **/
0292:            public static boolean equal(Object x, Object y) {
0293:                if (x == null || y == null)
0294:                    return x == y;
0295:                else if (x == Pair.EMPTY || y == Pair.EMPTY)
0296:                    return x == y;
0297:                else if (x instanceof  Object[]) {
0298:                    if (!(y instanceof  Object[]))
0299:                        return false;
0300:                    Object[] xo = (Object[]) x, yo = (Object[]) y;
0301:                    if (xo.length != yo.length)
0302:                        return false;
0303:                    for (int i = xo.length - 1; i >= 0; i--)
0304:                        if (!equal(xo[i], yo[i]))
0305:                            return false;
0306:                    return true;
0307:                } else
0308:                    return (x.equals(y) || eqv(x, y));
0309:            }
0310:
0311:            //   public static boolean eqv(Object x, Object y) {
0312:            //     try {
0313:            //     return x == y 
0314:            //       || (x instanceof Number && y instanceof Number &&
0315:            // 	  ((x instanceof Integer || x instanceof Long || x instanceof Short || x instanceof Byte) &&
0316:            //            (((Number)x).longValue()== ((Number) y).longValue()))
0317:            // 	  || 
0318:            // 	  ((x instanceof Float || x instanceof Double) &&
0319:            //            (((Number)x).doubleValue()== ((Number) y).doubleValue())))
0320:            //       || (x instanceof Character && x.equals(y))
0321:            //       || (x instanceof Boolean && x.equals(y));
0322:            //     } catch (ClassCastException e) { return false; }
0323:            //   }
0324:
0325:            /** Atomic equality. **/
0326:            public static boolean eqv(Object x, Object y) {
0327:                return x == y || x == null && y == null || x != null
0328:                        && y != null
0329:                        && sameAtomicClasses(x.getClass(), y.getClass())
0330:                        && x.equals(y);
0331:            }
0332:
0333:            private static boolean sameAtomicClasses(Class cx, Class cy) {
0334:                return cx == cy
0335:                        && (cx.getSuperclass() == Number.class
0336:                                || cx == Symbol.class || cx == Character.class || cx == Boolean.class);
0337:            }
0338:
0339:            /** Write the object to a port.  If quoted is true, use "str" and #\c,
0340:             * otherwise use str and c. **/
0341:            public static Object write(Object x, PrintWriter port,
0342:                    boolean quoted) {
0343:                port.print(stringify(x, quoted));
0344:                port.flush();
0345:                return x;
0346:            }
0347:
0348:            /** Check that the form has between min and max arguments (exclusive
0349:             * of the first element of the form). If the form has the wrong
0350:             * number of arguments, then complain. **/
0351:            public static boolean checkNargs(int min, int max, int given,
0352:                    Object form) {
0353:                if (given >= min && given <= max)
0354:                    return true;
0355:                else {
0356:                    E.warn("expected "
0357:                            + min
0358:                            + (min == max ? ""
0359:                                    : (max == Integer.MAX_VALUE) ? " or more"
0360:                                            : (" to " + max))
0361:                            + " arguments, but got " + given, form);
0362:                    return false;
0363:                }
0364:            }
0365:
0366:            //////////////// Output ////////////////
0367:
0368:            /** Convert a Scheme object to its printed representation, as a java
0369:             * String. If quoted is true, use "str" and #\c, otherwise use str and
0370:             * c. You need to pass in a StringBuffer that is used to accumulate the
0371:             * results. (If the interface didn't work that way, the system would use
0372:             * lots of little internal StringBuffers.  But note that you can still call
0373:             * <tt>stringify(x)</tt> and a new StringBuffer will be created for you. 
0374:             * If useJavaSyntax is true, then literals are printed using a Java syntax
0375:             **/
0376:
0377:            public static StringBuffer stringify(Object x, boolean quoted,
0378:                    StringBuffer buf) {
0379:                if (x == Pair.EMPTY) {
0380:                    buf.append("()");
0381:                } else if (x == null) {
0382:                    buf.append("#null");
0383:                } else if (x instanceof  Boolean) {
0384:                    if (Boolean.TRUE.equals(x))
0385:                        buf.append("#t");
0386:                    else
0387:                        buf.append("#f");
0388:                } else if (x == TRUE) {
0389:                    buf.append("#t");
0390:                } else if (x == FALSE) {
0391:                    buf.append("#f");
0392:                } else if (x instanceof  Pair) {
0393:                    ((Pair) x).stringifyPair(quoted, buf);
0394:                } else if (x instanceof  Character) {
0395:                    char ch = ((Character) x).charValue();
0396:                    if (ch == '\'')
0397:                        buf.append(quoted ? (useJavaSyntax ? "#'\\\'\'"
0398:                                : "#\\'") : "'");
0399:                    else if (useJavaSyntax) {
0400:                        if (quoted)
0401:                            buf.append("#'");
0402:                        stringifyChar(buf, ch, quoted);
0403:                        if (quoted)
0404:                            buf.append("'");
0405:                    } else {
0406:                        if (quoted)
0407:                            buf.append("#\\");
0408:                        if (quoted && (ch == ' ' || ch == '\n'))
0409:                            buf.append((ch == ' ') ? "space" : "newline");
0410:                        else
0411:                            buf.append(ch);
0412:                    }
0413:                } else if (x instanceof  String) { // string
0414:                    String s = (String) x;
0415:                    if (quoted)
0416:                        buf.append('"');
0417:                    if (useJavaSyntax)
0418:                        for (int i = 0; i < s.length(); i++)
0419:                            stringifyChar(buf, s.charAt(i), quoted);
0420:                    else
0421:                        for (int i = 0; i < s.length(); i++) {
0422:                            if (quoted
0423:                                    && (s.charAt(i) == '"' || s.charAt(i) == '\\'))
0424:                                buf.append('\\');
0425:                            buf.append(s.charAt(i));
0426:                        }
0427:
0428:                    if (quoted)
0429:                        buf.append('"');
0430:                } else if (x instanceof  Object[]) { // vector
0431:                    Object[] v = (Object[]) x;
0432:                    buf.append("#(");
0433:                    for (int i = 0; i < v.length; i++) {
0434:                        stringify(v[i], quoted, buf);
0435:                        if (i != v.length - 1)
0436:                            buf.append(' ');
0437:                    }
0438:                    buf.append(')');
0439:                } else if (x instanceof  Number) { // number
0440:                    buf.append(x);
0441:                    if ((x instanceof  Integer) || (x instanceof  Double)) /* do nothing */
0442:                        ;
0443:                    else if (x instanceof  Byte)
0444:                        buf.append("B");
0445:                    else if (x instanceof  Short)
0446:                        buf.append("S");
0447:                    else if (x instanceof  Long)
0448:                        buf.append("L");
0449:                    else if (x instanceof  Float)
0450:                        buf.append("F");
0451:                } else {
0452:                    buf.append(x);
0453:                }
0454:                return buf;
0455:            }
0456:
0457:            private static void stringifyChar(StringBuffer buf, char ch,
0458:                    boolean quoted) {
0459:                switch (ch) {
0460:                case '\b':
0461:                    buf.append(quoted ? "\\b" : "\b");
0462:                    break;
0463:                case '\t':
0464:                    buf.append(quoted ? "\\t" : "\t");
0465:                    break;
0466:                case '\n':
0467:                    buf.append(quoted ? "\\n" : "\n");
0468:                    break;
0469:                case '\f':
0470:                    buf.append(quoted ? "\\f" : "\f");
0471:                    break;
0472:                case '\r':
0473:                    buf.append(quoted ? "\\r" : "\r");
0474:                    break;
0475:                case '\"':
0476:                    buf.append(quoted ? "\\\"" : "\"");
0477:                    break;
0478:                case '\\':
0479:                    buf.append(quoted ? "\\\\" : "\\");
0480:                    break;
0481:                default:
0482:                    buf.append(ch);
0483:                }
0484:            }
0485:
0486:            /** Convert x to a String giving its external representation. 
0487:             * Strings and characters are quoted. **/
0488:            public static String stringify(Object x) {
0489:                return stringify(x, true);
0490:            }
0491:
0492:            /** Convert x to a String giving its external representation. 
0493:             * Strings and characters are quoted iff <tt>quoted</tt> is true.. **/
0494:            public static String stringify(Object x, boolean quoted) {
0495:                // Handle these cases without consing:
0496:                if (x instanceof  String && !quoted)
0497:                    return ((String) x);
0498:                else if (x instanceof  Symbol)
0499:                    return ((Symbol) x).toString();
0500:                else
0501:                    return stringify(x, quoted, new StringBuffer()).toString();
0502:            }
0503:
0504:            //////////////// Various ////////////////
0505:
0506:            public static String makeString(int size, Object fill) {
0507:                char[] chars = new char[size];
0508:                if (fill != MISSING) {
0509:                    char ch = to_char(fill);
0510:                    for (int i = 0; i < size; i++)
0511:                        chars[i] = ch;
0512:                }
0513:                return new String(chars);
0514:            }
0515:
0516:            public static String stringAppend(Pair args) {
0517:                if (args == Pair.EMPTY)
0518:                    return "";
0519:                StringBuffer result = new StringBuffer();
0520:                while (args != Pair.EMPTY) {
0521:                    if (Scheme.isInterruptable())
0522:                        Scheme.interruptCheck();
0523:                    result.append(stringify(args.first, false));
0524:                    args = toList(args.rest);
0525:                }
0526:                return result.toString();
0527:            }
0528:
0529:            public static Object memberAssoc(Object obj, Object list,
0530:                    boolean member, int eq) {
0531:                boolean found = false;
0532:                while (isPair(list)) {
0533:                    if (Scheme.isInterruptable())
0534:                        Scheme.interruptCheck();
0535:                    Object target = (member) ? first(list) : first(first(list));
0536:                    switch (eq) {
0537:                    case 1:
0538:                        found = (target == obj);
0539:                        break;
0540:                    case 2:
0541:                        found = eqv(target, obj);
0542:                        break;
0543:                    case 3:
0544:                        found = equal(target, obj);
0545:                        break;
0546:                    default:
0547:                        E.warn("Bad option to memberAssoc:" + eq);
0548:                        return FALSE;
0549:                    }
0550:                    if (found)
0551:                        return (member) ? list : first(list);
0552:                    list = rest(list);
0553:                }
0554:                return FALSE;
0555:            }
0556:
0557:            /** Compute (x op arg1 op arg2 op ...), in ints or doubles. **/
0558:            public static Object numCompute(Object x, Pair args, char op) {
0559:                return (x instanceof  Integer) ? numCompute(toInt(x), args, op)
0560:                        : numCompute(toReal(x), args, op);
0561:            }
0562:
0563:            /** Compute (result op arg1 op arg2 op ...). Return the result
0564:             * as an Object, but along the way, use result (a long) as an accumulator of
0565:             * the result so far. For compare ops, returns FALSE for false, and
0566:             * a number for true. **/
0567:            public static Object numCompute(long result, Pair args, char op) {
0568:                for (; isPair(args); args = toList(args.rest)) {
0569:                    if (!(args.first instanceof  Integer))
0570:                        return numCompute((double) result, args, op);
0571:                    long y = toInt(args.first);
0572:                    switch (op) {
0573:                    case '>':
0574:                        if (!(result > y))
0575:                            return FALSE;
0576:                        else
0577:                            result = y;
0578:                        break;
0579:                    case '<':
0580:                        if (!(result < y))
0581:                            return FALSE;
0582:                        else
0583:                            result = y;
0584:                        break;
0585:                    case '=':
0586:                        if (!(result == y))
0587:                            return FALSE;
0588:                        else
0589:                            result = y;
0590:                        break;
0591:                    case 'L':
0592:                        if (!(result <= y))
0593:                            return FALSE;
0594:                        else
0595:                            result = y;
0596:                        break;
0597:                    case 'G':
0598:                        if (!(result >= y))
0599:                            return FALSE;
0600:                        else
0601:                            result = y;
0602:                        break;
0603:                    case 'X':
0604:                        if (y > result)
0605:                            result = y;
0606:                        break; // max
0607:                    case 'N':
0608:                        if (y < result)
0609:                            result = y;
0610:                        break; // min
0611:                    case '+':
0612:                        result += y;
0613:                        break;
0614:                    case '-':
0615:                        result -= y;
0616:                        break;
0617:                    case '*':
0618:                        result *= y;
0619:                        break;
0620:                    case '/':
0621:                        if (result % y == 0)
0622:                            result /= y;
0623:                        else
0624:                            return numCompute((double) result, args, op);
0625:                        break;
0626:                    default:
0627:                        return E
0628:                                .error("internal error: unrecognized op: " + op);
0629:                    }
0630:                    // If overflow ints, move to doubles
0631:                    if (result < Integer.MIN_VALUE
0632:                            || result > Integer.MAX_VALUE)
0633:                        return numCompute((double) result, args, op);
0634:                }
0635:                return toNum(result);
0636:            }
0637:
0638:            /** Compute (result op arg1 op arg2 op ...). Return the result
0639:             * as an Object, but along the way, use result (a double) as an accumulator of
0640:             * the result so far. For compare ops, returns FALSE for false, and
0641:             * a number for true. **/
0642:            public static Object numCompute(double result, Pair args, char op) {
0643:                for (; isPair(args); args = toList(args.rest)) {
0644:                    double y = toReal(args.first);
0645:                    switch (op) {
0646:                    case '>':
0647:                        if (!(result > y))
0648:                            return FALSE;
0649:                        else
0650:                            result = y;
0651:                        break;
0652:                    case '<':
0653:                        if (!(result < y))
0654:                            return FALSE;
0655:                        else
0656:                            result = y;
0657:                        break;
0658:                    case '=':
0659:                        if (!(result == y))
0660:                            return FALSE;
0661:                        else
0662:                            result = y;
0663:                        break;
0664:                    case 'L':
0665:                        if (!(result <= y))
0666:                            return FALSE;
0667:                        else
0668:                            result = y;
0669:                        break;
0670:                    case 'G':
0671:                        if (!(result >= y))
0672:                            return FALSE;
0673:                        else
0674:                            result = y;
0675:                        break;
0676:                    case 'X':
0677:                        if (y > result)
0678:                            result = y;
0679:                        break; // max
0680:                    case 'N':
0681:                        if (y < result)
0682:                            result = y;
0683:                        break; // min
0684:                    case '+':
0685:                        result += y;
0686:                        break;
0687:                    case '-':
0688:                        result -= y;
0689:                        break;
0690:                    case '*':
0691:                        result *= y;
0692:                        break;
0693:                    case '/':
0694:                        result /= y;
0695:                        break;
0696:                    default:
0697:                        return E
0698:                                .error("internal error: unrecognized op: " + op);
0699:                    }
0700:                }
0701:                return toNum(result);
0702:            }
0703:
0704:            public static Object numberToString(Object x, Object y) {
0705:                int base = (y instanceof  Number) ? toInt(y) : 10;
0706:                if (base != 10 && x instanceof  Integer) { // An integer
0707:                    return Long.toString(toInt(x), base);
0708:                } else { // A floating point number
0709:                    return x.toString();
0710:                }
0711:            }
0712:
0713:            public static Object stringToNumber(Object x, Object y) {
0714:                return InputPort.schemeStringToNumber(stringify(x, false),
0715:                        (y instanceof  Number) ? toInt(y) : 10);
0716:            }
0717:
0718:            public static Object stringToList(Object x) {
0719:                Pair result = Pair.EMPTY;
0720:                String str = toStr(x);
0721:                for (int i = str.length() - 1; i >= 0; i--)
0722:                    result = new Pair(toChar(str.charAt(i)), result);
0723:                return result;
0724:            }
0725:
0726:            /** Convert a list of characters to a String. **/
0727:            public static String listToString(Object chars) {
0728:                char[] str = new char[toList(chars).length()];
0729:                for (int i = 0; isPair(chars); i++) {
0730:                    str[i] = to_char(first(chars));
0731:                    chars = rest(chars);
0732:                }
0733:                return new String(str);
0734:            }
0735:
0736:            /** Return <0 if x is alphabetically first, >0 if y is first,
0737:             * 0 if same.  Case insensitive iff ci is true.  Error if not strings. 
0738:             * NOTE: In Java 2, just use String.CompareIgnorecase.  But that
0739:             * method is missing in Java 1.0 and 1.1. **/
0740:            public static int stringCompareIgnoreCase(Object x, Object y) {
0741:                String xs = toStr(x), ys = toStr(y);
0742:                for (int i = 0; i < xs.length(); i++) {
0743:                    int diff = Character.toUpperCase(xs.charAt(i))
0744:                            - Character.toUpperCase(ys.charAt(i));
0745:                    if (diff != 0)
0746:                        return diff;
0747:                }
0748:                return xs.length() - ys.length();
0749:            }
0750:
0751:            public static long gcd(Pair args) {
0752:                return (args.rest == Pair.EMPTY) ? toInt(args.first) : gcd(Math
0753:                        .abs(toInt(args.first)), gcd((Pair) args.rest));
0754:            }
0755:
0756:            static long gcd(long a, long b) {
0757:                return (b == 0) ? a : gcd(b, a % b);
0758:            }
0759:
0760:            static long lcm(Object args) {
0761:                long L = 1, g = 1;
0762:                while (isPair(args)) {
0763:                    long n = Math.abs((long) toInt(first(args)));
0764:                    g = gcd(n, L);
0765:                    L = (g == 0) ? g : (n / g) * L;
0766:                    args = toList(rest(args));
0767:                }
0768:                return L;
0769:            }
0770:
0771:            public static PrintWriter openOutputFile(Object filename) {
0772:                try {
0773:                    return new PrintWriter(new FileWriter(stringify(filename,
0774:                            false)));
0775:                } catch (FileNotFoundException e) {
0776:                    return (PrintWriter) E.error(e.toString());
0777:                } catch (IOException e) {
0778:                    return (PrintWriter) E.error("IOException: " + e);
0779:                }
0780:            }
0781:
0782:            /** Opens a file, resource, or URL. Returns null if unsuccessful.**/
0783:            public static InputPort openInputFile(Object filename) {
0784:                return Scheme.open(toStr(filename));
0785:            }
0786:
0787:            public static Object callWithInputFile(Object filename,
0788:                    Procedure proc) {
0789:                InputPort in = null;
0790:                Object result = null;
0791:                try {
0792:                    in = openInputFile(filename);
0793:                    if (in == null)
0794:                        E.error("could not find '" + filename
0795:                                + "' as a resource URL, or File.");
0796:                    result = proc.apply(list(in));
0797:                } finally {
0798:                    if (in != null)
0799:                        in.close();
0800:                }
0801:                return result;
0802:            }
0803:
0804:            public static Object callWithOutputFile(Object filename,
0805:                    Procedure proc) {
0806:                PrintWriter out = null;
0807:                Object result = null;
0808:                try {
0809:                    out = openOutputFile(filename);
0810:                    result = proc.apply(list(out));
0811:                } finally {
0812:                    if (out != null)
0813:                        out.close();
0814:                }
0815:                return result;
0816:            }
0817:
0818:            /** Return true if x is a proper list: null-terminated and finite.
0819:             * Return false if it is an infinite or non-null-terminated list.
0820:             * Not to be confused with <tt>(or (pair? x) (null? x))</tt>. **/
0821:            public static boolean isList(Object x) {
0822:                Object slow = x, fast = x;
0823:                for (;;) {
0824:                    if (fast == Pair.EMPTY)
0825:                        return true;
0826:                    if (!isPair(fast) || !isPair(slow) || slow == rest(fast))
0827:                        return false;
0828:                    slow = rest(slow);
0829:                    fast = rest(fast);
0830:                    if (fast == Pair.EMPTY)
0831:                        return true;
0832:                    if (!isPair(fast))
0833:                        return false;
0834:                    fast = rest(fast);
0835:                }
0836:            }
0837:
0838:            /* Original not tail recursive version.
0839:            public static Object append(Pair args) {
0840:              if (isPair(args)) 
0841:                if (isPair(args.rest))
0842:            return append(args.first, append(toList(args.rest)));
0843:                else return args.first;
0844:              else return args;
0845:            }
0846:
0847:            public static Object append(Object x, Object y) {
0848:              return isPair(x) ? new Pair(first(x), append(rest(x), y)) : y;
0849:            }
0850:            Original not tail recursive version. */
0851:
0852:            /** args is a list of lists to be appended together. **/
0853:            public static Object append(Object args) {
0854:                if (isPair(args)) {
0855:                    Queue queue = new Queue();
0856:                    while (isPair(rest(args))) {
0857:                        if (Scheme.isInterruptable())
0858:                            Scheme.interruptCheck();
0859:                        for (Object x = first(args); isPair(x); x = rest(x))
0860:                            queue.add(first(x));
0861:                        args = rest(args);
0862:                    }
0863:                    queue.getLast().rest = first(args);
0864:                    return queue.getContent();
0865:                } else
0866:                    return args;
0867:            }
0868:
0869:            /*
0870:              ;;; Append unit tests:
0871:              (define (grow n)
0872:                (if (<= n 0) (list (list 1))
0873:                    (let ((L (grow (- n 1))))
0874:                      (append L L))))
0875:
0876:            ;;; Original version:
0877:            (length (apply append (grow 13)))	; -> 8192
0878:            (length (apply append (grow 14)))	; Stack overflow.
0879:
0880:            ;;; New version:
0881:            (length (apply append (grow 20)))       ; 1048576
0882:
0883:            (assert (eqv? (append 3) 3))
0884:            (assert (eqv? (append '() '() '()) '()))
0885:            (assert (= (append 3 3) 3))
0886:            (assert (equal? (append '(1) '() 2) '(1 . 2)))
0887:            (assert (equal? (append '(1) '() '(2 3)) '(1 2 3)))
0888:            (let ((x '(1 2 3))) (assert (eq? (append '() x) x)))
0889:             */
0890:            /** A continuation exception is a specially marked RuntimeException. **/
0891:            public static Object callCC(Procedure k) {
0892:                ContinuationException cc = new ContinuationException();
0893:                Continuation proc = new Continuation(cc);
0894:                try {
0895:                    return k.apply(list(proc));
0896:                } catch (ContinuationException e) {
0897:                    if (e == cc)
0898:                        return proc.value;
0899:                    else
0900:                        throw e;
0901:                }
0902:            }
0903:
0904:            /** Map proc over a list of lists of args.
0905:             * If result is a passed in as a Pair, then accumulate values there.  
0906:             * Otherwise, just return the empty list. **/
0907:            public static Pair map(Procedure proc, Object args, Pair result) {
0908:                Pair end = result;
0909:                if (rest(args) == Pair.EMPTY) { // One-argument map
0910:                    Object argList = first(args);
0911:                    while (isPair(argList)) {
0912:                        if (Scheme.isInterruptable())
0913:                            Scheme.interruptCheck();
0914:                        Object x = proc.apply(list(first(argList)));
0915:                        if (end != Pair.EMPTY)
0916:                            end = (Pair) (end.rest = list(x));
0917:                        argList = rest(argList);
0918:                    }
0919:                } else { // Multi-argument map
0920:                    Procedure car = toProc(Symbol.CAR.getGlobalValue()), cdr = toProc(Symbol.CDR
0921:                            .getGlobalValue());
0922:                    while (isPair(first(args))) {
0923:                        if (Scheme.isInterruptable())
0924:                            Scheme.interruptCheck();
0925:                        Object x = proc.apply(map(car, list(args), list(TRUE)));
0926:                        if (end != Pair.EMPTY)
0927:                            end = (Pair) (end.rest = list(x));
0928:                        args = map(cdr, list(args), list(TRUE));
0929:                    }
0930:                }
0931:                return ((U.isPair(result)) ? (Pair) rest(result) : result);
0932:            }
0933:
0934:            /** Call the procedure repeatedly nTimes, and return a list of the
0935:             * the last result, the elapsed time, and the memory used. **/
0936:            public static Pair timeCall(Procedure proc, int nTimes) {
0937:                Runtime runtime = Runtime.getRuntime();
0938:                runtime.gc();
0939:                long startTime = System.currentTimeMillis();
0940:                long startMem = runtime.freeMemory();
0941:                Object ans = FALSE;
0942:                for (int i = 0; i < nTimes; i++) {
0943:                    ans = proc.apply(Pair.EMPTY);
0944:                }
0945:                long time = System.currentTimeMillis() - startTime;
0946:                long mem = startMem - runtime.freeMemory();
0947:                return new Pair(ans, list(list(U.toNum(time), Symbol
0948:                        .intern("msec")), list(U.toNum(mem), Symbol
0949:                        .intern("bytes"))));
0950:            }
0951:
0952:            /** Used for debugging. **/
0953:            public static Object p(String x, Object y) {
0954:                if (Symbol.intern("debug").getGlobalValue() == U.TRUE) {
0955:                    Scheme.currentEvaluator().getError().println(
0956:                            x + stringify(y));
0957:                }
0958:                return y;
0959:            }
0960:
0961:            /** KRA 01OCT01: New vector semantics.
0962:                <p>
0963:
0964:                Any Java array is now treated as a Scheme vector.  Type tests
0965:                are inlined to keep the same performance for (vector-length),
0966:                (vector-ref) and (vector-set!) as the old code when accessing
0967:                Object[]'s
0968:             **/
0969:
0970:            /** Cast a Scheme object to a Scheme vector, or call error. **/
0971:            public static Object toVec(Object x) {
0972:                return x instanceof  Object[] ? x : x != null
0973:                        && x.getClass().isArray() ? x : E
0974:                        .typeError("vector", x);
0975:            }
0976:
0977:            public static boolean isVector(Object x) {
0978:                return x instanceof  Object[] || x != null
0979:                        && x.getClass().isArray();
0980:            }
0981:
0982:            public static Object makeVector(Object x) {
0983:                return new Object[U.toInt(x)];
0984:            }
0985:
0986:            public static Object makeVector(Object x, Object fill) {
0987:                Object[] v = new Object[U.toInt(x)];
0988:                for (int i = 0; i < U.toInt(x); i++)
0989:                    v[i] = fill;
0990:                return v;
0991:            }
0992:
0993:            public static Object vectorFill(Object vec, Object fill) {
0994:                for (int i = Array.getLength(vec) - 1; i >= 0; i--)
0995:                    Array.set(vec, i, fill);
0996:                return U.UNDEFINED;
0997:            }
0998:
0999:            public static Object vectorLength(Object x) {
1000:                return x instanceof  Object[] ? U.toNum(((Object[]) x).length)
1001:                        : x != null && x.getClass().isArray() ? U.toNum(Array
1002:                                .getLength(x)) : E.typeError("vector", x);
1003:            }
1004:
1005:            public static Object vectorRef(Object x, Object y) {
1006:                return x instanceof  Object[] ? ((Object[]) x)[U.toInt(y)]
1007:                        : x != null && x.getClass().isArray() ? Array.get(x, U
1008:                                .toInt(y)) : E.typeError("vector", x);
1009:            }
1010:
1011:            public static Object vectorSet(Object x, Object y, Object z) {
1012:                if (x instanceof  Object[])
1013:                    return ((Object[]) x)[U.toInt(y)] = z;
1014:                else if (x != null && x.getClass().isArray()) {
1015:                    Array.set(x, U.toInt(y), z);
1016:                    return z;
1017:                } else
1018:                    return E.typeError("vector", x);
1019:            }
1020:
1021:            public static Pair vectorToList(Object vec) {
1022:                Pair result = Pair.EMPTY;
1023:                for (int i = Array.getLength(vec) - 1; i >= 0; i--) {
1024:                    result = new Pair(Array.get(vec, i), result);
1025:                }
1026:                return result;
1027:            }
1028:
1029:            public static Object[] listToVector(Object x) {
1030:                Pair list = toList(x);
1031:                int L = list.length();
1032:                Object[] result = new Object[L];
1033:                for (int i = 0; isPair(list); i++, list = toList(list.rest))
1034:                    result[i] = first(list);
1035:                return result;
1036:            }
1037:
1038:            public static Object listToArray(Class C, Object x) {
1039:                Pair list = toList(x);
1040:                int L = list.length();
1041:                if (L == 0)
1042:                    return java.lang.reflect.Array.newInstance(C, 0);
1043:                else {
1044:                    Object result = java.lang.reflect.Array.newInstance(C, L);
1045:                    for (int i = 0; isPair(list); i++, list = toList(list.rest)) {
1046:                        java.lang.reflect.Array.set(result, i, first(list));
1047:                    }
1048:                    return result;
1049:                }
1050:            }
1051:
1052:            public static Pair arrayToList(Object x) {
1053:                Pair result = Pair.EMPTY;
1054:                for (int i = Array.getLength(x) - 1; i >= 0; i--) {
1055:                    result = new Pair(Array.get(x, i), result);
1056:                }
1057:                return result;
1058:            }
1059:
1060:            /** R5RS apply as requested by
1061:                "Hoehle, Joerg-Cyril" <Joerg-Cyril.Hoehle@t-systems.com>.
1062:                We splice the last argument onto the end of the argument list.
1063:             **/
1064:            public static Object apply(Procedure p, Pair args) {
1065:                Pair previous = null;
1066:                Pair last = args;
1067:                Pair next;
1068:                while (!(next = ((Pair) last.getRest())).isEmpty()) {
1069:                    if (Scheme.isInterruptable())
1070:                        Scheme.interruptCheck();
1071:                    previous = last;
1072:                    last = next;
1073:                }
1074:                if (previous == null)
1075:                    args = ((Pair) args.getFirst());
1076:                else
1077:                    previous.rest = ((Pair) (last.first)); // KRA 27MAY04: 
1078:                return p.apply(args);
1079:            }
1080:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.