Source Code Cross Referenced for Context.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:         * Context.java
0003:         *
0004:         * Copyright (c) 1997-2007 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.InputStreamReader;
0015:        import java.io.OutputStream;
0016:        import java.io.PrintWriter;
0017:        import java.io.Writer;
0018:        import java.net.URL;
0019:        import java.net.URLConnection;
0020:        import java.util.Enumeration;
0021:        import java.util.HashSet;
0022:        import java.util.Map;
0023:        import java.util.HashMap;
0024:        import java.util.Hashtable;
0025:        import java.util.Properties;
0026:        import java.util.Set;
0027:
0028:        import org.pnuts.util.Cell;
0029:
0030:        /**
0031:         * <em>Context</em> represents an internal state of a particular script
0032:         * execution. A Context is created when start executing a script and passed
0033:         * around during the execution.
0034:         *
0035:         * A pnuts.lang.Context object contains the following information.
0036:         * <ol>
0037:         * <li>Current Package (which Pnuts-package being used)
0038:         * <li>Imported Java-package list
0039:         * <li>Writer to which print() write data
0040:         * <li>Writer to which error() write message
0041:         * <li>ClassLoader
0042:         * <li>Modules added with use() function.
0043:         * <li>Units
0044:         * <li>Environments (accessed by Context.get() and set())
0045:         * <li>Stack frame (for the pure interpreter)
0046:         * <li>Encoding
0047:         * </ol>
0048:         *
0049:         * A clone is created when eval(), load(), or loadFile() is called in a script.
0050:         * When a clone is created, (1) and (2) of the clone are reset to the default
0051:         * value.
0052:         *
0053:         */
0054:        public class Context implements  Cloneable {
0055:            private static final boolean DEBUG = false;
0056:
0057:            public final static PrintWriter defaultOutputStream = new PrintWriter(
0058:                    System.out, false);
0059:
0060:            public final static PrintWriter defaultTerminalStream = defaultOutputStream;
0061:
0062:            public final static PrintWriter defaultErrorStream = new PrintWriter(
0063:                    System.err, true);
0064:
0065:            /**
0066:             * internal name for undefined state.
0067:             */
0068:            private final static Object UNDEF = new Object[0];
0069:
0070:            static String exceptionHandlerTableSymbol = Runtime.EXCEPTOIN_FIELD_SYMBOL;
0071:
0072:            static String finallyFunctionSymbol = "!finally".intern();
0073:
0074:            private ImportEnv defaultImports;
0075:
0076:            static Configuration defaultConfig = Configuration.getDefault();
0077:
0078:            static boolean defaultVerboseMode = false;
0079:            static {
0080:                try {
0081:                    String vb = Runtime.getProperty("pnuts.verbose");
0082:                    if (vb != null) {
0083:                        defaultVerboseMode = true;
0084:                    }
0085:                } catch (Throwable t) {
0086:                }
0087:            }
0088:
0089:            private static Runtime defaultRuntime = new Runtime();
0090:
0091:            private static PnutsImpl defaultPnutsImpl = PnutsImpl.getDefault();
0092:
0093:            Implementation pnutsImpl = defaultPnutsImpl;
0094:
0095:            /*
0096:             * A flag to tell if this context is created with eval() builtin function
0097:             */
0098:            boolean eval = false;
0099:
0100:            /*
0101:             * parent context from which this context is created
0102:             */
0103:            Context parent;
0104:
0105:            // eval depth
0106:            protected int depth = 0;
0107:
0108:            // caller
0109:
0110:            Function frame;
0111:
0112:            // the stack frame
0113:            StackFrame stackFrame;
0114:
0115:            Cell evalFrameStack;
0116:
0117:            // the stack which tracks load/loadFile chain
0118:            protected Cell loadingResource;
0119:
0120:            // line information
0121:            protected int beginLine = -1;
0122:
0123:            // line information
0124:            protected int endLine = -1;
0125:
0126:            // column information
0127:            protected int beginColumn = -1;
0128:
0129:            // import() state
0130:            protected ImportEnv importEnv;
0131:
0132:            // list of added modules
0133:            protected ModuleList moduleList;
0134:
0135:            // the module list copied from moduleList
0136:            ModuleList localModuleList;
0137:
0138:            private Set pendingModules;
0139:
0140:            // list of loaded files
0141:            protected SymbolTable provideTable = new SymbolTable();
0142:
0143:            // set of unit symbols
0144:            protected Hashtable unitTable;
0145:
0146:            // context-local variables
0147:            protected SymbolTable environment;
0148:
0149:            // script encoding
0150:            String encoding;
0151:
0152:            static SymbolTable globals = new SymbolTable();
0153:            static {
0154:                globals.set("pnuts_version".intern(), Pnuts.pnuts_version);
0155:                globals.set(Runtime.INT_SYMBOL, int.class);
0156:                globals.set(Runtime.SHORT_SYMBOL, short.class);
0157:                globals.set(Runtime.CHAR_SYMBOL, char.class);
0158:                globals.set(Runtime.BYTE_SYMBOL, byte.class);
0159:                globals.set(Runtime.LONG_SYMBOL, long.class);
0160:                globals.set(Runtime.FLOAT_SYMBOL, float.class);
0161:                globals.set(Runtime.DOUBLE_SYMBOL, double.class);
0162:                globals.set(Runtime.BOOLEAN_SYMBOL, boolean.class);
0163:                globals.set(Runtime.VOID_SYMBOL, void.class);
0164:                PnutsFunction[] builtins = PnutsFunction.primitives;
0165:                for (int i = 0; i < builtins.length; i++) {
0166:                    globals.set(builtins[i].getName().intern(), builtins[i]);
0167:                }
0168:            }
0169:
0170:            // streams for println()
0171:            private PrintWriter outputWriter;
0172:
0173:            private OutputStream outputStream;
0174:
0175:            // stream for error reporting
0176:            private PrintWriter errorWriter;
0177:
0178:            // stream for terminal (read-eval-print)
0179:            private PrintWriter terminalWriter;
0180:
0181:            // the name of the context
0182:            private String name;
0183:
0184:            // class loader
0185:            ClassLoader classLoader[];
0186:
0187:            // class loader for class definition
0188:            ClassLoader codeLoader;
0189:
0190:            boolean namespaceRefreshed[] = { false }; // shared by all clones
0191:
0192:            Runtime runtime = defaultRuntime;
0193:
0194:            boolean inGeneratorClosure; // for AST interpreter
0195:
0196:            BinaryOperator _add; // +
0197:            BinaryOperator _subtract; // -
0198:            BinaryOperator _multiply; // *
0199:            BinaryOperator _mod; // %
0200:            BinaryOperator _divide; // /
0201:            BinaryOperator _shiftArithmetic; // >>>
0202:            BinaryOperator _shiftLeft; // <<
0203:            BinaryOperator _shiftRight; // >>
0204:            BinaryOperator _and; // &
0205:            BinaryOperator _or; // |
0206:            BinaryOperator _xor; // ^
0207:            UnaryOperator _add1; // ++
0208:            UnaryOperator _subtract1; // --
0209:            UnaryOperator _not; // ~
0210:            UnaryOperator _negate; // -
0211:            BooleanOperator _eq; // ==
0212:            BooleanOperator _lt; // <
0213:            BooleanOperator _le; // <=
0214:            BooleanOperator _gt; // >
0215:            BooleanOperator _ge; // >=
0216:
0217:            /*
0218:             * Hook to be executed at the end of a script
0219:             */
0220:            Executable exitHook;
0221:
0222:            /*
0223:             * the current package
0224:             */
0225:            Package currentPackage = Package.getGlobalPackage();
0226:            {
0227:                setConfiguration(defaultConfig);
0228:                currentPackage.init(this );
0229:            }
0230:
0231:            Package rootPackage = currentPackage;
0232:
0233:            /*
0234:             * configuration of this context
0235:             */
0236:            Configuration config;
0237:
0238:            boolean verbose = defaultVerboseMode;
0239:
0240:            /**
0241:             * Create a new context
0242:             */
0243:            public Context() {
0244:                this (Package.getGlobalPackage());
0245:            }
0246:
0247:            /**
0248:             * Creates a context.
0249:             *
0250:             * @param pkg
0251:             *            the name of the package.
0252:             */
0253:            public Context(String pkg) {
0254:                this (Package.getPackage(pkg, null));
0255:            }
0256:
0257:            /**
0258:             * Creates a context.
0259:             *
0260:             * @param pkg
0261:             *            the initial package of the context. If null, the global
0262:             *            package is used.
0263:             */
0264:            public Context(Package pkg) {
0265:                if (pkg != null) {
0266:                    setCurrentPackage(pkg);
0267:                }
0268:                this .outputWriter = defaultOutputStream;
0269:                this .outputStream = System.out;
0270:                this .terminalWriter = defaultTerminalStream;
0271:                this .errorWriter = defaultErrorStream;
0272:                this .classLoader = new ClassLoader[] { config
0273:                        .getInitialClassLoader() };
0274:                this .importEnv = defaultImports;
0275:            }
0276:
0277:            /**
0278:             * Creates a context from a template
0279:             *
0280:             * @param context
0281:             *            The template
0282:             * @since 1.0beta9
0283:             */
0284:            public Context(Context context) {
0285:                this .outputWriter = context.outputWriter;
0286:                this .errorWriter = context.errorWriter;
0287:                this .terminalWriter = context.terminalWriter;
0288:                this .currentPackage = context.currentPackage;
0289:                this .pnutsImpl = context.pnutsImpl;
0290:                this .encoding = context.encoding;
0291:                this .setConfiguration(context.config);
0292:
0293:                this .classLoader = new ClassLoader[] { context.classLoader[0] };
0294:                this .namespaceRefreshed = new boolean[] { context.namespaceRefreshed[0] };
0295:
0296:                this .importEnv = (ImportEnv) context.importEnv.clone();
0297:
0298:                if (context.moduleList != null) {
0299:                    this .moduleList = (ModuleList) context.moduleList.clone();
0300:                }
0301:                if (context.localModuleList != null) {
0302:                    this .localModuleList = (ModuleList) context.localModuleList
0303:                            .clone();
0304:                }
0305:
0306:                if (context.unitTable != null) {
0307:                    this .unitTable = (Hashtable) context.unitTable.clone();
0308:                }
0309:                if (context.environment != null) {
0310:                    this .environment = (SymbolTable) context.environment
0311:                            .clone();
0312:                }
0313:                this .provideTable = (SymbolTable) context.provideTable.clone();
0314:            }
0315:
0316:            public Context(Properties properties) {
0317:                setConfiguration(Configuration.getDefault(properties));
0318:                setImplementation(PnutsImpl.getDefault(properties));
0319:            }
0320:
0321:            /**
0322:             * Make a clone of the context
0323:             */
0324:            public Object clone() {
0325:                return clone(true, true);
0326:            }
0327:
0328:            /**
0329:             * Make a clone of the context
0330:             *
0331:             * @param clear_attributes
0332:             *            If true, import() state and current package are reset to the
0333:             *            default values.
0334:             * @param clear_locals
0335:             *            If true, local stack is reset.
0336:             */
0337:            public Object clone(boolean clear_attributes, boolean clear_locals) {
0338:                synchronized (this ) {
0339:                    if (moduleList == null) {
0340:                        moduleList = new ModuleList(currentPackage);
0341:                    }
0342:                }
0343:                try {
0344:                    Context ret = (Context) super .clone();
0345:                    if (clear_locals) {
0346:                        if (stackFrame != null) {
0347:                            ret.stackFrame = new StackFrame();
0348:                        }
0349:                        ret.parent = this ;
0350:                        if (environment != null) {
0351:                            ret.environment = new SymbolTable(environment);
0352:                        }
0353:                    }
0354:                    if (clear_attributes) {
0355:                        ret.eval = false;
0356:                        ret.frame = null;
0357:                        ret.codeLoader = null;
0358:                        ret.importEnv = defaultImports;
0359:                        ret.currentPackage = rootPackage;
0360:                        ret.beginLine = -1;
0361:                        ret.beginColumn = -1;
0362:                    }
0363:                    return ret;
0364:                } catch (CloneNotSupportedException e) {
0365:                    throw new PnutsException(e, this );
0366:                }
0367:            }
0368:
0369:            /**
0370:             * Sets the name of the context
0371:             *
0372:             * @param name
0373:             *            The name of the context.
0374:             */
0375:            public void setName(String name) {
0376:                this .name = name;
0377:            }
0378:
0379:            /**
0380:             * Gets the name of the context
0381:             *
0382:             * @return The name of the context.
0383:             */
0384:            public String getName() {
0385:                return name;
0386:            }
0387:
0388:            /**
0389:             * Changes the PnutsImpl object associated with this context
0390:             *
0391:             * @param impl
0392:             *            The PnutsImpl object, which defines the implementation of the
0393:             *            interpreter. eval(), load(), and loadFile() of
0394:             *            pnuts.lang.Pnuts select an implementation (pure interpreter,
0395:             *            on-the-fly compiler, etc.), according to the context passed to
0396:             *            the methods.
0397:             *
0398:             * @deprecated replaced by setImplementation()
0399:             */
0400:            public void setPnutsImpl(PnutsImpl impl) {
0401:                setImplementation(impl);
0402:            }
0403:
0404:            /**
0405:             * Gets the PnutsImpl object associated with this context
0406:             *
0407:             * @deprecated replaced by getImplementation()
0408:             */
0409:            public PnutsImpl getPnutsImpl() {
0410:                return (PnutsImpl) getImplementation();
0411:            }
0412:
0413:            /**
0414:             * Changes the Implementation object associated with this context
0415:             *
0416:             * @param impl
0417:             *            The Implementation object, which defines the implementation of
0418:             *            the interpreter. eval(), load(), and loadFile() of
0419:             *            pnuts.lang.Pnuts select an implementation (pure interpreter,
0420:             *            on-the-fly compiler, etc.), according to the context passed to
0421:             *            the methods.
0422:             */
0423:            public void setImplementation(Implementation impl) {
0424:                if (impl != null) {
0425:                    pnutsImpl = impl;
0426:                }
0427:            }
0428:
0429:            /**
0430:             * Gets the Implementation object associated with this context
0431:             */
0432:            public Implementation getImplementation() {
0433:                return pnutsImpl;
0434:            }
0435:
0436:            /**
0437:             * Gets an environemnt variable associated with this context.
0438:             *
0439:             * @param symbol
0440:             *            the name of the variable, which must be intern'ed.
0441:             * @return the value of the variable
0442:             */
0443:            public Object get(String symbol) {
0444:                if (environment != null) {
0445:                    Value v = environment.lookup(symbol);
0446:                    if (v != null) {
0447:                        return v.get();
0448:                    }
0449:                }
0450:                return null;
0451:            }
0452:
0453:            /**
0454:             * Defines an environemnt variable associated with this context
0455:             *
0456:             * To access those environment variables, Context.get(String) should be
0457:             * called. Note that those variables can not be accessed just by specifying
0458:             * their names in Pnuts interpreter.
0459:             *
0460:             * Since the environment varariables are bound to the executing context,
0461:             * they are accessible from various modules that the script uses. Therefore,
0462:             * the name of environment variables should have prefixes so that name
0463:             * conflict is unlikely to occur. The name that starts with "pnuts." is
0464:             * reserved.
0465:             *
0466:             * @param symbol
0467:             *            the name of the variable, which must be intern'ed.
0468:             * @param value
0469:             *            the value of the variable
0470:             * @since 1.0beta8
0471:             */
0472:            public void set(String symbol, Object value) {
0473:                synchronized (this ) {
0474:                    if (environment == null) {
0475:                        environment = new SymbolTable();
0476:                    }
0477:                }
0478:                environment.set(symbol, value);
0479:            }
0480:
0481:            /**
0482:             * Returns an enumeration of the keys in the environment of this context.
0483:             */
0484:            public Enumeration keys() {
0485:                synchronized (this ) {
0486:                    if (environment == null) {
0487:                        environment = new SymbolTable();
0488:                    }
0489:                }
0490:                return environment.keys();
0491:            }
0492:
0493:            /**
0494:             * set output stream of the context
0495:             *
0496:             * @deprecated replaced by setTerminalWriter(Writer, boolean)
0497:             */
0498:            public void setOutputStream(Object out, boolean autoFlush) {
0499:                if (out instanceof  PrintWriter || out == null) {
0500:                    this .outputWriter = (PrintWriter) out;
0501:                    this .outputStream = null;
0502:                } else if (out instanceof  OutputStream) {
0503:                    this .outputStream = (OutputStream) out;
0504:                    this .outputWriter = new PrintWriter((OutputStream) out,
0505:                            autoFlush);
0506:                } else if (out instanceof  Writer) {
0507:                    this .outputStream = null;
0508:                    this .outputWriter = new PrintWriter((Writer) out, autoFlush);
0509:                } else {
0510:                    throw new IllegalArgumentException(Runtime.getMessage(
0511:                            "pnuts.lang.pnuts", "illegal.streamType",
0512:                            Runtime.NO_PARAM));
0513:                }
0514:            }
0515:
0516:            /**
0517:             * set output stream of the context
0518:             *
0519:             * @deprecated replaced by setTerminalWriter(Writer)
0520:             */
0521:            public void setOutputStream(Object outputStream) {
0522:                setOutputStream(outputStream, false);
0523:            }
0524:
0525:            /**
0526:             * Set the specified OutputStream as the standard output stream of the
0527:             * context, to which write() writes data. A PrintWriter is created from the
0528:             * specified OutputStream, which is returned by getWriter(). If null is
0529:             * specified, both getOutputStream() and getWriter() return null.
0530:             *
0531:             * @param out
0532:             *            the OutputStream
0533:             */
0534:            public void setOutputStream(OutputStream out) {
0535:                this .outputStream = out;
0536:                if (out == null) {
0537:                    this .outputWriter = null;
0538:                } else {
0539:                    this .outputWriter = new PrintWriter(out, false);
0540:                }
0541:            }
0542:
0543:            /**
0544:             * Set the specified Writer as the standard writer of the context.
0545:             * PrintWriter is created from the specified Writer if the Writer is not an
0546:             * instance of PrintWriter. If this method has been called,
0547:             * getOutputStream() returns null. If null is specifed to this method, both
0548:             * getWriter() and getOutputStream() return null.
0549:             *
0550:             * @param out
0551:             *            the Writer
0552:             */
0553:            public void setWriter(Writer out) {
0554:                setWriter(out, false);
0555:            }
0556:
0557:            /**
0558:             * Set the specified Writer as the standard writer of the context.
0559:             * PrintWriter is created from the specified Writer if the Writer is not an
0560:             * instance of PrintWriter. If this method has been called,
0561:             * getOutputStream() returns null. If null is specifed to this method, both
0562:             * getWriter() and getOutputStream() return null.
0563:             *
0564:             * @param out
0565:             *            the Writer
0566:             * @param autoFlush
0567:             *            A boolean; if true, the PrintWriter.println() methods will
0568:             *            flush the output buffer
0569:             */
0570:            public void setWriter(Writer out, boolean autoFlush) {
0571:                this .outputStream = null;
0572:                if (out instanceof  PrintWriter || out == null) {
0573:                    this .outputWriter = (PrintWriter) out;
0574:                } else {
0575:                    this .outputWriter = new PrintWriter(out, autoFlush);
0576:                }
0577:            }
0578:
0579:            /**
0580:             * Get the standard output stream of the context, to which write() writes
0581:             * data. This method returns the OutputStream previously set by
0582:             * setOutputStream(). If setWriter() has been called, getOutputStream()
0583:             * returns null.
0584:             *
0585:             * @return the standard output stream of the context
0586:             */
0587:            public OutputStream getOutputStream() {
0588:                return outputStream;
0589:            }
0590:
0591:            /**
0592:             * Get the standard writer of the context, to which print()/println() write
0593:             * messages.
0594:             *
0595:             * @return the standard writer of the context
0596:             */
0597:            public PrintWriter getWriter() {
0598:                return outputWriter;
0599:            }
0600:
0601:            /**
0602:             * Set the terminal stream of the context, in which the prompt is shown.
0603:             *
0604:             * @deprecated replaced by setTerminalWriter(Writer, boolean)
0605:             */
0606:            public void setTerminalStream(Object str, boolean autoFlush) {
0607:                if (str == null) {
0608:                    this .terminalWriter = null;
0609:                } else if (str instanceof  OutputStream) {
0610:                    this .terminalWriter = new PrintWriter((OutputStream) str,
0611:                            autoFlush);
0612:                } else if (str instanceof  Writer) {
0613:                    this .terminalWriter = new PrintWriter((Writer) str,
0614:                            autoFlush);
0615:                } else {
0616:                    throw new IllegalArgumentException(Runtime.getMessage(
0617:                            "pnuts.lang.pnuts", "illegal.streamType",
0618:                            Runtime.NO_PARAM));
0619:                }
0620:            }
0621:
0622:            /**
0623:             * Set the terminal stream of the context
0624:             *
0625:             * @deprecated replaced by setTerminalWriter(Writer)
0626:             */
0627:            public void setTerminalStream(Object stream) {
0628:                if (stream == null) {
0629:                    this .terminalWriter = null;
0630:                } else if (stream instanceof  PrintWriter) {
0631:                    this .terminalWriter = (PrintWriter) stream;
0632:                } else if (stream instanceof  Writer) {
0633:                    this .terminalWriter = new PrintWriter((Writer) stream, true);
0634:                } else if (stream instanceof  OutputStream) {
0635:                    this .terminalWriter = new PrintWriter(
0636:                            (OutputStream) stream, true);
0637:                } else {
0638:                    throw new IllegalArgumentException(String.valueOf(stream));
0639:                }
0640:            }
0641:
0642:            /**
0643:             * Set the terminal writer of the context
0644:             *
0645:             * @param w
0646:             *            the Writer
0647:             */
0648:            public void setTerminalWriter(Writer w) {
0649:                if (w instanceof  PrintWriter || w == null) {
0650:                    this .terminalWriter = (PrintWriter) w;
0651:                } else {
0652:                    this .terminalWriter = new PrintWriter(w);
0653:                }
0654:            }
0655:
0656:            /**
0657:             * Set the terminal writer of the context
0658:             *
0659:             * @param w
0660:             *            the Writer
0661:             */
0662:            public void setTerminalWriter(Writer w, boolean autoFlush) {
0663:                if (w == null) {
0664:                    this .terminalWriter = null;
0665:                } else {
0666:                    this .terminalWriter = new PrintWriter(w, autoFlush);
0667:                }
0668:            }
0669:
0670:            /**
0671:             * get terminal-output-stream of the context
0672:             *
0673:             * @deprecated replaced by getTerminalWriter(Writer)
0674:             */
0675:            public PrintWriter getTerminalStream() {
0676:                return terminalWriter;
0677:            }
0678:
0679:            /**
0680:             * get terminal-output-stream of the context
0681:             */
0682:            public PrintWriter getTerminalWriter() {
0683:                return terminalWriter;
0684:            }
0685:
0686:            /**
0687:             * Set an OutputStream or a Writer to which error() write messages If
0688:             * errorStream is null, exception is thrown out of eval loop.
0689:             *
0690:             * @deprecated replaced by setErrorWriter(Writer, boolean)
0691:             */
0692:            public void setErrorStream(Object errorStream, boolean autoFlush) {
0693:                if (errorStream == null) {
0694:                    this .errorWriter = null;
0695:                } else if (errorStream instanceof  OutputStream) {
0696:                    this .errorWriter = new PrintWriter(
0697:                            (OutputStream) errorStream, autoFlush);
0698:                } else if (errorStream instanceof  Writer) {
0699:                    this .errorWriter = new PrintWriter((Writer) errorStream,
0700:                            autoFlush);
0701:                } else {
0702:                    throw new IllegalArgumentException(Runtime.getMessage(
0703:                            "pnuts.lang.pnuts", "illegal.streamType",
0704:                            Runtime.NO_PARAM));
0705:                }
0706:            }
0707:
0708:            /**
0709:             * Set ar PrintWriter to which error() write messages
0710:             *
0711:             * @deprecated replaced by setErrorWriter(Writer)
0712:             */
0713:            public void setErrorStream(Object errorStream) {
0714:                if (errorStream == null) {
0715:                    this .errorWriter = null;
0716:                } else if (errorStream instanceof  OutputStream) {
0717:                    this .errorWriter = new PrintWriter(
0718:                            (OutputStream) errorStream, false);
0719:                } else if (errorStream instanceof  PrintWriter) {
0720:                    this .errorWriter = (PrintWriter) errorStream;
0721:                } else if (errorStream instanceof  Writer) {
0722:                    this .errorWriter = new PrintWriter((Writer) errorStream,
0723:                            false);
0724:                } else {
0725:                    throw new IllegalArgumentException(String
0726:                            .valueOf(errorStream));
0727:                }
0728:            }
0729:
0730:            /**
0731:             *
0732:             */
0733:            public void setErrorWriter(Writer w, boolean autoFlush) {
0734:                if (w instanceof  PrintWriter || w == null) {
0735:                    this .errorWriter = (PrintWriter) w;
0736:                } else {
0737:                    this .errorWriter = new PrintWriter(w, autoFlush);
0738:                }
0739:            }
0740:
0741:            public void setErrorWriter(Writer w) {
0742:                if (w instanceof  PrintWriter || w == null) {
0743:                    this .errorWriter = (PrintWriter) w;
0744:                } else {
0745:                    setErrorWriter(w, false);
0746:                }
0747:            }
0748:
0749:            /**
0750:             * Get an OutputStream or a Writer to which error() write messages
0751:             *
0752:             * @deprecated replaced by getErrorWriter
0753:             */
0754:            public PrintWriter getErrorStream() {
0755:                return errorWriter;
0756:            }
0757:
0758:            /**
0759:             * Get an PrintWriter to which error() write messages
0760:             */
0761:            public PrintWriter getErrorWriter() {
0762:                return errorWriter;
0763:            }
0764:
0765:            /**
0766:             * get the current package
0767:             */
0768:            public Package getCurrentPackage() {
0769:                return currentPackage;
0770:            }
0771:
0772:            /**
0773:             * set the current package
0774:             */
0775:            public void setCurrentPackage(Package pkg) {
0776:                pkg.init(this );
0777:                this .currentPackage = pkg;
0778:                Package root = pkg.root;
0779:                if (root != null) {
0780:                    this .rootPackage = root;
0781:                }
0782:            }
0783:
0784:            /**
0785:             * Changes the current class loader for this context.
0786:             *
0787:             * The initial value is set to
0788:             * Thread.currentThread().getContextClassLoader() when the instance is
0789:             * created.
0790:             *
0791:             * @param loader
0792:             *            the class loader
0793:             */
0794:            public void setClassLoader(ClassLoader loader) {
0795:                classLoader[0] = loader;
0796:                synchronized (namespaceRefreshed) {
0797:                    namespaceRefreshed[0] = true;
0798:                }
0799:            }
0800:
0801:            /**
0802:             * Gets the current class loader.
0803:             *
0804:             * The initial value is set to
0805:             * Thread.currentThread().getContextClassLoader() when the instance is
0806:             * created.
0807:             *
0808:             * @return the class loader
0809:             */
0810:            public ClassLoader getClassLoader() {
0811:                return classLoader[0];
0812:            }
0813:
0814:            /**
0815:             * Gets the current class loader for class geneartion
0816:             *
0817:             * The initial value is null.  Expressions that generate class
0818:             * create a classloader to load generated classes based on the current
0819:             * class loader.
0820:             *
0821:             * @return the class loader
0822:             */
0823:            public ClassLoader getCodeLoader() {
0824:                return this .codeLoader;
0825:            }
0826:
0827:            /**
0828:             * Sets the current class loader for class geneartion
0829:             *
0830:             * Expressions that generate class create a classloader to load generated
0831:             * classes based on the current class loader.
0832:             *
0833:             * @param loader the class loader
0834:             */
0835:            public void setCodeLoader(ClassLoader loader) {
0836:                this .codeLoader = loader;
0837:            }
0838:
0839:            /**
0840:             * Changes the configuration for this context.
0841:             *
0842:             * @param config
0843:             *            the configuration
0844:             */
0845:            public void setConfiguration(Configuration config) {
0846:                if (config == null) {
0847:                    return;
0848:                }
0849:                this .config = config;
0850:                this .defaultImports = Runtime.getDefaultImports(this );
0851:                if (this .importEnv == null) {
0852:                    this .importEnv = this .defaultImports;
0853:                }
0854:
0855:                // copy operators
0856:                this ._add = config._add;
0857:                this ._add1 = config._add1;
0858:                this ._subtract = config._subtract;
0859:                this ._subtract1 = config._subtract1;
0860:                this ._multiply = config._multiply;
0861:                this ._mod = config._mod;
0862:                this ._divide = config._divide;
0863:                this ._shiftArithmetic = config._shiftArithmetic;
0864:                this ._shiftLeft = config._shiftLeft;
0865:                this ._shiftRight = config._shiftRight;
0866:                this ._and = config._and;
0867:                this ._or = config._or;
0868:                this ._xor = config._xor;
0869:                this ._not = config._not;
0870:                this ._negate = config._negate;
0871:                this ._eq = config._eq;
0872:                this ._lt = config._lt;
0873:                this ._le = config._le;
0874:                this ._gt = config._gt;
0875:                this ._ge = config._ge;
0876:            }
0877:
0878:            /*
0879:             * Gets the current configuration
0880:             */
0881:            public Configuration getConfiguration() {
0882:                return config;
0883:            }
0884:
0885:            /**
0886:             * Sets a hook to be executed at the end of a script. The default value is
0887:             * null.
0888:             *
0889:             * @param hook
0890:             *            the hook
0891:             */
0892:            public void setExitHook(Executable hook) {
0893:                exitHook = hook;
0894:            }
0895:
0896:            /**
0897:             * Gets the hook to be executed at the end of a script
0898:             *
0899:             */
0900:            public Executable getExitHook() {
0901:                return exitHook;
0902:            }
0903:
0904:            void addClassToImport(String className) {
0905:                synchronized (this ) {
0906:                    if (importEnv == defaultImports) {
0907:                        importEnv = (ImportEnv) importEnv.clone();
0908:                    }
0909:                }
0910:                importEnv.addClass(className);
0911:            }
0912:
0913:            void addPackageToImport(String pkgName) {
0914:                synchronized (this ) {
0915:                    if (importEnv == defaultImports) {
0916:                        importEnv = (ImportEnv) importEnv.clone();
0917:                    }
0918:                }
0919:                importEnv.addPackage(pkgName);
0920:            }
0921:
0922:            void addStaticMembers(String name, boolean wildcard) {
0923:                synchronized (this ) {
0924:                    if (importEnv == defaultImports) {
0925:                        importEnv = (ImportEnv) importEnv.clone();
0926:                    }
0927:                }
0928:                importEnv.addStaticMembers(name, wildcard, this );
0929:            }
0930:
0931:            /*
0932:             * Declares explicitly that the context is reading from a script source
0933:             * (usually a URL). Must be followed by popFile() call.
0934:             */
0935:            synchronized void pushFile(Object file) {
0936:                Cell cell = new Cell();
0937:                cell.object = file;
0938:                cell.next = loadingResource;
0939:                loadingResource = cell;
0940:            }
0941:
0942:            /*
0943:             * Declares that the current script source is no longer used.
0944:             */
0945:            synchronized void popFile() {
0946:                if (exitHook != null) {
0947:                    exitHook.run(this );
0948:                }
0949:                if (loadingResource != null) {
0950:                    loadingResource = loadingResource.next;
0951:                }
0952:            }
0953:
0954:            public synchronized boolean unusePackage(Package pkg) {
0955:                if (moduleList != null) {
0956:                    if (moduleList.remove(pkg)) {
0957:                        localModuleList = null;
0958:                        return true;
0959:                    }
0960:                }
0961:                return false;
0962:            }
0963:
0964:            public boolean usePackage(Package pkg, boolean checkException) {
0965:                synchronized (this ) {
0966:                    if (moduleList == null) {
0967:                        moduleList = new ModuleList(currentPackage);
0968:                    }
0969:                    if (pendingModules == null) {
0970:                        pendingModules = new HashSet();
0971:                    }
0972:                }
0973:                boolean pending = pendingModules.contains(pkg);
0974:                try {
0975:                    if (!pending && !moduleList.contains(pkg)) {
0976:                        if (pkg.usedAsModule) {
0977:                            Context ctx = (Context) clone();
0978:                            ctx.setCurrentPackage(pkg);
0979:                            for (Enumeration e = pkg.providedModuleNames
0980:                                    .elements(); e.hasMoreElements();) {
0981:                                String m = (String) e.nextElement();
0982:                                if (DEBUG) {
0983:                                    System.out.println("! " + pkg.getName()
0984:                                            + " provides " + m);
0985:                                }
0986:                                ctx.usePackage(m);
0987:                            }
0988:
0989:                            if (pkg.requiredModuleNames.size() > 0) {
0990:                                ctx = (Context) ctx.clone();
0991:                                ctx.clearPackages();
0992:                            }
0993:
0994:                            for (Enumeration e = pkg.requiredModuleNames
0995:                                    .elements(); e.hasMoreElements();) {
0996:                                String m = (String) e.nextElement();
0997:                                if (DEBUG) {
0998:                                    System.out.println(pkg.getName()
0999:                                            + " requires " + m);
1000:                                }
1001:                                ctx.usePackage(m);
1002:                            }
1003:                        } else {
1004:                            pkg.initializeModule();
1005:                        }
1006:                        String name = pkg.getName();
1007:                        synchronized (pkg.moduleIntializationLock) {
1008:                            pendingModules.add(pkg);
1009:                            try {
1010:                                if (!pkg.initialized) {
1011:                                    if (name != null) {
1012:                                        loadModule(name, pkg);
1013:                                    }
1014:                                    pkg.initialized = true;
1015:                                }
1016:                            } finally {
1017:                                pendingModules.remove(pkg);
1018:                            }
1019:                            if (name != null && moduleList != null) {
1020:                                if (currentPackage.usedAsModule) {
1021:                                    if (moduleList.basePackage != currentPackage) {
1022:                                        if (DEBUG) {
1023:                                            System.out.println(currentPackage
1024:                                                    .getName()
1025:                                                    + " provides... " + name);
1026:                                        }
1027:                                        currentPackage.providedModuleNames
1028:                                                .addElement(name);
1029:                                    } else {
1030:                                        currentPackage.requiredModuleNames
1031:                                                .addElement(name);
1032:                                    }
1033:                                }
1034:                            }
1035:                        }
1036:                    }
1037:                    if (!pending) {
1038:                        moduleList.add(pkg);
1039:                    }
1040:                    localModuleList = null;
1041:                    return true;
1042:                } catch (Throwable t) {
1043:                    if (checkException) {
1044:                        Runtime.checkException(this , t);
1045:                    } else {
1046:                        if (verbose && terminalWriter != null) {
1047:                            t.printStackTrace(terminalWriter);
1048:                        }
1049:                    }
1050:                }
1051:                return false;
1052:            }
1053:
1054:            /**
1055:             * Add a package to the use()'d package list.
1056:             *
1057:             * @param name
1058:             *            the package name
1059:             * @return true if successfully use()'d.
1060:             */
1061:            public boolean usePackage(String name) {
1062:                return usePackage(name, false);
1063:            }
1064:
1065:            /**
1066:             * Add a package to the use()'d package list.
1067:             *
1068:             * @param name
1069:             *            the package name
1070:             * @param checkException
1071:             *            if false exceptions are ignored
1072:             * @return true if successfully use()'d.
1073:             */
1074:            public boolean usePackage(String name, boolean checkException) {
1075:                return usePackage(Package.getPackage(name, this ),
1076:                        checkException);
1077:            }
1078:
1079:            /**
1080:             * Loads a module is it has not been loaded yet.
1081:             *
1082:             * The initialization script is: 1) Replace :: and . with / then append
1083:             * "/init", e.g. pnuts.lib => pnuts/lib/init 2) The 1st line in
1084:             * META-INF/pnuts/module/ <module_name>
1085:             *
1086:             * @param name
1087:             *            the name of the module
1088:             * @param pkg
1089:             *            the associated package (name space)
1090:             * @exception FileNotFoundException
1091:             *                thrown when the initialization script is not found.
1092:             */
1093:            protected void loadModule(String name, Package pkg)
1094:                    throws IOException {
1095:                if (DEBUG) {
1096:                    System.out.println("loading " + name);
1097:                }
1098:                Context ctx = (Context) clone();
1099:
1100:                ctx.setCurrentPackage(pkg);
1101:                ctx.config = defaultConfig;
1102:
1103:                FileNotFoundException notfound = null;
1104:                try {
1105:                    Pnuts.load(pkg.getInitScript(), ctx);
1106:                } catch (FileNotFoundException e) {
1107:                    notfound = e;
1108:                }
1109:                if (notfound != null) {
1110:                    URL url = Pnuts.getResource(
1111:                            "META-INF/pnuts/module/" + name, this );
1112:                    if (url != null) {
1113:                        BufferedReader br = new BufferedReader(
1114:                                new InputStreamReader(url.openStream(), "UTF-8"));
1115:                        try {
1116:                            String line = br.readLine();
1117:                            if (line != null) {
1118:                                try {
1119:                                    Pnuts.load(line.trim(), ctx);
1120:                                } catch (FileNotFoundException e2) {
1121:                                    throw e2;
1122:                                }
1123:                                notfound = null;
1124:                            }
1125:                        } finally {
1126:                            br.close();
1127:                        }
1128:                    }
1129:                }
1130:                if (notfound != null) {
1131:                    throw notfound;
1132:                }
1133:
1134:                if (!pkg.exports) {
1135:                    pkg.exportFunctions();
1136:                }
1137:            }
1138:
1139:            /**
1140:             * Unregisteres all use()'d packages
1141:             */
1142:            public synchronized void clearPackages() {
1143:                moduleList = new ModuleList(currentPackage);
1144:                localModuleList = null;
1145:            }
1146:
1147:            synchronized ModuleList localModuleList() {
1148:                ModuleList list = this .localModuleList;
1149:                if (list == null && this .moduleList != null) {
1150:                    list = this .localModuleList = (ModuleList) this .moduleList
1151:                            .clone();
1152:                }
1153:                return list;
1154:            }
1155:
1156:            /**
1157:             * Returns the list of use()'d packages
1158:             */
1159:            public String[] usedPackages() {
1160:                if (moduleList == null) {
1161:                    return new String[] {};
1162:                } else {
1163:                    return moduleList.getPackageNames();
1164:                }
1165:            }
1166:
1167:            /**
1168:             * Loads a script file only if it has not been loaded. It is guaranteed that
1169:             * the script runs at most once in this context.
1170:             *
1171:             * @param file
1172:             *            the script file, which must be an intern'ed String.
1173:             */
1174:            void require(String file, boolean checkForUpdate)
1175:                    throws FileNotFoundException {
1176:                SymbolTable table = provideTable;
1177:                Binding b;
1178:                synchronized (table) {
1179:                    b = table.lookup0(file);
1180:                    if (b == null) {
1181:                        table.set(file, null);
1182:                        b = table.lookup0(file);
1183:                    }
1184:                }
1185:                synchronized (b) {
1186:                    Long timestamp = (Long) b.value;
1187:                    if (timestamp == null) {
1188:                        Pnuts.load(file, this );
1189:                    } else if (checkForUpdate) {
1190:                        long m = lastModified(file);
1191:                        if (m > timestamp.longValue()) {
1192:                            Pnuts.load(file, this );
1193:                        }
1194:                    }
1195:                }
1196:            }
1197:
1198:            long lastModified(String file) {
1199:                try {
1200:                    URL url = Runtime.getScriptURL(file + ".pnut", this );
1201:                    if (url == null) {
1202:                        return -1;
1203:                    }
1204:                    URLConnection c = url.openConnection();
1205:                    return c.getLastModified();
1206:                } catch (IOException e) {
1207:                    return -1;
1208:                }
1209:            }
1210:
1211:            void provide(String file) {
1212:                file = file.intern();
1213:                Binding b;
1214:                SymbolTable table = provideTable;
1215:                synchronized (table) {
1216:                    b = table.lookup0(file);
1217:                    if (b == null) {
1218:                        table.set(file, null);
1219:                        b = table.lookup0(file);
1220:                    }
1221:                }
1222:                synchronized (b) {
1223:                    b.set(new Long(System.currentTimeMillis()));
1224:                }
1225:            }
1226:
1227:            void revoke(String file) {
1228:                file = file.intern();
1229:                provideTable.removeBinding(file);
1230:            }
1231:
1232:            /**
1233:             * Get the source of the script.
1234:             *
1235:             * @return
1236:             *
1237:             * <pre>
1238:             *
1239:             *  java.net.URL object, when the script is not precompiled
1240:             *  pnuts.lang.Runtime object, when the script is precompiled
1241:             *
1242:             * </pre>
1243:             */
1244:            protected Object getScriptSource() {
1245:                if (frame != null) {
1246:                    return frame.file;
1247:                } else {
1248:                    Cell c = loadingResource;
1249:                    if (c != null) {
1250:                        return c.object;
1251:                    } else {
1252:                        return null;
1253:                    }
1254:                }
1255:            }
1256:
1257:            void updateLine(SimpleNode node) {
1258:                updateLine(node, node.beginLine, node.beginColumn);
1259:            }
1260:
1261:            /**
1262:             * AST interpreter calls this method when line number changes, giving AST nodes
1263:             * and line information
1264:             *
1265:             * Not that compiler does not call this method.
1266:             *
1267:             * @param node the current AST node
1268:             * @param beginLine the line number at which the current expression starts.
1269:             * @param beginColumn the column number at which theh current expression ends.
1270:             */
1271:            protected void updateLine(SimpleNode node, int beginLine,
1272:                    int beginColumn) {
1273:                updateLine(beginLine);
1274:                updateColumn(beginColumn);
1275:            }
1276:
1277:            /**
1278:             * Both AST interpreter and compiler call this method when line number changes.
1279:             *
1280:             * Subclasses may override this method to interact with
1281:             * running script. For example, a subclass may redefine this
1282:             * method so that it can stop the execution if Thread.interrupt()
1283:             * has been called.
1284:             *
1285:             * @param line the line number
1286:             */
1287:            protected void updateLine(int line) {
1288:                if (line > 0) {
1289:                    this .beginLine = line;
1290:                    this .endLine = line;
1291:                    this .beginColumn = -1;
1292:                }
1293:            }
1294:
1295:            protected void updateColumn(int column) {
1296:                if (column > 0) {
1297:                    this .beginColumn = column;
1298:                }
1299:            }
1300:
1301:            /**
1302:             * This method is called when the excecution is terminated normally.
1303:             */
1304:            protected void onExit(Object arg) {
1305:            }
1306:
1307:            /**
1308:             * This method is called when an exception is thrown.
1309:             */
1310:            protected void onError(Throwable t) {
1311:            }
1312:
1313:            /**
1314:             * Gets the value of a symbol.
1315:             *
1316:             * @param interned
1317:             *            a symbol (interned string)
1318:             * @return the value of the symbol
1319:             * @exception PnutsException
1320:             *                if the specified symbol is not defined
1321:             */
1322:            public Object getId(String interned) {
1323:                Object v = _getId(interned);
1324:                if (v == UNDEF) {
1325:                    return undefined(interned);
1326:                } else {
1327:                    return v;
1328:                }
1329:            }
1330:
1331:            /**
1332:             * Resolves the value of a symbol in the following order:
1333:             *
1334:             * (1) current package (2) builtin functions, primitive types, pnuts_version
1335:             * (3) module exports (4) imported classes (5) parent packages
1336:             *
1337:             * @param interned
1338:             *            a symbol (interned string)
1339:             * @return the value of the symbol, or null if it is not defined.
1340:             */
1341:            public Object resolveSymbol(String interned) {
1342:                Object v = _getId(interned);
1343:                if (v == UNDEF) {
1344:                    return null;
1345:                } else {
1346:                    return v;
1347:                }
1348:            }
1349:
1350:            static Map primitiveTypes = new HashMap();
1351:            static {
1352:                primitiveTypes.put("int", int.class);
1353:                primitiveTypes.put("short", short.class);
1354:                primitiveTypes.put("long", long.class);
1355:                primitiveTypes.put("byte", byte.class);
1356:                primitiveTypes.put("char", char.class);
1357:                primitiveTypes.put("long", long.class);
1358:                primitiveTypes.put("boolean", boolean.class);
1359:                primitiveTypes.put("float", float.class);
1360:                primitiveTypes.put("double", double.class);
1361:            }
1362:
1363:            /*
1364:             * Resolves a class using import()'ed names
1365:             *
1366:             * @param symbol an interned String
1367:             * @return a Class object that represents
1368:             * the class, or null if not found.
1369:             */
1370:            public Class resolveClass(String symbol) {
1371:                Class type = (Class) primitiveTypes.get(symbol);
1372:                if (type != null) {
1373:                    return type;
1374:                }
1375:
1376:                if (symbol.indexOf('.') > 0) {
1377:                    try {
1378:                        return Pnuts.loadClass(symbol, this );
1379:                    } catch (ClassNotFoundException e) {
1380:                        return null;
1381:                    }
1382:                } else {
1383:                    NamedValue binding = currentPackage.lookup(symbol);
1384:                    if (binding != null) {
1385:                        Object value = binding.get();
1386:                        if (value instanceof  Class) {
1387:                            return (Class) value;
1388:                        }
1389:                    }
1390:                    Object obj = importEnv.get(symbol, this );
1391:                    if (obj instanceof  Class) {
1392:                        return (Class) obj;
1393:                    } else {
1394:                        obj = _getId(symbol);
1395:                        if (obj instanceof  Class) {
1396:                            return (Class) obj;
1397:                        }
1398:                        return null;
1399:                    }
1400:                }
1401:            }
1402:
1403:            Object _getId(String symbol) {
1404:                Value v = currentPackage.lookup(symbol, this );
1405:                if (v != null) {
1406:                    return v.get();
1407:                }
1408:                v = globals.lookup0(symbol);
1409:                if (v != null) {
1410:                    return v.get();
1411:                }
1412:                if (moduleList != null) {
1413:                    v = moduleList.resolve(symbol, this );
1414:                    if (v != null) {
1415:                        return v.get();
1416:                    }
1417:                }
1418:
1419:                if (symbol.charAt(0) == '!') {
1420:                    return null;
1421:                }
1422:
1423:                synchronized (namespaceRefreshed) {
1424:                    if (namespaceRefreshed[0]) {
1425:                        resetImportEnv();
1426:                    }
1427:                    namespaceRefreshed[0] = false;
1428:                }
1429:
1430:                Object c = importEnv.get(symbol, this );
1431:                if (c != null) {
1432:                    return c;
1433:                }
1434:
1435:                Package parent = currentPackage.getParent();
1436:                if (parent != null) {
1437:                    v = parent.lookupRecursively(symbol, this );
1438:                }
1439:                if (v != null) {
1440:                    return v.get();
1441:                }
1442:
1443:                return UNDEF;
1444:            }
1445:
1446:            void resetImportEnv() {
1447:                importEnv.reset();
1448:                if (parent != null) {
1449:                    parent.resetImportEnv();
1450:                }
1451:            }
1452:
1453:            /**
1454:             * Registers an autoload script for the <em>name</em>. If <em>name</em>
1455:             * is not defined when accessed, the registerred <em>file</em> is loaded.
1456:             *
1457:             * @param name
1458:             *            variable name
1459:             * @param file
1460:             *            the file
1461:             */
1462:            public void autoload(String name, String file) {
1463:                currentPackage.autoload(name, file, this );
1464:            }
1465:
1466:            /**
1467:             * Registers an AutoloadHook for the <em>name</em> in the current package.
1468:             *
1469:             * @param name
1470:             *            variable name
1471:             * @param hook
1472:             *            the AutoloadHook
1473:             */
1474:            public void autoload(String name, AutoloadHook hook) {
1475:                currentPackage.autoload(name, hook);
1476:            }
1477:
1478:            Object undefined(String sym) {
1479:                return config.handleUndefinedSymbol(sym, this );
1480:            }
1481:
1482:            /**
1483:             * Checks if the name is defined in the context.
1484:             */
1485:            public boolean defined(String name) {
1486:                return _getId(name.intern()) != UNDEF;
1487:            }
1488:
1489:            /**
1490:             * Defines a unit.
1491:             *
1492:             * @param unit
1493:             *            The unit symbol
1494:             * @param fac
1495:             *            A QuantityFactory object which defines what kind of object is
1496:             *            created when a decimal number with this unit symbol is
1497:             *            evaluated.
1498:             */
1499:            public void registerQuantityFactory(String unit, QuantityFactory fac) {
1500:                synchronized (this ) {
1501:                    if (unitTable == null) {
1502:                        unitTable = new Hashtable(8);
1503:                    }
1504:                }
1505:                if (fac != null) {
1506:                    unitTable.put(unit, fac);
1507:                } else {
1508:                    unitTable.remove(unit);
1509:                }
1510:            }
1511:
1512:            ////// Methods below are used by the pure interpreter
1513:
1514:            /*
1515:             * open new scope with the pure interpreter
1516:             */
1517:            protected void open(Function f, Object args[]) {
1518:                String[] locals = f.locals;
1519:                stackFrame = new StackFrame(locals, stackFrame);
1520:                StackFrame sf = stackFrame;
1521:                for (int i = 0; i < args.length; i++) {
1522:                    sf.bind(locals[i], args[i]);
1523:                }
1524:                if (f.outer != null && f.name != null) {
1525:                    sf.bind(f.name, f.function);
1526:                }
1527:            }
1528:
1529:            /*
1530:             * close the scope with the pure interpreter
1531:             */
1532:            protected void close(Function func, Object args[]) {
1533:                stackFrame = stackFrame.parent;
1534:            }
1535:
1536:            /*
1537:             * open for/foreach scope with the pure interpreter
1538:             */
1539:            void openLocal(String locals[]) {
1540:                stackFrame.openLocal(locals);
1541:            }
1542:
1543:            /*
1544:             * close for/foreach scope with the pure interpreter
1545:             */
1546:            void closeLocal() {
1547:                stackFrame.closeLocal();
1548:            }
1549:
1550:            final void bind(String symbol, Object obj) {
1551:                stackFrame.bind(symbol, obj);
1552:            }
1553:
1554:            void resetStackFrame() {
1555:                if (stackFrame != null) {
1556:                    stackFrame = new StackFrame();
1557:                }
1558:            }
1559:
1560:            protected Object getValue(String symbol) {
1561:                Object val;
1562:
1563:                if (stackFrame != null) {
1564:                    Binding b = (Binding) stackFrame.lookup(symbol);
1565:                    if (b != null) {
1566:                        return b.value;
1567:                    }
1568:                    Function ff = frame;
1569:                    while (ff != null) {
1570:                        SymbolTable ls = ff.lexicalScope;
1571:                        if (ls != null) {
1572:                            Binding bb = ls.lookup0(symbol);
1573:                            if (bb != null) {
1574:                                return ((Binding) bb.value).value;
1575:                            }
1576:                        }
1577:                        ff = ff.outer;
1578:                    }
1579:                }
1580:                val = _getId(symbol);
1581:                if (val == UNDEF) {
1582:                    return undefined(symbol);
1583:                } else {
1584:                    return val;
1585:                }
1586:            }
1587:
1588:            protected void setValue(String symbol, Object obj) {
1589:                Binding b = (Binding) stackFrame.lookup(symbol);
1590:                if (b != null) {
1591:                    b.value = obj;
1592:                    return;
1593:                }
1594:
1595:                Function ff = frame;
1596:
1597:                while (ff != null) {
1598:                    SymbolTable ls = ff.lexicalScope;
1599:                    if (ls != null) {
1600:                        Binding bb = ls.lookup0(symbol);
1601:                        if (bb != null) {
1602:                            ((Binding) bb.value).value = obj;
1603:                            return;
1604:                        }
1605:                    }
1606:                    ff = ff.outer;
1607:                }
1608:
1609:                if (stackFrame.parent != null) {
1610:                    stackFrame.declare(symbol, obj);
1611:                } else {
1612:                    currentPackage.set(symbol, obj, this );
1613:                }
1614:            }
1615:
1616:            void catchException(Class t, PnutsFunction f) {
1617:                if (stackFrame.parent != null) {
1618:                    Runtime.TypeMap tmap = null;
1619:                    Value b = stackFrame.lookup(exceptionHandlerTableSymbol);
1620:                    if (b != null) {
1621:                        tmap = (Runtime.TypeMap) b.get();
1622:                    }
1623:                    Runtime.TypeMap newtmap = new Runtime.TypeMap(t, f, tmap);
1624:                    stackFrame.declare(exceptionHandlerTableSymbol, newtmap);
1625:                } else {
1626:                    Runtime.catchException(t, f, this );
1627:                }
1628:            }
1629:
1630:            void setFinallyFunction(final PnutsFunction func) {
1631:                if (stackFrame.parent != null) {
1632:                    stackFrame.declare(finallyFunctionSymbol, func);
1633:                    if (frame != null) {
1634:                        frame.finallySet = true;
1635:                    }
1636:                } else {
1637:                    Runtime.setExitHook(this , func);
1638:                }
1639:            }
1640:
1641:            /**
1642:             * Sets the verbose mode
1643:             */
1644:            public void setVerbose(boolean b) {
1645:                verbose = b;
1646:            }
1647:
1648:            /**
1649:             * Check the current verbose mode
1650:             *
1651:             * @return the current verbose mode
1652:             */
1653:            public boolean isVerbose() {
1654:                return verbose;
1655:            }
1656:
1657:            /**
1658:             * Changes the script encoding for the context
1659:             *
1660:             * @param encoding
1661:             *            the encoding
1662:             */
1663:            public void setScriptEncoding(String encoding) {
1664:                this .encoding = encoding;
1665:            }
1666:
1667:            /**
1668:             * Gets the current script encoding
1669:             *
1670:             * @return the current script encoding
1671:             */
1672:            public String getScriptEncoding() {
1673:                return this.encoding;
1674:            }
1675:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.