//******************* EVALUATOR **************************************
class Evaluator {
  // This just has one static method and uses existing objects.  It could
  // have been put into say the ExpTree class or somewhere else but
  // conceptually it really is seperate.  One can also imagine making an
  // evaluator object as I did for parser.

  public static int myPow(int base, int exp){
  //Used to find powers. Takes only integer bases and exponents.
        int t = 1;
        int m = exp;
        int n = base;
        if (m == 0) return 1;
        while (m != 1) {
            if (m % 2 == 0) {
                n = n*n;
                m = m/2;
            }
            else {
                m = m - 1;
                t = t * n;
            }
        }
        return t*n;
    }//method myPow
    
  public static int eval(SymbolTable S, ExpTree t){
      if (t == null) return 0;
      else if (S == null) {
        System.out.println("No definitions");
      return 0;}
      else {
          String r = t.root().toString();
          if (t instanceof Oper) {
          //If we have an operator, do whatever that operator says to do:
              if (r.equals("+")) return eval(S, (ExpTree) t.left()) + eval(S, (ExpTree) t.right());
              else if (r.equals("-")) return eval(S, (ExpTree) t.left()) - eval(S, (ExpTree) t.right());
              else if (r.equals("*")) return eval(S, (ExpTree) t.left()) * eval(S, (ExpTree) t.right());
              else if (r.equals("/")) return eval(S, (ExpTree) t.left()) / eval(S, (ExpTree) t.right());
              else if (r.equals("^")) return myPow(eval(S, (ExpTree) t.left()), eval(S, (ExpTree) t.right()));
          }
          else if (t instanceof Var) {
          //If we have a var, return the result
              char c = ((Character) t.root()).charValue();
              return S.lookup(c);
          }
          else {
              System.out.println("ERROR: invalid node");
          }
          return 0;
      }
  }//end method eval

  public static void main(String[] args){
    SymbolTable S = SymbolTable.getdefs(args[0]);
    char[] Data = Tokenizer.scan(args[1]);
    Parser P = new Parser(Data);
    ExpTree E = P.parse();
    System.out.println("The value is: " + eval(S,E));};
}//end Evaluator