Archived
1

Improved Evaluation

This commit is contained in:
Kim Wittenburg
2014-09-28 23:51:01 +02:00
parent d67a1949e9
commit 1c8b7e3c12

View File

@@ -12,8 +12,15 @@
#import "MPExpressionEvaluator.h" #import "MPExpressionEvaluator.h"
#import "MPEvaluationContext.h" #import "MPEvaluationContext.h"
#define ReturnIfNil(test) if(test == nil) return nil
@implementation MPSumFunction @implementation MPSumFunction
+ (NSString *)localizedFunctionName
{
return NSLocalizedString(@"Sum", @"Name of Sum Function");
}
#pragma mark Creation Methods #pragma mark Creation Methods
- (instancetype)init - (instancetype)init
{ {
@@ -100,35 +107,42 @@
} }
#pragma mark Evaluating Functions #pragma mark Evaluating Functions
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error - (MPTerm *)parseWithError:(MPParseError *__autoreleasing *)error
{ {
MPExpressionEvaluator *startEvaluator = self.startExpression.evaluator; MPExpressionEvaluator *startEvaluator = self.startExpression.evaluator;
NSDecimalNumber *start = [startEvaluator evaluateVariableDefinition:YES error:error]; MPTerm *start = [startEvaluator parseExpectingVariable:YES
if (!start) { error:error];
return nil; ReturnIfNil(start);
}
NSDecimalNumber *target = [self.targetExpression evaluateWithError:error]; MPExpressionEvaluator *targetEvaluator = self.targetExpression.evaluator;
if (!target) { MPTerm *target = [targetEvaluator parseExpectingVariable:NO
return nil; error:error];
} ReturnIfNil(target);
NSString *variable = startEvaluator.definedVariable.copy;
[[MPEvaluationContext sharedContext] push]; [[MPEvaluationContext sharedContext] push];
[[MPEvaluationContext sharedContext] defineVariable:variable withValue:[NSNull null]];
MPExpressionEvaluator *sumEvaluator = self.sumExpression.evaluator; MPExpressionEvaluator *sumEvaluator = self.sumExpression.evaluator;
NSDecimalNumber *value = [NSDecimalNumber zero]; MPTerm *sum = [sumEvaluator parseExpectingVariable:NO
for (NSDecimalNumber *iterator = start; [iterator compare:target] <= 0; iterator = [iterator decimalNumberByAdding:[[NSDecimalNumber alloc] initWithInteger:1]]) { error:error];
[[MPEvaluationContext sharedContext] bindValue:iterator toName:startEvaluator.definedVariable]; ReturnIfNil(sum);
NSDecimalNumber *summand = [sumEvaluator evaluateWithError:error];
if (summand) {
value = [value decimalNumberByAdding:summand];
} else {
return nil;
}
}
[[MPEvaluationContext sharedContext] pop]; [[MPEvaluationContext sharedContext] pop];
return [[MPTerm alloc] initWithBlock:^NSDecimalNumber *{
[[MPEvaluationContext sharedContext] push];
NSDecimalNumber *value = [NSDecimalNumber zero];
NSDecimalNumber *startValue = [start evaluate];
NSDecimalNumber *targetValue = [target evaluate];
for (NSDecimalNumber *iterator = startValue;
[iterator compare:targetValue] <= 0 ;
iterator = [iterator decimalNumberByAdding:[[NSDecimalNumber alloc] initWithInteger:1]]) {
[[MPEvaluationContext sharedContext] defineVariable:variable withValue:iterator];
value = [value decimalNumberByAdding:[sum evaluate]];
}
[[MPEvaluationContext sharedContext] pop];
return value; return value;
}];
} }
#pragma mark Working With Functions #pragma mark Working With Functions