Added the MPExpressionTree Classes
This commit is contained in:
@@ -9,12 +9,8 @@
|
||||
#import "MPSumFunction.h"
|
||||
#import "MPExpression.h"
|
||||
|
||||
#import "MPExpressionEvaluator.h"
|
||||
#import "MPEvaluationContext.h"
|
||||
|
||||
// TODO: Use this macro elsewhere
|
||||
#define ReturnIfNil(test) if(test == nil) return nil
|
||||
|
||||
@implementation MPSumFunction
|
||||
|
||||
MPFunctionAccessorImplementation(StartExpression, _startExpression)
|
||||
@@ -27,42 +23,47 @@ MPFunctionAccessorImplementation(SumExpression, _sumExpression)
|
||||
}
|
||||
|
||||
#pragma mark Evaluating Functions
|
||||
- (MPTerm *)parseWithError:(MPParseError *__autoreleasing *)error
|
||||
{
|
||||
MPExpressionEvaluator *startEvaluator = [[MPExpressionEvaluator alloc] initWithExpression:self.startExpression];
|
||||
MPTerm *start = [startEvaluator parseExpectingVariable:YES
|
||||
error:error];
|
||||
ReturnIfNil(start);
|
||||
|
||||
MPExpressionEvaluator *targetEvaluator = [[MPExpressionEvaluator alloc] initWithExpression:self.targetExpression];
|
||||
MPTerm *target = [targetEvaluator parseExpectingVariable:NO
|
||||
error:error];
|
||||
ReturnIfNil(target);
|
||||
- (BOOL)validate:(MPParseError *__autoreleasing *)error
|
||||
{
|
||||
MPExpressionTree *startTree = [self.startExpression parse];
|
||||
if (![startTree validateExpectingVariableDefinition:YES error:error]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSString *variable = startEvaluator.definedVariable.copy;
|
||||
MPExpressionTree *targetTree = [self.targetExpression parse];
|
||||
if (![targetTree validate:error]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
[[MPEvaluationContext sharedContext] push];
|
||||
[[MPEvaluationContext sharedContext] defineVariable:variable withValue:[NSNull null]];
|
||||
MPExpressionEvaluator *sumEvaluator = [[MPExpressionEvaluator alloc] initWithExpression:self.sumExpression];
|
||||
MPTerm *sum = [sumEvaluator parseExpectingVariable:NO
|
||||
error:error];
|
||||
ReturnIfNil(sum);
|
||||
[[MPEvaluationContext sharedContext] defineVariable:startTree.definedVariable withValue:[NSDecimalNumber notANumber]];
|
||||
MPExpressionTree *sumTree = [self.sumExpression parse];
|
||||
if (![sumTree validate:error]) {
|
||||
return NO;
|
||||
}
|
||||
[[MPEvaluationContext sharedContext] pop];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSDecimalNumber *)evaluate
|
||||
{
|
||||
MPExpressionTree *startTree = [self.startExpression parse];
|
||||
NSDecimalNumber *start = [startTree evaluate];
|
||||
NSDecimalNumber *target = [[self.targetExpression parse] evaluate];
|
||||
MPExpressionTree *sumTree = [self.sumExpression parse];
|
||||
|
||||
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;
|
||||
}];
|
||||
NSDecimalNumber *value = [NSDecimalNumber zero];
|
||||
|
||||
[[MPEvaluationContext sharedContext] push];
|
||||
for (NSDecimalNumber *current = start;
|
||||
[current compare:target] <= 0;
|
||||
current = [current decimalNumberByAdding:[[NSDecimalNumber alloc] initWithInteger:1]]) {
|
||||
[[MPEvaluationContext sharedContext] defineVariable:startTree.definedVariable withValue:current];
|
||||
value = [value decimalNumberByAdding:[sumTree evaluate]];
|
||||
}
|
||||
[[MPEvaluationContext sharedContext] pop];
|
||||
return value;
|
||||
}
|
||||
|
||||
#pragma mark Working With Functions
|
||||
|
||||
Reference in New Issue
Block a user