// // 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" @implementation MPSumFunction #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 - (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error { MPExpressionEvaluator *startEvaluator = self.startExpression.evaluator; NSDecimalNumber *start = [startEvaluator evaluateVariableDefinition:YES error:error]; if (!start) { return nil; } NSDecimalNumber *target = [self.targetExpression evaluateWithError:error]; if (!target) { return nil; } [[MPEvaluationContext sharedContext] push]; MPExpressionEvaluator *sumEvaluator = self.sumExpression.evaluator; NSDecimalNumber *value = [NSDecimalNumber zero]; for (NSDecimalNumber *iterator = start; [iterator compare:target] <= 0; iterator = [iterator decimalNumberByAdding:[[NSDecimalNumber alloc] initWithInteger:1]]) { [[MPEvaluationContext sharedContext] bindValue:iterator toName:startEvaluator.definedVariable]; NSDecimalNumber *summand = [sumEvaluator evaluateWithError:error]; if (summand) { value = [value decimalNumberByAdding:summand]; } else { return nil; } } [[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