Program: 74427
Project: 74427
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 ((functionName != null) && (_scope != null)) {
    value=_scope.get(functionName);
  }
  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) {
    _evaluateChild(node,1);
    ptolemy.data.Token token=_evaluatedChildToken;
    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");
    }
  }
  if (node.getFunctionName().compareTo("String_Node_Str") == 0) {
    if (argCount == 3) {
      if (argValues[0] instanceof FunctionToken) {
        FunctionToken function=(FunctionToken)argValues[0];
        if (((FunctionType)function.getType()).getArgCount() != 2) {
          throw new IllegalActionException("String_Node_Str" + "String_Node_Str" + "String_Node_Str");
        }
        ptolemy.data.Token current=argValues[1];
        if (argValues[2] instanceof ArrayToken) {
          ArrayToken array=(ArrayToken)argValues[2];
          for (int i=0; i < array.length(); i++) {
            current=function.apply(new ptolemy.data.Token[]{current,array.getElement(i)});
          }
          _evaluatedChildToken=current;
          return;
        }
 else         if (argValues[2] instanceof ObjectToken) {
          Object object=((ObjectToken)argValues[2]).getValue();
          if (object.getClass().isArray()) {
            Object[] array=(Object[])object;
            for (int i=0; i < array.length; i++) {
              Object second=array[i];
              if (!(second instanceof ptolemy.data.Token)) {
                second=ConversionUtilities.convertJavaTypeToToken(second);
              }
              current=function.apply(new ptolemy.data.Token[]{current,(ptolemy.data.Token)second});
            }
            _evaluatedChildToken=current;
            return;
          }
 else           if (object instanceof Iterable) {
            Iterator iterator=((Iterable)object).iterator();
            while (iterator.hasNext()) {
              Object second=iterator.next();
              if (!(second instanceof ptolemy.data.Token)) {
                second=ConversionUtilities.convertJavaTypeToToken(second);
              }
              current=function.apply(new ptolemy.data.Token[]{current,(ptolemy.data.Token)second});
            }
            _evaluatedChildToken=current;
            return;
          }
        }
      }
    }
    throw new IllegalActionException("String_Node_Str" + "String_Node_Str" + "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str");
  }
  if (functionName.equals("String_Node_Str") && argCount == 1) {
    ASTPtRootNode classNameNode=((ASTPtRootNode)node.jjtGetChild(1));
    if (classNameNode instanceof ASTPtLeafNode) {
      ptolemy.data.Token token=((ASTPtLeafNode)classNameNode).getToken();
      if (token != null && token instanceof StringToken) {
        String className=((StringToken)token).stringValue();
        _evaluatedChildToken=ObjectToken.object(className);
        return;
      }
    }
  }
  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;
  ptolemy.data.Token scopedValue=null;
  String functionName=node.getFunctionName();
  if ((functionName != null) && (_scope != null)) {
    scopedValue=_scope.get(functionName);
    if (!(scopedValue instanceof ObjectToken)) {
      value=scopedValue;
    }
  }
  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) {
    _evaluateChild(node,1);
    ptolemy.data.Token token=_evaluatedChildToken;
    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");
    }
  }
  if (node.getFunctionName().compareTo("String_Node_Str") == 0) {
    if (argCount == 3) {
      if (argValues[0] instanceof FunctionToken) {
        FunctionToken function=(FunctionToken)argValues[0];
        if (((FunctionType)function.getType()).getArgCount() != 2) {
          throw new IllegalActionException("String_Node_Str" + "String_Node_Str" + "String_Node_Str");
        }
        ptolemy.data.Token current=argValues[1];
        if (argValues[2] instanceof ArrayToken) {
          ArrayToken array=(ArrayToken)argValues[2];
          for (int i=0; i < array.length(); i++) {
            current=function.apply(new ptolemy.data.Token[]{current,array.getElement(i)});
          }
          _evaluatedChildToken=current;
          return;
        }
 else         if (argValues[2] instanceof ObjectToken) {
          Object object=((ObjectToken)argValues[2]).getValue();
          if (object.getClass().isArray()) {
            Object[] array=(Object[])object;
            for (int i=0; i < array.length; i++) {
              Object second=array[i];
              if (!(second instanceof ptolemy.data.Token)) {
                second=ConversionUtilities.convertJavaTypeToToken(second);
              }
              current=function.apply(new ptolemy.data.Token[]{current,(ptolemy.data.Token)second});
            }
            _evaluatedChildToken=current;
            return;
          }
 else           if (object instanceof Iterable) {
            Iterator iterator=((Iterable)object).iterator();
            while (iterator.hasNext()) {
              Object second=iterator.next();
              if (!(second instanceof ptolemy.data.Token)) {
                second=ConversionUtilities.convertJavaTypeToToken(second);
              }
              current=function.apply(new ptolemy.data.Token[]{current,(ptolemy.data.Token)second});
            }
            _evaluatedChildToken=current;
            return;
          }
        }
      }
    }
    throw new IllegalActionException("String_Node_Str" + "String_Node_Str" + "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str");
  }
  if (functionName.equals("String_Node_Str") && argCount == 1) {
    ASTPtRootNode classNameNode=((ASTPtRootNode)node.jjtGetChild(1));
    if (classNameNode instanceof ASTPtLeafNode) {
      ptolemy.data.Token token=((ASTPtLeafNode)classNameNode).getToken();
      if (token != null && token instanceof StringToken) {
        String className=((StringToken)token).stringValue();
        _evaluatedChildToken=ObjectToken.object(className);
        return;
      }
    }
  }
  ptolemy.data.Token result=_functionCall(node.getFunctionName(),argTypes,argValues);
  if (result == null && scopedValue instanceof ObjectToken) {
    result=scopedValue;
  }
  _evaluatedChildToken=(result);
}