package xtc.lang.blink;
import java.util.Stack;
import xtc.lang.JavaEntities;
import xtc.tree.GNode;
import xtc.tree.Node;
import xtc.tree.Visitor;
import xtc.util.Runtime;
import xtc.lang.jeannie.Utilities;
public final class CommandAstAnalyzer extends Visitor {
enum Language { C, JAVA, DEBUGGER };
private static class MiniVisitor_allNodesHaveLanguage extends Visitor {
public final void visit(final Node n) {
assert null != CommandAstAnalyzer.getNodeLanguage(n) : n.toString();
for (int i=0; i<n.size(); i++)
if (n.get(i) instanceof Node)
dispatch(n.getNode(i));
}
}
public static void assertAllNodesHaveLanguage(final Node n) {
new MiniVisitor_allNodesHaveLanguage().dispatch(n);
}
public static Language getNodeLanguage(final Node n) {
return (Language) n.getProperty("language");
}
public static Object getNodeVariableRemap(final Node n) {
return (Object) n.getProperty("variableRemap");
}
private static Language setNodeLanguage(final Node n, final Language language) {
n.setProperty("language", language);
return language;
}
final Runtime _runtime;
private final Stack<Language> _stack;
public CommandAstAnalyzer(final Runtime runtime) {
assert null != runtime ;
_runtime = runtime;
_stack = new Stack<Language>();
_stack.push(Language.DEBUGGER);
}
private boolean assrt(final Node n, final boolean cond, final String msgFormat, final Object... msgArgs) {
return JavaEntities.runtimeAssrt(_runtime, n, cond, msgFormat, msgArgs);
}
private final Language currentLanguage() {
return _stack.peek();
}
private final Object dispatchInLanguage(final Node n, final Language language) {
enterLanguage(language);
final Object result = dispatch(n);
exitLanguage(language);
return result;
}
private final void enterLanguage(final Language language) {
_stack.push(language);
}
private final void exitLanguage(final Language language) {
assert currentLanguage() == language;
_stack.pop();
}
private boolean setAndAssrtLanguage(final Node n, final Language language) {
setNodeLanguage(n, language);
return assrt(n, language == currentLanguage(), "expected language %s, current %s", language, currentLanguage());
}
public final void visit(final GNode n) {
assrt(n, false, "the Jeannie debugger does not support the %s feature", n.getName());
}
/** Visit an AdditiveExpression = Expression ("+" / "-") Expression. */
public final void visitAdditiveExpression(final GNode n) {
final Language curr = currentLanguage();
if (assrt(n, curr == Language.C || curr == Language.JAVA, "expected language C or Java, current %s", curr)) {
setNodeLanguage(n, curr);
dispatch(n.getNode(0));
dispatch(n.getNode(2));
}
}
/** Visit an AddressExpression = Expression. */
public final void visitAddressExpression(final GNode n) {
if (setAndAssrtLanguage(n, Language.C))
dispatch(n.getNode(0));
}
/** Visit Arguments = Expression*. */
public final void visitArguments(final GNode n) {
if (setAndAssrtLanguage(n, Language.JAVA))
for (int i=0; i<n.size(); i++)
dispatch(n.getNode(i));
}
/** Visit an AssignmentExpression = Expression ("=" / "+=" / "-=" / "*=" / "/=" / "%=" / "<<=" / ">>=" / "&=" / "^=" / "|=") Expression. */
public final void visitAssignmentExpression(final GNode n) {
if (setAndAssrtLanguage(n, Language.C)) {
dispatch(n.getNode(0));
dispatch(n.getNode(2));
}
}
/** Visit a BreakClassCommand = QualifiedIdentifier LineNumber. */
public final void visitBreakClassCommand(final GNode n) {
if (setAndAssrtLanguage(n, Language.DEBUGGER)) {
@SuppressWarnings("unused")
final String className = (String) dispatchInLanguage(n.getNode(0), Language.JAVA);
}
}
/** Visit a BreakClassCommand = QualifiedIdentifier. */
public final void visitBreakClassMethodCommand(final GNode n) {
if (setAndAssrtLanguage(n, Language.DEBUGGER)) {
@SuppressWarnings("unused")
final String className = (String) dispatchInLanguage(n.getNode(0), Language.JAVA);
}
}
/** Visit a BreakFileCommand = FileName LineNumber. */
public final void visitBreakFileCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit a BreakFileCommand = FileName LineNumber. */
public final void visitBreakFunctionCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit a C2jCommand = (no children). */
public final void visitC2jCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit a CallExpression = [Expression] null MethodName Arguments. */
public final void visitCallExpression(final GNode n) {
if (setAndAssrtLanguage(n, Language.JAVA)) {
if (null != n.get(0))
dispatch(n.getNode(0));
@SuppressWarnings("unused")
final String methodName = n.getString(2);
dispatch(n.getNode(3));
}
}
/** Visit a CInJavaExpression = C.UnaryExpression. */
public final void visitCInJavaExpression(final GNode n) {
if (setAndAssrtLanguage(n, Language.JAVA))
dispatchInLanguage(n.getNode(0), Language.C);
}
/** Visit a ContinueCommand = (no children). */
public final void visitContinueCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit a DeleteCommand = IntegerLiteral. */
public final void visitDeleteCommand(final GNode n) {
if (setAndAssrtLanguage(n, Language.DEBUGGER))
dispatchInLanguage(n.getNode(0), Language.JAVA);
}
/** Visit a DirectComponentSelection = Expression String. */
public final void visitDirectComponentSelection(final GNode n) {
if (setAndAssrtLanguage(n, Language.C))
dispatch(n.getNode(0));
}
/** Visit a DownCommand = IntegerLiteral. */
public final void visitDownCommand(final GNode n) {
if (setAndAssrtLanguage(n, Language.DEBUGGER))
dispatchInLanguage(n.getNode(0), Language.JAVA);
}
/** Visit a EqualityExpression = Expression ("==" / "!=") Expression. */
public final void visitEqualityExpression(final GNode n) {
final Language curr = currentLanguage();
if (assrt(n, curr == Language.C || curr == Language.JAVA, "expected language C or Java, current %s", curr)) {
setNodeLanguage(n, curr);
dispatch(n.getNode(0));
dispatch(n.getNode(2));
}
}
/** Visit a ExitCommand = (no children). */
public final void visitExitCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit a Expression = Expression ("=" / "+=" / "-=" / "*=" / "/=" / "&=" / "|=" / "^=" / "%=" / "<<=" / ">>=" / ">>>=") Expression. */
public final void visitExpression(final GNode n) {
if (setAndAssrtLanguage(n, Language.JAVA)) {
dispatch(n.getNode(0));
dispatch(n.getNode(2));
}
}
/** Visit ExpressionList = Expression+. */
public final void visitExpressionList(final GNode n) {
if (setAndAssrtLanguage(n, Language.C))
for (int i=0; i<n.size(); i++)
dispatch(n.getNode(i));
}
/** Visit a FunctionCall = Expression [ExpressionList]. */
public final void visitFunctionCall(final GNode n) {
if (setAndAssrtLanguage(n, Language.C)) {
dispatch(n.getNode(0));
if (null != n.get(1))
dispatch(n.getNode(1));
}
}
/** Visit a GdbCommand = RestOfLine. */
public final void visitGdbCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit a HelpCommand = (no children). */
public final void visitHelpCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit an IndirectionExpression = Expression. */
public final void visitIndirectionExpression(final GNode n) {
if (setAndAssrtLanguage(n, Language.C))
dispatch(n.getNode(0));
}
/** Visit a InfoBreakCommand = (no children). */
public final void visitInfoBreakCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit a InfoWatchCommand = (no children). */
public final void visitInfoWatchCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit an InitJCommand = (no children). */
public final void visitInitJCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit an IntegerConstant = String. */
public final void visitIntegerConstant(final GNode n) {
setAndAssrtLanguage(n, Language.C);
}
/** Visit an IntegerLiteral = String. */
public final void visitIntegerLiteral(final GNode n) {
setAndAssrtLanguage(n, Language.JAVA);
}
/** Visit a J2cCommand = (no children). */
public final void visitJ2cCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit a JavaInCExpression = Java.UnaryExpression. */
public final void visitJavaInCExpression(final GNode n) {
if (setAndAssrtLanguage(n, Language.C))
dispatchInLanguage(n.getNode(0), Language.JAVA);
}
/** Visit a JdbCommand = RestOfLine. */
public final void visitJdbCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit a JRetCommand = (no children). */
public final void visitJRetCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit a ListCommand = (no children). */
public final void visitListCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit a LocalsCommand = (no children). */
public final void visitLocalsCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit a MetaVariable = Identifier. */
public final void visitMetaVariable(final GNode n) {
setNodeLanguage(n, Language.DEBUGGER);
final Language curr = currentLanguage();
assrt(n, curr == Language.C || curr == Language.JAVA, "expected language C or Java, current %s", curr);
}
/** Visit a NextCommand = (no children). */
public final void visitNextCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit a RunCommand = (no children). */
public final void visitRunCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit an StringLiteral = (no children). */
public final void visitNullLiteral(final GNode n) {
setAndAssrtLanguage(n, Language.JAVA);
}
/** Visit a PrimaryIdentifier = String. */
public void visitPrimaryIdentifier(final GNode n) {
final Language curr = currentLanguage();
if (assrt(n, curr == Language.C || curr == Language.JAVA, "expected language C or Java, current %s", curr)) {
setNodeLanguage(n, curr);
}
}
/** Visit a PrintCExpressionCommand = C.Expression. */
public final void visitPrintCExpressionCommand(final GNode n) {
if (setAndAssrtLanguage(n, Language.DEBUGGER))
dispatchInLanguage(n.getNode(0), Language.C);
}
/** Visit a PrintJavaExpressionCommand = Java.Expression. */
public final void visitPrintJavaExpressionCommand(final GNode n) {
if (setAndAssrtLanguage(n, Language.DEBUGGER))
dispatchInLanguage(n.getNode(0), Language.JAVA);
}
/** Visit a QualifiedIdentifier = Identifier+. */
public final String visitQualifiedIdentifier(final GNode n) {
if (!setAndAssrtLanguage(n, Language.JAVA))
return null;
return Utilities.qualifiedIdentifierToString(n);
}
/** Visit a SelectionExpression = Expression Identifier. */
public final void visitSelectionExpression(final GNode n) {
setAndAssrtLanguage(n, Language.JAVA);
dispatch(n.getNode(0));
//dispatch(n.getNode(1)); // BK - this is string.
}
/** Visit a StatCommand = (no children). */
public final void visitStatCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit a StepCommand = (no children). */
public final void visitStepCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
/** Visit an StringConstant = String. */
public final void visitStringConstant(final GNode n) {
setAndAssrtLanguage(n, Language.JAVA);
}
/** Visit an StringLiteral = String. */
public final void visitStringLiteral(final GNode n) {
setAndAssrtLanguage(n, Language.JAVA);
}
/** Visit a SubscriptExpression = Expression Expression. */
public final void visitSubscriptExpression(final GNode n) {
final Language curr = currentLanguage();
if (assrt(n, curr == Language.C || curr == Language.JAVA, "expected language C or Java, current %s", curr)) {
setNodeLanguage(n, curr);
dispatch(n.getNode(0));
dispatch(n.getNode(1));
}
}
/** Visit a ThisExpression = [Expression]. */
public final void visitThisExpression(final GNode n) {
setAndAssrtLanguage(n, Language.JAVA);
assrt(n, null == n.get(0), "the Jeannie debugger does not support qualified this in Java expressions");
}
/** Visit an UpCommand = IntegerLiteral. */
public final void visitUpCommand(final GNode n) {
if (setAndAssrtLanguage(n, Language.DEBUGGER))
dispatchInLanguage(n.getNode(0), Language.JAVA);
}
/** Visit a WatchCExpressionCommand = C.Expression. */
public final void visitWatchCExpressionCommand(final GNode n) {
if (setAndAssrtLanguage(n, Language.DEBUGGER))
dispatchInLanguage(n, Language.C);
}
/** Visit a WatchJavaFieldCommand = [WatchKind] QualifiedIdentifier. */
public final void visitWatchJavaFieldCommand(final GNode n) {
if (setAndAssrtLanguage(n, Language.DEBUGGER)) {
@SuppressWarnings("unused")
final String className = (String) dispatchInLanguage(n.getNode(1), Language.JAVA);
}
}
/** Visit a WhereCommand = (no children). */
public final void visitWhereCommand(final GNode n) {
setAndAssrtLanguage(n, Language.DEBUGGER);
}
}