// // 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" #define ReturnIfNil(test) if(test == nil) return nil @implementation MPSumFunction + (NSString *)localizedFunctionName { return NSLocalizedString(@"Sum", @"Name of Sum Function"); } #pragma mark Creation Methods - (instancetype)init { self = [super init]; if (self) { _startExpression = [[MPExpression alloc] init]; _startExpression.parent = self; _targetExpression = [[MPExpression alloc] init]; _targetExpression.parent = self; _sumExpression = [[MPExpression alloc] init]; _sumExpression.parent = self; } return self; } #pragma mark Properties - (void)setStartExpression:(MPExpression *)startExpression { _startExpression.parent = nil; _startExpression = startExpression; _startExpression.parent = self; [self didChangeChildAtIndex:0]; } - (void)setTargetExpression:(MPExpression *)targetExpression { _targetExpression.parent = nil; _targetExpression = targetExpression; _targetExpression.parent = self; [self didChangeChildAtIndex:1]; } - (void)setSumExpression:(MPExpression *)sumExpression { _sumExpression.parent = nil; _sumExpression = sumExpression; _sumExpression.parent = self; [self didChangeChildAtIndex:2]; } #pragma mark Working With the Expression Tree - (NSUInteger)numberOfChildren { return 3; } - (MPExpression *)childAtIndex:(NSUInteger)index { switch (index) { case 0: return self.startExpression; case 1: return self.targetExpression; case 2: return self.sumExpression; default: return nil; } } - (void)setChild:(MPExpression *)child atIndex:(NSUInteger)index { switch (index) { // TODO: Copy child? case 0: self.startExpression = child; break; case 1: self.targetExpression = child; break; case 2: self.sumExpression = child; break; default: return; } [self didChangeChildAtIndex:index]; } - (NSArray *)children { return @[self.startExpression, self.targetExpression, self.sumExpression]; } #pragma mark Evaluating Functions - (MPTerm *)parseWithError:(MPParseError *__autoreleasing *)error { MPExpressionEvaluator *startEvaluator = self.startExpression.evaluator; MPTerm *start = [startEvaluator parseExpectingVariable:YES error:error]; ReturnIfNil(start); MPExpressionEvaluator *targetEvaluator = self.targetExpression.evaluator; 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 = self.sumExpression.evaluator; 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]; } - (NSUInteger)hash { #warning Unimplemented Method return [super hash]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { MPSumFunction *copy = [[MPSumFunction allocWithZone:zone] init]; copy.startExpression = [self.startExpression copy]; copy.targetExpression = [self.targetExpression copy]; copy.sumExpression = [self.sumExpression copy]; return copy; } @end