Source Code Cross Referenced for CodeGenerator.java in  » Parser » Rats-Parser-Generators » xtc » lang » jeannie » 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 » Parser » Rats Parser Generators » xtc.lang.jeannie 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * xtc - The eXTensible Compiler
0003:         * Copyright (C) 2007 IBM Corp.
0004:         *
0005:         * This program is free software; you can redistribute it and/or
0006:         * modify it under the terms of the GNU General Public License
0007:         * version 2 as published by the Free Software Foundation.
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
0012:         * GNU General Public License for more details.
0013:         *
0014:         * You should have received a copy of the GNU General Public License
0015:         * along with this program; if not, write to the Free Software
0016:         * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
0017:         * USA.
0018:         */
0019:        package xtc.lang.jeannie;
0020:
0021:        import java.io.File;
0022:        import java.util.ArrayList;
0023:        import java.util.HashMap;
0024:        import java.util.Iterator;
0025:        import java.util.List;
0026:        import java.util.Map;
0027:        import java.util.Set;
0028:        import java.util.Stack;
0029:
0030:        import xtc.Constants;
0031:        import xtc.Limits;
0032:        import xtc.lang.CAnalyzer;
0033:        import xtc.lang.JavaAnalyzer;
0034:        import xtc.lang.JavaEntities;
0035:        import xtc.lang.JavaTypeConverter;
0036:        import xtc.tree.GNode;
0037:        import xtc.tree.LineMarker;
0038:        import xtc.tree.Locatable;
0039:        import xtc.tree.Node;
0040:        import xtc.tree.Visitor;
0041:        import xtc.type.ClassT;
0042:        import xtc.type.FunctionT;
0043:        import xtc.type.MethodT;
0044:        import xtc.type.PointerT;
0045:        import xtc.type.Type;
0046:        import xtc.type.VariableT;
0047:        import xtc.type.VoidT;
0048:        import xtc.type.Type.Tag;
0049:        import xtc.util.Runtime;
0050:        import xtc.util.SymbolTable;
0051:        import xtc.util.SymbolTable.Scope;
0052:
0053:        /**
0054:         * A visitor that constructs separate C and Java ASTs from a JNI AST. Assumes
0055:         * that the input AST has been simplified with jeannie.AstSimplifier, and its types
0056:         * have been analyzed with jeannie.Analyzer.
0057:         * 
0058:         * @author Martin Hirzel
0059:         */
0060:        public class CodeGenerator extends Visitor {
0061:            public static final class Context {
0062:                final String _activeLanguage;
0063:                final String _cEnvStructName;
0064:                final boolean _cHasEnv;
0065:                final String _javaEnvClassName;
0066:                final String _javaEnvPackageName;
0067:                final boolean _javaIsStatic;
0068:                final String _openArray;
0069:                final Type _snippetType;
0070:
0071:                public Context(final Context other, final String activeLanguage) {
0072:                    this (activeLanguage, other._cEnvStructName, other._cHasEnv,
0073:                            other._javaEnvClassName, other._javaEnvPackageName,
0074:                            other._javaIsStatic, other._openArray,
0075:                            other._snippetType);
0076:                }
0077:
0078:                public Context(final String activeLanguage,
0079:                        final String cEnvStructName, final boolean cHasEnv,
0080:                        final String javaEnvClassName,
0081:                        final String javaEnvPackageName,
0082:                        final boolean javaIsStatic, final String openArray,
0083:                        final Type snippetType) {
0084:                    _activeLanguage = activeLanguage;
0085:                    _cEnvStructName = cEnvStructName;
0086:                    _cHasEnv = cHasEnv;
0087:                    _javaEnvClassName = javaEnvClassName;
0088:                    _javaEnvPackageName = javaEnvPackageName;
0089:                    _javaIsStatic = javaIsStatic;
0090:                    _openArray = openArray;
0091:                    _snippetType = snippetType;
0092:                }
0093:            }
0094:
0095:            public static final class Out {
0096:                public final List<Node> _cExternalDeclarations;
0097:                public final List<Node> _cMembers;
0098:                public final Node _cNode;
0099:                public final List<Node> _javaMembers;
0100:                public final Node _javaNode;
0101:
0102:                public Out(final List<Node> cExternalDeclarations,
0103:                        final List<Node> cMembers, final Node cNode,
0104:                        final List<Node> javaMembers, final Node javaNode) {
0105:                    _cExternalDeclarations = cExternalDeclarations;
0106:                    _cMembers = cMembers;
0107:                    _cNode = cNode;
0108:                    _javaMembers = javaMembers;
0109:                    _javaNode = javaNode;
0110:                }
0111:
0112:                public final Out addAll(final Out other) {
0113:                    if (null != other) {
0114:                        _cExternalDeclarations
0115:                                .addAll(other._cExternalDeclarations);
0116:                        _cMembers.addAll(other._cMembers);
0117:                        _javaMembers.addAll(other._javaMembers);
0118:                    }
0119:                    return this ;
0120:                }
0121:            }
0122:
0123:            static final class StringString {
0124:                final String _s1;
0125:                final String _s2;
0126:
0127:                StringString(final String s1, final String s2) {
0128:                    _s1 = s1;
0129:                    _s2 = s2;
0130:                }
0131:            }
0132:
0133:            static final class Substitutions implements  Iterable<StringString> {
0134:                private final Map<String, Map<String, String>> _map = new HashMap<String, Map<String, String>>();
0135:
0136:                final String get(final SymbolTable.Scope scope,
0137:                        final String srcId) {
0138:                    final Map<String, String> m = _map.get(scope
0139:                            .getQualifiedName());
0140:                    return null == m ? null : m.get(srcId);
0141:                }
0142:
0143:                public Iterator<StringString> iterator() {
0144:                    final List<StringString> l = new ArrayList<StringString>();
0145:                    for (final String scopeName : _map.keySet())
0146:                        for (final String srcId : _map.get(scopeName).keySet())
0147:                            l.add(new StringString(scopeName, srcId));
0148:                    return l.iterator();
0149:                }
0150:
0151:                final Substitutions put(final SymbolTable.Scope scope,
0152:                        final String srcId, final String tgtId) {
0153:                    final String scopeName = scope.getQualifiedName();
0154:                    if (!_map.containsKey(scopeName))
0155:                        _map.put(scopeName, new HashMap<String, String>());
0156:                    _map.get(scopeName).put(srcId, tgtId);
0157:                    return this ;
0158:                }
0159:            }
0160:
0161:            private static String getFileStem(final GNode n) {
0162:                final String fileName = n.getLocation().file;
0163:                final int lastSlash = Math.max(fileName.lastIndexOf('/'),
0164:                        fileName.lastIndexOf('\\'));
0165:                final int firstDot = fileName.indexOf('.', lastSlash);
0166:                final int end = -1 == firstDot ? fileName.length() : firstDot;
0167:                return fileName.substring(1 + lastSlash, end);
0168:            }
0169:
0170:            private static Type getType(final GNode n) {
0171:                return (Type) n.getProperty(Constants.TYPE);
0172:            }
0173:
0174:            private static GNode idNode(final Locatable loc, final String id) {
0175:                return setLoc(loc, GNode.create("PrimaryIdentifier", id));
0176:            }
0177:
0178:            /** Set location from loc to n, return n. */
0179:            public static GNode setLoc(final Locatable loc, final GNode n) {
0180:                n.setLocation(loc);
0181:                return n;
0182:            }
0183:
0184:            final Substitutions _cSubstitutions;
0185:
0186:            final Substitutions _javaSubstitutions;
0187:            final JeannieJavaFactory _astFactoryJava;
0188:            final JeannieCFactory _astFactoryC;
0189:            final Stack<Context> _contexts;
0190:            final Map<String, Integer> _freshIdCount;
0191:            final Runtime _runtime;
0192:            final SymbolTable _table;
0193:
0194:            Set<String> _usedIdentifiers;
0195:
0196:            public CodeGenerator(final Runtime runtime, final SymbolTable table) {
0197:                _astFactoryC = new JeannieCFactory();
0198:                _astFactoryJava = new JeannieJavaFactory();
0199:                _contexts = new Stack<Context>();
0200:                _cSubstitutions = new Substitutions();
0201:                _freshIdCount = new HashMap<String, Integer>();
0202:                _javaSubstitutions = new Substitutions();
0203:                _runtime = runtime;
0204:                _table = table;
0205:            }
0206:
0207:            private GNode abruptFlowCheck(final Locatable loc,
0208:                    final List<Node> cMembers, final List<Node> javaMembers) {
0209:                final GNode fieldName = cStringNode(liftIdJava(
0210:                        currentMethodScope(), loc, "returnAbrupt", JavaEntities
0211:                                .nameToBaseType("boolean"), javaMembers));
0212:                final GNode jump = abruptFlowJump(loc, cMembers);
0213:                final GNode result;
0214:                if (existsOpenArrayInSameSnippet()) {
0215:                    final String arr = context()._openArray;
0216:                    final String releaseAbrupt = liftIdC(declaringScope(arr),
0217:                            arr + "ReleaseAbrupt", typedefType("jint"),
0218:                            cMembers);
0219:                    result = (GNode) _astFactoryC.abruptFlowCheckOpenArray(
0220:                            releaseAbrupt, fieldName, jump);
0221:                } else {
0222:                    result = (GNode) _astFactoryC.abruptFlowCheck(fieldName,
0223:                            jump);
0224:                }
0225:                return setLoc(loc, result);
0226:            }
0227:
0228:            private GNode abruptFlowJump(final Locatable loc,
0229:                    final List<Node> cMembers) {
0230:                final GNode jumpStatement;
0231:                if (existsOpenArrayInSameSnippet()) {
0232:                    final String arr = context()._openArray;
0233:                    final String label = liftIdCLabel(declaringScope(arr),
0234:                            "release_" + arr);
0235:                    jumpStatement = (GNode) _astFactoryC
0236:                            .abruptFlowJumpOpenArray(label);
0237:                } else {
0238:                    final Type returnType = context()._snippetType;
0239:                    final GNode value = returnType.hasTag(Tag.VOID) ? null
0240:                            : GNode.create("CastExpression", Utilities
0241:                                    .cTypeToAst(returnType, null, "TypeName"),
0242:                                    GNode.create("IntegerConstant", "0"));
0243:                    jumpStatement = GNode.create("ReturnStatement", value);
0244:                }
0245:                return setLoc(loc, jumpStatement);
0246:            }
0247:
0248:            private GNode cEnvJavaTypeAst() {
0249:                final String name;
0250:                switch (Limits.POINTER_SIZE) {
0251:                case 4:
0252:                    name = "int";
0253:                    break;
0254:                case 8:
0255:                    name = "long";
0256:                    break;
0257:                default:
0258:                    throw new Error();
0259:                }
0260:                return JavaEntities.javaTypeToAst(_table, JavaEntities
0261:                        .nameToBaseType(name));
0262:            }
0263:
0264:            private Out cInJavaCode(final GNode n, final boolean isExpression) {
0265:                assert "Java".equals(context()._activeLanguage);
0266:                final GNode childNode = n.getGeneric(0);
0267:                final Type childType = isExpression ? getType(childNode)
0268:                        : VoidT.TYPE;
0269:                _contexts.push(new Context("C", context()._cEnvStructName,
0270:                        true, context()._javaEnvClassName,
0271:                        context()._javaEnvPackageName, context()._javaIsStatic,
0272:                        context()._openArray, childType));
0273:                final Out childOut = (Out) dispatch(childNode);
0274:                _contexts.pop();
0275:                final Type ownType = isExpression ? getType(n) : JavaEntities
0276:                        .nameToBaseType("void");
0277:                final String methodName = freshIdentifier("j2c");
0278:                final List<Node> javaMembers = cInJavaCode_javaMembers(
0279:                        methodName, ownType, childOut);
0280:                final Out ownOut = new Out(cInJavaCode_cExternalDeclarations(
0281:                        methodName, childType, childOut), childOut._cMembers,
0282:                        null, javaMembers, cInJavaCode_javaNode(n, methodName,
0283:                                javaMembers, isExpression));
0284:                return ownOut;
0285:            }
0286:
0287:            private List<Node> cInJavaCode_cExternalDeclarations(
0288:                    final String methodName, final Type childType,
0289:                    final Out childOut) {
0290:                final String functionName = mangledFunctionName(methodName);
0291:                final GNode function;
0292:                { //parse prototype with empty body first
0293:                    final String jniCall = _runtime.getString("jniCall");
0294:                    // on cygwin: "__attribute__((__stdcall__))"
0295:                    final String core = null == jniCall ? functionName
0296:                            : jniCall + " " + functionName;
0297:                    final Type pure = Utilities.pureCType(_table, _runtime,
0298:                            childType);
0299:                    String code = Utilities.cTypeToString(pure, core) + "(";
0300:                    code = Utilities.copyDropAuto(code);
0301:                    code += "  JNIEnv *env, jobject jEnv";
0302:                    // represent C pointer as Java long, i.e., using 64 bits
0303:                    if (context()._cHasEnv)
0304:                        switch (Limits.POINTER_SIZE) {
0305:                        case 4:
0306:                            code += ", const jint cEnv";
0307:                            break;
0308:                        case 8:
0309:                            code += ", const jlong cEnv";
0310:                            break;
0311:                        default:
0312:                            throw new Error();
0313:                        }
0314:                    code += ") { }";
0315:                    final Set<String> typedefs = Utilities.typedefs(childType);
0316:                    typedefs.addAll(Utilities.standardJniTypeDefs());
0317:                    function = Utilities.cStringToAst("FunctionDefinition",
0318:                            code, typedefs);
0319:                }
0320:                { //then plug in real body
0321:                    final String tag = context()._cEnvStructName;
0322:                    final Node action = childOut._cNode;
0323:                    final Node body;
0324:                    if (context()._cHasEnv)
0325:                        body = childType.isVoid() ? _astFactoryC
0326:                                .cInJavaStatementWithCEnv(tag, action)
0327:                                : _astFactoryC.cInJavaExpressionWithCEnv(tag,
0328:                                        action);
0329:                    else
0330:                        body = childType.isVoid() ? _astFactoryC
0331:                                .cInJavaStatementWithoutCEnv(tag, action)
0332:                                : _astFactoryC.cInJavaExpressionWithoutCEnv(
0333:                                        tag, action);
0334:                    function.set(function.size() - 1, setLoc(childOut._cNode,
0335:                            (GNode) body));
0336:                }
0337:                final List<Node> result = childOut._cExternalDeclarations;
0338:                result.add(function);
0339:                return result;
0340:            }
0341:
0342:            private List<Node> cInJavaCode_javaMembers(final String methodName,
0343:                    final Type ownType, final Out childOut) {
0344:                final GNode returnType = JavaEntities.javaTypeToAst(_table,
0345:                        ownType);
0346:                final Node n = context()._cHasEnv ? _astFactoryJava
0347:                        .cInJavaCodeWithCEnv(returnType, methodName,
0348:                                cEnvJavaTypeAst()) : _astFactoryJava
0349:                        .cInJavaCodeWithoutCEnv(returnType, methodName);
0350:                //TD 41 throws clause on j2c native method
0351:                final List<Node> result = childOut._javaMembers;
0352:                result.add(setLoc(childOut._cNode, (GNode) n));
0353:                return result;
0354:            }
0355:
0356:            private GNode cInJavaCode_javaNode(final Locatable loc,
0357:                    final String methodName, final List<Node> javaMembers,
0358:                    final boolean isExpression) {
0359:                final Node result;
0360:                if (isExpression) {
0361:                    result = context()._cHasEnv ? _astFactoryJava
0362:                            .cInJavaExpressionWithCEnv(methodName)
0363:                            : _astFactoryJava
0364:                                    .cInJavaExpressionWithoutCEnv(methodName);
0365:                } else {
0366:                    final String returnAbruptName = liftIdJava(
0367:                            currentMethodScope(), loc, "returnAbrupt",
0368:                            JavaEntities.nameToBaseType("boolean"), javaMembers);
0369:                    result = context()._cHasEnv ? _astFactoryJava
0370:                            .cInJavaStatementWithCEnv(methodName,
0371:                                    returnAbruptName) : _astFactoryJava
0372:                            .cInJavaStatementWithoutCEnv(methodName,
0373:                                    returnAbruptName);
0374:                }
0375:                return setLoc(loc, (GNode) result);
0376:            }
0377:
0378:            private final Context context() {
0379:                return _contexts.peek();
0380:            }
0381:
0382:            private GNode cStringNode(final String string) {
0383:                return GNode.create("StringConstant", "\"" + string + "\"");
0384:            }
0385:
0386:            private SymbolTable.Scope currentMethodScope() {
0387:                for (SymbolTable.Scope s = _table.current(); !s.isRoot(); s = s
0388:                        .getParent()) {
0389:                    final String scopeName = s.getName();
0390:                    if (SymbolTable.isInNameSpace(scopeName, "method")
0391:                            || SymbolTable.isFunctionScopeName(scopeName)
0392:                            || SymbolTable.isMacroScopeName(scopeName))
0393:                        return s;
0394:                }
0395:                return null;
0396:            }
0397:
0398:            private SymbolTable.Scope declaringScope(final String id) {
0399:                return _table.lookupScope(id);
0400:            }
0401:
0402:            private boolean existsOpenArrayInSameSnippet() {
0403:                final String o = context()._openArray;
0404:                if (null == o)
0405:                    return false;
0406:                final String a = context()._activeLanguage;
0407:                for (int i = _contexts.size() - 2; i >= 0; i--) {
0408:                    final Context c = _contexts.get(i);
0409:                    if (!a.equals(c._activeLanguage))
0410:                        return false;
0411:                    if (!o.equals(c._openArray))
0412:                        return true;
0413:                }
0414:                return true;
0415:            }
0416:
0417:            /**
0418:             * Returns a new globally unique identifier that starts with the base name.
0419:             * Takes care to avoid shadowing other identifiers that the program already
0420:             * uses, including free identifiers that are bound in imports or superclasses,
0421:             * and even "funny names" that programmers are unlikely to write but that may
0422:             * arise in other automatically generated code.
0423:             */
0424:            private String freshIdentifier(final String base) {
0425:                int i = _freshIdCount.containsKey(base) ? _freshIdCount.get(
0426:                        base).intValue() : -1;
0427:                String result;
0428:                do {
0429:                    i++;
0430:                    result = (0 == i) ? base : base + i;
0431:                } while (_usedIdentifiers.contains(result));
0432:                _freshIdCount.put(base, new Integer(i));
0433:                _usedIdentifiers.add(result);
0434:                return result;
0435:            }
0436:
0437:            private boolean isUtf8(final Type cPtrType, final Type javaType) {
0438:                if (JavaTypeConverter.isIdentical(javaType, JavaEntities
0439:                        .tString(_table))) {
0440:                    final Type cTgtType = ((PointerT) Utilities.c().pointerize(
0441:                            cPtrType)).getType();
0442:                    return Utilities.hasTypedefName(cTgtType, "jbyte");
0443:                }
0444:                return false;
0445:            }
0446:
0447:            private Out javaInCCode(final GNode n, final boolean isExpression) {
0448:                assert "C".equals(context()._activeLanguage);
0449:                _contexts.push(new Context(context(), "Java"));
0450:                final Out javaOut = (Out) dispatch(n);
0451:                _contexts.pop();
0452:                final Type javaType = isExpression ? JavaAnalyzer
0453:                        .getRValueNoError(getType(n)) : JavaEntities
0454:                        .nameToBaseType("void");
0455:                final String methodName = freshIdentifier("c2j");
0456:                final List<Node> cMembers = javaOut._cMembers;
0457:                final List<Node> javaMembers = javaOut._javaMembers;
0458:                final boolean isNonVoidExpression = isExpression
0459:                        && !getType(n).isVoid();
0460:                final Out ownOut = new Out(javaOut._cExternalDeclarations,
0461:                        cMembers, javaInCCode_cNode(methodName, javaType,
0462:                                isNonVoidExpression, n, cMembers, javaMembers),
0463:                        javaInCCode_javaMembers(methodName, javaType,
0464:                                isExpression, javaOut), null);
0465:                return ownOut;
0466:            }
0467:
0468:            private GNode javaInCCode_cNode(final String methodName,
0469:                    final Type javaType, final boolean isExpression,
0470:                    final GNode n, final List<Node> cMembers,
0471:                    final List<Node> javaMembers) {
0472:                final GNode name = cStringNode(methodName);
0473:                final boolean is32bit = 4 == Limits.POINTER_SIZE;
0474:                assert is32bit || 8 == Limits.POINTER_SIZE;
0475:                final GNode signature = cStringNode((is32bit ? "(I)" : "(J)")
0476:                        + JavaEntities.typeToDescriptor(_table, javaType));
0477:                final String apiFunction = "CallNonvirtual"
0478:                        + Utilities.javaTypeToApiType(javaType, true, false)
0479:                        + "Method";
0480:                final GNode abruptFlowCheck = abruptFlowCheck(n, cMembers,
0481:                        javaMembers);
0482:                final Node result;
0483:                if (isExpression) {
0484:                    final Type cType = Utilities.javaTypeToCType(_table,
0485:                            _runtime, n, javaType, false);
0486:                    final GNode tmpDeclaration = Utilities.cTypeToAst(cType,
0487:                            "tmp", "Declaration");
0488:                    result = is32bit ? _astFactoryC.javaInCExpression32(name,
0489:                            signature, tmpDeclaration, apiFunction,
0490:                            abruptFlowCheck) : _astFactoryC
0491:                            .javaInCExpression64(name, signature,
0492:                                    tmpDeclaration, apiFunction,
0493:                                    abruptFlowCheck);
0494:                } else {
0495:                    result = is32bit ? _astFactoryC.javaInCStatement32(name,
0496:                            signature, apiFunction, abruptFlowCheck)
0497:                            : _astFactoryC.javaInCStatement64(name, signature,
0498:                                    apiFunction, abruptFlowCheck);
0499:                }
0500:                return setLoc(n, (GNode) result);
0501:            }
0502:
0503:            private List<Node> javaInCCode_javaMembers(final String methodName,
0504:                    final Type javaType, final boolean isExpression,
0505:                    final Out javaOut) {
0506:                final GNode typeAst = JavaEntities.javaTypeToAst(_table,
0507:                        javaType);
0508:                final Node n = isExpression ? javaType.isVoid() ? _astFactoryJava
0509:                        .javaInCExpressionVoid(methodName, cEnvJavaTypeAst(),
0510:                                javaOut._javaNode)
0511:                        : _astFactoryJava.javaInCExpression(typeAst,
0512:                                methodName, cEnvJavaTypeAst(),
0513:                                javaOut._javaNode)
0514:                        : _astFactoryJava.javaInCStatement(methodName,
0515:                                cEnvJavaTypeAst(), javaOut._javaNode);
0516:                final List<Node> result = javaOut._javaMembers;
0517:                result.add(setLoc(javaOut._javaNode, (GNode) n));
0518:                return result;
0519:            }
0520:
0521:            private Out jeannieCancelOrCommit(final Locatable loc,
0522:                    final String arr, final boolean isCommit) {
0523:                final List<Node> cMembers = new ArrayList<Node>();
0524:                final GNode jump = abruptFlowJump(loc, cMembers);
0525:                final String field = liftIdC(declaringScope(arr), arr
0526:                        + "ReleaseAbrupt", typedefType("jint"), cMembers);
0527:                final Node n = isCommit ? _astFactoryC.commit(field, jump)
0528:                        : _astFactoryC.cancel(field, jump);
0529:                setLoc(loc, (GNode) n);
0530:                final Out ownOut = new Out(new ArrayList<Node>(0), cMembers,
0531:                        (GNode) n, new ArrayList<Node>(0), null);
0532:                return ownOut;
0533:            }
0534:
0535:            private String jeannieCopyApiFunction(final Type javaType,
0536:                    final boolean isAcquire, final boolean isUtf8) {
0537:                final StringBuffer result = new StringBuffer();
0538:                result.append(isAcquire ? "Get" : "Set");
0539:                if (JavaTypeConverter.isIdentical(javaType, JavaEntities
0540:                        .tString(_table)))
0541:                    result.append(isUtf8 ? "StringUTF" : "String");
0542:                else
0543:                    result.append(Utilities.javaTypeToApiType(javaType, true,
0544:                            true));
0545:                result.append("Region");
0546:                return result.toString();
0547:            }
0548:
0549:            private String liftIdC(final SymbolTable.Scope scope,
0550:                    final String srcId, final Type type,
0551:                    final List<Node> cMembers) {
0552:                if (null == _cSubstitutions.get(scope, srcId)) {
0553:                    final String tgtId = freshIdentifier("_" + srcId);
0554:                    final Type pureCType = Utilities.c().pointerize(
0555:                            Utilities.pureCType(_table, _runtime, type));
0556:                    final GNode fieldDecl = Utilities.cTypeToAst(pureCType,
0557:                            tgtId, "StructureDeclaration");
0558:                    cMembers.add(fieldDecl);
0559:                    _cSubstitutions.put(scope, srcId, tgtId);
0560:                }
0561:                return _cSubstitutions.get(scope, srcId);
0562:            }
0563:
0564:            private String liftIdCLabel(final SymbolTable.Scope scope,
0565:                    final String srcId) {
0566:                //TD 41 avoid clashes with locals
0567:                if (null == _cSubstitutions.get(scope, srcId)) {
0568:                    final String tgtId = freshIdentifier(srcId);
0569:                    _cSubstitutions.put(scope, srcId, tgtId);
0570:                }
0571:                return _cSubstitutions.get(scope, srcId);
0572:            }
0573:
0574:            private String liftIdJava(final SymbolTable.Scope scope,
0575:                    final Locatable loc, final String srcId, final Type type,
0576:                    final List<Node> javaMembers) {
0577:                if (null == _javaSubstitutions.get(scope, srcId)) {
0578:                    final String tgtId = freshIdentifier("_" + srcId);
0579:                    final Type r = JavaEntities.isGeneralLValueT(type) ? JavaEntities
0580:                            .dereference(type)
0581:                            : type;
0582:                    final Node n = _astFactoryJava.declareField(JavaEntities
0583:                            .javaTypeToAst(_table, r), tgtId);
0584:                    javaMembers.add(setLoc(loc, (GNode) n));
0585:                    _javaSubstitutions.put(scope, srcId, tgtId);
0586:                }
0587:                return _javaSubstitutions.get(scope, srcId);
0588:            }
0589:
0590:            private String mangledFunctionName(final String methodName) {
0591:                final String packageAndClass;
0592:                if (null == context()._javaEnvPackageName) {
0593:                    final ClassT baseClass = JavaEntities.currentType(_table)
0594:                            .toClass();
0595:                    final String baseName = JavaEntities.qNameWithDollars(
0596:                            _table, baseClass);
0597:                    packageAndClass = baseName + "$"
0598:                            + context()._javaEnvClassName;
0599:                } else {
0600:                    final String slashes = context()._javaEnvPackageName
0601:                            + context()._javaEnvClassName;
0602:                    packageAndClass = slashes.replace('/', '.');
0603:                }
0604:                final String qualifiedName = packageAndClass + '.' + methodName;
0605:                final String result = "Java_"
0606:                        + Utilities.jniMangledName(qualifiedName);
0607:                return result;
0608:            }
0609:
0610:            private Out processBuiltin(final GNode n) {
0611:                assert "C".equals(context()._activeLanguage);
0612:                final String name = n.getGeneric(0).getString(0);
0613:                final Out argsOut = (Out) dispatch(n.getGeneric(1));
0614:                assert null == argsOut._javaNode;
0615:                if ("_copyFromJava".equals(name)) {
0616:                    final GNode cArray = argsOut._cNode.getGeneric(0);
0617:                    final GNode cArrayStart = argsOut._cNode.getGeneric(1);
0618:                    final GNode javaArray = argsOut._cNode.getGeneric(2);
0619:                    final GNode javaArrayStart = argsOut._cNode.getGeneric(3);
0620:                    final GNode length = argsOut._cNode.getGeneric(4);
0621:                    final GNode abruptFlowCheck = abruptFlowCheck(n,
0622:                            argsOut._cMembers, argsOut._javaMembers);
0623:                    final Type javaType = Utilities.cTypeToJavaType(_table,
0624:                            _runtime, n.getGeneric(1).getGeneric(2), getType(n
0625:                                    .getGeneric(1).getGeneric(2)));
0626:                    final boolean primiv = JavaTypeConverter.isIdentical(
0627:                            javaType, JavaEntities.tString(_table))
0628:                            || javaType.isArray()
0629:                            && JavaEntities.isPrimitiveT(JavaEntities
0630:                                    .arrayElementType(javaType.toArray()));
0631:                    final Node ownNode;
0632:                    if (primiv) {
0633:                        final boolean utf8 = isUtf8(getType(n.getGeneric(1)
0634:                                .getGeneric(0)), javaType);
0635:                        final String apiFunction = jeannieCopyApiFunction(
0636:                                javaType, true, utf8);
0637:                        ownNode = utf8 ? _astFactoryC.copyBetweenJavaAndCUTF(
0638:                                javaArray, javaArrayStart, length, apiFunction,
0639:                                cArray, cArrayStart, abruptFlowCheck)
0640:                                : _astFactoryC.copyBetweenJavaAndC(apiFunction,
0641:                                        javaArray, javaArrayStart, length,
0642:                                        cArray, cArrayStart, abruptFlowCheck);
0643:                    } else {
0644:                        ownNode = _astFactoryC.copyFromJavaReference(javaArray,
0645:                                javaArrayStart, length, cArray, cArrayStart,
0646:                                abruptFlowCheck);
0647:                    }
0648:                    setLoc(n, (GNode) ownNode);
0649:                    final Out ownOut = new Out(new ArrayList<Node>(0),
0650:                            argsOut._cMembers, (GNode) ownNode,
0651:                            argsOut._javaMembers, null);
0652:                    return ownOut;
0653:                } else if ("_copyToJava".equals(name)) {
0654:                    final GNode javaArray = argsOut._cNode.getGeneric(0);
0655:                    final GNode javaArrayStart = argsOut._cNode.getGeneric(1);
0656:                    final GNode cArray = argsOut._cNode.getGeneric(2);
0657:                    final GNode cArrayStart = argsOut._cNode.getGeneric(3);
0658:                    final GNode length = argsOut._cNode.getGeneric(4);
0659:                    final GNode abruptFlowCheck = abruptFlowCheck(n,
0660:                            argsOut._cMembers, argsOut._javaMembers);
0661:                    final Type javaType = Utilities.cTypeToJavaType(_table,
0662:                            _runtime, n.getGeneric(1).getGeneric(0), getType(n
0663:                                    .getGeneric(1).getGeneric(0)));
0664:                    final boolean primiv = JavaTypeConverter.isIdentical(
0665:                            javaType, JavaEntities.tString(_table))
0666:                            || javaType.isArray()
0667:                            && JavaEntities.isPrimitiveT(JavaEntities
0668:                                    .arrayElementType(javaType.toArray()));
0669:                    final Node ownNode;
0670:                    if (primiv) {
0671:                        final boolean utf8 = isUtf8(getType(n.getGeneric(1)
0672:                                .getGeneric(2)), javaType);
0673:                        final String apiFunction = jeannieCopyApiFunction(
0674:                                javaType, false, utf8);
0675:                        ownNode = utf8 ? _astFactoryC.copyBetweenJavaAndCUTF(
0676:                                javaArray, javaArrayStart, length, apiFunction,
0677:                                cArray, cArrayStart, abruptFlowCheck)
0678:                                : _astFactoryC.copyBetweenJavaAndC(apiFunction,
0679:                                        javaArray, javaArrayStart, length,
0680:                                        cArray, cArrayStart, abruptFlowCheck);
0681:                    } else {
0682:                        ownNode = _astFactoryC.copyToJavaReference(javaArray,
0683:                                javaArrayStart, length, cArray, cArrayStart,
0684:                                abruptFlowCheck);
0685:                    }
0686:                    setLoc(n, (GNode) ownNode);
0687:                    final Out ownOut = new Out(new ArrayList<Node>(0),
0688:                            argsOut._cMembers, (GNode) ownNode,
0689:                            argsOut._javaMembers, null);
0690:                    return ownOut;
0691:                } else if ("_newJavaString".equals(name)) {
0692:                    final Type t = getType(n.getGeneric(1).getGeneric(0));
0693:                    final String apiFunction = "NewString"
0694:                            + (Utilities.isPtrTypedef(t, "jchar") ? "" : "UTF");
0695:                    final GNode cString = argsOut._cNode.getGeneric(0);
0696:                    final GNode abruptFlowCheck = abruptFlowCheck(n,
0697:                            argsOut._cMembers, argsOut._javaMembers);
0698:                    final GNode cNode = (GNode) _astFactoryC.newJavaString(
0699:                            apiFunction, cString, abruptFlowCheck);
0700:                    setLoc(n, (GNode) cNode);
0701:                    final Out ownOut = new Out(argsOut._cExternalDeclarations,
0702:                            argsOut._cMembers, cNode, argsOut._javaMembers,
0703:                            null);
0704:                    return ownOut;
0705:                } else if ("_stringUTFLength".equals(name)) {
0706:                    final Node ac = argsOut._cNode;
0707:                    final Node javaString = ac.getNode(0);
0708:                    final Node cNode;
0709:                    if (1 == n.getGeneric(1).size())
0710:                        cNode = _astFactoryC.stringUTFLength1(javaString);
0711:                    else
0712:                        cNode = _astFactoryC.stringUTFLength3(javaString, ac
0713:                                .getNode(1), ac.getNode(2));
0714:                    final Out ownOut = new Out(argsOut._cExternalDeclarations,
0715:                            argsOut._cMembers, setLoc(n, (GNode) cNode),
0716:                            argsOut._javaMembers, null);
0717:                    return ownOut;
0718:                } else {
0719:                    throw new Error("builtin " + name
0720:                            + " not (yet) implemented");
0721:                }
0722:            }
0723:
0724:            private List<Node> processDeclarators(final GNode declarators,
0725:                    final List<Node> cExternalDeclarations,
0726:                    final List<Node> cMembers, final List<Node> javaMembers) {
0727:                assert "Java".equals(context()._activeLanguage)
0728:                        && declarators.hasName("Declarators");
0729:                final List<Node> result = new ArrayList<Node>();
0730:                for (final Object declObj : declarators) {
0731:                    final GNode declNode = (GNode) declObj;
0732:                    final GNode initNode = declNode.getGeneric(2);
0733:                    if (null == initNode)
0734:                        continue;
0735:                    final Out initOut = (Out) dispatch(initNode);
0736:                    assert null == initOut._cNode;
0737:                    cExternalDeclarations
0738:                            .addAll(initOut._cExternalDeclarations);
0739:                    cMembers.addAll(initOut._cMembers);
0740:                    javaMembers.addAll(initOut._javaMembers);
0741:                    final VariableT type = getType(declNode).toVariable();
0742:                    final String srcId = type.getName();
0743:                    final String subst = liftIdJava(declaringScope(srcId),
0744:                            declNode, srcId, type, javaMembers);
0745:                    final Node javaNode;
0746:                    if (initOut._javaNode.hasName("ArrayInitializer")) {
0747:                        final GNode typeAst = JavaEntities.javaTypeToAst(
0748:                                _table, type.getType());
0749:                        javaNode = setLoc(initOut._javaNode, GNode.create(
0750:                                "NewArrayExpression", typeAst.getGeneric(0),
0751:                                null, typeAst.getGeneric(1), initOut._javaNode));
0752:                    } else {
0753:                        javaNode = initOut._javaNode;
0754:                    }
0755:                    result.add(setLoc(javaNode, (GNode) _astFactoryJava
0756:                            .setThisDotField(subst, javaNode)));
0757:                }
0758:                return result;
0759:            }
0760:
0761:            private Type typedefType(final String symbol) {
0762:                final Type result = (Type) _table.root().lookup(symbol);
0763:                assert null != result;
0764:                return result;
0765:            }
0766:
0767:            public final Out visit(final LineMarker m) {
0768:                final boolean c = "C".equals(context()._activeLanguage);
0769:                final Node n = m.getNode();
0770:                if (null == n)
0771:                    return new Out(new ArrayList<Node>(0), new ArrayList<Node>(
0772:                            0), c ? m : null, new ArrayList<Node>(0), c ? null
0773:                            : m);
0774:                final Out childOut = (Out) dispatch(n);
0775:                if (c) {
0776:                    assert null != childOut._cNode
0777:                            && null == childOut._javaNode;
0778:                    m.setNode(childOut._cNode);
0779:                } else {
0780:                    assert null == childOut._cNode
0781:                            && null != childOut._javaNode;
0782:                    m.setNode(childOut._javaNode);
0783:                }
0784:                final Out result = new Out(childOut._cExternalDeclarations,
0785:                        childOut._cMembers, c ? m : null,
0786:                        childOut._javaMembers, c ? null : m);
0787:                return result;
0788:            }
0789:
0790:            /** Catch-all visit method. */
0791:            public final Out visit(final Node n) {
0792:                _table.enter(n);
0793:                //TD 42 don't create a new node, just rewrite the old node's children
0794:                final GNode ownNode = setLoc(n, GNode.create(n.getName(), n
0795:                        .size()));
0796:                final boolean c = "C".equals(context()._activeLanguage);
0797:                final Out ownOut = new Out(new ArrayList<Node>(),
0798:                        new ArrayList<Node>(), c ? ownNode : null,
0799:                        new ArrayList<Node>(), c ? null : ownNode);
0800:                for (int i = 0; i < n.size(); i++)
0801:                    if (n.get(i) instanceof  Node) {
0802:                        final Out childOut = (Out) dispatch(n.getNode(i));
0803:                        ownNode
0804:                                .add(i, c ? childOut._cNode
0805:                                        : childOut._javaNode);
0806:                        ownOut.addAll(childOut);
0807:                        assert null == (c ? childOut._javaNode
0808:                                : childOut._cNode);
0809:                    } else {
0810:                        ownNode.add(i, n.get(i));
0811:                    }
0812:                _table.exit(n);
0813:                return ownOut;
0814:            }
0815:
0816:            /**
0817:             * Visit a BasicForControl = Modifiers Type Declarators [Expression] [ExpressionList]
0818:             *   / null null [ExpressionList] [Expression] [ExpressionList] (gosling_et_al_2000
0819:             * <a href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#40898">&sect;8.3</a>).
0820:             */
0821:            public final Out visitBasicForControl(final GNode n) {
0822:                assert "Java".equals(context()._activeLanguage);
0823:                if (null == context()._javaEnvClassName || null == n.get(0))
0824:                    return visit(n);
0825:                final List<Node> cExternalDeclarations = new ArrayList<Node>();
0826:                final List<Node> cMembers = new ArrayList<Node>();
0827:                final List<Node> javaMembers = new ArrayList<Node>();
0828:                final List<Node> decls = processDeclarators(n.getGeneric(2),
0829:                        cExternalDeclarations, cMembers, javaMembers);
0830:                final GNode initNode = 0 == decls.size() ? null : setLoc(n
0831:                        .getGeneric(2), (GNode) GNode.create("ExpressionList",
0832:                        decls.size()).addAll(decls));
0833:                final Out testOut = (Out) dispatch(n.getGeneric(3));
0834:                final Out incrOut = (Out) dispatch(n.getGeneric(4));
0835:                final GNode javaNode = setLoc(n, GNode.create(
0836:                        "BasicForControl", null, null, initNode,
0837:                        testOut._javaNode, incrOut._javaNode));
0838:                final Out ownOut = new Out(cExternalDeclarations, cMembers,
0839:                        null, javaMembers, javaNode);
0840:                ownOut.addAll(testOut).addAll(incrOut);
0841:                return ownOut;
0842:            }
0843:
0844:            /** Visit a CancelStatement = JeannieC.PrimaryIdentifier. */
0845:            public final Out visitCancelStatement(final GNode n) {
0846:                return jeannieCancelOrCommit(n, n.getGeneric(0).getString(0),
0847:                        false);
0848:            }
0849:
0850:            /** Visit a CDeclarations = ExternalDeclaration* Annotations. */
0851:            public final Out visitCDeclarations(final GNode n) {
0852:                final Out ownOut = new Out(new ArrayList<Node>(),
0853:                        new ArrayList<Node>(), null, new ArrayList<Node>(),
0854:                        null);
0855:                assert _table.current().isRoot();
0856:                assert 1 == _contexts.size()
0857:                        && "C".equals(context()._activeLanguage);
0858:                for (int i = 0; i < n.size() - 1; i++) {
0859:                    final Out childOut = (Out) dispatch(n.getNode(i));
0860:                    assert null == childOut._javaNode;
0861:                    ownOut._javaMembers.addAll(childOut._javaMembers);
0862:                    ownOut._cExternalDeclarations
0863:                            .addAll(childOut._cExternalDeclarations);
0864:                    ownOut._cExternalDeclarations.add(childOut._cNode);
0865:                }
0866:                assert _table.current().isRoot();
0867:                return ownOut;
0868:            }
0869:
0870:            /** Visit a CInCBlock = LocalLabelDeclaration* JeannieC.DeclarationOrStatement* Annotations. */
0871:            public final Out visitCInCBlock(final GNode n) {
0872:                assert "C".equals(context()._activeLanguage);
0873:                final Out genericOut = visit(n);
0874:                assert genericOut._cNode.hasName("CInCBlock");
0875:                final List<Node> cNodes = new ArrayList<Node>(n.size() - 1);
0876:                for (int i = 0; i < n.size() - 1; i++) {
0877:                    final GNode src = n.getGeneric(i), tgt = genericOut._cNode
0878:                            .getGeneric(i);
0879:                    if (src.hasName("Declaration")) {
0880:                        if (tgt.hasName("CompoundStatement")) //flatten, to expand scope of auxiliary declarations
0881:                            for (final Object t : tgt)
0882:                                cNodes.add((GNode) t);
0883:                        else if (!tgt.hasName("EmptyStatement")) //skip, to keep code more readable
0884:                            cNodes.add(tgt);
0885:                    } else {
0886:                        cNodes.add(tgt);
0887:                    }
0888:                }
0889:                final Out ownOut = new Out(genericOut._cExternalDeclarations,
0890:                        genericOut._cMembers, setLoc(n, GNode.create(
0891:                                "CompoundStatement", cNodes.size() + 1)),
0892:                        genericOut._javaMembers, genericOut._javaNode);
0893:                for (int i = 0; i < cNodes.size(); i++)
0894:                    ownOut._cNode.add(i, cNodes.get(i));
0895:                return ownOut;
0896:            }
0897:
0898:            /** Visit a CInJavaBlock = CInCBlock. */
0899:            public final Out visitCInJavaBlock(final GNode n) {
0900:                return cInJavaCode(n, false);
0901:            }
0902:
0903:            /** Visit a CInJavaExpression = JeannieC.UnaryExpression. */
0904:            public final Out visitCInJavaExpression(final GNode n) {
0905:                return cInJavaCode(n, true);
0906:            }
0907:
0908:            /**
0909:             * Visit a ClassBody = Declaration* (gosling_et_al_2000
0910:             * <a href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#18988">&sect;8.1.5</a>,
0911:             * <a href="http://java.sun.com/docs/books/jls/second_edition/html/interfaces.doc.html#236431">&sect;9.1.3</a>,
0912:             * <a href="http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#41147">&sect;15.9</a>).
0913:             */
0914:            public final Out visitClassBody(final GNode n) {
0915:                assert "Java".equals(context()._activeLanguage);
0916:                _table.enter(n);
0917:                final Out ownOut = new Out(new ArrayList<Node>(),
0918:                        new ArrayList<Node>(), null, new ArrayList<Node>(),
0919:                        setLoc(n, GNode.create("ClassBody")));
0920:                if (Utilities.containsJavaToCTransition(n)) {
0921:                    if (JavaEntities.isTypeTopLevel(JavaEntities
0922:                            .currentType(_table))) {
0923:                        final GNode name = GNode.create("StringLiteral", "\""
0924:                                + getFileStem(n) + "\"");
0925:                        final Node block = _astFactoryJava.loadLibrary(name);
0926:                        ownOut._javaNode.add(setLoc(n, GNode.create(
0927:                                "BlockDeclaration", "static", block)));
0928:                    }
0929:                }
0930:                for (final Object child : n) {
0931:                    final Out childOut = (Out) dispatch((GNode) child);
0932:                    ownOut._cExternalDeclarations
0933:                            .addAll(childOut._cExternalDeclarations);
0934:                    assert childOut._cMembers.isEmpty()
0935:                            && null == childOut._cNode;
0936:                    ownOut._javaNode.add(childOut._javaNode);
0937:                    ownOut._javaNode.addAll(childOut._javaMembers);
0938:                }
0939:                _table.exit(n);
0940:                return ownOut;
0941:            }
0942:
0943:            /** Visit a CommitStatement = JeannieC.PrimaryIdentifier. */
0944:            public final Out visitCommitStatement(final GNode n) {
0945:                return jeannieCancelOrCommit(n, n.getGeneric(0).getString(0),
0946:                        true);
0947:            }
0948:
0949:            /**
0950:             * Visit a CompilationUnit = CDeclarations [PackageDeclaration]
0951:             * ImportDeclaration* JeannieJava.Declaration*
0952:             * (gosling_et_al_2000 
0953:             * <a href="http://java.sun.com/docs/books/jls/second_edition/html/packages.doc.html#40031">&sect;7.3</a>).
0954:             */
0955:            public final Out visitCompilationUnit(final GNode n) {
0956:                assert _contexts.isEmpty();
0957:                _usedIdentifiers = JavaEntities.allUsedIdentifiers(n);
0958:                final GNode cNode = setLoc(n, GNode.create("TranslationUnit"));
0959:                final Out cChildOut;
0960:                {
0961:                    final StringBuffer packageName = new StringBuffer();
0962:                    if (null != n.get(1))
0963:                        for (final Object o : n.getNode(1).getNode(1))
0964:                            packageName.append(o).append('/');
0965:                    _contexts.push(new Context("C", null, false, null,
0966:                            packageName.toString(), true, null, null));
0967:                    cChildOut = (Out) dispatch(n.getGeneric(0));
0968:                    _contexts.pop();
0969:                }
0970:                assert cChildOut._cMembers.isEmpty()
0971:                        && null == cChildOut._cNode
0972:                        && null == cChildOut._javaNode;
0973:                cNode.addAll(cChildOut._cExternalDeclarations);
0974:                final GNode javaNode = setLoc(n, GNode
0975:                        .create("CompilationUnit"));
0976:                javaNode.add(n.getGeneric(1));
0977:                _contexts.push(new Context("Java", null, false, null, null,
0978:                        true, null, null));
0979:                JavaEntities.enterScopeByQualifiedName(_table, (String) n
0980:                        .getProperty(Constants.SCOPE));
0981:                for (int i = 2; i < n.size(); i++) {
0982:                    final Out javaChildOut = (Out) dispatch(n.getGeneric(i));
0983:                    cNode.addAll(javaChildOut._cExternalDeclarations);
0984:                    javaNode.add(javaChildOut._javaNode);
0985:                    assert javaChildOut._cMembers.isEmpty()
0986:                            && null == javaChildOut._cNode
0987:                            && javaChildOut._javaMembers.isEmpty();
0988:                }
0989:                javaNode.addAll(cChildOut._javaMembers);
0990:                _contexts.pop();
0991:                final Out ownOut = new Out(null, null, cNode, null, javaNode);
0992:                return ownOut;
0993:            }
0994:
0995:            /** Visit a JeannieC.Declaration = ["__extension__"] DeclarationSpecifiers [InitializedDeclaratorList]. */
0996:            public final Out visitDeclaration(final GNode n) {
0997:                assert "C".equals(context()._activeLanguage);
0998:                if (null == context()._cEnvStructName || null == n.get(2))
0999:                    return visit(n);
1000:                final List<Node> cExternalDeclarations = new ArrayList<Node>();
1001:                final List<Node> cMembers = new ArrayList<Node>();
1002:                final List<Node> javaMembers = new ArrayList<Node>();
1003:                final List<Node> declResults = new ArrayList<Node>();
1004:                for (final Object declObj : n.getGeneric(2)) {
1005:                    final GNode declNode = (GNode) declObj;
1006:                    final String srcId = Utilities
1007:                            .getSimpleDeclarator(declNode);
1008:                    final Type type = Utilities.pureCType(_table, _runtime,
1009:                            (Type) _table.lookup(srcId));
1010:                    final String tgtId = liftIdC(declaringScope(srcId), srcId,
1011:                            type, cMembers);
1012:                    if (declNode.getGeneric(1).hasName("ArrayDeclarator")) {
1013:                        final Out specsOut = (Out) dispatch(n.getGeneric(1));
1014:                        assert null == specsOut._javaNode;
1015:                        cExternalDeclarations
1016:                                .addAll(specsOut._cExternalDeclarations);
1017:                        cMembers.addAll(specsOut._cMembers);
1018:                        javaMembers.addAll(specsOut._javaMembers);
1019:                        final Out declOut = (Out) dispatch(declNode);
1020:                        assert null == declOut._javaNode;
1021:                        cExternalDeclarations
1022:                                .addAll(declOut._cExternalDeclarations);
1023:                        cMembers.addAll(declOut._cMembers);
1024:                        javaMembers.addAll(declOut._javaMembers);
1025:                        final GNode declLocal = setLoc(declNode, GNode.create(
1026:                                "Declaration", n.getString(0), specsOut._cNode,
1027:                                GNode.create("InitializedDeclaratorList",
1028:                                        declOut._cNode)));
1029:                        declResults.add(declLocal);
1030:                        final GNode setField = (GNode) _astFactoryC
1031:                                .setPCEnvField(tgtId, GNode.create(
1032:                                        "PrimaryIdentifier", srcId));
1033:                        declResults.add(setLoc(declNode, setField));
1034:                    } else if (null != declNode.getGeneric(4)) {
1035:                        final Out initOut = (Out) dispatch(declNode
1036:                                .getGeneric(4));
1037:                        assert null == initOut._javaNode;
1038:                        cExternalDeclarations
1039:                                .addAll(initOut._cExternalDeclarations);
1040:                        cMembers.addAll(initOut._cMembers);
1041:                        javaMembers.addAll(initOut._javaMembers);
1042:                        final GNode typeAST = Utilities.cTypeToAst(type, null,
1043:                                "TypeName");
1044:                        final GNode cast = GNode.create("CastExpression",
1045:                                typeAST, initOut._cNode);
1046:                        declResults.add(setLoc(declNode, (GNode) _astFactoryC
1047:                                .setPCEnvField(tgtId, cast)));
1048:                    }
1049:                }
1050:                final Node cNode = (0 == declResults.size()) ? GNode
1051:                        .create("EmptyStatement")
1052:                        : (1 == declResults.size()) ? declResults.get(0)
1053:                                : /* else */_astFactoryC.block(declResults);
1054:                final Out ownOut = new Out(cExternalDeclarations, cMembers,
1055:                        setLoc(n.getGeneric(2), (GNode) cNode), javaMembers,
1056:                        null);
1057:                return ownOut;
1058:            }
1059:
1060:            /**
1061:             * Visit a FieldDeclaration = Modifiers Type Declarators (gosling_et_al_2000
1062:             * <a href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#40898">&sect;8.3</a>).
1063:             */
1064:            public final Out visitFieldDeclaration(final GNode n) {
1065:                assert "Java".equals(context()._activeLanguage);
1066:                if (null == context()._javaEnvClassName)
1067:                    return visit(n);
1068:                final List<Node> cExternalDeclarations = new ArrayList<Node>();
1069:                final List<Node> cMembers = new ArrayList<Node>();
1070:                final List<Node> javaMembers = new ArrayList<Node>();
1071:                final List<Node> decls = processDeclarators(n.getGeneric(2),
1072:                        cExternalDeclarations, cMembers, javaMembers);
1073:                final GNode javaNode;
1074:                if (0 == decls.size()) {
1075:                    javaNode = GNode.create("EmptyStatement");
1076:                } else if (1 == decls.size()) {
1077:                    javaNode = GNode
1078:                            .create("ExpressionStatement", decls.get(0));
1079:                } else {
1080:                    javaNode = GNode.create("Block", decls.size());
1081:                    for (final Node d : decls)
1082:                        javaNode.add(GNode.create("ExpressionStatement", d));
1083:                }
1084:                final Out ownOut = new Out(cExternalDeclarations, cMembers,
1085:                        null, javaMembers, setLoc(n.getGeneric(2), javaNode));
1086:                return ownOut;
1087:            }
1088:
1089:            /**
1090:             * Visit a ForStatement = (Declaration / [Expression]) [Expression] [Expression] Statement.
1091:             */
1092:            public final Out visitForStatement(final GNode n) {
1093:                if ("Java".equals(context()._activeLanguage)
1094:                        || null == context()._cEnvStructName
1095:                        || null == n.get(0)
1096:                        || !n.getGeneric(0).hasName("Declaration"))
1097:                    return visit(n);
1098:                _table.enter(n);
1099:                final Out initOut = (Out) dispatch(n.getGeneric(0));
1100:                final Out testOut = (Out) dispatch(n.getGeneric(1));
1101:                final Out incrOut = (Out) dispatch(n.getGeneric(2));
1102:                final Out bodyOut = (Out) dispatch(n.getGeneric(3));
1103:                final GNode loopNode = GNode
1104:                        .create("ForStatement", null, null == testOut ? null
1105:                                : testOut._cNode, null == incrOut ? null
1106:                                : incrOut._cNode, bodyOut._cNode);
1107:                final GNode cNode = GNode.create("CompoundStatement",
1108:                        initOut._cNode, loopNode, null);
1109:                final Out ownOut = new Out(new ArrayList<Node>(),
1110:                        new ArrayList<Node>(), setLoc(n, cNode),
1111:                        new ArrayList<Node>(), null);
1112:                ownOut.addAll(initOut).addAll(testOut).addAll(incrOut).addAll(
1113:                        bodyOut);
1114:                _table.exit(n);
1115:                return ownOut;
1116:            }
1117:
1118:            /** Visit a FunctionCall = (PrimaryIdentifier / JeannieC.PostfixExpression) JeannieC.ExpressionList. */
1119:            public final Out visitFunctionCall(final GNode n) {
1120:                assert "C".equals(context()._activeLanguage);
1121:                if (null == context()._javaEnvClassName)
1122:                    return visit(n);
1123:                if (n.getGeneric(0).hasName("PrimaryIdentifier")
1124:                        && Analyzer.BUILTINS.contains(n.getGeneric(0)
1125:                                .getString(0)))
1126:                    return processBuiltin(n);
1127:                final Out plainOut = visit(n);
1128:                final Type cType = getType(n);
1129:                final GNode cNode;
1130:                final Node call = plainOut._cNode;
1131:                final GNode abruptFlowCheck = abruptFlowCheck(n,
1132:                        plainOut._cMembers, plainOut._javaMembers);
1133:                final Type cTypeMinusAnnotations = cType.isAnnotated() ? cType
1134:                        .toAnnotated().getType() : cType;
1135:                if (cTypeMinusAnnotations.isVoid()) {
1136:                    cNode = (GNode) _astFactoryC.checkedFunctionCallVoid(call,
1137:                            abruptFlowCheck);
1138:                } else {
1139:                    final GNode tmpDeclaration = Utilities.cTypeToAst(cType,
1140:                            "tmp", "Declaration");
1141:                    cNode = (GNode) _astFactoryC.checkedFunctionCallResult(
1142:                            tmpDeclaration, call, abruptFlowCheck);
1143:                }
1144:                setLoc(n, cNode);
1145:                final Out ownOut = new Out(plainOut._cExternalDeclarations,
1146:                        plainOut._cMembers, cNode, plainOut._javaMembers,
1147:                        plainOut._javaNode);
1148:                return ownOut;
1149:            }
1150:
1151:            /** Visit a FunctionDeclarator = (ParameterTypeList / IdentifierList) JavaThrows. */
1152:            public final Out visitFunctionDeclarator(final GNode n) {
1153:                assert "C".equals(context()._activeLanguage);
1154:                /* TD 41 jeannie.CodeGenerator.visitFunctionDeclarator: drop the throws clause */
1155:                return visit(n);
1156:            }
1157:
1158:            /** Visit a FunctionDefinition = ["__extension__"] [DeclarationSpecifiers] Declarator 
1159:             * [DeclarationList] CompoundStatement. */
1160:            public final Out visitFunctionDefinition(final GNode n) {
1161:                assert "C".equals(context()._activeLanguage);
1162:                if (!Utilities.containsCToJavaTransition(n))
1163:                    return visit(n);
1164:                _table.enter(n);
1165:                final String functionName = SymbolTable.fromNameSpace(_table
1166:                        .current().getName());
1167:                final String javaEnvClassName = freshIdentifier("JavaEnvFor_"
1168:                        + functionName);
1169:                final String cEnvStructName = freshIdentifier("CEnvFor_"
1170:                        + functionName);
1171:                final FunctionT function = ((Type) _table.current().getParent()
1172:                        .lookupLocally(functionName)).resolve().toFunction();
1173:                _contexts.push(new Context("C", cEnvStructName, true,
1174:                        javaEnvClassName, context()._javaEnvPackageName, true,
1175:                        null, function.getResult()));
1176:                final Out childOut = (Out) dispatch(n.getNode(4));
1177:                final List<Node> cExternalDeclarations = visitMethodDeclaration_cExternalDeclarations(childOut);
1178:                final GNode cNode;
1179:                {
1180:                    final Node body;
1181:                    final GNode javaEnvNode = GNode.create("StringConstant",
1182:                            '"' + context()._javaEnvPackageName
1183:                                    + javaEnvClassName + '"');
1184:                    final GNode copyFormals = setLoc(n.getGeneric(2), GNode
1185:                            .create("CompoundStatement", function
1186:                                    .getParameters().size() - 1));
1187:                    for (final Type formal : function.getParameters()) {
1188:                        final String srcId = formal.toVariable().getName();
1189:                        if (!"env".equals(srcId)) {
1190:                            final String fieldName = liftIdC(
1191:                                    declaringScope(srcId), srcId, formal
1192:                                            .toVariable().getType(),
1193:                                    childOut._cMembers);
1194:                            final Node copy = _astFactoryC.setPCEnvField(
1195:                                    fieldName, GNode.create(
1196:                                            "PrimaryIdentifier", srcId));
1197:                            copyFormals.add(copy);
1198:                        }
1199:                    }
1200:                    assert function.getResult().hasTag(Tag.VOID); //TD 06 C function definition that also contains Java code somewhere and returns non-void
1201:                    body = _astFactoryC.closureStatement(cEnvStructName,
1202:                            copyFormals, javaEnvNode, childOut._cNode);
1203:                    cNode = n;
1204:                    cNode.set(4, setLoc(childOut._cNode, (GNode) body));
1205:                }
1206:                final List<Node> javaTopLevelDeclarations;
1207:                {
1208:                    final GNode classBody = GNode.create("ClassBody",
1209:                            childOut._javaMembers.size());
1210:                    classBody.addAll(childOut._javaMembers);
1211:                    final GNode modifiers = GNode.create("Modifiers", GNode
1212:                            .create("Modifier", "final"));
1213:                    final GNode classDecl = setLoc(n, GNode.create(
1214:                            "ClassDeclaration", modifiers,
1215:                            context()._javaEnvClassName, null, null, null,
1216:                            classBody));
1217:                    javaTopLevelDeclarations = new ArrayList<Node>(1);
1218:                    javaTopLevelDeclarations.add(classDecl);
1219:                }
1220:                final Out ownOut = new Out(cExternalDeclarations,
1221:                        new ArrayList<Node>(), cNode, javaTopLevelDeclarations,
1222:                        null);
1223:                _contexts.pop();
1224:                _table.exit(n);
1225:                return ownOut;
1226:            }
1227:
1228:            /** Visit a JavaImports = ImportDeclaration*. */
1229:            public final Out visitJavaImports(final GNode n) {
1230:                assert "C".equals(context()._activeLanguage);
1231:                /* TD 41 jeannie.CodeGenerator.visitJavaImports: drop (or don't dispatch in first place) */
1232:                return visit(n);
1233:            }
1234:
1235:            /** Visit a JavaInCBlock = JavaInJavaBlock. */
1236:            public final Out visitJavaInCBlock(final GNode n) {
1237:                return javaInCCode(n.getGeneric(0), false);
1238:            }
1239:
1240:            /** Visit a JavaInCExpression = JeannieJava.UnaryExpression. */
1241:            public final Out visitJavaInCExpression(final GNode n) {
1242:                return javaInCCode(n.getGeneric(0), true);
1243:            }
1244:
1245:            /** Visit a JavaInCStatement = TryStatement / SynchronizedStatement / ThrowStatement. */
1246:            public final Out visitJavaInCStatement(final GNode n) {
1247:                return javaInCCode(n.getGeneric(0), false);
1248:            }
1249:
1250:            /** Visit a JavaInJavaBlock = JeannieJava.DeclarationOrStatement*. */
1251:            public final Out visitJavaInJavaBlock(final GNode n) {
1252:                assert "Java".equals(context()._activeLanguage);
1253:                final Out genericOut = visit(n);
1254:                assert genericOut._javaNode.hasName("JavaInJavaBlock");
1255:                final Out ownOut = new Out(genericOut._cExternalDeclarations,
1256:                        genericOut._cMembers, genericOut._cNode,
1257:                        genericOut._javaMembers, setLoc(n, GNode.create(
1258:                                "Block", n.size())));
1259:                for (int i = 0; i < n.size(); i++)
1260:                    ownOut._javaNode.add(i, genericOut._javaNode.get(i));
1261:                return ownOut;
1262:            }
1263:
1264:            /** Visit a JavaThrows = [ThrowsClause]. */
1265:            public final Out visitJavaThrows(final GNode n) {
1266:                assert "C".equals(context()._activeLanguage);
1267:                /* TD 41 jeannie.CodeGenerator.visitJavaThrows: drop (or don't dispatch in first place) */
1268:                return visit(n);
1269:            }
1270:
1271:            /** Visit a JavaType = Java.TypeName. */
1272:            public final Out visitJavaType(final GNode n) {
1273:                assert "C".equals(context()._activeLanguage);
1274:                final Type cType = Utilities.pureCType(_table, _runtime,
1275:                        getType(n));
1276:                final GNode ownNode = Utilities.cTypeToAst(cType, null,
1277:                        "TypeName");
1278:                final Out ownOut = new Out(new ArrayList<Node>(),
1279:                        new ArrayList<Node>(), ownNode, new ArrayList<Node>(),
1280:                        null);
1281:                return ownOut;
1282:            }
1283:
1284:            /**
1285:             * Visit a MethodDeclaration = Modifiers null Type Identifier FormalParameters [Dimensions]
1286:             * [ThrowsClause] [Block] (gosling_et_al_2000 <a
1287:             * href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#40420">&sect;8.4</a>,
1288:             * <a href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#41652">8.8</a>,
1289:             * <a href="http://java.sun.com/docs/books/jls/second_edition/html/interfaces.doc.html#78651">9.4</a>).
1290:             */
1291:            public final Out visitMethodDeclaration(final GNode n) {
1292:                assert "Java".equals(context()._activeLanguage);
1293:                if (!Utilities.containsJavaToCTransition(n))
1294:                    return visit(n);
1295:                _table.enter(n);
1296:                final MethodT method = JavaEntities.currentMethod(_table);
1297:                final String javaEnvClassName = freshIdentifier("JavaEnvFor_"
1298:                        + method.getName());
1299:                final String cEnvStructName = freshIdentifier("CEnvFor_"
1300:                        + Utilities.jniMangledName(_table, method));
1301:                _contexts.push(new Context("Java", cEnvStructName, false,
1302:                        javaEnvClassName, context()._javaEnvPackageName,
1303:                        Utilities.javaIsStaticMethod(n), null, method
1304:                                .getResult()));
1305:                final Out childOut = (Out) dispatch(n.getGeneric(7));
1306:                final Out ownOut = new Out(
1307:                        visitMethodDeclaration_cExternalDeclarations(childOut),
1308:                        new ArrayList<Node>(), null,
1309:                        visitMethodDeclaration_javaMembers(n, childOut),
1310:                        visitMethodDeclaration_javaNode(n));
1311:                _contexts.pop();
1312:                _table.exit(n);
1313:                return ownOut;
1314:            }
1315:
1316:            private List<Node> visitMethodDeclaration_cExternalDeclarations(
1317:                    final Out childOut) {
1318:                final List<Node> members = new ArrayList<Node>(
1319:                        childOut._cMembers.size());
1320:                members.addAll(childOut._cMembers);
1321:                final List<Node> result = new ArrayList<Node>(
1322:                        1 + childOut._cExternalDeclarations.size());
1323:                final GNode struct = (GNode) _astFactoryC.declareStruct(
1324:                        context()._cEnvStructName, members);
1325:                result.add(setLoc(null == childOut._cNode ? childOut._javaNode
1326:                        : childOut._cNode, struct));
1327:                result.addAll(childOut._cExternalDeclarations);
1328:                return result;
1329:            }
1330:
1331:            private List<Node> visitMethodDeclaration_javaMembers(
1332:                    final GNode n, final Out childOut) {
1333:                final GNode nodeFormals = n.getGeneric(4);
1334:                // field for caching result and formals
1335:                if (!Utilities.javaIsVoidMethod(n))
1336:                    liftIdJava(currentMethodScope(), n, "returnResult",
1337:                            getType(n).toMethod().getResult(),
1338:                            childOut._javaMembers);
1339:                for (final Object o : nodeFormals) {
1340:                    final GNode formal = (GNode) o;
1341:                    final String srcId = formal.getString(3);
1342:                    liftIdJava(declaringScope(srcId), formal, srcId,
1343:                            getType(formal), childOut._javaMembers);
1344:                }
1345:                // constructor
1346:                final List<Node> statements = new ArrayList<Node>();
1347:                final String idAbrupt = liftIdJava(currentMethodScope(), n,
1348:                        "returnAbrupt", JavaEntities.nameToBaseType("boolean"),
1349:                        childOut._javaMembers);
1350:                statements.add(GNode.create("ExpressionStatement",
1351:                        _astFactoryJava.setThisDotField(idAbrupt, GNode.create(
1352:                                "BooleanLiteral", "false"))));
1353:                for (final Object o : nodeFormals) {
1354:                    final GNode formal = (GNode) o;
1355:                    final String srcId = formal.getString(3);
1356:                    final String tgtId = _javaSubstitutions.get(
1357:                            declaringScope(srcId), srcId);
1358:                    statements.add(GNode.create("ExpressionStatement",
1359:                            _astFactoryJava.setThisDotField(tgtId, idNode(
1360:                                    formal, srcId))));
1361:                }
1362:                statements.add(childOut._javaNode);
1363:                final GNode constructor = GNode.create(
1364:                        "ConstructorDeclaration", GNode.create("Modifiers",
1365:                                false), null, context()._javaEnvClassName,
1366:                        nodeFormals, null, _astFactoryJava.block(statements));
1367:                // class declaration
1368:                childOut._javaMembers.add(constructor);
1369:                final GNode classBody = GNode.create("ClassBody",
1370:                        childOut._javaMembers.size());
1371:                classBody.addAll(childOut._javaMembers);
1372:                final GNode modifiers = context()._javaIsStatic ? GNode.create(
1373:                        "Modifiers", GNode.create("Modifier", "private"), GNode
1374:                                .create("Modifier", "static"), GNode.create(
1375:                                "Modifier", "final")) : GNode.create(
1376:                        "Modifiers", GNode.create("Modifier", "private"), GNode
1377:                                .create("Modifier", "final"));
1378:                final GNode classDecl = setLoc(n, GNode.create(
1379:                        "ClassDeclaration", modifiers,
1380:                        context()._javaEnvClassName, null, null, null,
1381:                        classBody));
1382:                final List<Node> result = new ArrayList<Node>(1);
1383:                result.add(classDecl);
1384:                return result;
1385:            }
1386:
1387:            private GNode visitMethodDeclaration_javaNode(final GNode n) {
1388:                final List<Node> actuals = new ArrayList<Node>(n.getGeneric(4)
1389:                        .size());
1390:                for (final Object o : n.getGeneric(4))
1391:                    actuals.add(idNode((Locatable) o, ((Node) o).getString(3)));
1392:                final GNode clazz = GNode.create("QualifiedIdentifier",
1393:                        context()._javaEnvClassName);
1394:                final Node body;
1395:                if (Utilities.javaIsVoidMethod(n)) {
1396:                    body = _astFactoryJava.closureStatement(clazz, actuals);
1397:                } else {
1398:                    final String resultFieldName = _javaSubstitutions.get(
1399:                            currentMethodScope(), "returnResult");
1400:                    body = _astFactoryJava.closureExpression(clazz, actuals,
1401:                            resultFieldName);
1402:                }
1403:                final GNode result = setLoc(n, GNode.create(
1404:                        "MethodDeclaration", 8));
1405:                result.add(0, GNode.create("Modifiers"));
1406:                for (final Object o : n.getGeneric(0))
1407:                    if (!"native".equals(((Node) o).getString(0)))
1408:                        result.getGeneric(0).add(o);
1409:                for (int i = 1; i < 7; i++)
1410:                    result.add(i, n.get(i));
1411:                result.add(7, body);
1412:                return result;
1413:            }
1414:
1415:            /**
1416:             * Visit a PrimaryIdentifier = Identifier (gosling_et_al_2000 <a
1417:             * href="http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#106941">&sect;6.5</a>).
1418:             */
1419:            public final Out visitPrimaryIdentifier(final GNode n) {
1420:                final String id = n.getString(0);
1421:                final Out ownOut;
1422:                final Type type = getType(n);
1423:                if ("C".equals(context()._activeLanguage)) {
1424:                    final GNode cNode;
1425:                    final List<Node> cMembers = new ArrayList<Node>();
1426:                    if (null == type || null == context()._cEnvStructName) {
1427:                        cNode = n;
1428:                    } else if (!type.isVariable()) {
1429:                        if (type.hasAttribute(Constants.ATT_STORAGE_AUTO, true))
1430:                            cNode = (GNode) _astFactoryC.getPCEnvField(liftIdC(
1431:                                    declaringScope(id), id, type, cMembers));
1432:                        else
1433:                            cNode = n;
1434:                    } else {
1435:                        final VariableT var = type.toVariable();
1436:                        if (VariableT.Kind.LOCAL == var.getKind()
1437:                                || VariableT.Kind.PARAMETER == var.getKind())
1438:                            cNode = (GNode) _astFactoryC.getPCEnvField(liftIdC(
1439:                                    declaringScope(id), id, var.getType(),
1440:                                    cMembers));
1441:                        else
1442:                            cNode = n;
1443:                    }
1444:                    ownOut = new Out(new ArrayList<Node>(0), cMembers, setLoc(
1445:                            n, cNode), new ArrayList<Node>(0), null);
1446:                } else {
1447:                    final GNode javaNode;
1448:                    final List<Node> javaMembers = new ArrayList<Node>();
1449:                    if (null == context()._javaEnvClassName
1450:                            || !JavaEntities.isParameterT(type)
1451:                            && !JavaEntities.isLocalT(type))
1452:                        javaNode = n;
1453:                    else
1454:                        javaNode = (GNode) _astFactoryJava
1455:                                .getThisDotField(liftIdJava(declaringScope(id),
1456:                                        n, id, type, javaMembers));
1457:                    ownOut = new Out(new ArrayList<Node>(0),
1458:                            new ArrayList<Node>(0), null, javaMembers, setLoc(
1459:                                    n, javaNode));
1460:                }
1461:                return ownOut;
1462:            }
1463:
1464:            /**
1465:             * Visit a ReturnStatement = [Expression] (gosling_et_al_2000 <a
1466:             * href="http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#6767">&sect;14.16</a>).
1467:             */
1468:            public final Out visitReturnStatement(final GNode n) {
1469:                final Out ownOut;
1470:                if ("C".equals(context()._activeLanguage)) {
1471:                    if (null == context()._cEnvStructName) {
1472:                        ownOut = visit(n);
1473:                    } else {
1474:                        final List<Node> cExternalDeclarations = new ArrayList<Node>();
1475:                        final List<Node> cMembers = new ArrayList<Node>();
1476:                        final List<Node> javaMembers = new ArrayList<Node>();
1477:                        final GNode ownNode;
1478:                        final GNode jumpStatement = abruptFlowJump(n, cMembers);
1479:                        final GNode abruptStringAst = cStringNode(liftIdJava(
1480:                                currentMethodScope(), n, "returnAbrupt",
1481:                                JavaEntities.nameToBaseType("boolean"),
1482:                                javaMembers));
1483:                        if (null == n.get(0)) {
1484:                            ownNode = (GNode) _astFactoryC.returnVoid(
1485:                                    abruptStringAst, jumpStatement);
1486:                        } else {
1487:                            final Out childOut = (Out) dispatch(n.getGeneric(0));
1488:                            cExternalDeclarations
1489:                                    .addAll(childOut._cExternalDeclarations);
1490:                            cMembers.addAll(childOut._cMembers);
1491:                            javaMembers.addAll(childOut._javaMembers);
1492:                            final Type fun = Utilities
1493:                                    .currentFunctionOrMethod(_table);
1494:                            assert fun.isMethod(); //TD 06 C return statement in C function that also contains Java code somewhere
1495:                            final Type javaType = Utilities.returnType(fun);
1496:                            final GNode resultStringAst = cStringNode(liftIdJava(
1497:                                    currentMethodScope(), n, "returnResult",
1498:                                    javaType, javaMembers));
1499:                            final GNode signatureStringAst = cStringNode(JavaEntities
1500:                                    .typeToDescriptor(_table, javaType));
1501:                            final String setter = "Set"
1502:                                    + Utilities.javaTypeToApiType(javaType,
1503:                                            true, false) + "Field";
1504:                            ownNode = (GNode) _astFactoryC.returnResult(
1505:                                    resultStringAst, signatureStringAst,
1506:                                    setter, childOut._cNode, abruptStringAst,
1507:                                    jumpStatement);
1508:                        }
1509:                        ownOut = new Out(cExternalDeclarations, cMembers,
1510:                                setLoc(n, ownNode), javaMembers, null);
1511:                    }
1512:                } else {
1513:                    if (null == context()._javaEnvClassName) {
1514:                        ownOut = visit(n);
1515:                    } else {
1516:                        final List<Node> cExternalDeclarations = new ArrayList<Node>();
1517:                        final List<Node> cMembers = new ArrayList<Node>();
1518:                        final List<Node> javaMembers = new ArrayList<Node>();
1519:                        final Type fun = Utilities
1520:                                .currentFunctionOrMethod(_table);
1521:                        assert fun.isMethod(); //TD 06 Java return statement in C function
1522:                        final Type javaType = fun.toMethod().getResult();
1523:                        final Node ownNode;
1524:                        final String substAbrupt = liftIdJava(
1525:                                currentMethodScope(), n, "returnAbrupt",
1526:                                JavaEntities.nameToBaseType("boolean"),
1527:                                javaMembers);
1528:                        if (null == n.get(0)) {
1529:                            ownNode = _astFactoryJava.returnVoid(substAbrupt);
1530:                        } else {
1531:                            final Out childOut = (Out) dispatch(n.getGeneric(0));
1532:                            cExternalDeclarations
1533:                                    .addAll(childOut._cExternalDeclarations);
1534:                            cMembers.addAll(childOut._cMembers);
1535:                            javaMembers.addAll(childOut._javaMembers);
1536:                            final String substResult = liftIdJava(
1537:                                    currentMethodScope(), n, "returnResult",
1538:                                    javaType, javaMembers);
1539:                            ownNode = _astFactoryJava.returnResult(substResult,
1540:                                    childOut._javaNode, substAbrupt);
1541:                        }
1542:                        ownOut = new Out(cExternalDeclarations, cMembers, null,
1543:                                javaMembers, setLoc(n, (GNode) ownNode));
1544:                    }
1545:                }
1546:                return ownOut;
1547:            }
1548:
1549:            /** 
1550:             * Visit a ThisExpression = [Expression] (gosling_et_al_2000
1551:             * <a href="http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#251519">&sect;15.8.3</a>,
1552:             * <a href="http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#251603">&sect;15.8.4</a>).
1553:             */
1554:            public final Out visitThisExpression(final GNode n) {
1555:                assert "Java".equals(context()._activeLanguage);
1556:                assert null == n.get(0); //TD 41 allow qualified this expressions in input
1557:                final String s = JavaEntities.currentType(_table).toClass()
1558:                        .getName();
1559:                final GNode ownNode = setLoc(n, GNode.create("ThisExpression",
1560:                        GNode.create("Type", GNode.create(
1561:                                "QualifiedIdentifier", s), GNode
1562:                                .create("Dimensions"))));
1563:                return visit(ownNode);
1564:            }
1565:
1566:            /** Visit a TranslationUnit = [JavaImports] ExternalDeclaration* Annotations. */
1567:            public final Out visitTranslationUnit(final GNode n) {
1568:                assert _contexts.isEmpty();
1569:                assert false && null == n;
1570:                /* TD 41 jeannie.CodeGenerator.visitTranslationUnit: invocation API, when outermost language is C */
1571:                return null;
1572:            }
1573:
1574:            /** Visit a WithStatement = (JeannieC.Declaration / JeannieC.AssignmentExpression) CInCBlock. */
1575:            public final Out visitWithStatement(final GNode n) {
1576:                assert "C".equals(context()._activeLanguage);
1577:                _table.enter(n);
1578:                final GNode initNode = n.getGeneric(0);
1579:                final String id;
1580:                final Type cPtrType, javaType;
1581:                final Out lhsOut, rhsOut;
1582:                if (initNode.hasName("Declaration")) {
1583:                    final GNode dtor = initNode.getGeneric(2).getGeneric(0);
1584:                    final GNode jNode = dtor.getGeneric(4);
1585:                    id = CAnalyzer.getDeclaredId(dtor.getGeneric(1)).getString(
1586:                            0);
1587:                    lhsOut = (Out) dispatch(setLoc(dtor.getGeneric(1), GNode
1588:                            .create("PrimaryIdentifier", id)));
1589:                    rhsOut = (Out) dispatch(jNode);
1590:                    cPtrType = ((Type) _table.current().lookupLocally(id));
1591:                    javaType = Utilities.cTypeToJavaType(_table, _runtime,
1592:                            jNode, getType(jNode));
1593:                } else {
1594:                    assert initNode.hasName("AssignmentExpression");
1595:                    final GNode cNode = initNode.getGeneric(0), jNode = initNode
1596:                            .getGeneric(2);
1597:                    id = cNode.getString(0);
1598:                    lhsOut = (Out) dispatch(cNode);
1599:                    rhsOut = (Out) dispatch(jNode);
1600:                    cPtrType = getType(cNode);
1601:                    javaType = Utilities.cTypeToJavaType(_table, _runtime,
1602:                            jNode, getType(jNode));
1603:                }
1604:                _contexts.push(new Context(context()._activeLanguage,
1605:                        context()._cEnvStructName, context()._cHasEnv,
1606:                        context()._javaEnvClassName,
1607:                        context()._javaEnvPackageName, context()._javaIsStatic,
1608:                        id, context()._snippetType));
1609:                final Out blockOut = (Out) dispatch(n.getGeneric(1));
1610:                _contexts.pop();
1611:                final List<Node> cMembers = new ArrayList<Node>(), javaMembers = new ArrayList<Node>();
1612:                final Node ownNode;
1613:                {
1614:                    final GNode abruptFlowCheck = abruptFlowCheck(n, cMembers,
1615:                            javaMembers);
1616:                    final Node init = rhsOut._cNode;
1617:                    final Scope scope = declaringScope(id);
1618:                    final String label = liftIdCLabel(scope, "release_" + id);
1619:                    final Node body = blockOut._cNode;
1620:                    final String caField = liftIdC(scope, id, cPtrType,
1621:                            cMembers);
1622:                    final String releaseAbrupt = liftIdC(scope, id
1623:                            + "ReleaseAbrupt", typedefType("jint"), cMembers);
1624:                    if (JavaTypeConverter.isIdentical(javaType, JavaEntities
1625:                            .tString(_table))) {
1626:                        final Type cJniType = typedefType("jstring");
1627:                        final String jsField = liftIdC(scope,
1628:                                id + "JavaString", cJniType, cMembers);
1629:                        ownNode = isUtf8(cPtrType, javaType) ? _astFactoryC
1630:                                .withStringUTF(jsField, init, releaseAbrupt,
1631:                                        caField, body, label, abruptFlowCheck)
1632:                                : _astFactoryC.withString(jsField, init,
1633:                                        releaseAbrupt, caField, body, label,
1634:                                        abruptFlowCheck);
1635:                    } else {
1636:                        final Type tElem = JavaEntities
1637:                                .arrayElementType(javaType.toArray());
1638:                        final boolean primiv = JavaEntities.isPrimitiveT(tElem);
1639:                        final Type cJniType = typedefType(primiv ? "j"
1640:                                + Utilities.javaTypeToApiType(javaType)
1641:                                : "jobject");
1642:                        final String jaField = liftIdC(scope, id + "JavaArray",
1643:                                cJniType, cMembers);
1644:                        if (primiv) {
1645:                            final String arrayDeclString = "j"
1646:                                    + Utilities.javaTypeToApiType(tElem)
1647:                                    + " ca[length];";
1648:                            final GNode caNode = Utilities.cStringToAst(
1649:                                    "Declaration", arrayDeclString, Utilities
1650:                                            .standardJniTypeDefs());
1651:                            final String getRegion = withArrayFunction(
1652:                                    javaType, true);
1653:                            final String setRegion = withArrayFunction(
1654:                                    javaType, false);
1655:                            ownNode = _astFactoryC.withPrimitiveArray(jaField,
1656:                                    init, releaseAbrupt, caNode, caField,
1657:                                    getRegion, body, label, setRegion,
1658:                                    abruptFlowCheck);
1659:                        } else {
1660:                            ownNode = _astFactoryC.withReferenceArray(jaField,
1661:                                    init, releaseAbrupt, caField, body, label,
1662:                                    abruptFlowCheck);
1663:                        }
1664:                    }
1665:                }
1666:                final Out ownOut = new Out(new ArrayList<Node>(0), cMembers,
1667:                        setLoc(n, (GNode) ownNode), javaMembers, null);
1668:                ownOut.addAll(lhsOut).addAll(rhsOut).addAll(blockOut);
1669:                _table.exit(n);
1670:                return ownOut;
1671:            }
1672:
1673:            private String withArrayFunction(final Type javaType,
1674:                    final boolean isAquire) {
1675:                final StringBuffer result = new StringBuffer();
1676:                result.append(isAquire ? "Get" : "Set");
1677:                result
1678:                        .append(Utilities.javaTypeToApiType(javaType, true,
1679:                                true));
1680:                result.append("Region");
1681:                return result.toString();
1682:            }
1683:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.