Archived
1

Added the MPExpressionTree Classes

This commit is contained in:
Kim Wittenburg
2014-10-13 23:53:04 +02:00
parent 82259f87e2
commit 5592128926
60 changed files with 1981 additions and 725 deletions

View File

@@ -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