// // MPSumFunction.m // MathPad // // Created by Kim Wittenburg on 22.04.14. // Copyright (c) 2014 Kim Wittenburg. All rights reserved. // #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) MPFunctionAccessorImplementation(TargetExpression, _targetExpression) MPFunctionAccessorImplementation(SumExpression, _sumExpression) - (NSArray *)childrenAccessors { return @[@"startExpression", @"targetExpression", @"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); NSString *variable = startEvaluator.definedVariable.copy; [[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] 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; }]; } #pragma mark Working With Functions /* - (BOOL)isEqualToFunction:(MPFunction *)aFunction { if (![aFunction isKindOfClass:[MPSumFunction class]]) { return NO; } MPSumFunction *sumFunction = (MPSumFunction *)aFunction; if (![self.startExpression isEqualToExpression:sumFunction.startExpression]) { return NO; } if (![self.targetExpression isEqualToExpression:sumFunction.targetExpression]) { return NO; } return [self.sumExpression isEqualToExpression:sumFunction.sumExpression]; }*/ - (NSString *)description { return [NSString stringWithFormat:@"Sum(From: %@; To: %@; Using: %@)", self.startExpression, self.targetExpression, self.sumExpression]; } @end