// // MPProduct.m // MathPad // // Created by Kim Wittenburg on 09.10.14. // Copyright (c) 2014 Kim Wittenburg. All rights reserved. // #import "MPProduct.h" #import "MPValueGroup.h" @implementation MPProduct { NSMutableArray *_factors; NSRange _range; } - (id)init { self = [super init]; if (self) { _factors = [[NSMutableArray alloc] init]; } return self; } - (instancetype)initWithTokenStream:(MPTokenStream *)tokenStream { self = [self init]; if (self) { [tokenStream beginIgnoringWhitespaceTokens]; MPTokenStreamRecordCurrentLocation(tokenStream); while (tokenStream.currentToken.tokenType != MPOperatorListToken && tokenStream.currentToken.tokenType != MPEOFToken) { [_factors addObject:[[MPFactor alloc] initWithTokenStream:tokenStream]]; } _range = MPTokenStreamRecordedRange(tokenStream); [tokenStream endIgnoringOrAcceptingWhitespaceTokens]; } return self; } - (NSRange)range { return _range; } - (BOOL)validate:(MPParseError *__autoreleasing *)error { if (_factors.count == 0) { if (error) { *error = MPParseError(_range, @"Expected Value"); } return NO; } MPFactor *factor = _factors[0]; if (factor.hasMultiplicationSymbol) { if (error) { *error = MPParseError(factor.multiplicationSymbolRange, @"Unexpected Symbol."); } 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; } - (NSArray *)expressionElements { NSMutableArray *elements = [[NSMutableArray alloc] init]; for (MPFactor *factor in _factors) { [elements addObjectsFromArray:factor.expressionElements]; } return elements; } - (NSArray *)factors { return _factors; } - (void)appendFactor:(MPFactor *)factor { [_factors addObject:factor]; } - (void)insertFactor:(MPFactor *)factor atIndex:(NSUInteger)index { [_factors insertObject:factor atIndex:index]; } - (void)removeFactor:(MPFactor *)factor { [_factors removeObject:factor]; } - (void)removeFactorAtIndex:(NSUInteger)index { [_factors removeObjectAtIndex:index]; } - (MPFactor *)factorAtIndex:(NSUInteger)index { return [_factors objectAtIndex:index]; } @end