package edu.mit.ai.psg.jeva.examples;

import edu.mit.ai.psg.jeva.*;
import edu.mit.ai.psg.strings.Stringify;
import java.io.PrintWriter;
import java.util.Stack;

/** <tt><a href="TraceCallsEvalHook.java.html">TraceCallsEvalHook.java</a></tt>
    traces only method call expressions.
    This version only works on single threaded programs. 
    Output defaults to System.err.

    It produce traces of the following form:
    <pre>
    ->System.out.println("result: "+fib(5))
    | ->fib(5)
    | | ->fib(n-2)
    | | | {n=5}
    | | | ->fib(n-2)
    | | | | {n=3}
    | | | <- 1
    | | | ->fib(n-1)
    | | | | {n=3}
    | | | <- 1
    | | <- 2
    | | ->fib(n-1)
    | | | {n=5}
    | | | ->fib(n-2)
    | | | | {n=4}
    | | | <- 1
    | | | ->fib(n-1)
    | | | | {n=4}
    | | | | ->fib(n-2)
    | | | | | {n=3}
    | | | | <- 1
    | | | | ->fib(n-1)
    | | | | | {n=3}
    | | | | <- 1
    | | | <- 2
    | | <- 3
    | <- 5
    result: 5
    <- null
    </pre> 

    @author CarlManning, caroma@ai.mit.edu<br>
    Copyright (c) 1999 Massachusetts Institute of Technology **/

public class TraceCallsEvalHook extends TraceAllEvalHook {
  public TraceCallsEvalHook() { super(); }
  public TraceCallsEvalHook(PrintWriter pw) { super(pw); }
  /** Override default to not trace **/
  public Object visit(IJevaNode node, Object data) { return null; }
  /** Cause trace on method invocations **/
  public Object visit(JNEMethodInvocationExpression node, Object data) {
    return trace(node, data);
  }
  /** Don't trace before subexpressions evaluated **/
  public Object indentedTrace(PrintWriter pw, IJevaNode node, Object data) {
    if (data instanceof EvalMethods.EvalHookPreData)
      return data;
    else return super.indentedTrace(pw, node, data);
  }
  /** test **/
  public static void main(String[] ignore) {
    EvalMethods.setEvalHook(new TraceCallsEvalHook());

    String pgm = ("public class Fibonacci {\n"+
		  "  public static void main(String[] ignore) {\n"+
		  "    System.out.println(\"result: \"+fib(5));\n"+
		  "  }\n"+
		  "  public static int fib(int n) {\n"+
		  "    if (n <= 2) return 1;\n"+
		  "    else return fib(n-2)+fib(n-1);"+
		  "  }\n"+
		  "}\n");
    try { Jeva.parseEvalStringCompilationUnit(pgm, new String[]{}); }
    catch (Throwable e) { e.printStackTrace(); }
  }
}

