Source Code Cross Referenced for Pnuts.java in  » Scripting » Pnuts » pnuts » lang » 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 » Pnuts » pnuts.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * @(#)Pnuts.java 1.11 05/05/26
0003:         *
0004:         * Copyright (c) 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
0005:         *
0006:         * See the file "LICENSE.txt" for information on usage and redistribution
0007:         * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
0008:         */
0009:        package pnuts.lang;
0010:
0011:        import java.io.BufferedReader;
0012:        import java.io.FileNotFoundException;
0013:        import java.io.IOException;
0014:        import java.io.InputStream;
0015:        import java.io.InputStreamReader;
0016:        import java.io.PrintWriter;
0017:        import java.io.Reader;
0018:        import java.io.Serializable;
0019:        import java.io.StringReader;
0020:        import java.io.Writer;
0021:        import java.net.URL;
0022:        import java.util.Properties;
0023:
0024:        import org.pnuts.util.Stack;
0025:        import org.pnuts.lang.DefaultParseEnv;
0026:        import org.pnuts.lang.PnutsClassLoader;
0027:
0028:        /**
0029:         * This class provides a set of static methods to parse/execute scripts.
0030:         * <p>
0031:         * This object also represents a parsed script. </p>
0032:         * <p>
0033:         * This class is serializable. When a Pnuts object is serialized, the syntax
0034:         * tree is written to the object stream, along with  the attributes such as
0035:         * line, column, and script source.</p>
0036:         * <p>
0037:         * When the object is deserialized, the parsed script is restored using
0038:         * the information read from the object stream.  If the script had been
0039:         * compiled, the script should be recompiled.</p>
0040:         * <p>
0041:         * Serialized objects of this class will not be compatible with
0042:         * future releases. The current serialization support is
0043:         * appropriate for short term storage or RMI between applications running
0044:         * the same version of Swing. </p>
0045:         */
0046:        public class Pnuts implements  Executable, Serializable {
0047:
0048:            //    final static boolean DEBUG = true;
0049:
0050:            static final long serialVersionUID = 3808410089278038986L;
0051:
0052:            /**
0053:             * The version number
0054:             */
0055:            public final static String pnuts_version = "1.2.1";
0056:
0057:            /**
0058:             * "prompt" string for the command shell
0059:             */
0060:            public static String prompt = "> ";
0061:
0062:            static String compiledClassPrefix;
0063:
0064:            static Properties defaultSettings;
0065:
0066:            private static Stack freeParsers = new Stack();
0067:
0068:            private static int java2 = 0;
0069:
0070:            static String getCompiledClassPrefix() {
0071:                if (compiledClassPrefix == null) {
0072:                    try {
0073:                        compiledClassPrefix = Runtime
0074:                                .getProperty("pnuts.compiled.script.prefix");
0075:                        if (compiledClassPrefix == null) {
0076:                            compiledClassPrefix = "";
0077:                        } else if (!"".equals(compiledClassPrefix)
0078:                                && !compiledClassPrefix.endsWith(".")) {
0079:                            compiledClassPrefix = compiledClassPrefix + ".";
0080:                        }
0081:                    } catch (Throwable t) {
0082:                    }
0083:                }
0084:                return compiledClassPrefix;
0085:            }
0086:
0087:            static PnutsParser getParser(Reader reader) {
0088:                synchronized (freeParsers) {
0089:                    if (freeParsers.size() > 0) {
0090:                        PnutsParser parser = (PnutsParser) freeParsers.pop();
0091:                        parser.ReInit(reader);
0092:                        return parser;
0093:                    } else {
0094:                        return new PnutsParser(reader);
0095:                    }
0096:                }
0097:            }
0098:
0099:            static void recycleParser(PnutsParser parser) {
0100:                synchronized (freeParsers) {
0101:                    if (freeParsers.size() < 3) {
0102:                        freeParsers.push(parser);
0103:                    }
0104:                }
0105:            }
0106:
0107:            /**
0108:             * Checks if the runtime environment supports J2SE.
0109:             * 
0110:             * @return true if the runtime environment supports J2SE
0111:             */
0112:            final public static boolean isJava2() {
0113:                if (java2 == 0) {
0114:                    try {
0115:                        if (Runtime.getProperty("pnuts.jdk11.compatible") != null) {
0116:                            java2 = -1;
0117:                        } else {
0118:                            Class.forName("java.lang.Package");
0119:                            java2 = 1;
0120:                        }
0121:                    } catch (Throwable t) {
0122:                        java2 = -1;
0123:                    }
0124:                }
0125:                if (java2 == 1) {
0126:                    return true;
0127:                } else {
0128:                    return false;
0129:                }
0130:            }
0131:
0132:            /**
0133:             * Sets properties that affect the behavior of Pnuts interpreter/compiler.
0134:             * 
0135:             * This method should be called before the classes that read the default
0136:             * settings, such as pnuts.lang.Configuration and pnuts.lang.PnutsImpl.
0137:             * Once those classes are loaded, this method call has no effect.
0138:             * 
0139:             * <pre>
0140:             * Pnuts.setDefaults(properties);
0141:             * Context c = new Context(); // this line should not precede setDefaults() call.
0142:             * 
0143:             * </pre>
0144:             * 
0145:             * @param properties
0146:             *            the properties that override the system properties.
0147:             */
0148:            public static void setDefaults(Properties properties) {
0149:                defaultSettings = properties;
0150:            }
0151:
0152:            /**
0153:             * Gets the properties previously set by setDefaults() method.
0154:             * 
0155:             * @return the default setting that affects the behavior of Pnuts
0156:             *         interpreter/compiler.
0157:             */
0158:            public static Properties getDefaults() {
0159:                return defaultSettings;
0160:            }
0161:
0162:            /**
0163:             * Loads the class by the following order.
0164:             * <OL>
0165:             * <LI>A class loader associated with Pnuts context.
0166:             * <LI>The class loader associated with the current Thread (J2SE).
0167:             * <LI>The class loader by which Pnuts classes are loaded.
0168:             * </OL>
0169:             * 
0170:             * @param name
0171:             *            the class name to be loaded
0172:             * @param context
0173:             *            the context in which the class is loaded
0174:             * @return the loaded class. Note that it is not initialized.
0175:             */
0176:            public final static Class loadClass(String name, Context context)
0177:                    throws ClassNotFoundException {
0178:                ClassLoader classLoader = context.getClassLoader();
0179:                if (classLoader != null) {
0180:                    try {
0181:                        return classLoader.loadClass(name);
0182:                    } catch (ClassNotFoundException e1) {
0183:                    } catch (LinkageError e2) {
0184:                    }
0185:                }
0186:                if (isJava2()) {
0187:                    ClassLoader ccl = Thread.currentThread()
0188:                            .getContextClassLoader();
0189:                    if (ccl != null && ccl != classLoader) {
0190:                        try {
0191:                            return ccl.loadClass(name);
0192:                        } catch (ClassNotFoundException e1) {
0193:                        } catch (LinkageError e2) {
0194:                        }
0195:                    }
0196:                }
0197:                return Class.forName(name);
0198:            }
0199:
0200:            /**
0201:             * Get the resource URL.
0202:             * 
0203:             * @param s
0204:             *            the resource name
0205:             * @param context
0206:             *            the context in which the resource is read
0207:             */
0208:            public final static URL getResource(String s, Context context) {
0209:                ClassLoader classLoader = context.getClassLoader();
0210:                if (classLoader != null) {
0211:                    URL url = classLoader.getResource(s);
0212:                    if (url != null) {
0213:                        return url;
0214:                    }
0215:                }
0216:                if (isJava2()) {
0217:                    ClassLoader ccl = Thread.currentThread()
0218:                            .getContextClassLoader();
0219:                    if (ccl != null) {
0220:                        URL url = ccl.getResource(s);
0221:                        if (url != null) {
0222:                            return url;
0223:                        }
0224:                    }
0225:                    return Pnuts.class.getResource(s);
0226:                } else {
0227:                    return ClassLoader.getSystemResource(s);
0228:                }
0229:            }
0230:
0231:            /**
0232:             * Sets a "prompt" string for the command shell
0233:             */
0234:            public static void setPrompt(String str) {
0235:                prompt = str;
0236:            }
0237:
0238:            /**
0239:             * Sets the verbose mode
0240:             * 
0241:             * @deprecated replaced by Context.setVerbose()
0242:             */
0243:            public static void setVerbose(boolean b) {
0244:                Context.defaultVerboseMode = b;
0245:            }
0246:
0247:            /**
0248:             * Check the current verbose mode
0249:             * 
0250:             * @return the current verbose mode
0251:             * 
0252:             * @deprecated replaced by Context.isVerbose()
0253:             */
0254:            public static boolean isVerbose() {
0255:                return Context.defaultVerboseMode;
0256:            }
0257:
0258:            /**
0259:             * Returns the string representation of an object. When the object is a
0260:             * number, a character, a boolean, or a string, it can be reconstructed by
0261:             * eval() function.
0262:             * 
0263:             * @param obj
0264:             *            the object.
0265:             * @return the string representation of the object
0266:             */
0267:            public static String format(Object obj) {
0268:                return Runtime.format(obj, 64);
0269:            }
0270:
0271:            /**
0272:             * Get the value of a global variable
0273:             * 
0274:             * @param str
0275:             *            the name of the global variable
0276:             * @return the value of the global variable <em>str</em>
0277:             * 
0278:             * @deprecated replaced by Context.getCurrentPackage().get(str.intern())
0279:             */
0280:            public static Object get(String str) {
0281:                return get(str, "");
0282:            }
0283:
0284:            /**
0285:             * Gets a global variable.
0286:             * 
0287:             * @param str
0288:             *            the name of the variable
0289:             * @param pkg
0290:             *            the package where the variable is defined
0291:             * @return the value of a variable "str" in the package "pkg"
0292:             * 
0293:             * @deprecated replaced by Package.getPackage(pkg, null).get(str)
0294:             */
0295:            public static Object get(String str, String pkg) {
0296:                Package p = Package.find(pkg);
0297:                if (p != null) {
0298:                    return p.get(str.intern());
0299:                } else {
0300:                    return null;
0301:                }
0302:            }
0303:
0304:            /**
0305:             * set a value "val" to a global variable "str"
0306:             * 
0307:             * @deprecated replaced by context.getCurrentPackage().set(str.intern(),
0308:             *             val)
0309:             */
0310:            public static void set(String str, Object val) {
0311:                set(str, val, "");
0312:            }
0313:
0314:            /**
0315:             * Set a value "val" to a variable "str" in package "pkg"
0316:             * 
0317:             * @param str
0318:             * @param val
0319:             * @param pkg
0320:             * 
0321:             * @deprecated replaced by Package.getPackage(pkg, null).set(str, val)
0322:             */
0323:            public static void set(String str, Object val, String pkg) {
0324:                if (str.length() > 0
0325:                        && Character.isJavaIdentifierStart(str.charAt(0))) {
0326:                    Package p = Package.find(pkg);
0327:                    if (p != null) {
0328:                        p.set(str.intern(), val);
0329:                    } else {
0330:                        throw new IllegalArgumentException(Runtime.getMessage(
0331:                                "pnuts.lang.pnuts", "package.notFound",
0332:                                new Object[] { pkg }));
0333:                    }
0334:                } else {
0335:                    throw new IllegalArgumentException(Runtime.getMessage(
0336:                            "pnuts.lang.pnuts", "illegal.symbolForId",
0337:                            Runtime.NO_PARAM));
0338:                }
0339:            }
0340:
0341:            /**
0342:             * Evaluates "str" in "context"
0343:             * 
0344:             * @param expr
0345:             *            the expression to be evaluated
0346:             * @param context
0347:             *            the context in which the expression is evaluated
0348:             * @return the result of the evaluation
0349:             */
0350:            public static Object eval(String expr, Context context) {
0351:                return context.pnutsImpl.eval(expr, context);
0352:            }
0353:
0354:            /**
0355:             * Loads a local script "file" in "context"
0356:             * 
0357:             * @param file
0358:             *            the script file to be loaded.
0359:             * @param context
0360:             *            the context in which the file is loaded.
0361:             */
0362:            public static Object loadFile(String file, Context context)
0363:                    throws FileNotFoundException {
0364:                Thread th = Thread.currentThread();
0365:                ClassLoader ccl = th.getContextClassLoader();
0366:                try {
0367:                    return context.pnutsImpl.loadFile(file, context);
0368:                } finally {
0369:                    th.setContextClassLoader(ccl);
0370:                }
0371:            }
0372:
0373:            /**
0374:             * Loads a script "file" in "context"
0375:             * 
0376:             * @param name
0377:             *            the name of the script to be loaded
0378:             * @param context
0379:             *            the context in which the script is loaded.
0380:             */
0381:            public static Object load(String name, Context context)
0382:                    throws FileNotFoundException {
0383:                Thread th = Thread.currentThread();
0384:                ClassLoader ccl = th.getContextClassLoader();
0385:                String file = name;
0386:                if (!name.endsWith(".pnut")) {
0387:                    file = name + ".pnut";
0388:
0389:                    final Executable rt = Runtime.getCompiledScript(name,
0390:                            context);
0391:
0392:                    if (rt != null) {
0393:                        if (context.verbose) {
0394:                            System.out.println("[loading "
0395:                                    + Pnuts.format(rt.getClass()) + "]");
0396:                        }
0397:                        int depth = enter(context);
0398:                        context.pushFile(rt);
0399:                        boolean completed = false;
0400:                        Context old = Runtime.getThreadContext();
0401:                        try {
0402:                            context.provide(name);
0403:                            Runtime.setThreadContext(context);
0404:                            Object ret = rt.run(context);
0405:                            completed = true;
0406:                            return ret;
0407:                        } catch (Jump jump) {
0408:                            completed = true;
0409:                            return jump.getValue();
0410:                        } finally {
0411:                            if (!completed) {
0412:                                context.revoke(name);
0413:                            }
0414:                            th.setContextClassLoader(ccl);
0415:                            context.popFile();
0416:                            context.depth = depth;
0417:                            Runtime.setThreadContext(old);
0418:                        }
0419:                    }
0420:                }
0421:                try {
0422:                    return context.pnutsImpl.load(file, context);
0423:                } finally {
0424:                    th.setContextClassLoader(ccl);
0425:                }
0426:            }
0427:
0428:            /**
0429:             * Loads a script specifed as a URL.
0430:             * 
0431:             * @param url
0432:             *            the URL
0433:             * @param context
0434:             *            the context in which the script is loaded.
0435:             */
0436:            public static Object load(URL url, Context context) {
0437:                Thread th = Thread.currentThread();
0438:                ClassLoader ccl = th.getContextClassLoader();
0439:                try {
0440:                    return context.pnutsImpl.load(url, context);
0441:                } finally {
0442:                    th.setContextClassLoader(ccl);
0443:                }
0444:            }
0445:
0446:            /**
0447:             * Loads a script from InputStream "in" in "context"
0448:             * 
0449:             * @param in
0450:             *            the input stream from which the script can be read.
0451:             * @param context
0452:             *            the context in which the script is loaded.
0453:             */
0454:            public static Object load(InputStream in, Context context) {
0455:                return load(Runtime.getScriptReader(in, context), context);
0456:            }
0457:
0458:            /**
0459:             * Load a script from an InputStream in the specified Context.
0460:             * 
0461:             * @param in
0462:             *            an InputStream from which the interpreter reads an input
0463:             * @param interactive
0464:             *            <ul>
0465:             *            <li>When "interactive" is true, the greeting message, the
0466:             *            prompt, and the results of evaluations are displayed. When an
0467:             *            exception is thrown and not caught by any exception handler,
0468:             *            it is caught at the top level of the interpreter, display an
0469:             *            error message, and resume the interactive session. If the
0470:             *            exception is caught by a handler that is registered at the top
0471:             *            level, the result of the handler becomes the return value of
0472:             *            the last expression.
0473:             * 
0474:             * <li>When "interactive" is false, exceptions are caught at the top level
0475:             * of the interpreter and exits this function. If the exception thrown is
0476:             * caught by a handler that is registered at the top level, the result of
0477:             * the handler becomes the return value of this method.
0478:             * </ul>
0479:             * @param context
0480:             *            a Context in which the interpretation is taken place.
0481:             * @return the result of the last expression
0482:             */
0483:            public static Object load(InputStream in, boolean interactive,
0484:                    Context context) {
0485:                return load(Runtime.getScriptReader(in, context), interactive,
0486:                        context);
0487:            }
0488:
0489:            /**
0490:             * This method loads a script
0491:             * 
0492:             * @param reader
0493:             *            the Reader from which the script is loaded
0494:             * @param context
0495:             *            the context in which the script is loaded
0496:             * @return the result of the last expression
0497:             */
0498:            public static Object load(Reader reader, Context context) {
0499:                PnutsParser parser = getParser(reader);
0500:                synchronized (context.namespaceRefreshed) {
0501:                    context.namespaceRefreshed[0] = false;
0502:                }
0503:                Thread th = Thread.currentThread();
0504:                ClassLoader ccl = th.getContextClassLoader();
0505:
0506:                int depth = enter(context);
0507:                Object value = null;
0508:                try {
0509:                    while (true) {
0510:                        try {
0511:                            SimpleNode start = parser.Start(DefaultParseEnv
0512:                                    .getInstance());
0513:                            switch (start.toplevel) {
0514:                            case -1:
0515:                                start.toplevel = 0;
0516:                                return value;
0517:                            case 0:
0518:                                reset(parser);
0519:                                break;
0520:                            case 1:
0521:                                value = context.pnutsImpl
0522:                                        .accept(start, context);
0523:                                if (start.toplevel == -1) {
0524:                                    return start.value;
0525:                                }
0526:                                reset(parser);
0527:                                context.onExit(value);
0528:                                break;
0529:                            }
0530:                        } catch (ParseException p) {
0531:                            Runtime.checkException(context, p);
0532:                        } catch (Escape esc) {
0533:                            reset(parser);
0534:                            throw esc;
0535:                        } catch (Throwable t) {
0536:                            if (t instanceof  PnutsException) {
0537:                                throw (PnutsException) t;
0538:                            } else if (t instanceof  ThreadDeath) {
0539:                                throw (ThreadDeath) t;
0540:                            } else {
0541:                                throw new PnutsException(t, context);
0542:                            }
0543:                        }
0544:                    }
0545:                } catch (Escape esc) {
0546:                    context.onExit(value);
0547:                    flush(context);
0548:                    return esc.getValue();
0549:                } catch (PnutsException pe) {
0550:                    context.onError(pe);
0551:                    throw pe;
0552:                } catch (Throwable t) {
0553:                    PnutsException e = new PnutsException(t, context);
0554:                    context.onError(t);
0555:                    throw e;
0556:                } finally {
0557:                    th.setContextClassLoader(ccl);
0558:                    Executable hook = context.exitHook;
0559:                    if (hook != null) {
0560:                        hook.run(context);
0561:                    }
0562:                    context.depth = depth;
0563:                    recycleParser(parser);
0564:                }
0565:            }
0566:
0567:            /**
0568:             * all public entry points must go through this to ensure the correct
0569:             * behavior of evalDepth method.
0570:             * 
0571:             * @param context
0572:             *            the context in which the execution is taken place.
0573:             * @return the last value of context.depth.
0574:             */
0575:            static int enter(Context context) {
0576:                int depth = context.depth;
0577:                if (depth < 0x7fffffff) {
0578:                    context.depth++;
0579:                }
0580:                return depth;
0581:            }
0582:
0583:            /**
0584:             * Get the depth of evaluation.
0585:             * 
0586:             * This value increases when load(), loadFile(), or eval() is called.
0587:             * 
0588:             * @param context
0589:             *            the context of the evaluation.
0590:             */
0591:            public static int evalDepth(Context context) {
0592:                return context.depth;
0593:            }
0594:
0595:            /**
0596:             * This method loads a script
0597:             * 
0598:             * @param reader
0599:             *            the Reader from which the script is loaded
0600:             * @param interactive
0601:             *            specifies if the execution is in interactive mode.
0602:             * @param context
0603:             *            the context in which the script is loaded
0604:             * @return the result of the last expression
0605:             */
0606:            public static Object load(Reader reader, boolean interactive,
0607:                    Context context) {
0608:                if (interactive) {
0609:                    return session(reader, context);
0610:                } else {
0611:                    return load(reader, context);
0612:                }
0613:            }
0614:
0615:            /**
0616:             * Parses a script from InputStream and return a Pnuts object
0617:             * 
0618:             * @return the Pnuts object including a parsed syntax tree
0619:             * @param in
0620:             *            the InputStream
0621:             * @deprecated replaced by parse(Reader)
0622:             */
0623:            public static Pnuts parse(InputStream in) throws ParseException,
0624:                    IOException {
0625:                return parse(new InputStreamReader(in));
0626:            }
0627:
0628:            /**
0629:             * parse a script from Reader and return a Pnuts object
0630:             * 
0631:             * @return the Pnuts object including a parsed syntax tree
0632:             * @param reader
0633:             *            the Reader
0634:             * @since Pnuts 1.0beta3
0635:             */
0636:            public static Pnuts parse(Reader reader) throws ParseException,
0637:                    IOException {
0638:                return parse(reader, DefaultParseEnv.getInstance());
0639:            }
0640:
0641:            /**
0642:             * parse a script from Reader and return a Pnuts object
0643:             */
0644:            public static Pnuts parse(Reader reader, ParseEnvironment env)
0645:                    throws ParseException, IOException {
0646:                PnutsParser parser = getParser(reader);
0647:                Pnuts p = new Pnuts();
0648:                try {
0649:                    p.startNodes = parser.StartSet(env);
0650:                } catch (ParseException e) {
0651:                    env.handleParseException(e);
0652:                } finally {
0653:                    recycleParser(parser);
0654:                }
0655:                return p;
0656:            }
0657:
0658:            /**
0659:             * parse a script from Reader and return a Pnuts object
0660:             * 
0661:             * @return the Pnuts object including a parsed syntax tree
0662:             * @param reader
0663:             *            the Reader
0664:             * @param scriptSource
0665:             *            the script source
0666:             */
0667:            public static Pnuts parse(Reader reader, Object scriptSource,
0668:                    Context context) throws IOException {
0669:                return parse(reader, scriptSource, context, DefaultParseEnv
0670:                        .getInstance(scriptSource));
0671:            }
0672:
0673:            /**
0674:             * parse a script from Reader and return a Pnuts object
0675:             * 
0676:             * @return the Pnuts object including a parsed syntax tree
0677:             * @param reader
0678:             *            the Reader
0679:             * @param scriptSource
0680:             *            the script source
0681:             * @param env
0682:             */
0683:            public static Pnuts parse(Reader reader, Object scriptSource,
0684:                    Context context, ParseEnvironment env) throws IOException {
0685:                Function frame = context.frame;
0686:                context.frame = null;
0687:
0688:                PnutsParser parser = getParser(reader);
0689:                try {
0690:                    Pnuts p = new Pnuts();
0691:                    p.startNodes = parser.StartSet(env);
0692:                    p.setScriptSource(scriptSource);
0693:                    return p;
0694:                } catch (ParseException e) {
0695:                    throw new PnutsException(e, context);
0696:                } finally {
0697:                    context.frame = frame;
0698:                    recycleParser(parser);
0699:                }
0700:            }
0701:
0702:            /**
0703:             * Parses a script and return a Pnuts object
0704:             * 
0705:             * @return the Pnuts object including a parsed syntax tree
0706:             * @param expr
0707:             *            the script
0708:             */
0709:            public static Pnuts parse(String expr) throws ParseException {
0710:                try {
0711:                    Pnuts p = parse(new StringReader(expr));
0712:                    p.scriptSource = expr;
0713:                    return p;
0714:                } catch (IOException e) {
0715:                    throw new InternalError();
0716:                }
0717:            }
0718:
0719:            /**
0720:             * Loads a script "file" only if the script has not been read. It is
0721:             * guaranteed that the script runs at most once in this context.
0722:             * 
0723:             * @param file
0724:             *            the script file, which must be an intern'ed String.
0725:             * @param context
0726:             *            the context in which the script is loaded
0727:             */
0728:            public static void require(String file, Context context)
0729:                    throws FileNotFoundException {
0730:                require(file, context, false);
0731:            }
0732:
0733:            public static void require(String file, Context context,
0734:                    boolean checkForUpdate) throws FileNotFoundException {
0735:                if (file.endsWith(".pnut")) {
0736:                    file = file.substring(0, file.length() - 5);
0737:                }
0738:                file = file.intern();
0739:                context.require(file, checkForUpdate);
0740:            }
0741:
0742:            static Object session(Reader r, Context context) {
0743:                BufferedReader br = new BufferedReader(r);
0744:                StringBuffer sbuf = new StringBuffer();
0745:                ParseEnvironment parseEnv = DefaultParseEnv.getInstance();
0746:                Object value = null;
0747:                while (true) {
0748:                    PnutsParser parser = null;
0749:                    try {
0750:                        PrintWriter term = null;
0751:                        flush(context);
0752:
0753:                        term = context.getTerminalWriter();
0754:                        if (term != null) {
0755:                            term.print(prompt);
0756:                            term.flush();
0757:                        }
0758:                        String line = br.readLine();
0759:                        if (line == null) {
0760:                            return value;
0761:                        }
0762:                        sbuf.append(line);
0763:                        StringReader sr = new StringReader(sbuf.toString());
0764:                        parser = getParser(sr);
0765:                        try {
0766:                            SimpleNode start = parser.Start(parseEnv);
0767:                            sbuf.setLength(0);
0768:                            try {
0769:                                value = context.pnutsImpl
0770:                                        .accept(start, context);
0771:                            } catch (Jump jump) {
0772:                                value = jump.getValue();
0773:                            } finally {
0774:                                context.onExit(value);
0775:                            }
0776:
0777:                            try {
0778:                                term.println(context.getConfiguration()
0779:                                        .formatObject(value));
0780:                                term.flush();
0781:                            } catch (ThreadDeath td) {
0782:                                throw td;
0783:                            } catch (Throwable t) {
0784:                                Runtime.checkException(context, t);
0785:                            }
0786:
0787:                        } catch (ParseException pe) {
0788:                            Token t = pe.currentToken;
0789:                            Token t2 = t.next;
0790:                            while (t != null) {
0791:                                t2 = t;
0792:                                t = t.next;
0793:                            }
0794:                            if (t2.kind != PnutsParserConstants.EOF) {
0795:                                throw pe;
0796:                            }
0797:                            sbuf.append('\n');
0798:                        } finally {
0799:                            recycleParser(parser);
0800:                        }
0801:                    } catch (ParseException p) {
0802:                        sbuf.setLength(0);
0803:                        if (context.depth > 1) {
0804:                            Runtime.checkException(context, p);
0805:                        } else {
0806:                            int line = context.beginLine;
0807:                            try {
0808:                                context.beginLine = p.currentToken.next.beginLine;
0809:                                Runtime.checkException(context, p);
0810:                            } catch (Jump j) {
0811:                                value = j.getValue();
0812:                                PrintWriter term = context.getTerminalWriter();
0813:                                if (term != null) {
0814:                                    term.println(value);
0815:                                    term.flush();
0816:                                }
0817:                            } catch (PnutsException t) {
0818:                                Runtime.printError(t, context);
0819:                            } finally {
0820:                                context.beginLine = line;
0821:                            }
0822:                            reset(parser);
0823:                            recover(context);
0824:                            value = null;
0825:                        }
0826:                    } catch (Escape esc) {
0827:                        reset(parser);
0828:                        context.onExit(value);
0829:                        return esc.getValue();
0830:                    } catch (Throwable t) {
0831:                        if (context.depth > 1) {
0832:                            if (t instanceof  PnutsException) {
0833:                                throw (PnutsException) t;
0834:                            } else if (t instanceof  ThreadDeath) {
0835:                                throw (ThreadDeath) t;
0836:                            } else {
0837:                                throw new PnutsException(t, context);
0838:                            }
0839:                        }
0840:                        if (t instanceof  ThreadDeath) {
0841:                            return null;
0842:                        }
0843:                        Runtime.printError(t, context);
0844:                        if (parser == null) {
0845:                            break;
0846:                        }
0847:                        reset(parser);
0848:                        recover(context);
0849:                        value = null;
0850:                    }
0851:                }
0852:                return null;
0853:            }
0854:
0855:            private static void reset(PnutsParser parser) {
0856:                parser.jjtree.reset();
0857:            }
0858:
0859:            private static void recover(Context context) {
0860:                context.resetStackFrame();
0861:                context.loadingResource = null;
0862:            }
0863:
0864:            private static void flush(Context context) {
0865:                PrintWriter out = context.getWriter();
0866:                if (out != null) {
0867:                    out.flush();
0868:                }
0869:            }
0870:
0871:            /**
0872:             * Create a classloader that can compile scripted classes
0873:             * with the current thread's context classloader as its parent classloader
0874:             *
0875:             * @param context the context in which scripts are compiled
0876:             * @return the classloader
0877:             */
0878:            public static ClassLoader createClassLoader(Context context) {
0879:                return createClassLoader(context, Thread.currentThread()
0880:                        .getContextClassLoader());
0881:            }
0882:
0883:            /**
0884:             * Create a classloader that can compile scripted classes
0885:             *
0886:             * @param context the context in which scripts are compiled
0887:             * @param parent the parent classloader
0888:             * @return the classloader
0889:             */
0890:            public static ClassLoader createClassLoader(Context context,
0891:                    ClassLoader parent) {
0892:                return new PnutsClassLoader(parent, context);
0893:            }
0894:
0895:            /**
0896:             * Parsed scripts
0897:             * 
0898:             * @serial
0899:             */
0900:            protected SimpleNode startNodes = null;
0901:
0902:            /**
0903:             * The script source, from where the script came. It is usually a URL
0904:             * object, but not limitted to. If this variable is not null, error message
0905:             * would include the positional information such as the line number and the
0906:             * file name.
0907:             */
0908:            protected Object scriptSource;
0909:
0910:            protected Pnuts() {
0911:            }
0912:
0913:            /**
0914:             * Executes a Pnuts object with the specified Context
0915:             * 
0916:             * @param context
0917:             *            the Context
0918:             * @return the result
0919:             */
0920:            public Object run(Context context) {
0921:                Thread th = Thread.currentThread();
0922:                ClassLoader ccl = th.getContextClassLoader();
0923:                int depth = enter(context);
0924:                context.pushFile(scriptSource);
0925:                Function frame = context.frame;
0926:                context.frame = null;
0927:                try {
0928:                    return accept(context);
0929:                } finally {
0930:                    th.setContextClassLoader(ccl);
0931:                    context.depth = depth;
0932:                    context.frame = frame;
0933:                    context.popFile();
0934:                }
0935:            }
0936:
0937:            /**
0938:             * Associates a script source with this parsed (compiled) expression.
0939:             * 
0940:             * @param src
0941:             *            the script source to be associated with.
0942:             */
0943:            public void setScriptSource(Object src) {
0944:                this .scriptSource = src;
0945:            }
0946:
0947:            /**
0948:             * Gets the script source associated with this parsed (compiled) expression
0949:             * 
0950:             * @return the script source to be associated with.
0951:             */
0952:            public Object getScriptSource() {
0953:                return this .scriptSource;
0954:            }
0955:
0956:            /**
0957:             * traverse the parsed tree with the specified Visitor and Context
0958:             * 
0959:             * @param context
0960:             *            the Context
0961:             * @return the result
0962:             * @since Pnuts 1.0beta3
0963:             */
0964:            public Object accept(Visitor visitor, Context context) {
0965:                int depth = enter(context);
0966:                Object value = null;
0967:                Context old = Runtime.getThreadContext();
0968:                Runtime.setThreadContext(context);
0969:                try {
0970:                    value = startNodes.accept(visitor, context);
0971:                    context.onExit(value);
0972:                    return value;
0973:                } catch (Escape esc) {
0974:                    context.onExit(value);
0975:                    Object val = esc.getValue();
0976:                    flush(context);
0977:                    return val;
0978:                } catch (PnutsException pe) {
0979:                    context.onError(pe);
0980:                    throw pe;
0981:                } catch (Throwable t) {
0982:                    PnutsException e = new PnutsException(t, context);
0983:                    context.onError(t);
0984:                    throw e;
0985:                } finally {
0986:                    context.depth = depth;
0987:                    Runtime.setThreadContext(old);
0988:                }
0989:            }
0990:
0991:            /**
0992:             * Obtain the script code from a parsed object
0993:             * 
0994:             * @return the script code
0995:             */
0996:            public String unparse() {
0997:                return Runtime.unparse(startNodes, null);
0998:            }
0999:
1000:            /**
1001:             * Obtain the script code from a parsed object and write it to the specified
1002:             * Writer.
1003:             * 
1004:             * @param writer
1005:             *            the Writer to which the script code is written
1006:             */
1007:            public void unparse(Writer writer) throws IOException {
1008:                writer.write(unparse());
1009:            }
1010:
1011:            /**
1012:             * Executes the parsed script
1013:             * 
1014:             * @param context
1015:             *            the context in which the script is executed
1016:             * @return the result
1017:             */
1018:            protected Object accept(Context context) {
1019:                Object value = null;
1020:                Thread th = Thread.currentThread();
1021:                ClassLoader ccl = th.getContextClassLoader();
1022:                try {
1023:                    value = context.pnutsImpl.accept(startNodes, context);
1024:                    context.onExit(value);
1025:                    return value;
1026:                } catch (Escape esc) {
1027:                    context.onExit(value);
1028:                    Object val = esc.getValue();
1029:                    flush(context);
1030:                    context.onExit(val);
1031:                    return val;
1032:                } catch (PnutsException pe) {
1033:                    context.onError(pe);
1034:                    throw pe;
1035:                } catch (Throwable t) {
1036:                    PnutsException e = new PnutsException(t, context);
1037:                    context.onError(t);
1038:                    throw e;
1039:                } finally {
1040:                    th.setContextClassLoader(ccl);
1041:                }
1042:            }
1043:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.