Source Code Cross Referenced for Evaluator.java in  » Scripting » jscheme » jsint » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


001:        package jsint;
002:
003:        import java.io.*;
004:        import java.util.HashMap;
005:
006:        /** This class represents a Scheme interpreter.
007:         * @author Peter Norvig, Copyright 1998, peter@norvig.com, <a href="license.txt">license</a>
008:         * subsequently modified by Jscheme project members
009:         * licensed under zlib licence (see license.txt)
010:         **/
011:
012:        public class Evaluator implements  java.io.Serializable {
013:            /** Should REP Loop exit? **/
014:            private boolean exit = false;
015:
016:            public boolean setExit(boolean exit) {
017:                return this .exit = exit;
018:            }
019:
020:            private transient InputPort input = new InputPort(System.in);
021:
022:            public void setInput(InputPort ip) {
023:                this .input = ip;
024:            }
025:
026:            public InputPort getInput() {
027:                return this .input;
028:            }
029:
030:            private transient PrintWriter output = new PrintWriter(System.out,
031:                    true);
032:
033:            public PrintWriter getOutput() {
034:                return this .output;
035:            }
036:
037:            public void setOutput(PrintWriter w) {
038:                this .output = w;
039:            }
040:
041:            private transient PrintWriter error = new PrintWriter(System.err,
042:                    true);
043:
044:            public PrintWriter getError() {
045:                return this .error;
046:            }
047:
048:            public void setError(PrintWriter w) {
049:                this .error = w;
050:            }
051:
052:            /** Is execution interruptable. **/
053:            public boolean INTERRUPTABLE = false;
054:
055:            /** Interrupt execution on thread <tt>t</tt>. **/
056:            public void interrupt(Thread t) {
057:                INTERRUPTABLE = true;
058:                t.interrupt();
059:            }
060:
061:            /** Maybe interrupt this thread of execution. **/
062:            public void interruptCheck() {
063:                if (INTERRUPTABLE && Thread.currentThread().interrupted()) {
064:                    INTERRUPTABLE = false;
065:                    throw new JschemeThrowable("Execution was interrupted.");
066:                }
067:            }
068:
069:            // The default environment for doing work.
070:            // We have to define and initialize this before the static block
071:            // that loads the primitives.
072:            public DynamicEnvironment interactionEnvironment = null;
073:            //    = new DynamicEnvironment();
074:
075:            // The R5RS "null-environment".
076:            public static DynamicEnvironment NULL_ENVIRONMENT = new DynamicEnvironment();
077:
078:            // The environment at system startup.  Any loaded environments are
079:            // created based off of this.
080:            public DynamicEnvironment INITIAL_ENVIRONMENT = null;
081:
082:            public DynamicEnvironment getInteractionEnvironment() {
083:                return interactionEnvironment;
084:            }
085:
086:            public static DynamicEnvironment getNullEnvironment() {
087:                return NULL_ENVIRONMENT;
088:            }
089:
090:            public DynamicEnvironment getInitialEnvironment() {
091:                return INITIAL_ENVIRONMENT;
092:            }
093:
094:            private static HashMap environmentCache = new HashMap();
095:            private static DynamicEnvironment BASE_ENVIRONMENT = null;
096:
097:            static {
098:                NULL_ENVIRONMENT.lockDown();
099:            }
100:
101:            public Evaluator() {
102:                Scheme.pushEvaluator(this );
103:                try {
104:                    if (BASE_ENVIRONMENT == null) {
105:                        interactionEnvironment = new DynamicEnvironment();
106:                        jsint.Primitive.loadPrimitives();
107:                        BASE_ENVIRONMENT = new DynamicEnvironment(
108:                                this .interactionEnvironment);
109:                        BASE_ENVIRONMENT.lockDown();
110:                    } else {
111:                        interactionEnvironment = new DynamicEnvironment(
112:                                BASE_ENVIRONMENT);
113:                    }
114:                    INITIAL_ENVIRONMENT = new DynamicEnvironment(
115:                            interactionEnvironment);
116:                    INITIAL_ENVIRONMENT.lockDown();
117:                } finally {
118:                    Scheme.popEvaluator();
119:                }
120:            }
121:
122:            public Evaluator(DynamicEnvironment env) {
123:                interactionEnvironment = new DynamicEnvironment(env);
124:                INITIAL_ENVIRONMENT = new DynamicEnvironment(
125:                        interactionEnvironment);
126:                INITIAL_ENVIRONMENT.lockDown();
127:            }
128:
129:            public void runJscheme() {
130:                if (exit)
131:                    return;
132:                showVersion();
133:                readEvalWriteLoop("> ");
134:            }
135:
136:            /**
137:             *  If true, results of REPL evaluations are named (e.g. $3) for
138:             *  future reference.
139:             */
140:            private boolean nameResults = true;
141:
142:            public void enableNamedResults(boolean enabled) {
143:                nameResults = enabled;
144:            }
145:
146:            /** Prompt, read, eval, and write the result.
147:             * Also sets up a catch for any RuntimeExceptions encountered.
148:             * Returns true on EOF, false if (exit) was evaluated. **/
149:            public boolean readEvalWriteLoop(String prompt) {
150:                int count = 0;
151:                while (!exit) {
152:                    try {
153:                        output.print(prompt);
154:                        output.flush();
155:                        Object x = input.read();
156:                        if (x == InputPort.EOF)
157:                            return true; // EOF
158:                        Object result = eval(x);
159:                        if (nameResults) {
160:                            String name = "$" + (++count);
161:                            output.print(name + " = ");
162:                            interactionEnvironment.setValue(
163:                                    Symbol.intern(name), result);
164:                        }
165:                        U.write(result, output, true);
166:                        output.write("\n");
167:                        output.println();
168:                        output.flush();
169:                    } catch (Throwable e) {
170:                        e.printStackTrace(error);
171:                        error.flush();
172:                    }
173:                }
174:                return false; // (exit) called.
175:            }
176:
177:            /**
178:             * load the current object (file or class) into a new Evaluator
179:             * and return the resulting Evaluator's DynamicEnvironment. 
180:             */
181:            public DynamicEnvironment loadEnvironment(Object x) {
182:
183:                Object cacheKey = x;
184:                Object cached = environmentCache.get(cacheKey);
185:
186:                // for filenames, use the CanonicalFile name as the hashkey, for
187:                // others use the object itself
188:                try {
189:                    if (x instanceof  String) {
190:                        cacheKey = (new java.io.File((String) x))
191:                                .getCanonicalFile().toString().intern();
192:                        cached = environmentCache.get(cacheKey);
193:                    }
194:                } catch (Exception e) {
195:                }
196:
197:                if (cached != null)
198:                    return (DynamicEnvironment) cached;
199:                else {
200:                    Evaluator evaluator = new Evaluator();
201:                    DynamicEnvironment env = evaluator.interactionEnvironment;
202:                    Scheme.pushEvaluator(evaluator);
203:                    evaluator.load(x);
204:                    env = evaluator.interactionEnvironment; // the evaluator might change its interactionEnvironment
205:                    Scheme.popEvaluator();
206:                    env.lockDown();
207:                    environmentCache.put(cacheKey, env);
208:                    return (env);
209:                }
210:            }
211:
212:            public Boolean environmentImport(Object x, Object prefix) {
213:                return environmentImport(x, prefix, false, null);
214:            }
215:
216:            public Boolean environmentImport(Object x, Object prefix,
217:                    boolean macrosFlag, jsint.Symbol[] procnames) {
218:                synchronized (interactionEnvironment) {
219:                    DynamicEnvironment env = loadEnvironment(x);
220:                    if (prefix instanceof  String)
221:                        if (macrosFlag && (((String) prefix).length() > 0)) {
222:                            E
223:                                    .error("(environment-import): macros cannot have a prefix"
224:                                            + prefix);
225:                            return Boolean.FALSE;
226:                        } else {
227:                            interactionEnvironment.importBindings(env,
228:                                    (String) prefix, macrosFlag, procnames);
229:                            return Boolean.TRUE;
230:                        }
231:                    else if ((prefix == U.MISSING)
232:                            || ((prefix instanceof  Boolean) && ((Boolean) prefix) == Boolean.FALSE)) {
233:                        interactionEnvironment.importBindings(env, null,
234:                                macrosFlag, procnames);
235:                        return Boolean.TRUE;
236:                    } else {
237:                        E
238:                                .error("(environment-import): prefix is not string or #f: "
239:                                        + prefix);
240:                        return Boolean.FALSE;
241:                    }
242:                }
243:            }
244:
245:            public Boolean languageImport(Object x) {
246:                synchronized (interactionEnvironment) {
247:                    DynamicEnvironment env = loadEnvironment(x);
248:                    interactionEnvironment.importBindings(env, null, true);
249:                    return Boolean.TRUE;
250:                }
251:            }
252:
253:            /** Eval all the expressions in a file. Calls load(InputPort). **/
254:            public Object load(Object fileName) {
255:                String name = fileName.toString();
256:                InputPort iport = Scheme.open(name);
257:                if (iport == null)
258:                    return E.warn("(load) can't open \"" + fileName + "\"");
259:                else
260:                    return load(iport);
261:            }
262:
263:            /** Eval all the expressions coming from an InputPort, putting them
264:                in the interactionEnvironment.  The interactionEnvironment might
265:                have been rebound to a module environment, but we don't care
266:                about that.  Returns TRUE on EOF, FALSE if (exit) was evaluated.
267:             **/
268:            public Object load(InputPort in) {
269:                while (!exit) {
270:                    try {
271:                        Object x = in.read();
272:                        if (x == InputPort.EOF)
273:                            return U.TRUE;
274:                        else
275:                            evalToplevel(x, interactionEnvironment);
276:                    } catch (Exception e) {
277:                        E.warn("Error during load (lineno "
278:                                + in.getLineNumber() + "): ", e);
279:                        e.printStackTrace(error);
280:                    }
281:                }
282:                return U.FALSE; // (exit)
283:            }
284:
285:            /** evalToplevel evaluates each element of a BEGIN.  This is so
286:                macros can be defined and then used.  Also toplevel macros can
287:                expand into begin.
288:             **/
289:            public Object evalToplevel(Object x, DynamicEnvironment env) {
290:                if (U.isPair(x)) {
291:                    Object mx = Macro.expand((Pair) x);
292:                    if (x != mx)
293:                        return evalToplevel(mx, env);
294:                    else if (U.first(x) == Symbol.BEGIN) {
295:                        Object xs = U.rest(x);
296:                        Object result = null;
297:                        while (U.isPair(xs)) {
298:                            result = eval(U.first(xs), env);
299:                            xs = U.rest(xs);
300:                        }
301:                        return result;
302:                    } else
303:                        return eval(x, env);
304:                } else
305:                    return eval(x, env);
306:            }
307:
308:            //////////////// Evaluation ////////////////
309:
310:            /** Evaluate an s-expression in the global environment. **/
311:            public Object eval(Object x) {
312:                return eval(x, interactionEnvironment);
313:            }
314:
315:            /** Evaluate an s-expression in a lexical environment. First analyze
316:             * it.
317:             **/
318:            public Object eval(Object x, Object env) {
319:                DynamicEnvironment dynamicEnv = ((env == U.MISSING) ? interactionEnvironment
320:                        : (DynamicEnvironment) env);
321:                Object analyzedCode = analyze(x, dynamicEnv,
322:                        LexicalEnvironment.NULLENV);
323:                return execute(analyzedCode, LexicalEnvironment.NULLENV);
324:            }
325:
326:            /** Analyze (or preprocess or precompile) an expression into "code".
327:             * The code returned is either a Symbol, a LocalVariable, a Closure, or
328:             * an array whose first element is either one of (quote if or begin set!)
329:             * or is code evaluating to a procedure. **/
330:            public Object analyze(Object x, DynamicEnvironment dynamicEnv,
331:                    LexicalEnvironment lexenv) {
332:                if (x instanceof  Symbol) {
333:                    LocalVariable localvar = lexenv.lookup((Symbol) x); // Convert symbol to variable
334:                    if (localvar == null)
335:                        return dynamicEnv.intern((Symbol) x);
336:                    else
337:                        return localvar;
338:                } else if (!U.isPair(x))
339:                    return new Object[] { Symbol.QUOTE, x }; // Convert 42 to #(quote 42)
340:                else {
341:                    Object f = U.first(x), xm;
342:                    int len = ((Pair) x).length();
343:                    if (Symbol.LAMBDA == f && len >= 3) { // Handle (lambda ...)
344:                        Object args = U.second(x);
345:                        LexicalEnvironment lexenv2 = new LexicalEnvironment(
346:                                args, null, lexenv);
347:                        return new Closure(args, analyze(Scheme.toBody(U.rest(U
348:                                .rest(x))), dynamicEnv, lexenv2), lexenv);
349:                    } else if (Symbol.MACRO == f && len >= 3) { // Handle (macro ...)
350:                        Object args = U.second(x);
351:                        LexicalEnvironment lexenv2 = new LexicalEnvironment(
352:                                args, null, lexenv);
353:                        return new Macro(args, analyze(Scheme.toBody(U.rest(U
354:                                .rest(x))), dynamicEnv, lexenv2), lexenv);
355:                    } else if (2 == len && Symbol.BEGIN == f)
356:                        return analyze(U.second(x), dynamicEnv, lexenv); // Convert (begin x) to x
357:                    else if (x != (xm = Macro.expand((Pair) x)))
358:                        return analyze(xm, dynamicEnv, lexenv); // Analyze macroexpansion
359:                    else if (Symbol.OR == f && len == 1)
360:                        return new Object[] { Symbol.QUOTE, U.FALSE };// (or) => '#f
361:                    else if (Symbol.IF == f && len == 3) // (if a b) => (if a b #f)
362:                        return analyze(U.append(U.list(x, U.list(U.FALSE))),
363:                                dynamicEnv, lexenv);
364:                    else if (Symbol.QUOTE == f && len == 2)
365:                        return new Object[] { Symbol.QUOTE, U.second(x) };
366:                    else {
367:                        // Complain if there is was syntax error.
368:                        checkLength(f, len, x);
369:                        // Compile into a special form, or an application.
370:                        Object[] xv = U.listToVector(x); // Convert list to vector
371:                        if (!isSpecial(f))
372:                            xv[0] = analyze(xv[0], dynamicEnv, lexenv);
373:                        for (int i = 1; i < xv.length; i++) {
374:                            xv[i] = analyze(xv[i], dynamicEnv, lexenv); // Convert each element
375:                        }
376:                        return xv;
377:                    }
378:                }
379:            }
380:
381:            /** Evaluate analyzed code in a lexical environment. Don't pass this
382:             * a raw s-expression; you need to analyze the s-expression
383:             * first.
384:             **/
385:            public Object execute(Object x, LexicalEnvironment lexenv) {
386:                // The purpose of the while loop is to allow tail recursion.
387:                // The idea is that in a tail recursive position, we do "x = ..."
388:                // and loop, rather than doing "return execute(...)".
389:                do {
390:                    if (!(x instanceof  Object[])) {
391:                        if (x instanceof  DynamicVariable)
392:                            return ((DynamicVariable) x).getDynamicValue();
393:                        else if (x instanceof  LocalVariable)
394:                            return lexenv.get((LocalVariable) x);
395:                        else
396:                            return ((Closure) x).copy(lexenv);
397:                    } else {
398:                        Object[] xv = (Object[]) x;
399:                        Object f = xv[0];
400:                        if (f == Symbol.QUOTE)
401:                            return xv[1];
402:                        else if (f == Symbol.IF)
403:                            x = (U.to_bool(execute(xv[1], lexenv))) ? xv[2]
404:                                    : xv[3];
405:                        else if (f == Symbol.BEGIN)
406:                            x = executeButLast(xv, lexenv);
407:                        else if (f == Symbol.OR) {
408:                            int xvlm1 = xv.length - 1;
409:                            for (int i = 1; i < xvlm1; i++) {
410:                                Object result = execute(xv[i], lexenv);
411:                                if (U.toBool(result) != U.FALSE)
412:                                    return result;
413:                            }
414:                            // Replace x with the final one
415:                            x = xv[xvlm1];
416:                        } else if (f == Symbol.SET
417:                                && xv[1] instanceof  DynamicVariable)
418:                            return ((DynamicVariable) xv[1])
419:                                    .setDynamicValue(execute(xv[2], lexenv));
420:                        else if (f == Symbol.SET
421:                                && xv[1] instanceof  LocalVariable)
422:                            return lexenv.set((LocalVariable) xv[1], execute(
423:                                    xv[2], lexenv));
424:                        else { // Function application.
425:                            if (INTERRUPTABLE)
426:                                interruptCheck();
427:                            try {
428:                                f = executef(f, lexenv);
429:                                if (f instanceof  Closure) {
430:                                    Closure c = (Closure) f;
431:                                    x = c.body;
432:                                    lexenv = new LexicalEnvironment(c.parms, c
433:                                            .makeArgArray(xv, this , lexenv),
434:                                            c.lexenv);
435:                                } else if (f instanceof  Generic) {
436:                                    Generic g = ((Generic) f);
437:                                    Object[] args = g.makeArgArray(xv, this ,
438:                                            lexenv);
439:                                    Closure c = g.findMethod(args);
440:                                    x = c.body;
441:                                    lexenv = new LexicalEnvironment(c.parms,
442:                                            args, c.lexenv);
443:                                } else { // OTHER PROCEDURE CALL
444:                                    Procedure p = U.toProc(f);
445:                                    return p.apply(p.makeArgArray(xv, this ,
446:                                            lexenv));
447:                                }
448:                                // Continuations, and (messageless) JschemeThrowables pass through
449:                            } catch (ContinuationException ce) {
450:                                throw ce;
451:                            } catch (RuntimeException e) {
452:                                if ((e instanceof  JschemeThrowable)
453:                                        && (e.getMessage() == null))
454:                                    throw e;
455:                                else
456:                                    throw new BacktraceException(e, xv, lexenv);
457:                            }
458:                        }
459:                    }
460:                } while (true);
461:            }
462:
463:            /** Specialized execute() where x is the function of an application. **/
464:            private Object executef(Object x, LexicalEnvironment lexenv) {
465:                if (x instanceof  DynamicVariable)
466:                    return ((DynamicVariable) x).getDynamicValue();
467:                else if (x instanceof  LocalVariable)
468:                    return lexenv.get((LocalVariable) x);
469:                else if (x instanceof  Closure)
470:                    return ((Closure) x).copy(lexenv);
471:                else
472:                    return execute(x, lexenv);
473:            }
474:
475:            private static boolean isSpecial(Object f) {
476:                return f == Symbol.SET || f == Symbol.IF || f == Symbol.BEGIN
477:                        || f == Symbol.OR || f == Symbol.QUOTE;
478:            }
479:
480:            private static void checkLength(Object f, int len, Object x) {
481:                if ((f == Symbol.LAMBDA && len < 3)
482:                        || (f == Symbol.MACRO && len < 3)
483:                        || (f == Symbol.SET && len != 3)
484:                        || (f == Symbol.IF && len != 4)
485:                        || (f == Symbol.BEGIN && len <= 2)
486:                        || (f == Symbol.OR && len < 2)
487:                        || (f == Symbol.QUOTE && len != 2))
488:                    E.warn("wrong number of arguments for syntax:", x);
489:            }
490:
491:            /** Evaluate **/
492:            private Object executeButLast(Object[] xv, LexicalEnvironment lexenv) {
493:                for (int i = 1; i < xv.length - 1; i++) {
494:                    execute(xv[i], lexenv);
495:                }
496:                return xv[xv.length - 1];
497:            }
498:
499:            private void showVersion() {
500:                error.println(getVersion());
501:            }
502:
503:            private String getVersion() {
504:                String defaultmsg = "Jscheme http://jscheme.sourceforge.net";
505:                String name = "jsint/version.txt";
506:                ClassLoader loader = Import.getClassLoader();
507:                InputStream stream = (loader == null) ? ClassLoader
508:                        .getSystemResourceAsStream(name) : loader
509:                        .getResourceAsStream(name);
510:                if (stream == null)
511:                    return defaultmsg;
512:                else {
513:                    BufferedReader r = new BufferedReader(
514:                            new InputStreamReader(stream));
515:                    try {
516:                        return r.readLine();
517:                    } catch (IOException e) {
518:                        return defaultmsg;
519:                    }
520:                }
521:            }
522:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.