I am new to programming. I want to add some new functions such as derivatives and integrations to ddmathparser
. The only one I can find is the short tutorial on ddmathparser
's wiki page https://github.com/davedelong/DDMathParser/wiki/Adding-New-Functions . However, I can't follow it because it's too short and after reading it several times, I still can't understand what it's doing. So can anyone elaborate steps to add a new function or give me some more detailed tutorials of doing this?
I really did my research but I can't find one. Thanks very much.
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
DDMathParser author here.
Here's how you add a multiply by two
function:
DDMathEvaluator *evaluator = [DDMathEvaluator sharedMathEvaluator];
// a function takes arguments, variable values, the evaluator, and an error pointer
// and returns a new expression
[evaluator registerFunction:^DDExpression *(NSArray *args, NSDictionary *vars, DDMathEvaluator *eval, NSError *__autoreleasing *error) {
DDExpression *final = nil;
// multiplyBy2() can only handle a single argument
if ([args count] == 1) {
// get the argument and simply wrap it in a "multiply()" function
DDExpression *argExpression = [args objectAtIndex:0];
DDExpression *twoExpression = [DDExpression numberExpressionWithNumber:@2];
final = [DDExpression functionExpressionWithFunction:DDOperatorMultiply arguments:@[argExpression, twoExpression] error:nil];
} else if (error) {
// there wasn't only one argument
NSString *description = [NSString stringWithFormat:@"multiplyBy2() requires 1 argument. %ld were given", [args count]];
*error = [NSError errorWithDomain:DDMathParserErrorDomain code:DDErrorCodeInvalidNumberOfArguments userInfo:@{NSLocalizedDescriptionKey: description}];
}
return final;
} forName:@"multiplyBy2"];
Now you can do:
NSNumber *result = [@"multiplyBy2(21)" stringByEvaluatingString];
and get back @42
.
What's going on here:
Internally, DDMathEvaluator
essentially has a big NSDictionary
where it keeps a list of all the functions it knows about, keyed off the name of that function, kind of like this:
_functions = @{
@"multiply" : multiplyFunctionBlock,
@"add" : addFunctionBlock,
...
};
(Obviously it's a bit more complicated than that, but that's the basic idea)
When the evaluator evaluates a string and comes across the a function, it looks up in this dictionary what the block for the function is. It retrieves the block, and then executes the block with the arguments (if there are any) from the string. The result of the block is the result of the function.
That result gets substituted back in, and evaluation continues.