// // MPProduct.m // MathPad // // Created by Kim Wittenburg on 09.10.14. // Copyright (c) 2014 Kim Wittenburg. All rights reserved. // #import "MPProduct.h" #import "MPFactor.h" #import "MPValueGroup.h" #import "MPTokenStream.h" #import "MPToken.h" #import "MPExpression.h" @implementation MPProduct { NSMutableArray *_factors; } - (id)init { self = [super init]; if (self) { _factors = [[NSMutableArray alloc] init]; } return self; } - (instancetype)initWithTokenStream:(MPTokenStream *)tokenStream { self = [self init]; if (self) { [tokenStream beginIgnoringWhitespaceTokens]; while ([tokenStream hasMoreTokens] && tokenStream.currentToken.tokenType != MPOperatorListToken) { [_factors addObject:[[MPFactor alloc] initWithTokenStream:tokenStream]]; } [tokenStream endIgnoringOrAcceptingWhitespaceTokens]; } return self; } - (NSArray *)factors { return _factors; } - (BOOL)validate:(NSError *__autoreleasing *)error { if (_factors.count == 0) { if (error) { *error = MPParseError(5, NSLocalizedString(@"Expected A Value.", @"Error message. Displayed when a value was expected in an expression but none was found."), nil); } return NO; } MPFactor *factor = _factors[0]; if (factor.hasMultiplicationSymbol) { if (error) { *error = MPParseError(6, NSLocalizedString(@"Unexpected Symbol.", @"Error message. Displayed when or inappropriate symbol was encountered during parsing."), nil); } return NO; } if (![factor.value validate:error]) { return NO; } for (NSUInteger index = 1; index < _factors.count; index++) { factor = _factors[index]; if (![factor validate:error]) { return NO; } } return YES; } - (NSDecimalNumber *)evaluate { NSDecimalNumber *value = [NSDecimalNumber one]; for (MPFactor *factor in _factors) { NSDecimalNumber *currentValue = [factor evaluate]; if ([currentValue isEqualToNumber:[NSDecimalNumber notANumber]]) { value = currentValue; break; } value = [value decimalNumberByMultiplyingBy:currentValue]; if ([value compare:@(0)] == NSOrderedSame) { break; } } return value; } @end