use of org.cytoscape.equations.Function in project cytoscape-impl by cytoscape.
the class EquationParserImpl method parseFunctionCall.
/**
* Implements func_call --> ident "(" ")" | ident "(" expr {"," expr} ")".
*/
private AbstractNode parseFunctionCall() {
Token token = tokeniser.getToken();
final int functionNameStartPos = tokeniser.getStartPos();
if (token != Token.IDENTIFIER)
throw new IllegalStateException(functionNameStartPos + ": function name expected.");
final String originalName = tokeniser.getIdent();
final String functionNameCandidate = originalName.toUpperCase();
if (functionNameCandidate.equals("DEFINED"))
return parseDefined();
final Function func = nameToFunctionMap.get(functionNameCandidate);
if (func == null) {
if (tokeniser.getToken() == Token.OPEN_PAREN)
throw new IllegalStateException(functionNameStartPos + ": call to unknown function " + originalName + "().");
else
throw new IllegalStateException(functionNameStartPos + ": unknown text \"" + originalName + "\", maybe you forgot to put quotes around this text?");
}
token = tokeniser.getToken();
final int openParenPos = tokeniser.getStartPos();
if (token != Token.OPEN_PAREN)
throw new IllegalStateException(openParenPos + ": expected '(' after function name \"" + functionNameCandidate + "\".");
// Parse the comma-separated argument list.
final ArrayList<Class<?>> argTypes = new ArrayList<Class<?>>();
ArrayList<AbstractNode> args = new ArrayList<AbstractNode>();
int sourceLocation;
for (; ; ) {
token = tokeniser.getToken();
sourceLocation = tokeniser.getStartPos();
if (token == Token.CLOSE_PAREN)
break;
tokeniser.ungetToken(token);
final AbstractNode exprNode = parseExpr();
argTypes.add(exprNode.getType());
args.add(exprNode);
token = tokeniser.getToken();
sourceLocation = tokeniser.getStartPos();
if (token != Token.COMMA)
break;
}
final Class<?> returnType = func.validateArgTypes(argTypes.toArray(new Class<?>[argTypes.size()]));
if (returnType == null)
throw new IllegalStateException((openParenPos + 1) + ": invalid number or type of arguments in call to " + functionNameCandidate + "().");
if (token != Token.CLOSE_PAREN)
throw new IllegalStateException(sourceLocation + ": expected the closing parenthesis of a call to " + functionNameCandidate + ".");
AbstractNode[] nodeArray = new AbstractNode[args.size()];
return new FuncCallNode(functionNameStartPos, func, returnType, args.toArray(nodeArray));
}
use of org.cytoscape.equations.Function in project cytoscape-impl by cytoscape.
the class InterpreterImpl method call.
private void call() throws EmptyStackException, IllegalStateException, FunctionError {
// 1. get the function
final Object o = argumentStack.pop();
if (!(o instanceof Function))
throw new IllegalStateException("expected a column function after the CALL opcode but found \"" + o.getClass() + "\" instead.");
final Function func = (Function) o;
// 2. get and validate the argument count
final int argCount;
try {
argCount = (Integer) argumentStack.pop();
} catch (final Exception e) {
throw new IllegalStateException("invalid argument count type following a CALL opcode.");
}
final int MIN_ARG_COUNT = 0;
// This is an arbitrary limit and exists only to find bugs.
final int MAX_ARG_COUNT = 100;
// Should it prove to be too low we could easily make it much bigger.
if (argCount < MIN_ARG_COUNT || argCount > MAX_ARG_COUNT)
throw new IllegalStateException("invalid argument count type following a CALL opcode (range must be in [" + MIN_ARG_COUNT + ", " + MAX_ARG_COUNT + "]).");
// 3. collect the actual arguments
final Object[] args = new Object[argCount];
for (int argNo = 0; argNo < argCount; ++argNo) args[argNo] = argumentStack.pop();
// 4. now actually call the function
argumentStack.push(func.evaluateFunction(args));
}
use of org.cytoscape.equations.Function in project cytoscape-impl by cytoscape.
the class FormulaBuilderDialog method initComponents.
private void initComponents() {
final JLabel fnIconLabel = new JLabel("f(x)");
Font iconFont = null;
try {
iconFont = Font.createFont(Font.TRUETYPE_FONT, getClass().getResourceAsStream("/fonts/jsMath-cmti10.ttf"));
iconFont = iconFont.deriveFont(36.0f);
fnIconLabel.setFont(iconFont);
} catch (Exception e) {
throw new RuntimeException("Error loading font", e);
}
final JPanel buttonPanel = LookAndFeelUtil.createOkCancelPanel(getOkButton(), getCancelButton(), "Column_Data_Functions_and_Equations");
final JPanel contents = new JPanel();
final GroupLayout layout = new GroupLayout(contents);
contents.setLayout(layout);
layout.setAutoCreateContainerGaps(true);
layout.setAutoCreateGaps(true);
layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING, true).addComponent(getFunctionPanel(), DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE).addGroup(layout.createSequentialGroup().addComponent(fnIconLabel, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE).addComponent(getFormulaTextField(), 380, 520, Short.MAX_VALUE)).addComponent(getApplyToPanel(), DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE).addComponent(buttonPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE));
layout.setVerticalGroup(layout.createSequentialGroup().addComponent(getFunctionPanel()).addGroup(layout.createParallelGroup(Alignment.CENTER, false).addComponent(fnIconLabel, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE).addComponent(getFormulaTextField(), 60, 60, Short.MAX_VALUE)).addComponent(getApplyToPanel()).addComponent(buttonPanel));
getContentPane().add(contents);
LookAndFeelUtil.setDefaultOkCancelKeyStrokes(getRootPane(), getOkButton().getAction(), getCancelButton().getAction());
getRootPane().setDefaultButton(getOkButton());
pack();
setResizable(false);
if (((DefaultListModel<Function>) getFunctionList().getModel()).size() > 0)
getFunctionList().setSelectedIndex(0);
}
use of org.cytoscape.equations.Function in project cytoscape-impl by cytoscape.
the class FormulaBuilderDialog method getFunctionList.
private JList<Function> getFunctionList() {
if (functionList == null) {
DefaultListModel<Function> model = new DefaultListModel<>();
functionList = new JList<>(model);
functionList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
functionList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
functionSelected();
}
});
functionList.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
final Function fn = (Function) value;
this.setText(fn.getName());
this.setToolTipText(fn.getFunctionSummary());
return this;
}
});
final EquationParser parser = compiler.getParser();
final List<Function> functions = new ArrayList<>(parser.getRegisteredFunctions());
final Collator collator = Collator.getInstance(Locale.getDefault());
Collections.sort(functions, new Comparator<Function>() {
@Override
public int compare(Function f1, Function f2) {
return collator.compare(f1.getName(), f2.getName());
}
});
final Class<?> requestedReturnType = getAttributeType(targetAttrName);
int index = 0;
for (final Function fn : functions) {
if (returnTypeIsCompatible(requestedReturnType, fn.getReturnType()))
model.add(index++, fn);
}
}
return functionList;
}
use of org.cytoscape.equations.Function in project cytoscape-impl by cytoscape.
the class InterpreterTest method testFunctionWithBadRuntimeReturnType.
@Test
public void testFunctionWithBadRuntimeReturnType() throws Exception {
final Function badReturnFunction = new BadReturnFunction();
if (// Avoid duplicate registration!
parser.getFunction(badReturnFunction.getName()) == null)
parser.registerFunctionInternal(badReturnFunction);
final Map<String, Class<?>> attribNameToTypeMap = new HashMap<String, Class<?>>();
assertTrue(compiler.compile("=BAD()", attribNameToTypeMap));
final Map<String, IdentDescriptor> nameToDescriptorMap = new HashMap<String, IdentDescriptor>();
try {
interpreter.execute(compiler.getEquation(), nameToDescriptorMap);
} catch (final IllegalStateException e) {
// If we get here, everything is as expected and we let the test pass!
}
}
Aggregations