Source Code Cross Referenced for PnutsInterpreter.java in  » Scripting » Pnuts » pnuts » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


0001:        /*
0002:         * PnutsInterpreter.java
0003:         *
0004:         * Copyright (c) 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
0005:         *
0006:         * See the file "LICENSE.txt" for information on usage and redistribution
0007:         * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
0008:         */
0009:        package pnuts.lang;
0010:
0011:        import java.io.PrintWriter;
0012:        import java.lang.reflect.Array;
0013:        import java.util.Enumeration;
0014:        import java.util.Map;
0015:        import java.util.HashMap;
0016:        import java.util.Set;
0017:        import java.util.HashSet;
0018:        import java.util.List;
0019:        import java.util.Iterator;
0020:        import java.util.ArrayList;
0021:
0022:        import org.pnuts.lang.ConstraintsTransformer;
0023:        import org.pnuts.lang.GeneratorHelper;
0024:        import org.pnuts.util.Cell;
0025:
0026:        import pnuts.compiler.Compiler;
0027:        import pnuts.compiler.ClassGenerator;
0028:
0029:        /**
0030:         * The pure interpreter
0031:         */
0032:        public class PnutsInterpreter extends Runtime implements  Visitor {
0033:
0034:            private final static Integer one = new Integer(1);
0035:
0036:            private final static Object GENERATOR = new Object();
0037:
0038:            private final static Object FUNCTION = new Object();
0039:
0040:            static PnutsInterpreter instance = new PnutsInterpreter();
0041:            static Compiler compiler = new Compiler();
0042:
0043:            static PnutsInterpreter getInstance() {
0044:                return instance;
0045:            }
0046:
0047:            final static int CODE = 0;
0048:            final static int VALUE = 1;
0049:            final static int BROKEN = 0;
0050:            final static int CONT = 1;
0051:            final static int PASSED = 2;
0052:
0053:            public Object start(SimpleNode node, Context context) {
0054:                if (node.jjtGetNumChildren() > 0) {
0055:                    if (context.stackFrame == null) {
0056:                        context.stackFrame = new StackFrame();
0057:                    }
0058:                    try {
0059:                        return accept(node, 0, context);
0060:                    } catch (Throwable t) {
0061:                        checkException(context, t);
0062:                    }
0063:                }
0064:                return null;
0065:            }
0066:
0067:            public Object startSet(SimpleNode node, Context context) {
0068:                if (context.stackFrame == null) {
0069:                    context.stackFrame = new StackFrame();
0070:                }
0071:                int n = node.jjtGetNumChildren();
0072:                Object ret = null;
0073:                try {
0074:                    for (int i = 0; i < n; i++) {
0075:                        ret = accept(node, i, context);
0076:                    }
0077:                } catch (Throwable t) {
0078:                    checkException(context, t);
0079:                } finally {
0080:                    if (context.evalFrameStack == null) {
0081:                        PrintWriter pw = context.getWriter();
0082:                        if (pw != null) {
0083:                            pw.flush();
0084:                        }
0085:                    } else {
0086:                        Cell cell = context.evalFrameStack;
0087:                        if (cell != null) {
0088:                            context.evalFrameStack = cell.next;
0089:                            context.stackFrame = (StackFrame) cell.object;
0090:                        }
0091:                    }
0092:                }
0093:                return ret;
0094:            }
0095:
0096:            public Object expressionList(SimpleNode node, Context context) {
0097:                Object ret = null;
0098:                int n = node.jjtGetNumChildren();
0099:                for (int i = 0; i < n; i++) {
0100:                    ret = accept(node, i, context);
0101:                }
0102:                return ret;
0103:            }
0104:
0105:            public Object global(SimpleNode node, Context context) {
0106:                String symbol = node.str;
0107:                Package pkg = Package.find("", context);
0108:                if (pkg != null) {
0109:                    Value val = pkg.lookup(symbol, context);
0110:                    if (val != null) {
0111:                        return val.get();
0112:                    }
0113:                }
0114:                return context.undefined(symbol);
0115:            }
0116:
0117:            public Object idNode(SimpleNode node, Context context) {
0118:                return context.getValue(node.str);
0119:            }
0120:
0121:            public Object className(SimpleNode node, Context context) {
0122:                return resolveClassNameNode(node, context);
0123:            }
0124:
0125:            public Object arrayType(SimpleNode node, Context context) {
0126:                SimpleNode n = node;
0127:                int count = 0;
0128:                while (n != null
0129:                        && n.id == PnutsParserTreeConstants.JJTARRAYTYPE) {
0130:                    count++;
0131:                    n = n.jjtGetChild(0);
0132:                }
0133:                if (n != null && n.id == PnutsParserTreeConstants.JJTINDEXNODE) {
0134:                    Class type;
0135:                    Object[] idx = parseIndex(n);
0136:                    SimpleNode idx0 = (SimpleNode) idx[0];
0137:                    Object tgt = idx0.accept(this , context);
0138:                    if (tgt instanceof  Class) {
0139:                        type = Runtime.arrayType((Class) tgt, count);
0140:                    } else {
0141:                        throw new PnutsException("classOrArray.expected",
0142:                                new Object[] { Pnuts.format(tgt) }, context);
0143:                    }
0144:                    Object[] dim = (Object[]) idx[1];
0145:                    int[] idim = new int[dim.length];
0146:                    for (int i = 0; i < dim.length; i++) {
0147:                        Object o = ((SimpleNode) dim[i]).accept(this , context);
0148:                        if (o instanceof  Number) {
0149:                            idim[i] = ((Number) o).intValue();
0150:                        } else {
0151:                            throw new PnutsException("number.expected",
0152:                                    new Object[] { Pnuts.format(o) }, context);
0153:                        }
0154:                    }
0155:                    return Array.newInstance(type, idim);
0156:                } else if (node.jjtGetParent().id != PnutsParserTreeConstants.JJTNEW) {
0157:                    Object tgt = n.accept(this , context);
0158:                    if (tgt instanceof  Class) {
0159:                        return Runtime.arrayType((Class) tgt, count);
0160:                    } else {
0161:                        throw new PnutsException("classOrArray.expected",
0162:                                new Object[] { Pnuts.format(tgt) }, context);
0163:                    }
0164:                } else {
0165:                    throw new IllegalArgumentException();
0166:                }
0167:            }
0168:
0169:            public Object[] _listElements(SimpleNode node, Context context) {
0170:                int n = node.jjtGetNumChildren();
0171:                Object array[] = new Object[n];
0172:
0173:                for (int i = 0; i < n; i++) {
0174:                    array[i] = accept(node, i, context);
0175:                }
0176:                return array;
0177:            }
0178:
0179:            public Object listElements(SimpleNode node, Context context) {
0180:                if ("{".equals(node.str)) {
0181:                    List list = context.config.createList();
0182:                    int n = node.jjtGetNumChildren();
0183:                    for (int i = 0; i < n; i++) {
0184:                        list.add(accept(node, i, context));
0185:                    }
0186:                    return list;
0187:                } else {
0188:                    return context.config.makeArray(
0189:                            _listElements(node, context), context);
0190:                }
0191:            }
0192:
0193:            public Object mapNode(SimpleNode node, Context context) {
0194:                int n = node.jjtGetNumChildren();
0195:                Map map = context.config.createMap(n, context);
0196:                for (int i = 0; i < n; i++) {
0197:                    SimpleNode c = node.jjtGetChild(i);
0198:                    map.put(accept(c, 0, context), accept(c, 1, context));
0199:                }
0200:                return map;
0201:            }
0202:
0203:            public Object castExpression(SimpleNode node, Context context) {
0204:                SimpleNode typeNode = node.jjtGetChild(0);
0205:                Class type = resolveTypeNode(typeNode, context);
0206:                Object obj = accept(node, 1, context);
0207:                return Runtime.cast(context, type, obj, true);
0208:            }
0209:
0210:            public Object classNode(SimpleNode node, Context context) {
0211:                SimpleNode c = node.jjtGetChild(0);
0212:                String className = null;
0213:                if (c.id == PnutsParserTreeConstants.JJTCLASSNAME) {
0214:                    StringBuffer sbuf = new StringBuffer();
0215:                    sbuf.append(c.children[0].str);
0216:                    int n = c.jjtGetNumChildren();
0217:                    for (int i = 1; i < n; i++) {
0218:                        SimpleNode ch = c.children[i];
0219:                        sbuf.append('.');
0220:                        sbuf.append(ch.str);
0221:                    }
0222:                    className = sbuf.toString();
0223:                } else {
0224:                    className = (String) c.accept(this , context);
0225:                }
0226:                try {
0227:                    return Pnuts.loadClass(className, context);
0228:                } catch (ClassNotFoundException e) {
0229:                    throw new PnutsException(e, context);
0230:                }
0231:            }
0232:
0233:            Object buildSubclassInstance(SimpleNode node, Context context) {
0234:                return compiler.buildSubclassInstance(node, context);
0235:            }
0236:
0237:            public Object newNode(SimpleNode node, Context context) {
0238:                int n = node.jjtGetNumChildren();
0239:                SimpleNode n0 = node.jjtGetChild(0);
0240:                if (n == 3
0241:                        && node.jjtGetChild(2).id == PnutsParserTreeConstants.JJTCLASSDEFBODY) { // subclass
0242:                    return buildSubclassInstance(node, context);
0243:
0244:                } else if (n0.id == PnutsParserTreeConstants.JJTINDEXNODE) {
0245:                    Object[] idx = parseIndex(n0);
0246:                    SimpleNode c = (SimpleNode) idx[0];
0247:                    Object[] dim = (Object[]) idx[1];
0248:                    Class cls = resolveClassNameNode(c, context);
0249:                    return newArray(cls, dim, context);
0250:
0251:                } else if (n0.id == PnutsParserTreeConstants.JJTARRAYTYPE) {
0252:                    return arrayType(n0, context);
0253:
0254:                } else if (n0.id == PnutsParserTreeConstants.JJTARRAYNODE) {
0255:                    Class type = (Class) accept(n0, 0, context);
0256:                    Object obj = _listElements(n0.jjtGetChild(1), context);
0257:                    return Runtime.cast(context, type, obj, true);
0258:
0259:                } else { // instantiation
0260:                    SimpleNode nameNode = node.jjtGetChild(0);
0261:                    Class cls = resolveClassNameNode(nameNode, context);
0262:                    Object[] arg = _listElements(node.jjtGetChild(1), context);
0263:                    return Runtime.callConstructor(context, cls, arg, null);
0264:                }
0265:            }
0266:
0267:            public Object classDef(SimpleNode node, Context context) {
0268:                return compiler.defineClass(node, context);
0269:            }
0270:
0271:            public Object methodDef(SimpleNode node, Context context) {
0272:                return null;
0273:            }
0274:
0275:            public Object classDefBody(SimpleNode node, Context context) {
0276:                return null;
0277:            }
0278:
0279:            public Object classScript(SimpleNode node, Context context) {
0280:                return null;
0281:            }
0282:
0283:            public Object packageNode(SimpleNode node, Context context) {
0284:                int n = node.jjtGetNumChildren();
0285:                if (n == 0) {
0286:                    if ("(".equals(node.str)) {
0287:                        return PnutsFunction.PACKAGE.call(NO_PARAM, context);
0288:                    } else {
0289:                        return PnutsFunction.PACKAGE;
0290:                    }
0291:                } else {
0292:                    SimpleNode c = node.jjtGetChild(0);
0293:                    if (n == 1 && c.id != PnutsParserTreeConstants.JJTPACKAGE) { // package("...")
0294:                        return PnutsFunction.PACKAGE.call(new Object[] { c
0295:                                .accept(this , context) }, context);
0296:                    } else {
0297:                        StringBuffer sbuf = new StringBuffer();
0298:                        sbuf.append(node.jjtGetChild(0).str);
0299:                        for (int i = 1; i < n; i++) {
0300:                            sbuf.append('.');
0301:                            sbuf.append(node.jjtGetChild(i).str);
0302:                        }
0303:                        return PnutsFunction.PACKAGE.call(new Object[] { sbuf
0304:                                .toString() }, context);
0305:                    }
0306:                }
0307:            }
0308:
0309:            public Object importNode(SimpleNode node, Context context) {
0310:                String t2 = node.str;
0311:                int n = node.jjtGetNumChildren();
0312:                if (n == 0) {
0313:                    if ("*".equals(t2)) { // import *
0314:                        context.addPackageToImport("");
0315:                        return null;
0316:                    } else if ("(".equals(t2)) {
0317:                        return context.importEnv.list();
0318:                    } else {
0319:                        return PnutsFunction.IMPORT;
0320:                    }
0321:                }
0322:                if (n == 1
0323:                        && node.children[0].id != PnutsParserTreeConstants.JJTPACKAGE) { // import(...)
0324:                    String s = (String) node.children[0].accept(this , context);
0325:                    if (s == null) {
0326:                        context.importEnv = new ImportEnv();
0327:                    } else if (!s.endsWith("*")) {
0328:                        context.addClassToImport(s);
0329:                    } else {
0330:                        int idx = s.lastIndexOf('.');
0331:                        if (idx > 0) {
0332:                            context.addPackageToImport(s.substring(0, idx));
0333:                        } else {
0334:                            context.addPackageToImport("");
0335:                        }
0336:                    }
0337:                    return null;
0338:                }
0339:                StringBuffer sbuf = new StringBuffer();
0340:                sbuf.append(node.children[0].str);
0341:                for (int i = 1; i < n; i++) {
0342:                    sbuf.append('.');
0343:                    sbuf.append(node.children[i].str);
0344:                }
0345:                String arg = sbuf.toString();
0346:                if (node.info != null) { // static import
0347:                    context.addStaticMembers(arg, t2 != null);
0348:                } else {
0349:                    if (t2 == null) {
0350:                        context.addClassToImport(arg);
0351:                    } else {
0352:                        context.addPackageToImport(arg);
0353:                    }
0354:                }
0355:                return null;
0356:            }
0357:
0358:            public Object rangeNode(SimpleNode node, Context context) {
0359:                Object target = accept(node, 0, context);
0360:                Object idx1 = accept(node, 1, context);
0361:                Object idx2 = null;
0362:                if (node.jjtGetNumChildren() >= 3) {
0363:                    idx2 = accept(node, 2, context);
0364:                }
0365:                return Runtime.getRange(target, idx1, idx2, context);
0366:            }
0367:
0368:            /**
0369:             * @return [base_component_node, [idx_node_0, idx_node_1, ...]]
0370:             */
0371:            static Object[] parseIndex(SimpleNode node) {
0372:                SimpleNode c0 = node.jjtGetChild(0);
0373:                SimpleNode c1 = node.jjtGetChild(1);
0374:                if (c0.id != PnutsParserTreeConstants.JJTINDEXNODE) {
0375:                    return new Object[] { c0, new Object[] { c1 } };
0376:                } else {
0377:                    Object[] r = parseIndex(c0);
0378:                    Object[] d = (Object[]) r[1];
0379:                    Object[] a = new Object[d.length + 1];
0380:                    System.arraycopy(d, 0, a, 0, d.length);
0381:                    a[d.length] = c1;
0382:                    return new Object[] { r[0], a };
0383:                }
0384:            }
0385:
0386:            static void convertIndexNode(SimpleNode node) {
0387:                SimpleNode n0 = node.jjtGetChild(0);
0388:                SimpleNode n1 = node.jjtGetChild(1);
0389:                if (ConstraintsTransformer.isPredicate(n1)) {
0390:                    SimpleNode n = ConstraintsTransformer.buildFunc(n1);
0391:                    node.jjtAddChild(n, 1);
0392:                    n.jjtSetParent(node);
0393:                }
0394:                if (n0.id == PnutsParserTreeConstants.JJTINDEXNODE) {
0395:                    convertIndexNode(n0);
0396:                }
0397:            }
0398:
0399:            public Object indexNode(SimpleNode node, Context context) {
0400:                synchronized (node) {
0401:                    if (node.getAttribute("index") == null) {
0402:                        node.setAttribute("index", Boolean.TRUE);
0403:                        convertIndexNode(node);
0404:                    }
0405:                }
0406:                Object[] idx = parseIndex(node);
0407:                SimpleNode c = (SimpleNode) idx[0];
0408:                Object[] dim = (Object[]) idx[1];
0409:                Object target = c.accept(this , context);
0410:                if (target instanceof  Class) {
0411:                    return newArray((Class) target, dim, context);
0412:                } else {
0413:                    for (int i = 0; i < dim.length; i++) {
0414:                        target = Runtime.getElement(target,
0415:                                ((SimpleNode) dim[i]).accept(this , context),
0416:                                context);
0417:                    }
0418:                    return target;
0419:                }
0420:            }
0421:
0422:            Object newArray(Class cls, Object[] dim, Context context) {
0423:                int[] sizes = new int[dim.length];
0424:                for (int i = 0; i < dim.length; i++) {
0425:                    sizes[i] = ((Number) ((SimpleNode) dim[i]).accept(this ,
0426:                            context)).intValue();
0427:                }
0428:                return Array.newInstance(cls, sizes);
0429:            }
0430:
0431:            public Object methodNode(SimpleNode node, Context context) {
0432:                Object target = accept(node, 0, context);
0433:                Object[] arg = _listElements(node.jjtGetChild(1), context);
0434:
0435:                SimpleNode argNode = node.children[1];
0436:                Class types[] = null;
0437:                for (int i = 0; i < arg.length; i++) {
0438:                    SimpleNode n = argNode.children[i];
0439:                    if (n.id == PnutsParserTreeConstants.JJTCASTEXPRESSION) {
0440:                        if (types == null) {
0441:                            types = new Class[arg.length];
0442:                        }
0443:                        types[i] = resolveType(n.jjtGetChild(0), context);
0444:                    }
0445:                }
0446:
0447:                if (target == null) {
0448:                    PnutsException pe = new PnutsException(
0449:                            new NullPointerException(), context);
0450:                    pe.line = node.beginLine;
0451:                    throw pe;
0452:                }
0453:                return Runtime.callMethod(context, target.getClass(), node.str,
0454:                        arg, types, target);
0455:            }
0456:
0457:            public Object staticMethodNode(SimpleNode node, Context context) {
0458:                SimpleNode c1 = node.children[0];
0459:                String pkgName = getPackageName(c1);
0460:
0461:                SimpleNode argNode = node.children[1];
0462:                Class types[] = null;
0463:                Object[] arg = null;
0464:
0465:                Package pkg = Package.find(pkgName, context);
0466:                if (pkg != null) {
0467:                    Object fun = pkg.get(node.str, context);
0468:
0469:                    if (fun instanceof  PnutsFunction) {
0470:                        arg = _listElements(node.jjtGetChild(1), context);
0471:                        PnutsFunction ft = (PnutsFunction) fun;
0472:                        return ft.exec(arg, context);
0473:                    } else if (fun instanceof  Class) {
0474:                        arg = _listElements(node.jjtGetChild(1), context);
0475:                        for (int i = 0; i < arg.length; i++) {
0476:                            SimpleNode n = argNode.children[i];
0477:                            if (n.id == PnutsParserTreeConstants.JJTCASTEXPRESSION) {
0478:                                if (types == null) {
0479:                                    types = new Class[arg.length];
0480:                                }
0481:                                types[i] = resolveType(n.jjtGetChild(0),
0482:                                        context);
0483:                            }
0484:                        }
0485:                        return Runtime.callConstructor(context, (Class) fun,
0486:                                arg, types);
0487:                    } else {
0488:                        throw new PnutsException(
0489:                                "illegal.staticCall",
0490:                                new Object[] {
0491:                                        pkgName,
0492:                                        node.str,
0493:                                        new Integer(argNode.jjtGetNumChildren()) },
0494:                                context);
0495:                    }
0496:                }
0497:                Object target = accept(node, 0, context);
0498:                arg = _listElements(node.jjtGetChild(1), context);
0499:                if (target instanceof  Class) {
0500:                    for (int i = 0; i < arg.length; i++) {
0501:                        SimpleNode n = argNode.children[i];
0502:                        if (n.id == PnutsParserTreeConstants.JJTCASTEXPRESSION) {
0503:                            if (types == null) {
0504:                                types = new Class[arg.length];
0505:                            }
0506:                            types[i] = resolveType(n.jjtGetChild(0), context);
0507:                        }
0508:                    }
0509:                    return Runtime.callMethod(context, (Class) target,
0510:                            node.str, arg, types, null);
0511:                } else {
0512:                    throw new PnutsException("illegal.staticCall",
0513:                            new Object[] { pkgName, node.str,
0514:                                    new Integer(arg.length) }, context);
0515:                }
0516:            }
0517:
0518:            public Object memberNode(SimpleNode node, Context context) {
0519:                Object target = accept(node, 0, context);
0520:
0521:                if (target == null) {
0522:                    throw new PnutsException(new NullPointerException(),
0523:                            context);
0524:                } else if (Runtime.isArray(target) && node.str.equals("length")) {
0525:                    return new Integer(Runtime.getArrayLength(target));
0526:                }
0527:                if (node.info != null) { /* experimental BIND feature */
0528:                    Object[] info = (Object[]) node.info;
0529:                    Object obj = info[0];
0530:                    SimpleNode c = (SimpleNode) info[1];
0531:                    SimpleNode c0 = c.jjtGetChild(0);
0532:                    Map table = (Map) info[2];
0533:                    watchProperty(table, obj, c.str, target, node.str,
0534:                            (Callable) toFunctionNode(c0).accept(this , context));
0535:                    if (c0 == node) {
0536:                        watchProperty(table, target, node.str, obj, c.str, null);
0537:                    }
0538:                    node.info = null;
0539:                }
0540:                return Runtime.getField(context, target, node.str);
0541:            }
0542:
0543:            static String getPackageName(SimpleNode node) {
0544:                if (node.jjtGetNumChildren() > 0) {
0545:                    SimpleNode c1 = node.children[0];
0546:                    return getPackageName(c1) + "::" + node.str;
0547:                } else {
0548:                    return node.str;
0549:                }
0550:            }
0551:
0552:            public Object staticMemberNode(SimpleNode node, Context context) {
0553:
0554:                SimpleNode c1 = node.children[0];
0555:                String pkgName = getPackageName(c1);
0556:
0557:                Package pkg = Package.find(pkgName, context);
0558:                if (pkg != null) {
0559:                    Value v = pkg.lookup(node.str, context);
0560:                    if (v != null) {
0561:                        return v.get();
0562:                    } else {
0563:                        return context.undefined(node.str);
0564:                    }
0565:                }
0566:                Object target = c1.accept(this , context);
0567:                if (target instanceof  Class) {
0568:                    return Runtime.getStaticField(context, (Class) target,
0569:                            node.str);
0570:                } else {
0571:                    throw new PnutsException("packageOrClass.expected",
0572:                            new Object[] { Pnuts.format(target) }, context);
0573:                }
0574:            }
0575:
0576:            public Object applicationNode(SimpleNode node, Context context) {
0577:
0578:                Object target = accept(node, 0, context);
0579:                Object[] arg = _listElements(node.jjtGetChild(1), context);
0580:
0581:                SimpleNode argNode = node.children[1];
0582:                Class types[] = null;
0583:                for (int i = 0; i < arg.length; i++) {
0584:                    SimpleNode n = argNode.children[i];
0585:                    if (n.id == PnutsParserTreeConstants.JJTCASTEXPRESSION) {
0586:                        if (types == null) {
0587:                            types = new Class[arg.length];
0588:                        }
0589:                        types[i] = resolveType(n.jjtGetChild(0), context);
0590:                    }
0591:                }
0592:                return Runtime.call(context, target, arg, types,
0593:                        node.beginLine, node.beginColumn);
0594:            }
0595:
0596:            // node.info => [int[] unitOffset]
0597:
0598:            public Object integerNode(SimpleNode node, Context context) {
0599:                if (node.value != null) {
0600:                    return node.value;
0601:                }
0602:                String str = node.str;
0603:                Object[] a = (Object[]) node.info;
0604:                int[] off = (int[]) a[1];
0605:                Number n = (Number) a[0];
0606:                if (off != null) {
0607:                    int offset = off[0];
0608:                    return Runtime.quantity(n, str.substring(0, offset), str
0609:                            .substring(offset), context);
0610:                } else {
0611:                    node.value = n;
0612:                    return n;
0613:                }
0614:            }
0615:
0616:            public Object floatingNode(SimpleNode node, Context context) {
0617:                if (node.value != null) {
0618:                    return node.value;
0619:                }
0620:                String str = node.str;
0621:                Object[] p = (Object[]) node.info;
0622:                Number n = (Number) p[0];
0623:                if (p[1] != null) {
0624:                    int offset = ((int[]) p[1])[0];
0625:                    return Runtime.quantity(n, str.substring(0, offset), str
0626:                            .substring(offset), context);
0627:                } else {
0628:                    node.value = n;
0629:                    return n;
0630:                }
0631:            }
0632:
0633:            public Object characterNode(SimpleNode node, Context context) {
0634:                return node.info;
0635:            }
0636:
0637:            public Object stringNode(SimpleNode node, Context context) {
0638:                String str = node.str;
0639:                if (str != null) {
0640:                    return str;
0641:                } else {
0642:                    int n = node.jjtGetNumChildren();
0643:                    StringBuffer sbuf = new StringBuffer();
0644:                    for (int i = 0; i < n; i++) {
0645:                        SimpleNode c = node.jjtGetChild(i);
0646:                        if (c.id == PnutsParserTreeConstants.JJTSTRINGNODE) {
0647:                            sbuf.append(c.str);
0648:                        } else {
0649:                            sbuf
0650:                                    .append(String.valueOf(c.accept(this ,
0651:                                            context)));
0652:                        }
0653:                    }
0654:                    return sbuf.toString();
0655:                }
0656:            }
0657:
0658:            public Object trueNode(SimpleNode node, Context context) {
0659:                return Boolean.TRUE;
0660:            }
0661:
0662:            public Object falseNode(SimpleNode node, Context context) {
0663:                return Boolean.FALSE;
0664:            }
0665:
0666:            public Object nullNode(SimpleNode node, Context context) {
0667:                return null;
0668:            }
0669:
0670:            private void doAssign(String symbol, Object expr, Context context) {
0671:                if (context.inGeneratorClosure) {
0672:                    if (context.frame.outer != null) {
0673:                        context.setValue(symbol, expr);
0674:                    } else {
0675:                        context.getCurrentPackage().set(symbol, expr);
0676:                    }
0677:                } else {
0678:                    context.setValue(symbol, expr);
0679:                }
0680:            }
0681:
0682:            private Object doAssign(SimpleNode node, Object expr,
0683:                    Context context, BinaryOperator op) {
0684:                if (node.id == PnutsParserTreeConstants.JJTIDNODE) {
0685:                    if (op != null) {
0686:                        expr = op.operateOn(context.getValue(node.str), expr);
0687:                    }
0688:                    doAssign(node.str, expr, context);
0689:                    return expr;
0690:                } else if (node.id == PnutsParserTreeConstants.JJTGLOBAL) {
0691:                    Package pkg = Package.getPackage("", context);
0692:                    if (op != null) {
0693:                        expr = op.operateOn(pkg.get(node.str, context), expr);
0694:                    }
0695:                    pkg.set(node.str, expr, context);
0696:                    return expr;
0697:
0698:                } else if (node.id == PnutsParserTreeConstants.JJTINDEXNODE) {
0699:                    Object o = accept(node, 0, context);
0700:                    Object idx = accept(node, 1, context);
0701:                    if (o instanceof  String) {
0702:                        if (op != null || !(expr instanceof  Character)) {
0703:                            throw new PnutsException("illegal.assign",
0704:                                    NO_PARAM, context);
0705:                        }
0706:                        expr = Runtime.replaceChar((String) o, (Number) idx,
0707:                                expr);
0708:                        String sym = node.jjtGetChild(0).str;
0709:                        if (sym != null) {
0710:                            context.setValue(sym, expr);
0711:                        }
0712:                        return expr;
0713:                    } else {
0714:                        if (op != null) {
0715:                            expr = op.operateOn(Runtime.getElement(o, idx,
0716:                                    context), expr);
0717:                        }
0718:                        Runtime.setElement(o, idx, expr, context);
0719:                        return expr;
0720:                    }
0721:                } else if (node.id == PnutsParserTreeConstants.JJTSTATICMEMBERNODE) {
0722:                    SimpleNode c1 = node.children[0];
0723:                    String pkgName = getPackageName(c1);
0724:                    Package pkg = Package.find(pkgName, context);
0725:                    if (pkg != null) {
0726:                        if (op != null) {
0727:                            Object f = pkg.get(node.str, context);
0728:                            expr = op.operateOn(f, expr);
0729:                        }
0730:                        pkg.set(node.str, expr, context);
0731:                        return expr;
0732:                    }
0733:                    Object target = c1.accept(this , context);
0734:                    if (target instanceof  Class) {
0735:                        Class clazz = (Class) target;
0736:                        if (op != null) {
0737:                            expr = op.operateOn(Runtime.getStaticField(context,
0738:                                    clazz, node.str), expr);
0739:                        }
0740:                        Runtime.putStaticField(context, clazz, node.str, expr);
0741:                        return expr;
0742:                    } else {
0743:                        throw new PnutsException("package.notFound", NO_PARAM,
0744:                                context);
0745:                    }
0746:                } else if (node.id == PnutsParserTreeConstants.JJTMEMBERNODE) {
0747:                    Object target = accept(node, 0, context);
0748:                    if (op != null) {
0749:                        expr = op.operateOn(Runtime.getField(context, target,
0750:                                node.str), expr);
0751:                    }
0752:                    Runtime.putField(context, target, node.str, expr);
0753:                    return expr;
0754:                } else if (node.id == PnutsParserTreeConstants.JJTRANGENODE) {
0755:                    if (op != null) {
0756:                        throw new PnutsException("illegal.assign", NO_PARAM,
0757:                                context);
0758:                    }
0759:                    Object target = accept(node, 0, context);
0760:                    Object idx1 = accept(node, 1, context);
0761:                    Object idx2 = null;
0762:                    if (node.jjtGetNumChildren() >= 3) {
0763:                        idx2 = accept(node, 2, context);
0764:                    }
0765:                    Object value = setRange(target, idx1, idx2, expr, context);
0766:                    if (target instanceof  String) {
0767:                        SimpleNode cld = node.children[0];
0768:
0769:                        if (cld.id == PnutsParserTreeConstants.JJTIDNODE
0770:                                || cld.id == PnutsParserTreeConstants.JJTGLOBAL
0771:                                || cld.id == PnutsParserTreeConstants.JJTINDEXNODE
0772:                                || cld.id == PnutsParserTreeConstants.JJTSTATICMEMBERNODE
0773:                                || cld.id == PnutsParserTreeConstants.JJTMEMBERNODE) {
0774:                            return doAssign(cld, value, context, null);
0775:                        } else {
0776:                            return value;
0777:                        }
0778:                    }
0779:                    return value;
0780:                } else {
0781:                    throw new PnutsException("illegal.assign", NO_PARAM,
0782:                            context);
0783:                }
0784:            }
0785:
0786:            private Object assign(SimpleNode node, Context context,
0787:                    BinaryOperator op) {
0788:
0789:                Object expr = accept(node, 1, context);
0790:                try {
0791:                    SimpleNode lhs = node.children[0];
0792:                    if (lhs.id == PnutsParserTreeConstants.JJTMULTIASSIGNLHS) {
0793:                        int n = lhs.jjtGetNumChildren();
0794:                        for (int i = 0; i < n; i++) {
0795:                            doAssign(lhs.children[i].str, Runtime.getElementAt(
0796:                                    expr, i, context), context);
0797:                        }
0798:                        return expr;
0799:                    } else {
0800:                        return doAssign(lhs, expr, context, op);
0801:                    }
0802:                } catch (PnutsException p) {
0803:                    throw p;
0804:                } catch (Throwable t) {
0805:                    throw new PnutsException(t, context);
0806:                }
0807:            }
0808:
0809:            public Object assignment(SimpleNode node, Context context) {
0810:                return assign(node, context, null);
0811:            }
0812:
0813:            public Object assignmentTA(SimpleNode node, Context context) {
0814:                return assign(node, context, context._multiply);
0815:            }
0816:
0817:            public Object assignmentMA(SimpleNode node, Context context) {
0818:                return assign(node, context, context._mod);
0819:            }
0820:
0821:            public Object assignmentDA(SimpleNode node, Context context) {
0822:                return assign(node, context, context._divide);
0823:            }
0824:
0825:            public Object assignmentPA(SimpleNode node, Context context) {
0826:                return assign(node, context, context._add);
0827:            }
0828:
0829:            public Object assignmentSA(SimpleNode node, Context context) {
0830:                return assign(node, context, context._subtract);
0831:            }
0832:
0833:            public Object assignmentLA(SimpleNode node, Context context) {
0834:                return assign(node, context, context._shiftLeft);
0835:            }
0836:
0837:            public Object assignmentRA(SimpleNode node, Context context) {
0838:                return assign(node, context, context._shiftRight);
0839:            }
0840:
0841:            public Object assignmentRAA(SimpleNode node, Context context) {
0842:                return assign(node, context, context._shiftArithmetic);
0843:            }
0844:
0845:            public Object assignmentAA(SimpleNode node, Context context) {
0846:                return assign(node, context, context._and);
0847:            }
0848:
0849:            public Object assignmentEA(SimpleNode node, Context context) {
0850:                return assign(node, context, context._xor);
0851:            }
0852:
0853:            public Object assignmentOA(SimpleNode node, Context context) {
0854:                return assign(node, context, context._or);
0855:            }
0856:
0857:            public Object logOrNode(SimpleNode node, Context context) {
0858:                Object o1 = accept(node, 0, context);
0859:                if (!(o1 instanceof  Boolean)) {
0860:                    o1 = Runtime.toBoolean(o1);
0861:                }
0862:                if (((Boolean) o1).booleanValue()) {
0863:                    return Boolean.TRUE;
0864:                } else {
0865:                    Object o2 = accept(node, 1, context);
0866:                    if (!(o2 instanceof  Boolean)) {
0867:                        o2 = Runtime.toBoolean(o2);
0868:                    }
0869:                    return o2;
0870:                }
0871:            }
0872:
0873:            public Object logAndNode(SimpleNode node, Context context) {
0874:                Object o1 = accept(node, 0, context);
0875:                if (!(o1 instanceof  Boolean)) {
0876:                    o1 = Runtime.toBoolean(o1);
0877:                }
0878:                if (((Boolean) o1).booleanValue()) {
0879:                    Object o2 = accept(node, 1, context);
0880:                    if (!(o2 instanceof  Boolean)) {
0881:                        o2 = Runtime.toBoolean(o2);
0882:                    }
0883:                    return o2;
0884:                } else {
0885:                    return Boolean.FALSE;
0886:                }
0887:            }
0888:
0889:            public Object orNode(SimpleNode node, Context context) {
0890:                return context._or.operateOn(accept(node, 0, context), accept(
0891:                        node, 1, context));
0892:            }
0893:
0894:            public Object xorNode(SimpleNode node, Context context) {
0895:                return context._xor.operateOn(accept(node, 0, context), accept(
0896:                        node, 1, context));
0897:            }
0898:
0899:            public Object andNode(SimpleNode node, Context context) {
0900:                return context._and.operateOn(accept(node, 0, context), accept(
0901:                        node, 1, context));
0902:            }
0903:
0904:            public Object equalNode(SimpleNode node, Context context) {
0905:                return eq(accept(node, 0, context), accept(node, 1, context),
0906:                        context) ? Boolean.TRUE : Boolean.FALSE;
0907:            }
0908:
0909:            public Object notEqNode(SimpleNode node, Context context) {
0910:                return eq(accept(node, 0, context), accept(node, 1, context),
0911:                        context) ? Boolean.FALSE : Boolean.TRUE;
0912:            }
0913:
0914:            public Object instanceof Expression(SimpleNode node, Context context) {
0915:                Object o1 = accept(node, 0, context);
0916:                Class type = resolveType(node.jjtGetChild(1), context);
0917:                return (type.isInstance(o1) ? Boolean.TRUE : Boolean.FALSE);
0918:            }
0919:
0920:            public Object ltNode(SimpleNode node, Context context) {
0921:                if (context._lt.operateOn(accept(node, 0, context), accept(
0922:                        node, 1, context))) {
0923:                    return Boolean.TRUE;
0924:                } else {
0925:                    return Boolean.FALSE;
0926:                }
0927:            }
0928:
0929:            public Object gtNode(SimpleNode node, Context context) {
0930:                if (context._gt.operateOn(accept(node, 0, context), accept(
0931:                        node, 1, context))) {
0932:                    return Boolean.TRUE;
0933:                } else {
0934:                    return Boolean.FALSE;
0935:                }
0936:            }
0937:
0938:            public Object leNode(SimpleNode node, Context context) {
0939:                if (context._le.operateOn(accept(node, 0, context), accept(
0940:                        node, 1, context))) {
0941:                    return Boolean.TRUE;
0942:                } else {
0943:                    return Boolean.FALSE;
0944:                }
0945:            }
0946:
0947:            public Object geNode(SimpleNode node, Context context) {
0948:                if (context._ge.operateOn(accept(node, 0, context), accept(
0949:                        node, 1, context))) {
0950:                    return Boolean.TRUE;
0951:                } else {
0952:                    return Boolean.FALSE;
0953:                }
0954:            }
0955:
0956:            public Object shiftLeftNode(SimpleNode node, Context context) {
0957:                try {
0958:                    return context._shiftLeft.operateOn(
0959:                            accept(node, 0, context), accept(node, 1, context));
0960:                } catch (Exception e) {
0961:                    throw new PnutsException(e, context);
0962:                }
0963:            }
0964:
0965:            public Object shiftRightNode(SimpleNode node, Context context) {
0966:                try {
0967:                    return context._shiftRight.operateOn(accept(node, 0,
0968:                            context), accept(node, 1, context));
0969:                } catch (Exception e) {
0970:                    throw new PnutsException(e, context);
0971:                }
0972:            }
0973:
0974:            public Object shiftArithmeticNode(SimpleNode node, Context context) {
0975:                try {
0976:                    return context._shiftArithmetic.operateOn(accept(node, 0,
0977:                            context), accept(node, 1, context));
0978:                } catch (Exception e) {
0979:                    throw new PnutsException(e, context);
0980:                }
0981:            }
0982:
0983:            public Object addNode(SimpleNode node, Context context) {
0984:                try {
0985:                    return context._add.operateOn(accept(node, 0, context),
0986:                            accept(node, 1, context));
0987:                } catch (Exception e) {
0988:                    throw new PnutsException(e, context);
0989:                }
0990:            }
0991:
0992:            public Object subtractNode(SimpleNode node, Context context) {
0993:                try {
0994:                    return context._subtract.operateOn(
0995:                            accept(node, 0, context), accept(node, 1, context));
0996:                } catch (Exception e) {
0997:                    throw new PnutsException(e, context);
0998:                }
0999:            }
1000:
1001:            public Object multNode(SimpleNode node, Context context) {
1002:                try {
1003:                    return context._multiply.operateOn(
1004:                            accept(node, 0, context), accept(node, 1, context));
1005:                } catch (Exception e) {
1006:                    throw new PnutsException(e, context);
1007:                }
1008:            }
1009:
1010:            public Object divideNode(SimpleNode node, Context context) {
1011:                try {
1012:                    return context._divide.operateOn(accept(node, 0, context),
1013:                            accept(node, 1, context));
1014:                } catch (Exception e) {
1015:                    throw new PnutsException(e, context);
1016:                }
1017:            }
1018:
1019:            public Object modNode(SimpleNode node, Context context) {
1020:                try {
1021:                    return context._mod.operateOn(accept(node, 0, context),
1022:                            accept(node, 1, context));
1023:                } catch (Exception e) {
1024:                    throw new PnutsException(e, context);
1025:                }
1026:            }
1027:
1028:            public Object negativeNode(SimpleNode node, Context context) {
1029:                try {
1030:                    return context._negate.operateOn(accept(node, 0, context));
1031:                } catch (Exception e) {
1032:                    throw new PnutsException(e, context);
1033:                }
1034:            }
1035:
1036:            public Object preIncrNode(SimpleNode node, Context context) {
1037:                return doAssign(node.children[0], one, context, context._add);
1038:            }
1039:
1040:            public Object preDecrNode(SimpleNode node, Context context) {
1041:                return doAssign(node.children[0], one, context,
1042:                        context._subtract);
1043:            }
1044:
1045:            public Object postIncrNode(SimpleNode node, Context context) {
1046:                SimpleNode n = node.children[0];
1047:                Object ret = n.accept(this , context);
1048:                doAssign(n, one, context, context._add);
1049:                return ret;
1050:            }
1051:
1052:            public Object postDecrNode(SimpleNode node, Context context) {
1053:                SimpleNode n = node.children[0];
1054:                Object ret = n.accept(this , context);
1055:                doAssign(n, one, context, context._subtract);
1056:                return ret;
1057:            }
1058:
1059:            public Object notNode(SimpleNode node, Context context) {
1060:                return context._not.operateOn(accept(node, 0, context));
1061:            }
1062:
1063:            public Object logNotNode(SimpleNode node, Context context) {
1064:                Object o = accept(node, 0, context);
1065:                if (o instanceof  Boolean) {
1066:                    return ((Boolean) o).booleanValue() ? Boolean.FALSE
1067:                            : Boolean.TRUE;
1068:                } else {
1069:                    return Runtime.toBoolean(o).booleanValue() ? Boolean.FALSE
1070:                            : Boolean.TRUE;
1071:                }
1072:            }
1073:
1074:            public Object continueNode(SimpleNode node, Context context) {
1075:                throw new Runtime.Continue();
1076:            }
1077:
1078:            public Object breakNode(SimpleNode node, Context context) {
1079:                Object o = null;
1080:                if (node.jjtGetNumChildren() > 0) {
1081:                    o = accept(node, 0, context);
1082:                }
1083:
1084:                if (context.inGeneratorClosure) {
1085:                    throw new Generator.Break(o);
1086:                } else {
1087:                    throw new Runtime.Break(o);
1088:                }
1089:            }
1090:
1091:            public Object returnNode(SimpleNode node, Context context) {
1092:                Object o = null;
1093:                if (node.jjtGetNumChildren() > 0) {
1094:                    o = accept(node, 0, context);
1095:                }
1096:                throw new Jump(o);
1097:            }
1098:
1099:            public Object yieldNode(SimpleNode node, Context context) {
1100:                throw new PnutsException(
1101:                        "yield must be used in a generator function", context);
1102:            }
1103:
1104:            public Object catchNode(SimpleNode node, Context context) {
1105:                int nargs = node.jjtGetNumChildren();
1106:                if (nargs == 0) {
1107:                    return PnutsFunction.CATCH;
1108:                } else if (nargs == 1) {
1109:                    Class cls = (Class) accept(node, 0, context);
1110:                    PnutsFunction func = (PnutsFunction) accept(node, 1,
1111:                            context);
1112:                    context.catchException(cls, func);
1113:                }
1114:                return null;
1115:            }
1116:
1117:            public Object throwNode(SimpleNode node, Context context) {
1118:                int nargs = node.jjtGetNumChildren();
1119:                if (nargs == 0) {
1120:                    return PnutsFunction.THROW;
1121:                } else if (nargs == 1) {
1122:                    Object arg = accept(node, 0, context);
1123:                    if (arg instanceof  PnutsException) {
1124:                        throw (PnutsException) arg;
1125:                    } else if (arg instanceof  Throwable) {
1126:                        throw new PnutsException((Throwable) arg, context);
1127:                    } else {
1128:                        throw new PnutsException(String.valueOf(arg), context);
1129:                    }
1130:                }
1131:                return null;
1132:            }
1133:
1134:            public Object finallyNode(SimpleNode node, Context context) {
1135:                int n = node.jjtGetNumChildren();
1136:                if (n == 1) {
1137:                    PnutsFunction f = (PnutsFunction) accept(node, 0, context);
1138:                    context.setFinallyFunction(f);
1139:                    return f;
1140:                } else if (n == 2) {
1141:                    PnutsFunction f0 = (PnutsFunction) accept(node, 0, context);
1142:                    PnutsFunction f1 = (PnutsFunction) accept(node, 1, context);
1143:                    try {
1144:                        return f0.exec(NO_PARAM, context);
1145:                    } finally {
1146:                        f1.exec(NO_PARAM, context);
1147:                    }
1148:                }
1149:                return null;
1150:            }
1151:
1152:            public Object tryStatement(SimpleNode node, Context context) {
1153:                int n = node.jjtGetNumChildren();
1154:                SimpleNode lastNode = node.jjtGetChild(n - 1);
1155:                PnutsException pe = null;
1156:                Object value = null;
1157:                boolean handled = false;
1158:                SimpleNode finallyBlock = null;
1159:                if (lastNode.id == PnutsParserTreeConstants.JJTFINALLYBLOCK) {
1160:                    finallyBlock = lastNode;
1161:                }
1162:                try {
1163:                    value = accept(node, 0, context);
1164:                } catch (Escape esc) {
1165:                    throw esc;
1166:                } catch (Runtime.Break brk) {
1167:                    throw brk;
1168:                } catch (Runtime.Continue cont) {
1169:                    throw cont;
1170:                } catch (Throwable t) {
1171:                    if (t instanceof  PnutsException) {
1172:                        pe = (PnutsException) t;
1173:                        t = ((PnutsException) t).getThrowable();
1174:                    }
1175:                    for (int i = 1; i < n; i++) {
1176:                        SimpleNode c = node.jjtGetChild(i);
1177:                        if (c.id == PnutsParserTreeConstants.JJTCATCHBLOCK) {
1178:                            String var = c.str;
1179:                            StringBuffer sbuf = new StringBuffer();
1180:                            SimpleNode classNode = c.jjtGetChild(0);
1181:                            sbuf.append(classNode.jjtGetChild(0).str);
1182:                            for (int j = 1; j < classNode.jjtGetNumChildren(); j++) {
1183:                                sbuf.append('.');
1184:                                sbuf.append(classNode.jjtGetChild(j).str);
1185:                            }
1186:                            Class cls = context.resolveClass(sbuf.toString());
1187:
1188:                            if (cls != null && cls.isInstance(t)) {
1189:                                try {
1190:                                    context.openLocal(new String[] {});
1191:                                    context.bind(var, t);
1192:                                    return accept(c, 1, context);
1193:                                } finally {
1194:                                    context.closeLocal();
1195:                                }
1196:                            }
1197:                        }
1198:                    }
1199:                    if (pe != null) {
1200:                        throw pe;
1201:                    } else {
1202:                        throw new PnutsException(t, context);
1203:                    }
1204:                } finally {
1205:                    if (finallyBlock != null) {
1206:                        accept(finallyBlock, 0, context);
1207:                    }
1208:                }
1209:                return value;
1210:            }
1211:
1212:            public Object catchBlock(SimpleNode node, Context context) {
1213:                return null;
1214:            }
1215:
1216:            public Object blockNode(SimpleNode node, Context context) {
1217:                Object last = null;
1218:                int n = node.jjtGetNumChildren();
1219:                for (int i = 0; i < n; i++) {
1220:                    last = accept(node, i, context);
1221:                }
1222:                return last;
1223:            }
1224:
1225:            public Object ifStatement(SimpleNode node, Context context) {
1226:
1227:                Object con = accept(node, 0, context);
1228:                if (condition(con, context)) {
1229:                    return accept(node, 1, context);
1230:                }
1231:                int n = node.jjtGetNumChildren();
1232:                for (int i = 2; i < n; i++) {
1233:                    SimpleNode _node = node.children[i];
1234:                    if (_node.id == PnutsParserTreeConstants.JJTELSEIFNODE) {
1235:                        if (condition(accept(_node, 0, context), context)) {
1236:                            return accept(_node, 1, context);
1237:                        }
1238:                    } else if (_node.id == PnutsParserTreeConstants.JJTELSENODE) {
1239:                        return accept(_node, 0, context);
1240:                    }
1241:                }
1242:                return null;
1243:            }
1244:
1245:            static boolean condition(Object cond, Context context) {
1246:                if (cond instanceof  Boolean) {
1247:                    return ((Boolean) cond).booleanValue();
1248:                } else {
1249:                    return (Runtime.toBoolean(cond)).booleanValue();
1250:                }
1251:            }
1252:
1253:            public Object doStatement(SimpleNode node, Context context) {
1254:                Object last = null;
1255:                try {
1256:                    while (true) {
1257:                        try {
1258:                            last = accept(node, 0, context);
1259:                            Object cond = accept(node, 1, context);
1260:                            if (!(cond instanceof  Boolean)) {
1261:                                cond = Runtime.toBoolean(cond);
1262:                            }
1263:                            boolean b = ((Boolean) cond).booleanValue();
1264:                            if (!b) {
1265:                                return last;
1266:                            }
1267:                        } catch (Runtime.Continue cont) {
1268:                        }
1269:                    }
1270:                } catch (Runtime.Break brk) {
1271:                    return brk.getValue();
1272:                }
1273:            }
1274:
1275:            public Object whileStatement(SimpleNode node, Context context) {
1276:                Object last = null;
1277:                try {
1278:                    while (true) {
1279:                        Object cond = accept(node, 0, context);
1280:                        if (!(cond instanceof  Boolean)) {
1281:                            cond = Runtime.toBoolean(cond);
1282:                        }
1283:                        try {
1284:                            boolean b = ((Boolean) cond).booleanValue();
1285:                            if (b) {
1286:                                last = accept(node, 1, context);
1287:                            } else {
1288:                                return last;
1289:                            }
1290:                        } catch (Runtime.Continue cont) {
1291:                        }
1292:                    }
1293:                } catch (Runtime.Break brk) {
1294:                    return brk.getValue();
1295:                }
1296:            }
1297:
1298:            public Object forStatement(SimpleNode node, final Context context) {
1299:                SimpleNode initNode = null;
1300:                SimpleNode condNode = null;
1301:                SimpleNode updateNode = null;
1302:                SimpleNode blockNode = null;
1303:                int j = 0;
1304:                SimpleNode n = node.children[j];
1305:                if (n.id == PnutsParserTreeConstants.JJTFORENUM) {
1306:                    int nc = n.jjtGetNumChildren();
1307:                    SimpleNode node0 = n.children[0];
1308:                    String[] vars;
1309:                    Object n0;
1310:                    if (node0.id == PnutsParserTreeConstants.JJTMULTIASSIGNLHS) {
1311:                        int nc2 = node0.jjtGetNumChildren();
1312:                        vars = new String[nc2];
1313:                        for (int i = 0; i < nc2; i++) {
1314:                            vars[i] = node0.jjtGetChild(i).str;
1315:                        }
1316:                        n0 = n.children[1].accept(this , context);
1317:                    } else {
1318:                        vars = new String[] { n.str };
1319:                        n0 = node0.accept(this , context);
1320:                    }
1321:                    blockNode = node.children[1];
1322:                    if (node0.id == PnutsParserTreeConstants.JJTMULTIASSIGNLHS
1323:                            || nc == 1) {
1324:                        return doForeach(vars, n0, blockNode, context);
1325:                    } else if (nc == 2) {
1326:                        Object n1 = n.children[1].accept(this , context);
1327:                        int start = ((Number) n0).intValue();
1328:                        int end = ((Number) n1).intValue();
1329:                        return doForeach(n.str, start, end, blockNode, context);
1330:                    } else {
1331:                        throw new IllegalArgumentException();
1332:                    }
1333:                } else if (n.id == PnutsParserTreeConstants.JJTFORINIT) {
1334:                    initNode = n;
1335:                    j++;
1336:                }
1337:                n = node.children[j];
1338:                if (n.id != PnutsParserTreeConstants.JJTFORUPDATE
1339:                        && n.id != PnutsParserTreeConstants.JJTBLOCK) {
1340:                    condNode = n;
1341:                    j++;
1342:                }
1343:                n = node.children[j];
1344:                if (n.id == PnutsParserTreeConstants.JJTFORUPDATE) {
1345:                    updateNode = n;
1346:                    j++;
1347:                }
1348:
1349:                blockNode = node.children[j];
1350:
1351:                Object last = null;
1352:
1353:                if (initNode != null) {
1354:                    int num = initNode.jjtGetNumChildren();
1355:                    String[] env = new String[num];
1356:                    for (int i = 0; i < env.length; i++) {
1357:                        SimpleNode sn = initNode.children[i];
1358:                        env[i] = sn.str;
1359:                    }
1360:                    context.openLocal(env);
1361:                    for (int i = 0; i < env.length; i++) {
1362:                        SimpleNode sn = initNode.children[i];
1363:                        context.bind(env[i], accept(sn, 0, context));
1364:                    }
1365:                } else {
1366:                    context.openLocal(new String[] {});
1367:                }
1368:
1369:                Object c = null;
1370:                if (condNode != null) {
1371:                    c = condNode.accept(this , context);
1372:                } else {
1373:                    c = Boolean.TRUE;
1374:                }
1375:                try {
1376:                    while (true) {
1377:                        if (!(c instanceof  Boolean)) {
1378:                            c = Runtime.toBoolean(c);
1379:                        }
1380:                        if (!((Boolean) c).booleanValue()) {
1381:                            break;
1382:                        }
1383:                        try {
1384:                            last = blockNode.accept(this , context);
1385:                        } catch (Runtime.Continue cont) {
1386:                        }
1387:                        if (updateNode != null) {
1388:                            expressionList(updateNode, context);
1389:                        }
1390:                        if (condNode != null) {
1391:                            c = condNode.accept(this , context);
1392:                        }
1393:                    }
1394:                } catch (Runtime.Break brk) {
1395:                    last = brk.getValue();
1396:                } finally {
1397:                    context.closeLocal();
1398:                }
1399:                return last;
1400:            }
1401:
1402:            private Object doForeach(String var, int start, int end,
1403:                    SimpleNode blockNode, Context context) {
1404:                Object last = null;
1405:                context.openLocal(new String[] { var });
1406:                int delta;
1407:                try {
1408:                    if (start < end) {
1409:                        for (int i = start; i <= end; i++) {
1410:                            try {
1411:                                context.bind(var, new Integer(i));
1412:                                last = blockNode.accept(this , context);
1413:                            } catch (Runtime.Continue cont) {
1414:                            }
1415:                        }
1416:                    } else {
1417:                        for (int i = start; i >= end; i--) {
1418:                            try {
1419:                                context.bind(var, new Integer(i));
1420:                                last = blockNode.accept(this , context);
1421:                            } catch (Runtime.Continue cont) {
1422:                            }
1423:                        }
1424:                    }
1425:                } catch (Runtime.Break brk) {
1426:                    last = brk.getValue();
1427:                } finally {
1428:                    context.closeLocal();
1429:                }
1430:                return last;
1431:            }
1432:
1433:            private Object doForeach(final String[] vars, Object array,
1434:                    SimpleNode blockNode, final Context context) {
1435:                if (array == null) {
1436:                    return null;
1437:                }
1438:                if (array instanceof  Generator) {
1439:                    final String tmpVar = "_tmp".intern();
1440:                    if (vars.length > 1) {
1441:                        blockNode = GeneratorHelper.expandMultiAssign(vars,
1442:                                tmpVar, blockNode);
1443:                    }
1444:                    Function f = new Function(null,
1445:                            vars.length > 1 ? new String[] { tmpVar } : vars,
1446:                            1, false, blockNode, context.getCurrentPackage(),
1447:                            context) {
1448:                        protected Object exec(Object[] args, Context context) {
1449:                            boolean inGeneratorClosure = context.inGeneratorClosure;
1450:                            try {
1451:                                context.inGeneratorClosure = true;
1452:                                return super .exec(args, context);
1453:                            } finally {
1454:                                context.inGeneratorClosure = inGeneratorClosure;
1455:                            }
1456:                        }
1457:                    };
1458:                    return Runtime.applyGenerator((Generator) array, f
1459:                            .register(null), context);
1460:                }
1461:
1462:                Enumeration e = Runtime.toEnumeration(array, context);
1463:                if (e == null) {
1464:                    throw new PnutsException("illegal.type.foreach",
1465:                            new Object[] { Pnuts.format(array) }, context);
1466:                }
1467:                Object last = null;
1468:                context.openLocal(vars);
1469:                try {
1470:                    if (vars.length == 1) {
1471:                        while (e.hasMoreElements()) {
1472:                            try {
1473:                                context.bind(vars[0], e.nextElement());
1474:                                last = blockNode.accept(this , context);
1475:                            } catch (Runtime.Continue cont) {
1476:                            }
1477:                        }
1478:                    } else {
1479:                        while (e.hasMoreElements()) {
1480:                            try {
1481:                                Object elem = e.nextElement();
1482:                                for (int i = 0; i < vars.length; i++) {
1483:                                    context.bind(vars[i], Runtime.getElementAt(
1484:                                            elem, i, context));
1485:                                }
1486:                                last = blockNode.accept(this , context);
1487:                            } catch (Runtime.Continue cont) {
1488:                            }
1489:                        }
1490:                    }
1491:                } catch (Runtime.Break brk) {
1492:                    last = brk.getValue();
1493:                } finally {
1494:                    context.closeLocal();
1495:                }
1496:                return last;
1497:            }
1498:
1499:            public Object foreachStatement(SimpleNode node, Context context) {
1500:                SimpleNode n1 = node.children[0];
1501:                SimpleNode n2 = node.children[1];
1502:                String var = node.str;
1503:
1504:                return doForeach(new String[] { var },
1505:                        n1.accept(this , context), n2, context);
1506:            }
1507:
1508:            public Object switchStatement(SimpleNode node, Context context) {
1509:                int n = node.jjtGetNumChildren();
1510:                Object target = accept(node, 0, context);
1511:                Object last = null;
1512:                boolean matched = false;
1513:                try {
1514:                    for (int i = 1; i < n; i++) {
1515:                        SimpleNode _node = node.children[i];
1516:                        if (_node.jjtGetNumChildren() == 1) { // case
1517:                            Object o = accept(_node, 0, context);
1518:                            i++;
1519:                            if (matched || eq(target, o, context)) {
1520:                                last = accept(node, i, context);
1521:                                matched = true;
1522:                            }
1523:                        } else { // default
1524:                            matched = true;
1525:                            last = accept(node, ++i, context);
1526:                        }
1527:                    }
1528:                } catch (Runtime.Break brk) {
1529:                    last = brk.getValue();
1530:                }
1531:                return last;
1532:            }
1533:
1534:            public Object switchBlock(SimpleNode node, Context context) {
1535:                int n = node.jjtGetNumChildren();
1536:                Object last = null;
1537:                for (int i = 0; i < n; i++) {
1538:                    last = accept(node, i, context);
1539:                }
1540:                return last;
1541:            }
1542:
1543:            public Object functionStatement(SimpleNode node, Context context) {
1544:                SimpleNode param = node.jjtGetChild(0);
1545:                int nargs = param.jjtGetNumChildren();
1546:                String[] locals = new String[nargs];
1547:                SimpleNode n0 = null;
1548:                SimpleNode block = node.jjtGetChild(1);
1549:
1550:                synchronized (node) {
1551:                    if (node.getAttribute("type") == null) {
1552:                        if (Runtime.isGenerator(block)) {
1553:                            node.setAttribute("type", GENERATOR);
1554:                        } else {
1555:                            node.setAttribute("type", FUNCTION);
1556:                        }
1557:                    }
1558:                }
1559:
1560:                boolean varargs = "[".equals(param.str);
1561:
1562:                for (int j = 0; j < nargs; j++) {
1563:                    locals[j] = param.children[j].str;
1564:                }
1565:
1566:                String symbol = node.str;
1567:                StackFrame stackFrame = context.stackFrame;
1568:                Package pkg = context.getCurrentPackage();
1569:
1570:                Function f;
1571:                if (node.getAttribute("type") == GENERATOR) {
1572:                    f = new Generator.GeneratorFunction(symbol, locals, nargs,
1573:                            block, pkg, context);
1574:                } else {
1575:                    f = new Function(symbol, locals, nargs, varargs, block,
1576:                            pkg, context);
1577:                }
1578:                //		String name = f.getName();
1579:                PnutsFunction ht = null;
1580:
1581:                if (symbol != null) {
1582:                    if (stackFrame.parent != null) {
1583:                        Object o = null;
1584:                        Binding b = (Binding) stackFrame.lookup(symbol);
1585:                        boolean found = false;
1586:                        if (b != null) {
1587:                            o = b.value;
1588:                            if (o instanceof  PnutsFunction) {
1589:                                ht = f.register((PnutsFunction) o);
1590:                            } else {
1591:                                ht = Runtime.defineUnboundFunction(f, symbol,
1592:                                        pkg);
1593:                            }
1594:                            found = true;
1595:                        } else {
1596:                            Function ff = context.frame;
1597:                            while (ff != null) {
1598:                                SymbolTable ls = ff.lexicalScope;
1599:                                if (ls != null) {
1600:                                    Binding bb = ls.lookup0(symbol);
1601:                                    if (bb != null) {
1602:                                        o = ((Binding) bb.value).value;
1603:                                        if (o instanceof  PnutsFunction) {
1604:                                            ht = f.register((PnutsFunction) o,
1605:                                                    true);
1606:                                        } else {
1607:                                            ht = Runtime.defineUnboundFunction(
1608:                                                    f, symbol, pkg);
1609:                                        }
1610:                                        found = true;
1611:                                        break;
1612:                                    }
1613:                                }
1614:                                ff = ff.outer;
1615:                            }
1616:                        }
1617:                        if (!found) {
1618:                            ht = Runtime.defineUnboundFunction(f, symbol, pkg);
1619:                        }
1620:
1621:                        if (b != null) {
1622:                            b.set(ht);
1623:                        } else {
1624:                            stackFrame.assign(symbol, ht);
1625:                        }
1626:                    } else {
1627:                        ht = Runtime.defineTopLevelFunction(f, symbol, pkg,
1628:                                context);
1629:                    }
1630:                } else {
1631:                    ht = f.register(null);
1632:                }
1633:                return ht;
1634:            }
1635:
1636:            public Object ternary(SimpleNode node, Context context) {
1637:                if (condition(accept(node, 0, context), context)) {
1638:                    return accept(node, 1, context);
1639:                } else {
1640:                    return accept(node, 2, context);
1641:                }
1642:            }
1643:
1644:            protected Object accept(SimpleNode node, int idx, Context context) {
1645:                return node.children[idx].accept(this , context);
1646:            }
1647:
1648:            static String getClassName(SimpleNode node) {
1649:                int n = node.jjtGetNumChildren();
1650:                if (n > 1) {
1651:                    StringBuffer sbuf = new StringBuffer();
1652:                    sbuf.append(node.children[0].str);
1653:                    for (int i = 1; i < n; i++) {
1654:                        sbuf.append('.');
1655:                        sbuf.append(node.children[i].str);
1656:                    }
1657:                    return sbuf.toString().intern();
1658:                } else {
1659:                    return node.children[0].str;
1660:                }
1661:            }
1662:
1663:            static Class resolveTypeNode(SimpleNode typeNode, Context context) {
1664:                Class type = null;
1665:                if (typeNode.id == PnutsParserTreeConstants.JJTARRAYTYPE) {
1666:                    SimpleNode n = typeNode;
1667:                    int count = 0;
1668:                    while (n != null
1669:                            && n.id == PnutsParserTreeConstants.JJTARRAYTYPE) {
1670:                        count++;
1671:                        n = n.jjtGetChild(0);
1672:                    }
1673:                    if (n != null
1674:                            && n.id == PnutsParserTreeConstants.JJTCLASSNAME) {
1675:                        type = Runtime.arrayType(resolveClassNameNode(n,
1676:                                context), count);
1677:                    }
1678:                } else if (typeNode.id == PnutsParserTreeConstants.JJTCLASSNAME) {
1679:                    type = resolveClassNameNode(typeNode, context);
1680:                } else {
1681:                    throw new RuntimeException();
1682:                }
1683:                return type;
1684:            }
1685:
1686:            static Class resolveClassNameNode(SimpleNode node, Context context) {
1687:                int n = node.jjtGetNumChildren();
1688:                if (n == 1) {
1689:                    String sym = node.children[0].str;
1690:                    if (sym == INT_SYMBOL) {
1691:                        return Integer.TYPE;
1692:                    } else if (sym == SHORT_SYMBOL) {
1693:                        return Short.TYPE;
1694:                    } else if (sym == CHAR_SYMBOL) {
1695:                        return Character.TYPE;
1696:                    } else if (sym == BYTE_SYMBOL) {
1697:                        return Byte.TYPE;
1698:                    } else if (sym == LONG_SYMBOL) {
1699:                        return Long.TYPE;
1700:                    } else if (sym == FLOAT_SYMBOL) {
1701:                        return Float.TYPE;
1702:                    } else if (sym == DOUBLE_SYMBOL) {
1703:                        return Double.TYPE;
1704:                    } else if (sym == BOOLEAN_SYMBOL) {
1705:                        return Boolean.TYPE;
1706:                    } else if (sym == VOID_SYMBOL) {
1707:                        return Void.TYPE;
1708:                    }
1709:                }
1710:                String name = getClassName(node);
1711:                Class cls = context.resolveClass(name);
1712:                if (cls == null) {
1713:                    throw new PnutsException("class.notFound",
1714:                            new Object[] { name }, context);
1715:                }
1716:                return cls;
1717:            }
1718:
1719:            public Class resolveType(SimpleNode typeNode, Context context) {
1720:                Class type = null;
1721:                if (typeNode.id == PnutsParserTreeConstants.JJTARRAYTYPE) {
1722:                    SimpleNode n = typeNode;
1723:                    int count = 0;
1724:                    while (n != null
1725:                            && n.id == PnutsParserTreeConstants.JJTARRAYTYPE) {
1726:                        count++;
1727:                        n = n.jjtGetChild(0);
1728:                    }
1729:                    if (n != null
1730:                            && n.id != PnutsParserTreeConstants.JJTCLASSNAME) {
1731:                        throw new RuntimeException();
1732:                    }
1733:                    return Runtime.arrayType(resolveClassNameNode(n, context),
1734:                            count);
1735:                } else if (typeNode.id == PnutsParserTreeConstants.JJTCLASSNAME) {
1736:                    return resolveClassNameNode(typeNode, context);
1737:                } else {
1738:                    throw new PnutsException("class.expected", NO_PARAM,
1739:                            context);
1740:                }
1741:            }
1742:
1743:            public Object beanDef(SimpleNode node, Context context) {
1744:                SimpleNode classNameNode = node.jjtGetChild(0);
1745:                Configuration config = context.getConfiguration();
1746:
1747:                boolean marked = (node.info != null); /* experimental BIND feature */
1748:                Map table = new HashMap(); // temporary hashtable to collect listeners
1749:                try {
1750:                    Class cls = (Class) classNameNode.accept(this , context);
1751:                    Object target = config.callConstructor(context, cls,
1752:                            NO_PARAM, null);
1753:
1754:                    for (int i = 1; i < node.jjtGetNumChildren(); i++) {
1755:                        SimpleNode c = node.jjtGetChild(i);
1756:                        boolean bound = "::".equals(c.info);
1757:
1758:                        String propertyName = c.str;
1759:                        SimpleNode valueNode = c.jjtGetChild(0);
1760:                        if (bound && !marked) { /* experimental BIND feature */
1761:                            List memberNodes = new ArrayList();
1762:                            c.info = memberNodes;
1763:                            markMemberNodeInBeanDef(c, target, table, valueNode);
1764:                        }
1765:                        Object value = valueNode.accept(this , context);
1766:                        config.putField(context, target, propertyName, value);
1767:                    }
1768:                    if (!marked) {
1769:                        Runtime.setupPropertyChangeListeners(table, context);/* experimental BIND feature */
1770:                        node.info = target;
1771:                    }
1772:                    return target;
1773:                } catch (Exception e) {
1774:                    throw new PnutsException(e, context);
1775:                }
1776:            }
1777:
1778:            static void markMemberNodeInBeanDef(SimpleNode beanPropertyDef,
1779:                    Object target, Map table, SimpleNode node) {
1780:                if (node.id == PnutsParserTreeConstants.JJTMEMBERNODE) {
1781:                    node.info = new Object[] { target, beanPropertyDef, table };
1782:                } else if (node.id != PnutsParserTreeConstants.JJTFUNCTIONSTATEMENT) {
1783:                    for (int i = 0; i < node.jjtGetNumChildren(); i++) {
1784:                        markMemberNodeInBeanDef(beanPropertyDef, target, table,
1785:                                node.jjtGetChild(i));
1786:                    }
1787:                }
1788:            }
1789:
1790:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.