/*
* xtc - The eXTensible Compiler
* Copyright (C) 2007 IBM Corp.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*/
package xtc.lang.jeannie;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import xtc.lang.JavaAstSimplifier;
import xtc.tree.LineMarker;
import xtc.tree.Node;
import xtc.tree.Visitor;
/**
* A visitor that simplifies Jeannie ASTs. Uses JavaAstSimplifier on the Java
* parts of the AST, while leaving the C part of the AST untouched.
*/
public class AstSimplifier extends Visitor {
private static final class JavaSimplifier extends JavaAstSimplifier {
final AstSimplifier _jeannieSimplifier;
JavaSimplifier(final AstSimplifier jeannieSimplifier) {
_jeannieSimplifier = jeannieSimplifier;
}
public final Node visit(final Node n) {
if (GOTO_C.contains(n.getName())) {
_jeannieSimplifier._inJava = false;
final Node result = _jeannieSimplifier.genericDispatch(n);
_jeannieSimplifier._inJava = true;
return result;
}
return super.visit(n);
}
}
private static final Set<String> GOTO_C =
Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(new String[] {
"CDeclarations", "CInJavaBlock", "CInJavaExpression", "TranslationUnit" })));
private static final Set<String> GOTO_JAVA =
Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(new String[] {
"CompilationUnit", "JavaImports", "JavaInCBlock", "JavaInCExpression", "JavaInCStatement", "JavaThrows", "JavaType" })));
private boolean _inJava;
private final JavaSimplifier _javaSimplifier;
/** Create a new jeannie.AstSimplifier, and specify the initial language with "Java" or "C". */
public AstSimplifier(final String language) {
_inJava = "Java".equals(language);
_javaSimplifier = new JavaSimplifier(this);
}
private final Node genericDispatch(final Node n) {
for (int i=0; i<n.size(); i++) {
final Object o = n.get(i);
if (o instanceof Node)
n.set(i, dispatch((Node) o));
}
return n;
}
public final LineMarker visit(final LineMarker m) {
m.setNode((Node) dispatch(m.getNode()));
return m;
}
/** Dispatch the node in C or in Java depending on the current language, and
* depending on whether the node itself indicates a language transition.
* Transitions from Java to C are handled indirectly by
* JeannieJAstSimplifier.visit(GNode).
*/
public final Node visit(final Node n) {
final Node result;
if (_inJava) {
result = (Node) _javaSimplifier.dispatch(n);
} else if (GOTO_JAVA.contains(n.getName())) {
_inJava = true;
result = genericDispatch(n);
_inJava = false;
} else {
result = genericDispatch(n);
}
return result;
}
}