-
Notifications
You must be signed in to change notification settings - Fork 153
Custom Functions
By default, DDMathParser will automatically recognize any "identifier" as a function, even if no such function is defined. For example, the following will happily become an Expression with no complaints:
let e = try Expression(string: "foo() + bar() - baz() * bip()")
Of course, this will fail to evaluate, unless you define what the foo, bar, baz, and bip functions are.
Custom functions are defined on Evaluator instances. A custom function has a set of names and a closure to perform the evaluation:
let foo = Function(name: "foo", evaluator: { (arguments: Array<Expression>, substitutions: Substitutions, evaluator: Evaluator) throws -> Double
...
})
The closure takes three arguments:
- The arguments to the function, as un-evaluated
Expressionobjects - Any substitutions for variable values
- The
Evaluatorperforming the evaluation. You should always prefer to use thisEvaluatorwithin the closure, rather than capturing the externalEvaluatorinstance within the closure.
When the function is evaluated, you'll either return a Double if the expression can be correctly evaluated, or throw if a critical error is encountered (such as the incorrect number of arguments, attempting to divide by zero, etc). The thrown error can be either the appropriate EvaluationError or a custom ErrorType of your own making.
After this, all you need to do is register the function with your Evaluator:
var evaluator = Evaluator()
try evaluator.registerFunction(foo)
Registering a function may throw an error if any of the names of the function collides with the name of any existing function.
Some function names are really long, like hacovercosin. You can use the registerAlias(_:forFunctionName:) method on Evaluator to define new ways of recognizing functions. For example:
var evaluator = Evaluator()
try evaluator.registerAlias("hcvcs", forFunctionName: "hacovercosin")
Now this Evaluator would be able to evaluate hcvcs(42). This operation would throw an error if either hcvcs is already in use by another function, or there is no such function hacovercosin.