/** * Visit a function node. The values of the child nodes are first pushed onto the stack. Then the * function class associated with the node is used to evaluate the function. * * <p>If a function implements SpecialEvaluationI then the evaluate method of PFMC is called. */ public Object visit(ASTFunNode node, Object data) throws ParseException { if (node == null) return null; PostfixMathCommandI pfmc = node.getPFMC(); // check if the function class is set if (pfmc == null) throw new ParseException("No function class associated with " + node.getName()); // Some operators (=) need a special method for evaluation // as the pfmc.run method does not have enough information // in such cases we call the evaluate method which passes // all available info. Note evaluating the children is // the responsibility of the evaluate method. if (pfmc instanceof SpecialEvaluationI) { return ((SpecialEvaluationI) pfmc).evaluate(node, data, this, stack, this.symTab); } if (pfmc instanceof CallbackEvaluationI) { Object val = ((CallbackEvaluationI) pfmc).evaluate(node, this); stack.push(val); return val; } if (debug == true) { System.out.println("Stack size before childrenAccept: " + stack.size()); } // evaluate all children (each leaves their result on the stack) data = node.childrenAccept(this, data); if (debug == true) { System.out.println("Stack size after childrenAccept: " + stack.size()); } if (pfmc.getNumberOfParameters() == -1) { // need to tell the class how many parameters it can take off // the stack because it accepts a variable number of params pfmc.setCurNumberOfParameters(node.jjtGetNumChildren()); } // try to run the function pfmc.run(stack); if (debug == true) { System.out.println("Stack size after run: " + stack.size()); } return data; }