1 package de.congrace.exp4j;
3 import java.util.ArrayList;
4 import java.util.Collections;
7 import java.util.Stack;
9 import de.congrace.exp4j.FunctionToken.Function;
12 * this classed is used to create custom functions for exp4j<br/>
16 * CustomFunction fooFunc = new CustomFunction("foo") {
17 * public double applyFunction(double value) {
18 * return value*Math.E;
22 * Calculable calc = new ExpressionBuilder("foo(x)").withCustomFunction(fooFunc).withVariable("x",varX).build();
23 * assertTrue(calc.calculate() == Math.E * varX);
29 public abstract class CustomFunction extends CalculationToken {
33 * create a new single value input CustomFunction with a set name
36 * the name of the function (e.g. foo)
38 protected CustomFunction(String value) throws InvalidCustomFunctionException{
40 for (Function f:Function.values()) {
41 if (value.equalsIgnoreCase(f.toString())){
42 throw new InvalidCustomFunctionException(value + " is already reserved as a function name");
48 * create a new single value input CustomFunction with a set name
51 * the name of the function (e.g. foo)
53 protected CustomFunction(String value,int argumentCount) throws InvalidCustomFunctionException{
55 this.argc=argumentCount;
56 for (Function f:Function.values()) {
57 if (value.equalsIgnoreCase(f.toString())){
58 throw new InvalidCustomFunctionException(value + " is already reserved as a function name");
64 * apply the function to a value
67 * the values to which the function should be applied.
68 * @return the function value
70 public abstract Variable applyFunction(List<Variable> vars);
73 void mutateStackForCalculation(Stack<Variable> stack, VariableSet variables) {
74 List<Variable> args = new ArrayList<Variable>(argc);
75 for (int i=0; i < argc; i++) {
76 args.add(i, stack.pop() );
78 Collections.reverse(args); // Put elements in logical order
80 stack.push(this.applyFunction(args));
84 void mutateStackForInfixTranslation(Stack<Token> operatorStack, StringBuilder output) {
85 operatorStack.push(this);
87 public int getArgumentCount() {