Source Code Cross Referenced for EvaluateVisitor.java in  » Scripting » oscript-2.10.4 » oscript » interpreter » 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 » oscript 2.10.4 » oscript.interpreter 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*=============================================================================
0002:         *     Copyright Texas Instruments 2000-2003.  All Rights Reserved.
0003:         *   
0004:         * This program is free software; you can redistribute it and/or
0005:         * modify it under the terms of the GNU Lesser General Public
0006:         * License as published by the Free Software Foundation; either
0007:         * version 2 of the License, or (at your option) any later version.
0008:         * 
0009:         * This program is distributed in the hope that it will be useful,
0010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012:         * Lesser General Public License for more details.
0013:         * 
0014:         * You should have received a copy of the GNU Lesser General Public
0015:         * License along with this library; if not, write to the Free Software
0016:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0017:         * 
0018:         * $ProjectHeader: OSCRIPT 0.155 Fri, 20 Dec 2002 18:34:22 -0800 rclark $
0019:         */
0020:
0021:        package oscript.interpreter;
0022:
0023:        import oscript.syntaxtree.*;
0024:        import oscript.util.StackFrame;
0025:        import oscript.data.*;
0026:        import oscript.exceptions.*;
0027:        import oscript.visitor.ObjectVisitor;
0028:        import oscript.parser.OscriptParser;
0029:        import oscript.parser.OscriptParserConstants;
0030:        import oscript.parser.ParseException;
0031:        import oscript.OscriptInterpreter;
0032:        import oscript.translator.*;
0033:
0034:        /* RET like instructions "return", "break", and "continue" are used by
0035:         *     throwing an exception, and catching it in the appropriate places.
0036:         */
0037:        class Return extends RuntimeException {
0038:            Return() {
0039:                super ();
0040:            }
0041:        }
0042:
0043:        class Break extends RuntimeException {
0044:            Break() {
0045:                super ();
0046:            }
0047:        }
0048:
0049:        class Continue extends RuntimeException {
0050:            Continue() {
0051:                super ();
0052:            }
0053:        }
0054:
0055:        /* NOTE: in places where values are cached in the syntaxtree, there is too
0056:         *       much overlap between EvaluateVisitor and CompilerVisitor... try to
0057:         *       find a way to rectify this.
0058:         */
0059:
0060:        /**
0061:         * The EvaluateVisitor is the heart of the interpreter.
0062:         * 
0063:         * @author Rob Clark (rob@ti.com)
0064:         * <!--$Format: " * @version $Revision$"$-->
0065:         * @version 1.123
0066:         */
0067:        public class EvaluateVisitor implements  ObjectVisitor,
0068:                OscriptParserConstants {
0069:            /**
0070:             * The current scope.  This is passed as an argument to the constructor, 
0071:             * and does not change for the live of the evaluator.
0072:             */
0073:            private Scope this Scope;
0074:
0075:            /* For now I am using this naming convention to encode values that are
0076:             * "returned" by some of the visit methods.  I want to avoid the overhead
0077:             * of allocating memory to return values, so we do it by instance variables.
0078:             * The convention is that they are set by the visitor and read-only to
0079:             * everyone else.  
0080:             */
0081:            private int NodeToken_kind;
0082:            private NodeToken NodeToken_lastToken; // for generating error messages
0083:            private java.util.Vector NodeToken_lastSpecials;
0084:
0085:            private int[] Arglist_names;
0086:            private boolean Arglist_varargs;
0087:
0088:            private int Permissions_attr;
0089:
0090:            // to save a bit on the overhead of allocating a new object, and
0091:            // filling in the stack trace (which we don't need), we reuse
0092:            // these exceptions:
0093:            private Value retVal = Value.UNDEFINED;
0094:            private static final Return RETURN = new Return();
0095:            private static final Break BREAK = new Break();
0096:            private static final Continue CONTINUE = new Continue();
0097:
0098:            /*=======================================================================*/
0099:            /**
0100:             * Class Constructor.  An <code>EvaluateVisitor</code> is constructed
0101:             * to evaluate within a specified context (scope).  The context' purpose
0102:             * is twofold:  1) it is used to implement block structure, for example:
0103:             * <pre>
0104:             *   ... some script ...
0105:             *   {
0106:             *      var someVar;
0107:             *      ... some script ...
0108:             *   }
0109:             * </pre>
0110:             * the block containing the variable <code>someVar</code> is evaluated
0111:             * in a new context (with the current context as the previous context).
0112:             * <p>
0113:             * It is also used for 2) implementing function/method calls.  When a
0114:             * function/method is called, a new context is created, with the
0115:             * context the function/method was declared in as the previous
0116:             * context.
0117:             * <p>
0118:             * NOTE: there are cases where we re-use the <code>EvaluateVisitor</code>
0119:             * for efficiency... need to document that better.
0120:             * 
0121:             * @param thisScope    the context to evaluate within
0122:             */
0123:            public EvaluateVisitor(Scope this Scope) {
0124:                this .this Scope = this Scope;
0125:            }
0126:
0127:            /*=======================================================================*/
0128:            /**
0129:             */
0130:            public NodeToken getLastNodeToken() {
0131:                return NodeToken_lastToken;
0132:            }
0133:
0134:            /*=======================================================================*/
0135:            /**
0136:             */
0137:            public Value evaluateFunction(Program n) {
0138:                Value val = null;
0139:
0140:                try {
0141:                    val = (Value) (n.accept(this , null));
0142:                } catch (Return r) {
0143:                    val = retVal;
0144:                }
0145:
0146:                if (val == null)
0147:                    val = Value.NULL;
0148:
0149:                return val;
0150:            }
0151:
0152:            /*=======================================================================*/
0153:            /**
0154:             */
0155:            public Object visit(NodeList n, Object argu) {
0156:                return null;
0157:            }
0158:
0159:            /*=======================================================================*/
0160:            /**
0161:             */
0162:            public Object visit(NodeListOptional n, Object argu) {
0163:                return null;
0164:            }
0165:
0166:            /*=======================================================================*/
0167:            /**
0168:             */
0169:            public Object visit(NodeOptional n, Object argu) {
0170:                return null;
0171:            }
0172:
0173:            /*=======================================================================*/
0174:            /**
0175:             */
0176:            public Object visit(NodeSequence n, Object argu) {
0177:                return null;
0178:            }
0179:
0180:            /*=======================================================================*/
0181:            /**
0182:             */
0183:            public Object visit(NodeToken n, Object argu) {
0184:                NodeToken_kind = n.kind;
0185:                NodeToken_lastToken = n;
0186:
0187:                StackFrame.currentStackFrame().setLineNumber(this Scope,
0188:                        n.beginLine);
0189:
0190:                if (n.specialTokens != null)
0191:                    NodeToken_lastSpecials = n.specialTokens;
0192:
0193:                if (n.cachedValue == null) {
0194:                    switch (n.kind) {
0195:                    case IDENTIFIER:
0196:                        n.cachedValue = n.otokenImage;
0197:                        break;
0198:                    case INTEGER_LITERAL:
0199:                    case HEX_LITERAL:
0200:                    case OCTAL_LITERAL:
0201:                    case BINARY_LITERAL:
0202:                    case DECIMAL_LITERAL:
0203:                        n.cachedValue = OExactNumber
0204:                                .makeExactNumber(n.otokenImage
0205:                                        .castToExactNumber());
0206:                        break;
0207:                    case FLOATING_POINT_LITERAL:
0208:                        n.cachedValue = OInexactNumber
0209:                                .makeInexactNumber(n.otokenImage
0210:                                        .castToInexactNumber());
0211:                        break;
0212:                    case STRING_LITERAL:
0213:                        n.cachedValue = new OString(OString.chop(n.tokenImage
0214:                                .substring(1, n.tokenImage.length() - 1))); // should this be intern'd???
0215:                        break;
0216:                    case REGEXP_LITERAL:
0217:                        n.cachedValue = RegExp.createRegExp(n.otokenImage);
0218:                        break;
0219:                    case TRUE:
0220:                        n.cachedValue = OBoolean.TRUE;
0221:                        break;
0222:                    case FALSE:
0223:                        n.cachedValue = OBoolean.FALSE;
0224:                        break;
0225:                    case NULL:
0226:                        n.cachedValue = Value.NULL;
0227:                        break;
0228:                    case UNDEFINED:
0229:                        n.cachedValue = Value.UNDEFINED;
0230:                        break;
0231:                    case -1:
0232:                    default:
0233:                        // leave as null
0234:                    }
0235:                }
0236:
0237:                return n.cachedValue;
0238:            }
0239:
0240:            /*=======================================================================*/
0241:            /**
0242:             * <PRE>
0243:             * f0 -> ( &lt;UNIX_SELF_EXECUTABLE_COMMENT&gt; )?
0244:             * f1 -> Program(false)
0245:             * f2 -> &lt;EOF&gt;
0246:             * </PRE>
0247:             */
0248:            public Object visit(ProgramFile n, Object argu) {
0249:                return n.f1.accept(this , argu);
0250:            }
0251:
0252:            /*=======================================================================*/
0253:            /**
0254:             * <PRE>
0255:             * f0 -> ( EvaluationUnit() )*
0256:             * </PRE>
0257:             */
0258:            public Object visit(Program n, Object argu) {
0259:                Value val = null;
0260:
0261:                for (int i = 0; i < n.f0.size(); i++) {
0262:                    val = (Value) (n.f0.elementAt(i).accept(this , argu));
0263:                }
0264:
0265:                return val;
0266:            }
0267:
0268:            /*=======================================================================*/
0269:            /**
0270:             * <PRE>
0271:             * f0 -> ScopeBlock()
0272:             *       | VariableDeclarationBlock()
0273:             *       | FunctionDeclaration()
0274:             *       | TryStatement()
0275:             *       | ForLoopStatement()
0276:             *       | WhileLoopStatement()
0277:             *       | ConditionalStatement()
0278:             *       | SynchronizedStatement()
0279:             *       | ReturnStatement()
0280:             *       | BreakStatement()
0281:             *       | ContinueStatement()
0282:             *       | ExpressionBlock()
0283:             *       | ThrowBlock()
0284:             *       | ImportBlock()
0285:             *       | MixinBlock()
0286:             *       | EvalBlock()
0287:             * </PRE>
0288:             */
0289:            public Object visit(EvaluationUnit n, Object argu) {
0290:                return n.f0.accept(this , argu);
0291:            }
0292:
0293:            /*=======================================================================*/
0294:            /**
0295:             * <PRE>
0296:             * f0 -> "{"
0297:             * f1 -> Program()
0298:             * f2 -> "}"
0299:             * </PRE>
0300:             */
0301:            public Object visit(ScopeBlock n, Object argu) {
0302:                // push new scope:
0303:                Scope savedThisScope = this Scope;
0304:                this Scope = new BasicScope(this Scope);
0305:
0306:                Object retVal;
0307:
0308:                try {
0309:                    retVal = n.f1.accept(this , argu);
0310:                } finally {
0311:                    // pop:
0312:                    this Scope = savedThisScope;
0313:                }
0314:
0315:                return retVal;
0316:            }
0317:
0318:            /*=======================================================================*/
0319:            /**
0320:             * <PRE>
0321:             * f0 -> VariableDeclaration()
0322:             * f1 -> ";"
0323:             * </PRE>
0324:             */
0325:            public Object visit(VariableDeclarationBlock n, Object argu) {
0326:                return n.f0.accept(this , argu);
0327:            }
0328:
0329:            /*=======================================================================*/
0330:            /**
0331:             * <PRE>
0332:             * f0 -> Expression()
0333:             * f1 -> ";"
0334:             * </PRE>
0335:             */
0336:            public Object visit(ExpressionBlock n, Object argu) {
0337:                return n.f0.accept(this , argu);
0338:            }
0339:
0340:            /*=======================================================================*/
0341:            /**
0342:             * <PRE>
0343:             * f0 -> "throw"
0344:             * f1 -> Expression()
0345:             * f2 -> ";"
0346:             * </PRE>
0347:             */
0348:            public Object visit(ThrowBlock n, Object argu) {
0349:                Value val = returnHelper((Value) (n.f1.accept(this , argu)));
0350:
0351:                throw PackagedScriptObjectException.makeExceptionWrapper2(val);
0352:            }
0353:
0354:            /*=======================================================================*/
0355:            /**
0356:             * <PRE>
0357:             * f0 -> "import"
0358:             * f1 -> Expression()
0359:             * f2 -> ";"
0360:             * </PRE>
0361:             */
0362:            public Object visit(ImportBlock n, Object argu) {
0363:                Value val = (Value) (n.f1.accept(this , argu));
0364:                return OscriptInterpreter.importHelper(val.castToString(),
0365:                        this Scope);
0366:            }
0367:
0368:            /*=======================================================================*/
0369:            /**
0370:             * <PRE>
0371:             * f0 -> "mixin"
0372:             * f1 -> Expression()
0373:             * f2 -> ";"
0374:             * </PRE>
0375:             */
0376:            public Object visit(MixinBlock n, Object argu) {
0377:                this Scope.mixin((Value) (n.f1.accept(this , argu)));
0378:                return null;
0379:            }
0380:
0381:            /*=======================================================================*/
0382:            /**
0383:             * <PRE>
0384:             * f0 -> "eval"
0385:             * f1 -> Expression()
0386:             * f2 -> ";"
0387:             * </PRE>
0388:             */
0389:            public Object visit(EvalBlock n, Object argu) {
0390:                // f1 should evaluate to a string:
0391:                Value val = (Value) (n.f1.accept(this , argu));
0392:
0393:                try {
0394:                    OscriptInterpreter.eval(val.castToString(), this Scope);
0395:                } catch (ParseException e) {
0396:                    throw PackagedScriptObjectException
0397:                            .makeExceptionWrapper(new OException(e.getMessage()));
0398:                }
0399:
0400:                return null;
0401:            }
0402:
0403:            /*=======================================================================*/
0404:            /**
0405:             * <PRE>
0406:             * f0 -> Permissions()
0407:             * f1 -> "var"
0408:             * f2 -> &lt;IDENTIFIER&gt;
0409:             * f3 -> ( "=" Expression() )?
0410:             * </PRE>
0411:             */
0412:            public Object visit(VariableDeclaration n, Object argu) {
0413:                n.f0.accept(this , argu);
0414:
0415:                Value val = null;
0416:
0417:                if (n.f3.present())
0418:                    val = (Value) (((NodeSequence) (n.f3.node)).elementAt(1)
0419:                            .accept(this , argu));
0420:
0421:                Value var = this Scope.createMember((Value) (n.f2.accept(this ,
0422:                        argu)), Permissions_attr);
0423:
0424:                if (n.f3.present())
0425:                    var.opAssign(val);
0426:
0427:                return null;
0428:            }
0429:
0430:            /*=======================================================================*/
0431:            /**
0432:             * <PRE>
0433:             * f0 -> Permissions()
0434:             * f1 -> "function"
0435:             * f2 -> &lt;IDENTIFIER&gt;
0436:             * f3 -> "("
0437:             * f4 -> ( Arglist() )?
0438:             * f5 -> ")"
0439:             * f6 -> ( "extends" PrimaryExpressionWithTrailingFxnCallExpList() FunctionCallExpressionList() )?
0440:             * f7 -> "{"
0441:             * f8 -> Program()
0442:             * f9 -> "}"
0443:             * </PRE>
0444:             */
0445:            public Object visit(FunctionDeclaration n, Object argu) {
0446:                return FunctionDeclarationTranslator.translate(n).accept(this ,
0447:                        argu);
0448:            }
0449:
0450:            /*=======================================================================*/
0451:            /**
0452:             * <PRE>
0453:             * f0 -> Permissions()
0454:             * f1 -> &lt;IDENTIFIER&gt;
0455:             * f2 -> ( "," Permissions() &lt;IDENTIFIER&gt; )*
0456:             * f3 -> ( "..." )?
0457:             * </PRE>
0458:             */
0459:            public Object visit(Arglist n, Object argu) {
0460:                if (n.cachedValue == null) {
0461:                    int len = 2 * (n.f2.size() + 1);
0462:
0463:                    n.cachedValue = new int[len];
0464:                    n.cachedValue[0] = Symbol.getSymbol(
0465:                            (OString) (n.f1.accept(this , argu))).getId();
0466:                    n.cachedValue[1] = getPermissions(n.f0,
0467:                            Reference.ATTR_PRIVATE);
0468:
0469:                    for (int i = 0; i < n.f2.size(); i++) {
0470:                        n.cachedValue[2 * (i + 1)] = Symbol.getSymbol(
0471:                                (OString) (((NodeSequence) (n.f2.elementAt(i)))
0472:                                        .elementAt(2).accept(this , argu)))
0473:                                .getId();
0474:                        n.cachedValue[2 * (i + 1) + 1] = getPermissions(
0475:                                (Permissions) (((NodeSequence) (n.f2
0476:                                        .elementAt(i))).elementAt(1)),
0477:                                Reference.ATTR_PRIVATE);
0478:                    }
0479:                }
0480:
0481:                Arglist_names = n.cachedValue;
0482:                Arglist_varargs = n.f3.present();
0483:
0484:                return null;
0485:            }
0486:
0487:            /*=======================================================================*/
0488:            /**
0489:             * <PRE>
0490:             * f0 -> "try"
0491:             * f1 -> EvaluationUnit()
0492:             * f2 -> ( "catch" "(" Expression() &lt;IDENTIFIER&gt; ")" EvaluationUnit() )*
0493:             * f3 -> ( "catch" "(" &lt;IDENTIFIER&gt; ")" EvaluationUnit() )?
0494:             * f4 -> ( "finally" EvaluationUnit() )?
0495:             * </PRE>
0496:             */
0497:            public Object visit(TryStatement n, Object argu) {
0498:                try {
0499:                    n.f1.accept(this , argu);
0500:                } catch (PackagedScriptObjectException e) {
0501:                    NodeToken nt = getLastNodeToken();
0502:
0503:                    boolean handled = false;
0504:
0505:                    for (int i = 0; (i < n.f2.size()) && !handled; i++) {
0506:                        NodeSequence seq = (NodeSequence) (n.f2.elementAt(i));
0507:
0508:                        Value val = (Value) (seq.elementAt(2)
0509:                                .accept(this , argu));
0510:
0511:                        if (e.val.bopInstanceOf(val).castToBoolean()) {
0512:                            handled = true;
0513:
0514:                            // push:
0515:                            Scope savedThisScope = this Scope;
0516:                            this Scope = new BasicScope(this Scope);
0517:
0518:                            try {
0519:                                Value var = this Scope
0520:                                        .createMember((Value) (seq.elementAt(3)
0521:                                                .accept(this , argu)), 0 /*XXX*/);
0522:                                var.opAssign(e.val);
0523:
0524:                                seq.elementAt(5).accept(this , argu);
0525:                            } finally {
0526:                                // pop:
0527:                                this Scope = savedThisScope;
0528:                            }
0529:                        }
0530:                    }
0531:
0532:                    if (n.f3.present() && !handled) {
0533:                        handled = true;
0534:
0535:                        NodeSequence seq = (NodeSequence) (n.f3.node);
0536:
0537:                        // push:
0538:                        Scope savedThisScope = this Scope;
0539:                        this Scope = new BasicScope(this Scope);
0540:
0541:                        try {
0542:                            Value var = this Scope
0543:                                    .createMember((Value) (seq.elementAt(2)
0544:                                            .accept(this , argu)), 0 /*XXX*/);
0545:                            var.opAssign(e.val);
0546:
0547:                            seq.elementAt(4).accept(this , argu);
0548:                        } finally {
0549:                            // pop:
0550:                            this Scope = savedThisScope;
0551:                        }
0552:                    }
0553:
0554:                    if (!handled)
0555:                        throw e;
0556:                } finally {
0557:                    // XXX this is maybe a bug, if BREAK, CONTINUE, or RETURN are thrown...
0558:                    if (n.f4.present())
0559:                        ((NodeSequence) (n.f4.node)).elementAt(1).accept(this ,
0560:                                argu);
0561:                }
0562:
0563:                return null;
0564:            }
0565:
0566:            /*=======================================================================*/
0567:            /**
0568:             * <PRE>
0569:             * f0 -> "for"
0570:             * f1 -> "("
0571:             * f2 -> ( PreLoopStatement() )?
0572:             * f3 -> ";"
0573:             * f4 -> ( Expression() )?
0574:             * f5 -> ";"
0575:             * f6 -> ( Expression() )?
0576:             * f7 -> ")"
0577:             * f8 -> EvaluationUnit()
0578:             * </PRE>
0579:             */
0580:            public Object visit(ForLoopStatement n, Object argu) {
0581:                return ForLoopStatementTranslator.translate(n).accept(this ,
0582:                        argu);
0583:            }
0584:
0585:            /*=======================================================================*/
0586:            /**
0587:             * <PRE>
0588:             * f0 -> "for"
0589:             * f1 -> "("
0590:             * f2 -> PreLoopStatement()
0591:             * f3 -> ":"
0592:             * f4 -> Expression()
0593:             * f5 -> ")"
0594:             * f6 -> EvaluationUnit()
0595:             * </PRE>
0596:             */
0597:            public Object visit(CollectionForLoopStatement n, Object argu) {
0598:                return CollectionForLoopStatementTranslator.translate(n)
0599:                        .accept(this , argu);
0600:            }
0601:
0602:            /*=======================================================================*/
0603:            /**
0604:             * <PRE>
0605:             * f0 -> VariableDeclaration()
0606:             *       | Expression()
0607:             * </PRE>
0608:             */
0609:            public Object visit(PreLoopStatement n, Object argu) {
0610:                return n.f0.accept(this , argu);
0611:            }
0612:
0613:            /*=======================================================================*/
0614:            /**
0615:             * <PRE>
0616:             * f0 -> "while"
0617:             * f1 -> "("
0618:             * f2 -> Expression()
0619:             * f3 -> ")"
0620:             * f4 -> EvaluationUnit()
0621:             * </PRE>
0622:             */
0623:            public Object visit(WhileLoopStatement n, Object argu) {
0624:                while (((Value) (n.f2.accept(this , argu))).castToBoolean()) {
0625:                    // evaluate body:
0626:                    try {
0627:                        n.f4.accept(this , argu);
0628:                    } catch (Break e) {
0629:                        break;
0630:                    } catch (Continue e) {
0631:                        continue;
0632:                    }
0633:                }
0634:
0635:                return null;
0636:            }
0637:
0638:            /*=======================================================================*/
0639:            /**
0640:             * <PRE>
0641:             * f0 -> "if"
0642:             * f1 -> "("
0643:             * f2 -> Expression()
0644:             * f3 -> ")"
0645:             * f4 -> EvaluationUnit()
0646:             * f5 -> ( "else" EvaluationUnit() )?
0647:             * </PRE>
0648:             */
0649:            public Object visit(ConditionalStatement n, Object argu) {
0650:                Value val = (Value) (n.f2.accept(this , argu));
0651:
0652:                if (val.castToBoolean()) {
0653:                    n.f4.accept(this , argu);
0654:                } else if (n.f5.present()) {
0655:                    ((NodeSequence) (n.f5.node)).elementAt(1)
0656:                            .accept(this , argu);
0657:                }
0658:
0659:                return null;
0660:            }
0661:
0662:            /*=======================================================================*/
0663:            /**
0664:             * <PRE>
0665:             * f0 -> "synchronized"
0666:             * f1 -> "("
0667:             * f2 -> Expression()
0668:             * f3 -> ")"
0669:             * f4 -> EvaluationUnit()
0670:             * </PRE>
0671:             */
0672:            public Object visit(SynchronizedStatement n, Object argu) {
0673:                Value syncVal = (Value) (n.f2.accept(this , argu));
0674:
0675:                synchronized (syncVal.getMonitor()) {
0676:                    n.f4.accept(this , argu);
0677:                }
0678:
0679:                return null;
0680:            }
0681:
0682:            /*=======================================================================*/
0683:            /**
0684:             * <PRE>
0685:             * f0 -> "return"
0686:             * f1 -> ( Expression() )?
0687:             * </PRE>
0688:             */
0689:            public Object visit(ReturnStatement n, Object argu) {
0690:                retVal = Value.UNDEFINED;
0691:
0692:                if (n.f1.present())
0693:                    retVal = returnHelper((Value) (n.f1.node.accept(this , argu)));
0694:
0695:                throw RETURN;
0696:            }
0697:
0698:            private static final Value returnHelper(Value val) {
0699:                // XXX
0700:                return oscript.compiler.CompiledNodeEvaluator.returnHelper(val);
0701:            }
0702:
0703:            /*=======================================================================*/
0704:            /**
0705:             * <PRE>
0706:             * f0 -> "break"
0707:             * f1 -> ";"
0708:             * </PRE>
0709:             */
0710:            public Object visit(BreakStatement n, Object argu) {
0711:                throw new Break();
0712:            }
0713:
0714:            /*=======================================================================*/
0715:            /**
0716:             * <PRE>
0717:             * f0 -> "continue"
0718:             * f1 -> ";"
0719:             * </PRE>
0720:             */
0721:            public Object visit(ContinueStatement n, Object argu) {
0722:                throw new Continue();
0723:            }
0724:
0725:            /*=======================================================================*/
0726:            /**
0727:             * <PRE>
0728:             * f0 -> AssignmentExpression()
0729:             * f1 -> ( "," AssignmentExpression() )*
0730:             * </PRE>
0731:             */
0732:            public Object visit(Expression n, Object argu) {
0733:                Value val = (Value) (n.f0.accept(this , argu));
0734:
0735:                for (int i = 0; i < n.f1.size(); i++) {
0736:                    NodeSequence seq = (NodeSequence) (n.f1.elementAt(i));
0737:                    NodeToken op = (NodeToken) (seq.elementAt(0));
0738:
0739:                    val = (Value) (seq.elementAt(1).accept(this , argu));
0740:                }
0741:
0742:                return val;
0743:            }
0744:
0745:            /*=======================================================================*/
0746:            /**
0747:             * <PRE>
0748:             * f0 -> "("
0749:             * f1 -> ( FunctionCallExpressionListBody() )?
0750:             * f2 -> ")"
0751:             * </PRE>
0752:             */
0753:            public Object visit(FunctionCallExpressionList n, Object argu) {
0754:                n.f0.accept(this , argu); // to record last NodeToken
0755:
0756:                if (n.f1.present())
0757:                    return n.f1.node.accept(this , argu);
0758:                else
0759:                    return new Value[0];
0760:            }
0761:
0762:            /*=======================================================================*/
0763:            /**
0764:             * <PRE>
0765:             * f0 -> AssignmentExpression()
0766:             * f1 -> ( "," AssignmentExpression() )*
0767:             * </PRE>
0768:             */
0769:            public Object visit(FunctionCallExpressionListBody n, Object argu) {
0770:                Value[] vals = new Value[1 + n.f1.size()];
0771:
0772:                vals[0] = ((Value) (n.f0.accept(this , argu))).unhand();
0773:
0774:                for (int i = 0; i < n.f1.size(); i++) {
0775:                    NodeSequence seq = (NodeSequence) (n.f1.elementAt(i));
0776:
0777:                    vals[i + 1] = ((Value) (seq.elementAt(1).accept(this , argu)))
0778:                            .unhand();
0779:                }
0780:
0781:                return vals;
0782:            }
0783:
0784:            /*=======================================================================*/
0785:            /**
0786:             * <PRE>
0787:             * f0 -> ConditionalExpression()
0788:             * f1 -> ( ( "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&gt;&gt;=" | "&lt;&lt;=" | "&gt;&gt;&gt;=" | "&=" | "^=" | "|=" ) ConditionalExpression() )*
0789:             * </PRE>
0790:             */
0791:            public Object visit(AssignmentExpression n, Object argu) {
0792:                Value lastVal = null;
0793:                int lastOp = -1;
0794:
0795:                for (int i = n.f1.size() - 1; i >= -1; i--) {
0796:                    Value val;
0797:                    int op = lastOp; // the op this time through the loop was determined last time
0798:
0799:                    if (i >= 0) {
0800:                        NodeSequence seq = (NodeSequence) (n.f1.elementAt(i));
0801:
0802:                        val = (Value) (seq.elementAt(1).accept(this , argu));
0803:                        lastOp = ((NodeToken) (((NodeChoice) (seq.elementAt(0))).choice)).kind;
0804:                    } else {
0805:                        val = (Value) (n.f0.accept(this , argu));
0806:                    }
0807:
0808:                    if (op != -1) {
0809:                        switch (op) {
0810:                        case ASSIGN:
0811:                            // no-op
0812:                            break;
0813:                        case PLUSASSIGN:
0814:                            lastVal = val.bopPlus(lastVal);
0815:                            break;
0816:                        case MINUSASSIGN:
0817:                            lastVal = val.bopMinus(lastVal);
0818:                            break;
0819:                        case STARASSIGN:
0820:                            lastVal = val.bopMultiply(lastVal);
0821:                            break;
0822:                        case SLASHASSIGN:
0823:                            lastVal = val.bopDivide(lastVal);
0824:                            break;
0825:                        case ANDASSIGN:
0826:                            lastVal = val.bopBitwiseAnd(lastVal);
0827:                            break;
0828:                        case ORASSIGN:
0829:                            lastVal = val.bopBitwiseOr(lastVal);
0830:                            break;
0831:                        case XORASSIGN:
0832:                            lastVal = val.bopBitwiseXor(lastVal);
0833:                            break;
0834:                        case REMASSIGN:
0835:                            lastVal = val.bopRemainder(lastVal);
0836:                            break;
0837:                        case LSHIFTASSIGN:
0838:                            lastVal = val.bopLeftShift(lastVal);
0839:                            break;
0840:                        case RSIGNEDSHIFTASSIGN:
0841:                            lastVal = val.bopSignedRightShift(lastVal);
0842:                            break;
0843:                        case RUNSIGNEDSHIFTASSIGN:
0844:                            lastVal = val.bopUnsignedRightShift(lastVal);
0845:                            break;
0846:                        default:
0847:                            throw new ProgrammingErrorException(
0848:                                    "unknown operator: " + op);
0849:                        }
0850:
0851:                        val.opAssign(lastVal);
0852:                    }
0853:
0854:                    lastVal = val;
0855:                }
0856:
0857:                return lastVal;
0858:            }
0859:
0860:            /*=======================================================================*/
0861:            /**
0862:             * <PRE>
0863:             * f0 -> LogicalOrExpression()
0864:             * f1 -> ( "?" LogicalOrExpression() ":" LogicalOrExpression() )?
0865:             * </PRE>
0866:             */
0867:            public Object visit(ConditionalExpression n, Object argu) {
0868:                Value val = (Value) (n.f0.accept(this , argu));
0869:
0870:                if (n.f1.present()) {
0871:                    if (val.castToBoolean())
0872:                        val = (Value) (((NodeListInterface) n.f1.node)
0873:                                .elementAt(1).accept(this , argu));
0874:                    else
0875:                        val = (Value) (((NodeListInterface) n.f1.node)
0876:                                .elementAt(3).accept(this , argu));
0877:                }
0878:
0879:                return val;
0880:            }
0881:
0882:            /*=======================================================================*/
0883:            /**
0884:             * <PRE>
0885:             * f0 -> LogicalAndExpression()
0886:             * f1 -> ( "||" LogicalAndExpression() )*
0887:             * </PRE>
0888:             */
0889:            public Object visit(LogicalOrExpression n, Object argu) {
0890:                Value val = (Value) (n.f0.accept(this , argu));
0891:
0892:                for (int i = 0; i < n.f1.size(); i++) {
0893:                    if (val.castToBoolean())
0894:                        break;
0895:
0896:                    NodeSequence seq = (NodeSequence) (n.f1.elementAt(i));
0897:
0898:                    // evaluate rhs:
0899:                    Value val2 = (Value) (seq.elementAt(1).accept(this , argu));
0900:
0901:                    val = val.bopLogicalOr(val2);
0902:                }
0903:
0904:                return val;
0905:            }
0906:
0907:            /*=======================================================================*/
0908:            /**
0909:             * <PRE>
0910:             * f0 -> BitwiseOrExpression()
0911:             * f1 -> ( "&&" BitwiseOrExpression() )*
0912:             * </PRE>
0913:             */
0914:            public Object visit(LogicalAndExpression n, Object argu) {
0915:                Value val = (Value) (n.f0.accept(this , argu));
0916:
0917:                for (int i = 0; i < n.f1.size(); i++) {
0918:                    if (!val.castToBoolean())
0919:                        break;
0920:
0921:                    NodeSequence seq = (NodeSequence) (n.f1.elementAt(i));
0922:
0923:                    // evaluate rhs:
0924:                    Value val2 = (Value) (seq.elementAt(1).accept(this , argu));
0925:
0926:                    val = val.bopLogicalAnd(val2);
0927:                }
0928:
0929:                return val;
0930:            }
0931:
0932:            /*=======================================================================*/
0933:            /**
0934:             * <PRE>
0935:             * f0 -> BitwiseXorExpression()
0936:             * f1 -> ( "|" BitwiseXorExpression() )*
0937:             * </PRE>
0938:             */
0939:            public Object visit(BitwiseOrExpression n, Object argu) {
0940:                Value val = (Value) (n.f0.accept(this , argu));
0941:
0942:                for (int i = 0; i < n.f1.size(); i++) {
0943:                    Value val2 = (Value) ((((NodeSequence) n.f1.elementAt(i)))
0944:                            .elementAt(1).accept(this , argu));
0945:
0946:                    val = val.bopBitwiseOr(val2);
0947:                }
0948:
0949:                return val;
0950:            }
0951:
0952:            /*=======================================================================*/
0953:            /**
0954:             * <PRE>
0955:             * f0 -> BitwiseAndExpression()
0956:             * f1 -> ( "^" BitwiseAndExpression() )*
0957:             * </PRE>
0958:             */
0959:            public Object visit(BitwiseXorExpression n, Object argu) {
0960:                Value val = (Value) (n.f0.accept(this , argu));
0961:
0962:                for (int i = 0; i < n.f1.size(); i++) {
0963:                    Value val2 = (Value) ((((NodeSequence) n.f1.elementAt(i)))
0964:                            .elementAt(1).accept(this , argu));
0965:
0966:                    val = val.bopBitwiseXor(val2);
0967:                }
0968:
0969:                return val;
0970:            }
0971:
0972:            /*=======================================================================*/
0973:            /**
0974:             * <PRE>
0975:             * f0 -> EqualityExpression()
0976:             * f1 -> ( "&" EqualityExpression() )*
0977:             * </PRE>
0978:             */
0979:            public Object visit(BitwiseAndExpression n, Object argu) {
0980:                Value val = (Value) (n.f0.accept(this , argu));
0981:
0982:                for (int i = 0; i < n.f1.size(); i++) {
0983:                    Value val2 = (Value) ((((NodeSequence) n.f1.elementAt(i)))
0984:                            .elementAt(1).accept(this , argu));
0985:
0986:                    val = val.bopBitwiseAnd(val2);
0987:                }
0988:
0989:                return val;
0990:            }
0991:
0992:            /*=======================================================================*/
0993:            /**
0994:             * <PRE>
0995:             * f0 -> RelationalExpression()
0996:             * f1 -> ( ( "==" | "!=" ) RelationalExpression() )*
0997:             * </PRE>
0998:             */
0999:            public Object visit(EqualityExpression n, Object argu) {
1000:                Value val = (Value) (n.f0.accept(this , argu));
1001:
1002:                for (int i = 0; i < n.f1.size(); i++) {
1003:                    NodeSequence seq = (NodeSequence) (n.f1.elementAt(i));
1004:                    NodeToken op = (NodeToken) (((NodeChoice) (seq.elementAt(0))).choice);
1005:
1006:                    Value val2 = (Value) (seq.elementAt(1).accept(this , argu));
1007:
1008:                    switch (op.kind) {
1009:                    case EQ:
1010:                        val = val.bopEquals(val2);
1011:                        break;
1012:                    case NE:
1013:                        val = val.bopNotEquals(val2);
1014:                        break;
1015:                    default:
1016:                        throw new ProgrammingErrorException("bad binary op: "
1017:                                + OscriptParser.getTokenString(op.kind));
1018:                    }
1019:                }
1020:
1021:                return val;
1022:            }
1023:
1024:            /*=======================================================================*/
1025:            /**
1026:             * <PRE>
1027:             * f0 -> ShiftExpression()
1028:             * f1 -> ( ( "&lt;" | "&gt;" | "&gt;=" | "&lt;=" | "instanceof" ) ShiftExpression() )*
1029:             * </PRE>
1030:             */
1031:            public Object visit(RelationalExpression n, Object argu) {
1032:                Value val = (Value) (n.f0.accept(this , argu));
1033:
1034:                for (int i = 0; i < n.f1.size(); i++) {
1035:                    NodeSequence seq = (NodeSequence) (n.f1.elementAt(i));
1036:                    NodeToken op = (NodeToken) (((NodeChoice) (seq.elementAt(0))).choice);
1037:
1038:                    Value val2 = (Value) (seq.elementAt(1).accept(this , argu));
1039:
1040:                    switch (op.kind) {
1041:                    case LT:
1042:                        val = val.bopLessThan(val2);
1043:                        break;
1044:                    case GT:
1045:                        val = val.bopGreaterThan(val2);
1046:                        break;
1047:                    case LE:
1048:                        val = val.bopLessThanOrEquals(val2);
1049:                        break;
1050:                    case GE:
1051:                        val = val.bopGreaterThanOrEquals(val2);
1052:                        break;
1053:                    case INSTANCEOF:
1054:                        val = val.bopInstanceOf(val2);
1055:                        break;
1056:                    default:
1057:                        throw new ProgrammingErrorException("bad binary op: "
1058:                                + OscriptParser.getTokenString(op.kind));
1059:                    }
1060:                }
1061:
1062:                return val;
1063:            }
1064:
1065:            /*=======================================================================*/
1066:            /**
1067:             * <PRE>
1068:             * f0 -> AdditiveExpression()
1069:             * f1 -> ( ( "&lt;&lt;" | "&gt;&gt;" | "&gt;&gt;&gt;" ) AdditiveExpression() )*
1070:             * </PRE>
1071:             */
1072:            public Object visit(ShiftExpression n, Object argu) {
1073:                Value val = (Value) (n.f0.accept(this , argu));
1074:
1075:                for (int i = 0; i < n.f1.size(); i++) {
1076:                    NodeSequence seq = (NodeSequence) (n.f1.elementAt(i));
1077:                    NodeToken op = (NodeToken) (((NodeChoice) (seq.elementAt(0))).choice);
1078:
1079:                    Value val2 = (Value) (seq.elementAt(1).accept(this , argu));
1080:
1081:                    switch (op.kind) {
1082:                    case LSHIFT:
1083:                        val = val.bopLeftShift(val2);
1084:                        break;
1085:                    case RSIGNEDSHIFT:
1086:                        val = val.bopSignedRightShift(val2);
1087:                        break;
1088:                    case RUNSIGNEDSHIFT:
1089:                        val = val.bopUnsignedRightShift(val2);
1090:                        break;
1091:                    default:
1092:                        throw new ProgrammingErrorException("bad binary op: "
1093:                                + OscriptParser.getTokenString(op.kind));
1094:                    }
1095:                }
1096:
1097:                return val;
1098:            }
1099:
1100:            /*=======================================================================*/
1101:            /**
1102:             * <PRE>
1103:             * f0 -> MultiplicativeExpression()
1104:             * f1 -> ( ( "+" | "-" ) MultiplicativeExpression() )*
1105:             * </PRE>
1106:             */
1107:            public Object visit(AdditiveExpression n, Object argu) {
1108:                Value val = (Value) (n.f0.accept(this , argu));
1109:
1110:                for (int i = 0; i < n.f1.size(); i++) {
1111:                    NodeSequence seq = (NodeSequence) (n.f1.elementAt(i));
1112:                    NodeToken op = (NodeToken) (((NodeChoice) (seq.elementAt(0))).choice);
1113:
1114:                    Value val2 = (Value) (seq.elementAt(1).accept(this , argu));
1115:
1116:                    switch (op.kind) {
1117:                    case PLUS:
1118:                        val = val.bopPlus(val2);
1119:                        break;
1120:                    case MINUS:
1121:                        val = val.bopMinus(val2);
1122:                        break;
1123:                    default:
1124:                        throw new ProgrammingErrorException("bad binary op: "
1125:                                + OscriptParser.getTokenString(op.kind));
1126:                    }
1127:                }
1128:
1129:                return val;
1130:            }
1131:
1132:            /*=======================================================================*/
1133:            /**
1134:             * <PRE>
1135:             * f0 -> UnaryExpression()
1136:             * f1 -> ( ( "*" | "/" | "%" ) UnaryExpression() )*
1137:             * </PRE>
1138:             */
1139:            public Object visit(MultiplicativeExpression n, Object argu) {
1140:                Value val = (Value) (n.f0.accept(this , argu));
1141:
1142:                for (int i = 0; i < n.f1.size(); i++) {
1143:                    NodeSequence seq = (NodeSequence) (n.f1.elementAt(i));
1144:                    NodeToken op = (NodeToken) (((NodeChoice) (seq.elementAt(0))).choice);
1145:
1146:                    Value val2 = (Value) (seq.elementAt(1).accept(this , argu));
1147:
1148:                    switch (op.kind) {
1149:                    case STAR:
1150:                        val = val.bopMultiply(val2);
1151:                        break;
1152:                    case SLASH:
1153:                        val = val.bopDivide(val2);
1154:                        break;
1155:                    case REM:
1156:                        val = val.bopRemainder(val2);
1157:                        break;
1158:                    default:
1159:                        throw new ProgrammingErrorException("bad binary op: "
1160:                                + OscriptParser.getTokenString(op.kind));
1161:                    }
1162:                }
1163:
1164:                return val;
1165:            }
1166:
1167:            /*=======================================================================*/
1168:            /**
1169:             * <PRE>
1170:             * f0 -> ( ( "++" | "--" | "+" | "-" | "~" | "!" ) )?
1171:             * f1 -> PostfixExpression()
1172:             * </PRE>
1173:             */
1174:            public Object visit(UnaryExpression n, Object argu) {
1175:                Value val = (Value) (n.f1.accept(this , argu));
1176:
1177:                if (n.f0.present()) {
1178:                    // get NodeToken_kind
1179:                    n.f0.node.accept(this , argu);
1180:
1181:                    switch (NodeToken_kind) {
1182:                    case INCR:
1183:                        val.opAssign(val.uopIncrement());
1184:                        break;
1185:                    case DECR:
1186:                        val.opAssign(val.uopDecrement());
1187:                        break;
1188:                    case PLUS:
1189:                        val = val.uopPlus();
1190:                        break;
1191:                    case MINUS:
1192:                        val = val.uopMinus();
1193:                        break;
1194:                    case TILDE:
1195:                        val = val.uopBitwiseNot();
1196:                        break;
1197:                    case BANG:
1198:                        val = val.uopLogicalNot();
1199:                        break;
1200:                    default:
1201:                        throw new ProgrammingErrorException("bad unary op: "
1202:                                + NodeToken_kind);
1203:                    }
1204:                }
1205:
1206:                return val;
1207:            }
1208:
1209:            /*=======================================================================*/
1210:            /**
1211:             * <PRE>
1212:             * f0 -> TypeExpression()
1213:             * f1 -> ( "++" | "--" )?
1214:             * </PRE>
1215:             */
1216:            public Object visit(PostfixExpression n, Object argu) {
1217:                Value val = (Value) (n.f0.accept(this , argu));
1218:
1219:                if (n.f1.present()) {
1220:                    // get NodeToken_kind
1221:                    n.f1.node.accept(this , argu);
1222:
1223:                    // save original value:
1224:                    Value origVal = val.unhand();
1225:
1226:                    // do op:
1227:                    switch (NodeToken_kind) {
1228:                    case INCR:
1229:                        val.opAssign(val.uopIncrement());
1230:                        break;
1231:                    case DECR:
1232:                        val.opAssign(val.uopDecrement());
1233:                        break;
1234:                    default:
1235:                        throw new ProgrammingErrorException("bad unary op: "
1236:                                + NodeToken_kind);
1237:                    }
1238:
1239:                    val = origVal;
1240:                }
1241:
1242:                return val;
1243:            }
1244:
1245:            /*=======================================================================*/
1246:            /**
1247:             * <PRE>
1248:             * f0 -> AllocationExpression()
1249:             *       | CastExpression()
1250:             *       | PrimaryExpression()
1251:             * </PRE>
1252:             */
1253:            public Object visit(TypeExpression n, Object argu) {
1254:                return n.f0.accept(this , argu);
1255:            }
1256:
1257:            /*=======================================================================*/
1258:            /**
1259:             * <PRE>
1260:             * f0 -> "new"
1261:             * f1 -> PrimaryExpressionWithTrailingFxnCallExpList()
1262:             * f2 -> FunctionCallExpressionList()
1263:             * </PRE>
1264:             */
1265:            public Object visit(AllocationExpression n, Object argu) {
1266:                Value val = (Value) (n.f1.accept(this , argu));
1267:                Value[] args = (Value[]) (n.f2.accept(this , argu));
1268:
1269:                return val.callAsConstructor(args);
1270:            }
1271:
1272:            /*=======================================================================*/
1273:            /**
1274:             * <PRE>
1275:             * f0 -> "("
1276:             * f1 -> PrimaryExpressionNotFunction()
1277:             * f2 -> ")"
1278:             * f3 -> PrimaryExpression()
1279:             * </PRE>
1280:             */
1281:            public Object visit(CastExpression n, Object argu) {
1282:                return ((Value) (n.f1.accept(this , argu)))
1283:                        .bopCast((Value) (n.f3.accept(this , argu)));
1284:            }
1285:
1286:            /*=======================================================================*/
1287:            /**
1288:             * <PRE>
1289:             * f0 -> PrimaryPrefix()
1290:             * f1 -> ( PrimaryPostfix() )*
1291:             * </PRE>
1292:             */
1293:            public Object visit(PrimaryExpression n, Object argu) {
1294:                Value val = (Value) (n.f0.accept(this , argu));
1295:
1296:                for (int i = 0; i < n.f1.size(); i++) {
1297:                    val = (Value) (n.f1.elementAt(i).accept(this , val));
1298:                }
1299:
1300:                return val;
1301:            }
1302:
1303:            /*=======================================================================*/
1304:            /**
1305:             * <PRE>
1306:             * f0 -> PrimaryPrefix()
1307:             * f1 -> ( PrimaryPostfix() )*
1308:             * </PRE>
1309:             */
1310:            public Object visit(PrimaryExpressionNotFunction n, Object argu) {
1311:                Value val = (Value) (n.f0.accept(this , argu));
1312:
1313:                for (int i = 0; i < n.f1.size(); i++) {
1314:                    val = (Value) (n.f1.elementAt(i).accept(this , val));
1315:                }
1316:
1317:                return val;
1318:            }
1319:
1320:            /*=======================================================================*/
1321:            /**
1322:             * <PRE>
1323:             * f0 -> PrimaryPrefix()
1324:             * f1 -> ( PrimaryPostfixWithTrailingFxnCallExpList() )*
1325:             * </PRE>
1326:             */
1327:            public Object visit(PrimaryExpressionWithTrailingFxnCallExpList n,
1328:                    Object argu) {
1329:                Value val = (Value) (n.f0.accept(this , argu));
1330:
1331:                for (int i = 0; i < n.f1.size(); i++) {
1332:                    val = (Value) (n.f1.elementAt(i).accept(this , val));
1333:                }
1334:
1335:                return val;
1336:            }
1337:
1338:            /*=======================================================================*/
1339:            /**
1340:             * <PRE>
1341:             * f0 -> PrimaryPrefixNotFunction()
1342:             *       | FunctionPrimaryPrefix()
1343:             *       | ShorthandFunctionPrimaryPrefix()
1344:             * </PRE>
1345:             */
1346:            public Object visit(PrimaryPrefix n, Object argu) {
1347:                return n.f0.accept(this , argu);
1348:            }
1349:
1350:            /*=======================================================================*/
1351:            /**
1352:             * <PRE>
1353:             * f0 -> ThisPrimaryPrefix()
1354:             *       | SuperPrimaryPrefix()
1355:             *       | CalleePrimaryPrefix()
1356:             *       | IdentifierPrimaryPrefix()
1357:             *       | ParenPrimaryPrefix()
1358:             *       | ArrayDeclarationPrimaryPrefix()
1359:             *       | Literal()
1360:             * </PRE>
1361:             */
1362:            public Object visit(PrimaryPrefixNotFunction n, Object argu) {
1363:                return n.f0.accept(this , argu);
1364:            }
1365:
1366:            /*=======================================================================*/
1367:            /**
1368:             * <PRE>
1369:             * f0 -> "this"
1370:             * </PRE>
1371:             */
1372:            public Object visit(ThisPrimaryPrefix n, Object argu) {
1373:                return this Scope.getThis();
1374:            }
1375:
1376:            /*=======================================================================*/
1377:            /**
1378:             * <PRE>
1379:             * f0 -> "super"
1380:             * </PRE>
1381:             */
1382:            public Object visit(SuperPrimaryPrefix n, Object argu) {
1383:                return this Scope.getSuper();
1384:            }
1385:
1386:            /*=======================================================================*/
1387:            /**
1388:             * <PRE>
1389:             * f0 -> "callee"
1390:             * </PRE>
1391:             */
1392:            public Object visit(CalleePrimaryPrefix n, Object argu) {
1393:                return this Scope.getCallee();
1394:            }
1395:
1396:            /*=======================================================================*/
1397:            /**
1398:             * <PRE>
1399:             * f0 -> &lt;IDENTIFIER&gt;
1400:             * </PRE>
1401:             */
1402:            public Object visit(IdentifierPrimaryPrefix n, Object argu) {
1403:                return this Scope
1404:                        .lookupInScope((Value) (n.f0.accept(this , argu)));
1405:            }
1406:
1407:            /*=======================================================================*/
1408:            /**
1409:             * <PRE>
1410:             * f0 -> "("
1411:             * f1 -> Expression()
1412:             * f2 -> ")"
1413:             * </PRE>
1414:             */
1415:            public Object visit(ParenPrimaryPrefix n, Object argu) {
1416:                return n.f1.accept(this , argu);
1417:            }
1418:
1419:            /*=======================================================================*/
1420:            private static final int[] EMPTY_ARG_NAMES = new int[0];
1421:
1422:            /**
1423:             * <PRE>
1424:             * f0 -> "function"
1425:             * f1 -> "("
1426:             * f2 -> ( Arglist() )?
1427:             * f3 -> ")"
1428:             * f4 -> ( "extends" PrimaryExpressionWithTrailingFxnCallExpList() FunctionCallExpressionList() )?
1429:             * f5 -> "{"
1430:             * f6 -> Program()
1431:             * f7 -> "}"
1432:             * </PRE>
1433:             */
1434:            public Object visit(FunctionPrimaryPrefix n, Object argu) {
1435:                if (n.fd == null) {
1436:                    Value oname = Symbol.getSymbol(n.id);
1437:                    String name = oname.castToString();
1438:                    int[] argIds;
1439:                    boolean varargs;
1440:
1441:                    // just in case, to get the specials...
1442:                    n.f0.accept(this , argu);
1443:
1444:                    // get arglist:
1445:                    if (n.f2.present()) {
1446:                        n.f2.node.accept(this , argu);
1447:                        argIds = Arglist_names;
1448:                        varargs = Arglist_varargs;
1449:                    } else {
1450:                        argIds = EMPTY_ARG_NAMES;
1451:                        varargs = false;
1452:                    }
1453:
1454:                    // get extends evaluator:
1455:                    oscript.NodeEvaluator functionCallExpressionListEvaluator = null;
1456:
1457:                    if (n.f4.present()) {
1458:                        FunctionCallExpressionList functionCallExpressionList = (FunctionCallExpressionList) (((NodeSequence) (n.f4.node))
1459:                                .elementAt(2));
1460:
1461:                        synchronized (functionCallExpressionList) {
1462:                            if (functionCallExpressionList.nodeEvaluator == null) {
1463:                                functionCallExpressionList.nodeEvaluator = oscript.OscriptInterpreter
1464:                                        .createNodeEvaluator(name + "$extends",
1465:                                                functionCallExpressionList);
1466:                            }
1467:                        }
1468:
1469:                        functionCallExpressionListEvaluator = functionCallExpressionList.nodeEvaluator;
1470:                    }
1471:
1472:                    oscript.NodeEvaluator nodeEvaluator = OscriptInterpreter
1473:                            .createNodeEvaluator(name, n.f6);
1474:
1475:                    {
1476:                        oscript.util.SymbolTable smit = nodeEvaluator
1477:                                .getSharedMemberIndexTable(oscript.NodeEvaluator.ALL);
1478:                        for (int i = 0; i < argIds.length; i += 2)
1479:                            smit.create(argIds[i]);
1480:                    }
1481:
1482:                    oscript.NodeEvaluator staticNodeEvaluator = null;
1483:                    if (n.f6.staticNodes != null)
1484:                        staticNodeEvaluator = OscriptInterpreter
1485:                                .createNodeEvaluator(name + "$static",
1486:                                        n.f6.staticNodes);
1487:
1488:                    // the syntaxtree won't change, so we only need to parse the comment once:
1489:                    synchronized (n) {
1490:                        if (!n.commentParsed) {
1491:                            n.commentParsed = true;
1492:                            if (NodeToken_lastSpecials != null)
1493:                                n.comment = Function.extractJavadocComment(
1494:                                        NodeToken_lastSpecials, oname, argIds);
1495:                        }
1496:                    }
1497:
1498:                    n.fd = new Function.FunctionData(n.id, argIds, varargs,
1499:                            functionCallExpressionListEvaluator, nodeEvaluator,
1500:                            staticNodeEvaluator, n.hasVarInScope,
1501:                            n.hasFxnInScope, n.comment);
1502:                }
1503:
1504:                // get extends:
1505:                Value super Fxn = null;
1506:                if (n.f4.present()) {
1507:                    Value val = (Value) (((NodeSequence) (n.f4.node))
1508:                            .elementAt(1).accept(this , argu));
1509:                    super Fxn = val.unhand();
1510:                }
1511:
1512:                return new Function(this Scope, super Fxn, n.fd);
1513:            }
1514:
1515:            /*=======================================================================*/
1516:            /**
1517:             * <PRE>
1518:             * f0 -> "'{"
1519:             * f1 -> Program(true)
1520:             * f2 -> "}"
1521:             * </PRE>
1522:             */
1523:            public Object visit(ShorthandFunctionPrimaryPrefix n, Object argu) {
1524:                return ShorthandFunctionPrimaryPrefixTranslator.translate(n)
1525:                        .accept(this , argu);
1526:            }
1527:
1528:            /*=======================================================================*/
1529:            /**
1530:             * <PRE>
1531:             * f0 -> "["
1532:             * f1 ->   (FunctionCallExpressionListBody())?
1533:             * f2 -> "]"
1534:             * </PRE>
1535:             */
1536:            public Object visit(ArrayDeclarationPrimaryPrefix n, Object argu) {
1537:                Value[] vals;
1538:
1539:                if (n.f1.present())
1540:                    vals = (Value[]) (n.f1.node.accept(this , argu));
1541:                else
1542:                    vals = new Value[0];
1543:
1544:                return new OArray(vals);
1545:            }
1546:
1547:            /*=======================================================================*/
1548:            /**
1549:             * <PRE>
1550:             * f0 -> FunctionCallPrimaryPostfix()
1551:             *       | ArraySubscriptPrimaryPostfix()
1552:             *       | ThisScopeQualifierPrimaryPostfix()
1553:             *       | PropertyIdentifierPrimaryPostfix()
1554:             * </PRE>
1555:             */
1556:            public Object visit(PrimaryPostfix n, Object argu) {
1557:                return n.f0.accept(this , argu);
1558:            }
1559:
1560:            /*=======================================================================*/
1561:            /**
1562:             * <PRE>
1563:             * f0 -> ArraySubscriptPrimaryPostfix()
1564:             *       | ThisScopeQualifierPrimaryPostfix()
1565:             *       | PropertyIdentifierPrimaryPostfix()
1566:             * </PRE>
1567:             */
1568:            public Object visit(PrimaryPostfixWithTrailingFxnCallExpList n,
1569:                    Object argu) {
1570:                return n.f0.accept(this , argu);
1571:            }
1572:
1573:            /*=======================================================================*/
1574:            /**
1575:             * <PRE>
1576:             * f0 -> FunctionCallExpressionList()
1577:             * </PRE>
1578:             */
1579:            public Object visit(FunctionCallPrimaryPostfix n, Object argu) {
1580:                Value[] args = (Value[]) (n.f0.accept(this , argu));
1581:
1582:                return ((Value) argu).callAsFunction(args);
1583:            }
1584:
1585:            /*=======================================================================*/
1586:            /**
1587:             * <PRE>
1588:             * f0 -> "["
1589:             * f1 -> Expression()
1590:             * f2 -> ( ".." Expression() )?
1591:             * f3 -> "]"
1592:             * </PRE>
1593:             */
1594:            public Object visit(ArraySubscriptPrimaryPostfix n, Object argu) {
1595:                Value idx1 = (Value) (n.f1.accept(this , argu));
1596:
1597:                if (n.f2.present()) {
1598:                    Value idx2 = (Value) (((NodeSequence) (n.f2.node))
1599:                            .elementAt(1).accept(this , argu));
1600:                    return ((Value) argu).elementsAt(idx1, idx2);
1601:                } else {
1602:                    return ((Value) argu).elementAt(idx1);
1603:                }
1604:            }
1605:
1606:            /*=======================================================================*/
1607:            /**
1608:             * <PRE>
1609:             * f0 -> "."
1610:             * f1 -> &lt;IDENTIFIER&gt;
1611:             * </PRE>
1612:             */
1613:            public Object visit(PropertyIdentifierPrimaryPostfix n, Object argu) {
1614:                n.f0.accept(this , argu); // to record last NodeToken
1615:                return ((Value) argu).getMember((Value) (n.f1
1616:                        .accept(this , argu)));
1617:            }
1618:
1619:            /*=======================================================================*/
1620:            /**
1621:             * <PRE>
1622:             * f0 -> "."
1623:             * f1 -> "this"
1624:             * </PRE>
1625:             */
1626:            public Object visit(ThisScopeQualifierPrimaryPostfix n, Object argu) {
1627:                n.f0.accept(this , argu); // to record last NodeToken
1628:                return this Scope.getThis((Value) argu);
1629:            }
1630:
1631:            /*=======================================================================*/
1632:            /**
1633:             * <PRE>
1634:             * f0 -> &lt;INTEGER_LITERAL&gt;
1635:             *       | &lt;FLOATING_POINT_LITERAL&gt;
1636:             *       | &lt;STRING_LITERAL&gt;
1637:             *       | &lt;REGEXP_LITERAL&gt;
1638:             *       | "true"
1639:             *       | "false"
1640:             *       | "null"
1641:             *       | "undefined"
1642:             * </PRE>
1643:             */
1644:            public Object visit(Literal n, Object argu) {
1645:                return n.f0.choice.accept(this , argu);
1646:            }
1647:
1648:            /*=======================================================================*/
1649:            /**
1650:             * <PRE>
1651:             * f0 -> ( "static" | "const" | "private" | "protected" | "public" )*
1652:             * </PRE>
1653:             */
1654:            public Object visit(Permissions n, Object argu) {
1655:                Permissions_attr = getPermissions(n, Reference.ATTR_PROTECTED);
1656:                return null;
1657:            }
1658:
1659:            /**
1660:             * Get the permissions mask...
1661:             * 
1662:             * @param n            the permissions syntaxtree node
1663:             * @param attr         the default permissions value
1664:             * @return the permissions mask
1665:             */
1666:            private int getPermissions(Permissions n, int attr) {
1667:                for (int i = 0; i < n.f0.size(); i++) {
1668:                    n.f0.elementAt(i).accept(this , null);
1669:
1670:                    switch (NodeToken_kind) {
1671:                    case PRIVATE:
1672:                        attr = (attr & 0xf0) | Reference.ATTR_PRIVATE;
1673:                        break;
1674:                    case PROTECTED:
1675:                        attr = (attr & 0xf0) | Reference.ATTR_PROTECTED;
1676:                        break;
1677:                    case PUBLIC:
1678:                        attr = (attr & 0xf0) | Reference.ATTR_PUBLIC;
1679:                        break;
1680:                    case STATIC:
1681:                        attr |= Reference.ATTR_STATIC;
1682:                        break;
1683:                    case CONST:
1684:                        attr |= Reference.ATTR_CONST;
1685:                        break;
1686:                    default:
1687:                        throw new ProgrammingErrorException(
1688:                                "bad kind: "
1689:                                        + OscriptParser
1690:                                                .getTokenString(NodeToken_lastToken.kind));
1691:                    }
1692:                }
1693:
1694:                return attr;
1695:            }
1696:        }
1697:
1698:        /*
1699:         *   Local Variables:
1700:         *   tab-width: 2
1701:         *   indent-tabs-mode: nil
1702:         *   mode: java
1703:         *   c-indentation-style: java
1704:         *   c-basic-offset: 2
1705:         *   eval: (c-set-offset 'substatement-open '0)
1706:         *   eval: (c-set-offset 'case-label '+)
1707:         *   eval: (c-set-offset 'inclass '+)
1708:         *   eval: (c-set-offset 'inline-open '0)
1709:         *   End:
1710:         */
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.