001: /*
002: * xtc - The eXTensible Compiler
003: * Copyright (C) 2007 IBM Corp.
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License
007: * version 2 as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
017: * USA.
018: */
019: package xtc.lang.jeannie;
020:
021: import java.util.Arrays;
022: import java.util.Collections;
023: import java.util.HashSet;
024: import java.util.Set;
025:
026: import xtc.lang.JavaAstSimplifier;
027: import xtc.tree.LineMarker;
028: import xtc.tree.Node;
029: import xtc.tree.Visitor;
030:
031: /**
032: * A visitor that simplifies Jeannie ASTs. Uses JavaAstSimplifier on the Java
033: * parts of the AST, while leaving the C part of the AST untouched.
034: */
035: public class AstSimplifier extends Visitor {
036: private static final class JavaSimplifier extends JavaAstSimplifier {
037: final AstSimplifier _jeannieSimplifier;
038:
039: JavaSimplifier(final AstSimplifier jeannieSimplifier) {
040: _jeannieSimplifier = jeannieSimplifier;
041: }
042:
043: public final Node visit(final Node n) {
044: if (GOTO_C.contains(n.getName())) {
045: _jeannieSimplifier._inJava = false;
046: final Node result = _jeannieSimplifier
047: .genericDispatch(n);
048: _jeannieSimplifier._inJava = true;
049: return result;
050: }
051: return super .visit(n);
052: }
053: }
054:
055: private static final Set<String> GOTO_C = Collections
056: .unmodifiableSet(new HashSet<String>(Arrays
057: .asList(new String[] { "CDeclarations",
058: "CInJavaBlock", "CInJavaExpression",
059: "TranslationUnit" })));
060:
061: private static final Set<String> GOTO_JAVA = Collections
062: .unmodifiableSet(new HashSet<String>(Arrays
063: .asList(new String[] { "CompilationUnit",
064: "JavaImports", "JavaInCBlock",
065: "JavaInCExpression", "JavaInCStatement",
066: "JavaThrows", "JavaType" })));
067:
068: private boolean _inJava;
069:
070: private final JavaSimplifier _javaSimplifier;
071:
072: /** Create a new jeannie.AstSimplifier, and specify the initial language with "Java" or "C". */
073: public AstSimplifier(final String language) {
074: _inJava = "Java".equals(language);
075: _javaSimplifier = new JavaSimplifier(this );
076: }
077:
078: private final Node genericDispatch(final Node n) {
079: for (int i = 0; i < n.size(); i++) {
080: final Object o = n.get(i);
081: if (o instanceof Node)
082: n.set(i, dispatch((Node) o));
083: }
084: return n;
085: }
086:
087: public final LineMarker visit(final LineMarker m) {
088: m.setNode((Node) dispatch(m.getNode()));
089: return m;
090: }
091:
092: /** Dispatch the node in C or in Java depending on the current language, and
093: * depending on whether the node itself indicates a language transition.
094: * Transitions from Java to C are handled indirectly by
095: * JeannieJAstSimplifier.visit(GNode).
096: */
097: public final Node visit(final Node n) {
098: final Node result;
099: if (_inJava) {
100: result = (Node) _javaSimplifier.dispatch(n);
101: } else if (GOTO_JAVA.contains(n.getName())) {
102: _inJava = true;
103: result = genericDispatch(n);
104: _inJava = false;
105: } else {
106: result = genericDispatch(n);
107: }
108: return result;
109: }
110: }
|