Program: 75399
Project: 75399
Buggy source:
/** 
 * Apply a function to the children of the specified node. This also handles indexing into matrices and arrays, which look like function calls. In the simplest cases, if the function is being applied to an expression that evaluated to a FunctionToken, an ArrayToken, or a MatrixToken, then the function application is simply applied to the available arguments. More complex is if the function is being applied to an expression that does not evaluate as above, resulting in three cases:  Of primary interest is a function node that represents the invocation of a Java method registered with the expression parser.  This method uses the reflection mechanism in the CachedMethod class to find the correct method, based on the types of the arguments and invoke it.  See that class for information about how method arguments are matched. A second case is the eval() function, which is handled specially in this method.  The argument to the function is evaluated, and the parsed as a string using the expression parser.  The result is then evaluated *in this evaluator*. This has the effect that any identifiers are evaluated in the same scope as the original expression. A third case is the matlab() function, which is also handled specially in this method, allowing the evaluation of expressions in matlab if matlab is installed.  The format of the function is covered in  {@link ptolemy.data.expr.MatlabUtilities#evaluate(String,Set,ParserScope)}.
 * @param node The specified node.
 * @exception IllegalActionException If an evaluation error occurs.
 */
public void visitFunctionApplicationNode(ASTPtFunctionApplicationNode node) throws IllegalActionException {
  ptolemy.data.Token value=null;
  String functionName=node.getFunctionName();
  if (_scope != null && functionName != null) {
    value=_scope.get(node.getFunctionName());
  }
  int argCount=node.jjtGetNumChildren() - 1;
  Type[] argTypes=new Type[argCount];
  ptolemy.data.Token[] argValues=new ptolemy.data.Token[argCount];
  for (int i=0; i < argCount; i++) {
    _evaluateChild(node,i + 1);
    ptolemy.data.Token token=_evaluatedChildToken;
    argValues[i]=token;
    argTypes[i]=token.getType();
  }
  if (value != null || functionName == null) {
    ptolemy.data.Token result;
    value=_evaluateChild(node,0);
    if (value instanceof ArrayToken) {
      if (argCount == 1) {
        result=_evaluateArrayIndex(node,value,argValues[0]);
      }
 else {
        throw new IllegalActionException("String_Node_Str" + "String_Node_Str" + node.getFunctionName());
      }
    }
 else     if (value instanceof MatrixToken) {
      if (argCount == 2) {
        result=_evaluateMatrixIndex(node,value,argValues[0],argValues[1]);
      }
 else {
        throw new IllegalActionException("String_Node_Str" + "String_Node_Str" + node.getFunctionName());
      }
    }
 else     if (value instanceof FunctionToken) {
      FunctionToken function=(FunctionToken)value;
      if (function.getNumberOfArguments() != argCount) {
        throw new IllegalActionException("String_Node_Str" + "String_Node_Str" + value.toString());
      }
      result=function.apply(argValues);
    }
 else {
      throw new IllegalActionException("String_Node_Str" + value.toString());
    }
    _evaluatedChildToken=(result);
    return;
  }
  if (node.getFunctionName().compareTo("String_Node_Str") == 0) {
    if (argCount == 1) {
      ptolemy.data.Token token=argValues[0];
      if (token instanceof StringToken) {
        PtParser parser=new PtParser();
        ASTPtRootNode tree=parser.generateParseTree(((StringToken)token).stringValue());
        tree.visit(this);
        return;
      }
    }
    throw new IllegalActionException("String_Node_Str" + "String_Node_Str" + "String_Node_Str");
  }
  if (node.getFunctionName().compareTo("String_Node_Str") == 0) {
    if (argCount == 1) {
      ptolemy.data.Token token=argValues[0];
      if (token instanceof StringToken) {
        String expression=((StringToken)token).stringValue();
        ParseTreeFreeVariableCollector collector=new ParseTreeFreeVariableCollector();
        Set freeVariables=collector.collectFreeVariables(node,_scope);
        _evaluatedChildToken=MatlabUtilities.evaluate(expression,freeVariables,_scope);
        return;
      }
    }
 else {
      throw new IllegalActionException("String_Node_Str" + "String_Node_Str" + "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str");
    }
  }
  ptolemy.data.Token result=_functionCall(node.getFunctionName(),argTypes,argValues);
  _evaluatedChildToken=(result);
}

Fixed version (ground truth):
/** 
 * Apply a function to the children of the specified node. This also handles indexing into matrices and arrays, which look like function calls. In the simplest cases, if the function is being applied to an expression that evaluated to a FunctionToken, an ArrayToken, or a MatrixToken, then the function application is simply applied to the available arguments. More complex is if the function is being applied to an expression that does not evaluate as above, resulting in three cases:  Of primary interest is a function node that represents the invocation of a Java method registered with the expression parser.  This method uses the reflection mechanism in the CachedMethod class to find the correct method, based on the types of the arguments and invoke it.  See that class for information about how method arguments are matched. A second case is the eval() function, which is handled specially in this method.  The argument to the function is evaluated, and the parsed as a string using the expression parser.  The result is then evaluated *in this evaluator*. This has the effect that any identifiers are evaluated in the same scope as the original expression. A third case is the matlab() function, which is also handled specially in this method, allowing the evaluation of expressions in matlab if matlab is installed.  The format of the function is covered in  {@link ptolemy.data.expr.MatlabUtilities#evaluate(String,Set,ParserScope)}.
 * @param node The specified node.
 * @exception IllegalActionException If an evaluation error occurs.
 */
public void visitFunctionApplicationNode(ASTPtFunctionApplicationNode node) throws IllegalActionException {
  ptolemy.data.Token value=null;
  String functionName=node.getFunctionName();
  if (functionName != null && _scope != null) {
    value=_scope.get(node.getFunctionName());
  }
  int argCount=node.jjtGetNumChildren() - 1;
  Type[] argTypes=new Type[argCount];
  ptolemy.data.Token[] argValues=new ptolemy.data.Token[argCount];
  for (int i=0; i < argCount; i++) {
    _evaluateChild(node,i + 1);
    ptolemy.data.Token token=_evaluatedChildToken;
    argValues[i]=token;
    argTypes[i]=token.getType();
  }
  if (value != null || functionName == null) {
    ptolemy.data.Token result;
    if (value == null) {
      value=_evaluateChild(node,0);
    }
    if (value instanceof ArrayToken) {
      if (argCount == 1) {
        result=_evaluateArrayIndex(node,value,argValues[0]);
      }
 else {
        throw new IllegalActionException("String_Node_Str" + "String_Node_Str" + node.getFunctionName());
      }
    }
 else     if (value instanceof MatrixToken) {
      if (argCount == 2) {
        result=_evaluateMatrixIndex(node,value,argValues[0],argValues[1]);
      }
 else {
        throw new IllegalActionException("String_Node_Str" + "String_Node_Str" + node.getFunctionName());
      }
    }
 else     if (value instanceof FunctionToken) {
      FunctionToken function=(FunctionToken)value;
      if (function.getNumberOfArguments() != argCount) {
        throw new IllegalActionException("String_Node_Str" + "String_Node_Str" + value.toString());
      }
      result=function.apply(argValues);
    }
 else {
      throw new IllegalActionException("String_Node_Str" + value.toString());
    }
    _evaluatedChildToken=(result);
    return;
  }
  if (node.getFunctionName().compareTo("String_Node_Str") == 0) {
    if (argCount == 1) {
      ptolemy.data.Token token=argValues[0];
      if (token instanceof StringToken) {
        PtParser parser=new PtParser();
        ASTPtRootNode tree=parser.generateParseTree(((StringToken)token).stringValue());
        tree.visit(this);
        return;
      }
    }
    throw new IllegalActionException("String_Node_Str" + "String_Node_Str" + "String_Node_Str");
  }
  if (node.getFunctionName().compareTo("String_Node_Str") == 0) {
    if (argCount == 1) {
      ptolemy.data.Token token=argValues[0];
      if (token instanceof StringToken) {
        String expression=((StringToken)token).stringValue();
        ParseTreeFreeVariableCollector collector=new ParseTreeFreeVariableCollector();
        Set freeVariables=collector.collectFreeVariables(node,_scope);
        _evaluatedChildToken=MatlabUtilities.evaluate(expression,freeVariables,_scope);
        return;
      }
    }
 else {
      throw new IllegalActionException("String_Node_Str" + "String_Node_Str" + "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str");
    }
  }
  ptolemy.data.Token result=_functionCall(node.getFunctionName(),argTypes,argValues);
  _evaluatedChildToken=(result);
}