109 lines
3.5 KiB
Objective-C
109 lines
3.5 KiB
Objective-C
//
|
|
// MPExpressionEvaluator.m
|
|
// MathPad
|
|
//
|
|
// Created by Kim Wittenburg on 31.08.14.
|
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
|
//
|
|
|
|
#import "MPExpressionEvaluator.h"
|
|
#import "MPExpression.h"
|
|
#import "MPFunction.h"
|
|
#import "MPParsedFactor.h"
|
|
#import "MPFunction+MPParsedFactor.h"
|
|
|
|
@interface MPExpressionEvaluator ()
|
|
@property (readwrite, nonatomic, strong) NSString *definedVariable;
|
|
|
|
@end
|
|
|
|
@implementation MPExpressionEvaluator {
|
|
MPElementParser *parser;
|
|
}
|
|
- (id)initWithExpression:(MPExpression *)expression
|
|
{
|
|
self = [super init];
|
|
if (self) {
|
|
_expression = expression;
|
|
parser = [[MPElementParser alloc] init];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
#pragma mark Evaluating Expressions
|
|
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error
|
|
{
|
|
return [self evaluateVariableDefinition:NO error:error];
|
|
}
|
|
|
|
- (NSDecimalNumber *)evaluateVariableDefinition:(BOOL)flag error:(MPParseError *__autoreleasing *)error
|
|
{
|
|
// Empty Expression
|
|
if (self.expression.numberOfElements == 0) {
|
|
*error = MPParseError(NSMakeRange(0, 0), @"Expected Expression");
|
|
return nil;
|
|
}
|
|
|
|
NSMutableArray *products = [[NSMutableArray alloc] init];
|
|
MPParsedProduct *currentProduct = nil;
|
|
|
|
for (NSUInteger elementIndex = 0; elementIndex < self.expression.numberOfElements; elementIndex++) {
|
|
|
|
id<MPExpressionElement> element = [self.expression elementAtIndex:elementIndex];
|
|
|
|
if ([element isString]) {
|
|
id<MPParsedFactor> nextFactor = nil;
|
|
if (elementIndex < self.expression.numberOfElements - 1) {
|
|
MPFunction *nextFunction = (MPFunction *)[self.expression elementAtIndex:elementIndex+1];
|
|
nextFactor = nextFunction;
|
|
}
|
|
|
|
NSArray *newProducts;
|
|
if (elementIndex == 0 && flag) {
|
|
NSString *definedVariable;
|
|
newProducts = [parser parseElement:(NSString *)element
|
|
previousProduct:currentProduct
|
|
nextFactor:nextFactor
|
|
definesVariable:YES
|
|
definedVariable:&definedVariable
|
|
error:error];
|
|
self.definedVariable = definedVariable;
|
|
} else {
|
|
newProducts = [parser parseElement:(NSString *)element
|
|
previousProduct:currentProduct
|
|
nextFactor:nextFactor
|
|
error:error];
|
|
}
|
|
if (!newProducts) {
|
|
return nil;
|
|
}
|
|
|
|
for (NSUInteger productIndex = 0; productIndex < newProducts.count-1; productIndex++) {
|
|
[products addObject:newProducts[productIndex]];
|
|
}
|
|
currentProduct = newProducts.lastObject;
|
|
|
|
elementIndex++;
|
|
} else {
|
|
if (!currentProduct) {
|
|
currentProduct = [[MPParsedProduct alloc] init];
|
|
}
|
|
[currentProduct addFactor:(MPFunction *)element];
|
|
}
|
|
}
|
|
|
|
[products addObject:currentProduct];
|
|
|
|
NSDecimalNumber *value = [NSDecimalNumber zero];
|
|
for (MPParsedProduct *product in products) {
|
|
NSDecimalNumber *productValue = [product evaluateWithError:error];
|
|
if (!productValue) {
|
|
return nil;
|
|
}
|
|
value = [value decimalNumberByAdding:productValue];
|
|
}
|
|
return value;
|
|
}
|
|
|
|
@end
|