Redesign of the Evaluation System
This commit is contained in:
@@ -25,13 +25,13 @@
|
|||||||
|
|
||||||
- (NSArray *)parseElement:(NSString *)string
|
- (NSArray *)parseElement:(NSString *)string
|
||||||
previousProduct:(MPParsedProduct *)previousProduct
|
previousProduct:(MPParsedProduct *)previousProduct
|
||||||
nextFactor:(MPParsedFactor *)nextFactor
|
nextFactor:(id<MPParsedFactor>)nextFactor
|
||||||
definesVariable:(BOOL)flag
|
definesVariable:(BOOL)flag
|
||||||
definedVariable:(NSString *__autoreleasing *)variableName
|
definedVariable:(NSString *__autoreleasing *)variableName
|
||||||
error:(out MPParseError *__autoreleasing *)error;
|
error:(out MPParseError *__autoreleasing *)error;
|
||||||
- (NSArray *)parseElement:(NSString *)string
|
- (NSArray *)parseElement:(NSString *)string
|
||||||
previousProduct:(MPParsedProduct *)previousProduct
|
previousProduct:(MPParsedProduct *)previousProduct
|
||||||
nextFactor:(MPParsedFactor *)nextFactor
|
nextFactor:(id<MPParsedFactor>)nextFactor
|
||||||
error:(out MPParseError *__autoreleasing *)error;
|
error:(out MPParseError *__autoreleasing *)error;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -9,6 +9,11 @@
|
|||||||
#import "MPElementParser.h"
|
#import "MPElementParser.h"
|
||||||
#import "NSRegularExpression+MPParsingAdditions.h"
|
#import "NSRegularExpression+MPParsingAdditions.h"
|
||||||
|
|
||||||
|
#import "MPParsedFactor.h"
|
||||||
|
#import "MPParsedNumber.h"
|
||||||
|
#import "MPParsedVariable.h"
|
||||||
|
#import "MPParsedOperator.h"
|
||||||
|
|
||||||
#define MPMultiplicationSymbol @"*"
|
#define MPMultiplicationSymbol @"*"
|
||||||
|
|
||||||
@interface MPElementParser ()
|
@interface MPElementParser ()
|
||||||
@@ -24,11 +29,8 @@
|
|||||||
|
|
||||||
- (NSRange)parseWhitespaces;
|
- (NSRange)parseWhitespaces;
|
||||||
- (NSRange)parseMultiplicationSymbol;
|
- (NSRange)parseMultiplicationSymbol;
|
||||||
- (NSRange)parseOperators;
|
- (MPParsedOperator *)parseOperators;
|
||||||
- (NSUInteger)countOperatorsInRange:(NSRange)range
|
- (MPParsedNumber *)parseNumber;
|
||||||
multiplicator:(out NSDecimalNumber *__autoreleasing *)multiplicator;
|
|
||||||
- (NSRange)parseNumber;
|
|
||||||
- (NSDecimalNumber *)numberInRange:(NSRange)range;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -84,7 +86,7 @@ static BOOL useUserDefaults;
|
|||||||
|
|
||||||
- (NSArray *)parseElement:(NSString *)string
|
- (NSArray *)parseElement:(NSString *)string
|
||||||
previousProduct:(MPParsedProduct *)previousProduct
|
previousProduct:(MPParsedProduct *)previousProduct
|
||||||
nextFactor:(MPParsedFactor *)nextFactor
|
nextFactor:(id<MPParsedFactor>)nextFactor
|
||||||
error:(out MPParseError *__autoreleasing *)error
|
error:(out MPParseError *__autoreleasing *)error
|
||||||
{
|
{
|
||||||
return [self parseElement:string
|
return [self parseElement:string
|
||||||
@@ -97,7 +99,7 @@ static BOOL useUserDefaults;
|
|||||||
|
|
||||||
- (NSArray *)parseElement:(NSString *)string
|
- (NSArray *)parseElement:(NSString *)string
|
||||||
previousProduct:(MPParsedProduct *)previousProduct
|
previousProduct:(MPParsedProduct *)previousProduct
|
||||||
nextFactor:(MPParsedFactor *)nextFactor
|
nextFactor:(id<MPParsedFactor>)nextFactor
|
||||||
definesVariable:(BOOL)flag
|
definesVariable:(BOOL)flag
|
||||||
definedVariable:(NSString *__autoreleasing *)variableName
|
definedVariable:(NSString *__autoreleasing *)variableName
|
||||||
error:(out MPParseError *__autoreleasing *)error
|
error:(out MPParseError *__autoreleasing *)error
|
||||||
@@ -123,90 +125,86 @@ static BOOL useUserDefaults;
|
|||||||
NSMutableArray *products = [[NSMutableArray alloc] init];
|
NSMutableArray *products = [[NSMutableArray alloc] init];
|
||||||
MPParsedProduct *currentProduct = previousProduct;
|
MPParsedProduct *currentProduct = previousProduct;
|
||||||
|
|
||||||
while (![self isAtEnd]) {
|
while (YES) {
|
||||||
[self parseWhitespaces];
|
[self parseWhitespaces];
|
||||||
|
|
||||||
NSRange multiplicationSymbolRange = [self parseMultiplicationSymbol];
|
NSRange multiplicationSymbolRange = [self parseMultiplicationSymbol];
|
||||||
BOOL hasMultiplicationSymbol = multiplicationSymbolRange.location != NSNotFound;
|
BOOL hasMultiplicationSymbol = multiplicationSymbolRange.location != NSNotFound;
|
||||||
|
|
||||||
NSRange operatorsRange = [self parseOperators];
|
MPParsedOperator *operators = [self parseOperators];
|
||||||
BOOL hasOperators = operatorsRange.location != NSNotFound;
|
|
||||||
|
|
||||||
// NSRange functionRange = ...
|
// NSRange functionRange = ...
|
||||||
// BOOL hasFunction = functionRange.location != NSNotFound;
|
// BOOL hasFunction = functionRange.location != NSNotFound;
|
||||||
|
|
||||||
NSRange numberRange = [self parseNumber];
|
MPParsedNumber *number = [self parseNumber];
|
||||||
BOOL hasNumber = numberRange.location != NSNotFound;
|
|
||||||
|
|
||||||
|
|
||||||
NSDecimalNumber *operatorMultiplicator;
|
if (!number.exists) {
|
||||||
NSUInteger operatorCount = [self countOperatorsInRange:operatorsRange
|
|
||||||
multiplicator:&operatorMultiplicator];
|
|
||||||
|
|
||||||
if (!hasNumber) {
|
|
||||||
if ([self isAtEnd] && nextFactor != nil) {
|
if ([self isAtEnd] && nextFactor != nil) {
|
||||||
if (hasMultiplicationSymbol) {
|
if (hasMultiplicationSymbol) {
|
||||||
if (operatorCount > self.maximumOperatorChainLengthInFunction) {
|
if (operators.numberOfOperators > self.maximumOperatorChainLengthInFunction) {
|
||||||
self.error = MPParseError(operatorsRange, @"Too many operators in multiplication.");
|
self.error = MPParseError(operators.range, @"Too many operators in multiplication.");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
[currentProduct addFactor:[MPParsedFactor factorWithDecimalNumber:operatorMultiplicator]];
|
[currentProduct addFactor:operators];
|
||||||
} else if (hasOperators) {
|
} else if (operators.exists) {
|
||||||
if (operatorCount > self.maximumOperatorChainLength) {
|
if (operators.numberOfOperators > self.maximumOperatorChainLength) {
|
||||||
self.error = MPParseError(operatorsRange, @"Too many operators.");
|
self.error = MPParseError(operators.range, @"Too many operators.");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
[products addObject:currentProduct];
|
[products addObject:currentProduct];
|
||||||
currentProduct = [[MPParsedProduct alloc] init];
|
currentProduct = [[MPParsedProduct alloc] init];
|
||||||
[currentProduct addFactor:[MPParsedFactor factorWithDecimalNumber:[[NSDecimalNumber alloc] initWithUnsignedInteger:operatorCount]]];
|
[currentProduct addFactor:operators];
|
||||||
} else if (self.allowsImplicitMultiplications) {
|
} else if (self.allowsImplicitMultiplications) {
|
||||||
|
NSLog(@"Here I am");
|
||||||
if (!currentProduct) {
|
if (!currentProduct) {
|
||||||
currentProduct = [[MPParsedProduct alloc] init];
|
currentProduct = [[MPParsedProduct alloc] init];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
NSLog(@"ERR");
|
||||||
self.error = MPParseError(NSMakeRange(self.parsePosition, 0), @"Implicit Multiplication not allowed.");
|
self.error = MPParseError(NSMakeRange(self.parsePosition, 0), @"Implicit Multiplication not allowed.");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else if ([self isAtEnd]) {
|
} else if ([self isAtEnd]) {
|
||||||
|
if (hasMultiplicationSymbol || operators.exists) {
|
||||||
self.error = MPParseError(NSMakeRange(self.parsePosition, 0), @"Unexpected End. Expected Number.");
|
self.error = MPParseError(NSMakeRange(self.parsePosition, 0), @"Unexpected End. Expected Number.");
|
||||||
return nil;
|
return nil;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.error = MPParseError(NSMakeRange(self.parsePosition, 1), @"Unexpected Symbol. Expected Number.");
|
self.error = MPParseError(NSMakeRange(self.parsePosition, 1), @"Unexpected Symbol. Expected Number.");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
NSDecimalNumber *number = [self numberInRange:numberRange];
|
|
||||||
NSDecimalNumber *value = [operatorMultiplicator decimalNumberByMultiplyingBy:number];
|
|
||||||
|
|
||||||
if (hasMultiplicationSymbol) {
|
if (hasMultiplicationSymbol) {
|
||||||
if (currentProduct) {
|
if (currentProduct) {
|
||||||
if (operatorCount > self.maximumOperatorChainLengthInMultiplication) {
|
if (operators.numberOfOperators > self.maximumOperatorChainLengthInMultiplication) {
|
||||||
self.error = MPParseError(operatorsRange, @"Too many operators in multiplication.");
|
self.error = MPParseError(operators.range, @"Too many operators in multiplication.");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
[currentProduct addFactor:[MPParsedFactor factorWithDecimalNumber:value]];
|
[currentProduct addFactor:operators];
|
||||||
|
[currentProduct addFactor:number];
|
||||||
} else {
|
} else {
|
||||||
self.error = MPParseError(multiplicationSymbolRange, @"Unexpected Symbol. Expected Number.");
|
self.error = MPParseError(multiplicationSymbolRange, @"Unexpected Symbol. Expected Number.");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
} else if (hasOperators) {
|
} else if (operators.exists) {
|
||||||
if (operatorCount > self.maximumOperatorChainLength) {
|
if (operators.numberOfOperators > self.maximumOperatorChainLength) {
|
||||||
self.error = MPParseError(operatorsRange, @"Too many operators.");
|
self.error = MPParseError(operators.range, @"Too many operators.");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
if (currentProduct) {
|
if (currentProduct) {
|
||||||
[products addObject:currentProduct];
|
[products addObject:currentProduct];
|
||||||
}
|
}
|
||||||
currentProduct = [[MPParsedProduct alloc] init];
|
currentProduct = [[MPParsedProduct alloc] initWithFactor:operators];
|
||||||
[currentProduct addFactor:[MPParsedFactor factorWithDecimalNumber:value]];
|
[currentProduct addFactor:number];
|
||||||
} else if (!currentProduct) {
|
} else if (!currentProduct) {
|
||||||
currentProduct = [[MPParsedProduct alloc] init];
|
currentProduct = [[MPParsedProduct alloc] initWithFactor:number];
|
||||||
[currentProduct addFactor:[MPParsedFactor factorWithDecimalNumber:value]];
|
|
||||||
} else if (self.allowsImplicitMultiplications) {
|
} else if (self.allowsImplicitMultiplications) {
|
||||||
[currentProduct addFactor:[MPParsedFactor factorWithDecimalNumber:value]];
|
[currentProduct addFactor:number];
|
||||||
} else {
|
} else {
|
||||||
self.error = MPParseError(NSMakeRange(numberRange.location, 0), @"Implicit Multiplication not allowed.");
|
self.error = MPParseError(NSMakeRange(number.range.location, 0), @"Implicit Multiplication not allowed.");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -276,7 +274,7 @@ static NSRegularExpression *multiplicationSymbolRegex;
|
|||||||
}
|
}
|
||||||
|
|
||||||
static NSRegularExpression *operatorsRegex;
|
static NSRegularExpression *operatorsRegex;
|
||||||
- (NSRange)parseOperators
|
- (MPParsedOperator *)parseOperators
|
||||||
{
|
{
|
||||||
if (!operatorsRegex) {
|
if (!operatorsRegex) {
|
||||||
operatorsRegex = [NSRegularExpression regularExpressionWithPattern:@"\\A\\s*([+-](?:\\s*[+-])*)\\s*"
|
operatorsRegex = [NSRegularExpression regularExpressionWithPattern:@"\\A\\s*([+-](?:\\s*[+-])*)\\s*"
|
||||||
@@ -285,33 +283,18 @@ static NSRegularExpression *operatorsRegex;
|
|||||||
}
|
}
|
||||||
NSTextCheckingResult *match = [operatorsRegex firstMatchInString:self.input
|
NSTextCheckingResult *match = [operatorsRegex firstMatchInString:self.input
|
||||||
fromIndex:self.parsePosition];
|
fromIndex:self.parsePosition];
|
||||||
if (match == nil) {
|
NSRange matchRange;
|
||||||
return NSMakeRange(NSNotFound, 0);
|
if (!match) {
|
||||||
}
|
matchRange = NSMakeRange(NSNotFound, 0);
|
||||||
|
} else {
|
||||||
self.parsePosition = NSMaxRange(match.range);
|
self.parsePosition = NSMaxRange(match.range);
|
||||||
return [match rangeAtIndex:1];
|
matchRange = [match rangeAtIndex:1];
|
||||||
|
}
|
||||||
|
return [[MPParsedOperator alloc] initWithRange:matchRange
|
||||||
|
inString:self.input];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSUInteger)countOperatorsInRange:(NSRange)range
|
- (MPParsedNumber *)parseNumber
|
||||||
multiplicator:(out NSDecimalNumber *__autoreleasing *)outMultiplicator
|
|
||||||
{
|
|
||||||
if (range.location == NSNotFound) {
|
|
||||||
*outMultiplicator = [NSDecimalNumber one];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
NSString *operatorsString = [self.input substringWithRange:range];
|
|
||||||
NSString *operators = [[operatorsString componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsJoinedByString:@""];
|
|
||||||
NSInteger multiplicator = 1;
|
|
||||||
for (NSUInteger characterIndex; characterIndex < operators.length; characterIndex++) {
|
|
||||||
if ([[operators substringWithRange:NSMakeRange(characterIndex, 1)] isEqualToString:@"-"]) {
|
|
||||||
multiplicator *= -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*outMultiplicator = [[NSDecimalNumber alloc] initWithInteger:multiplicator];
|
|
||||||
return operators.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSRange)parseNumber
|
|
||||||
{
|
{
|
||||||
NSString *decimalSeparatorRegexString = [NSRegularExpression escapedPatternForString:[[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator]];
|
NSString *decimalSeparatorRegexString = [NSRegularExpression escapedPatternForString:[[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator]];
|
||||||
NSString *numberRegexFormat = [NSString stringWithFormat:@"\\A\\s*((?:\\d+(?:%@\\d+)?)|(?:%@\\d+))\\s*", decimalSeparatorRegexString, decimalSeparatorRegexString];
|
NSString *numberRegexFormat = [NSString stringWithFormat:@"\\A\\s*((?:\\d+(?:%@\\d+)?)|(?:%@\\d+))\\s*", decimalSeparatorRegexString, decimalSeparatorRegexString];
|
||||||
@@ -320,17 +303,15 @@ static NSRegularExpression *operatorsRegex;
|
|||||||
error:NULL];
|
error:NULL];
|
||||||
NSTextCheckingResult *match = [numberRegex firstMatchInString:self.input
|
NSTextCheckingResult *match = [numberRegex firstMatchInString:self.input
|
||||||
fromIndex:self.parsePosition];
|
fromIndex:self.parsePosition];
|
||||||
|
NSRange matchRange;
|
||||||
if (!match) {
|
if (!match) {
|
||||||
return NSMakeRange(NSNotFound, 0);
|
matchRange = NSMakeRange(NSNotFound, 0);
|
||||||
}
|
} else {
|
||||||
self.parsePosition = NSMaxRange(match.range);
|
self.parsePosition = NSMaxRange(match.range);
|
||||||
return [match rangeAtIndex:1];
|
matchRange = [match rangeAtIndex:1];
|
||||||
}
|
}
|
||||||
|
return [[MPParsedNumber alloc] initWithRange:matchRange
|
||||||
- (NSDecimalNumber *)numberInRange:(NSRange)range
|
inString:self.input];
|
||||||
{
|
|
||||||
NSString *numberString = [self.input substringWithRange:range];
|
|
||||||
return [NSDecimalNumber decimalNumberWithString:numberString];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
23
MathPad/MPEvaluationContext.h
Normal file
23
MathPad/MPEvaluationContext.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// MPEvaluationContext.h
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 12.09.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@interface MPEvaluationContext : NSObject
|
||||||
|
|
||||||
|
+ (MPEvaluationContext *)sharedContext;
|
||||||
|
|
||||||
|
- (void)push;
|
||||||
|
- (void)pop;
|
||||||
|
|
||||||
|
- (void)bindValue:(NSDecimalNumber *)value toName:(NSString *)variableName;
|
||||||
|
- (void)unbindVariableName:(NSString *)variableName;
|
||||||
|
|
||||||
|
- (NSDecimalNumber *)valueForVariableName:(NSString *)variableName;
|
||||||
|
|
||||||
|
@end
|
||||||
63
MathPad/MPEvaluationContext.m
Normal file
63
MathPad/MPEvaluationContext.m
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
//
|
||||||
|
// MPEvaluationContext.m
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 12.09.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPEvaluationContext.h"
|
||||||
|
|
||||||
|
@interface MPEvaluationContext ()
|
||||||
|
@property (nonatomic, strong) NSMutableArray *stack;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MPEvaluationContext
|
||||||
|
|
||||||
|
static MPEvaluationContext *sharedContext;
|
||||||
|
+ (MPEvaluationContext *)sharedContext
|
||||||
|
{
|
||||||
|
if (!sharedContext) {
|
||||||
|
sharedContext = [[MPEvaluationContext alloc] init];
|
||||||
|
}
|
||||||
|
return sharedContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)init
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
_stack = [[NSMutableArray alloc] init];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)push
|
||||||
|
{
|
||||||
|
[self.stack addObject:[[NSMutableDictionary alloc] init]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)pop
|
||||||
|
{
|
||||||
|
[self.stack removeLastObject];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)bindValue:(NSDecimalNumber *)value toName:(NSString *)variableName
|
||||||
|
{
|
||||||
|
NSMutableDictionary *currentBindings = self.stack.lastObject;
|
||||||
|
currentBindings[variableName] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)unbindVariableName:(NSString *)variableName
|
||||||
|
{
|
||||||
|
NSMutableDictionary *currentBindings = self.stack.lastObject;
|
||||||
|
[currentBindings removeObjectForKey:variableName];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDecimalNumber *)valueForVariableName:(NSString *)variableName
|
||||||
|
{
|
||||||
|
NSMutableDictionary *currentBindings = self.stack.lastObject;
|
||||||
|
return currentBindings[variableName];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -16,15 +16,9 @@
|
|||||||
|
|
||||||
// Do not instanciate yourself, use evaluator property of MPExpression instead
|
// Do not instanciate yourself, use evaluator property of MPExpression instead
|
||||||
- (instancetype)initWithExpression:(MPExpression *)expression;
|
- (instancetype)initWithExpression:(MPExpression *)expression;
|
||||||
|
|
||||||
@property (readonly, nonatomic, weak) MPExpression *expression;
|
@property (readonly, nonatomic, weak) MPExpression *expression;
|
||||||
|
|
||||||
#pragma mark Evaluating Expressions
|
#pragma mark Evaluating Expressions
|
||||||
@property (readonly, nonatomic, strong) NSDictionary *variableBindings;
|
|
||||||
|
|
||||||
- (void)bindValue:(NSDecimalNumber *)value toVariableName:(NSString *)name;
|
|
||||||
- (void)unbindVariableName:(NSString *)name;
|
|
||||||
|
|
||||||
@property (readonly, nonatomic, strong) NSString *definedVariable;
|
@property (readonly, nonatomic, strong) NSString *definedVariable;
|
||||||
|
|
||||||
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error;
|
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error;
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#import "MPExpressionEvaluator.h"
|
#import "MPExpressionEvaluator.h"
|
||||||
#import "MPExpression.h"
|
#import "MPExpression.h"
|
||||||
#import "MPFunction.h"
|
#import "MPFunction.h"
|
||||||
|
#import "MPParsedFactor.h"
|
||||||
|
#import "MPFunction+MPParsedFactor.h"
|
||||||
|
|
||||||
@interface MPExpressionEvaluator ()
|
@interface MPExpressionEvaluator ()
|
||||||
@property (readwrite, nonatomic, strong) NSString *definedVariable;
|
@property (readwrite, nonatomic, strong) NSString *definedVariable;
|
||||||
@@ -16,7 +18,6 @@
|
|||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation MPExpressionEvaluator {
|
@implementation MPExpressionEvaluator {
|
||||||
NSMutableDictionary *_variableBindings;
|
|
||||||
MPElementParser *parser;
|
MPElementParser *parser;
|
||||||
}
|
}
|
||||||
- (id)initWithExpression:(MPExpression *)expression
|
- (id)initWithExpression:(MPExpression *)expression
|
||||||
@@ -24,29 +25,12 @@
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
if (self) {
|
if (self) {
|
||||||
_expression = expression;
|
_expression = expression;
|
||||||
_variableBindings = [[NSMutableDictionary alloc] init];
|
|
||||||
parser = [[MPElementParser alloc] init];
|
parser = [[MPElementParser alloc] init];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark Evaluating Expressions
|
#pragma mark Evaluating Expressions
|
||||||
- (NSDictionary *)variableBindings
|
|
||||||
{
|
|
||||||
return [_variableBindings copy];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)bindValue:(NSDecimalNumber *)value toVariableName:(NSString *)name
|
|
||||||
{
|
|
||||||
[_variableBindings setObject:value
|
|
||||||
forKey:name];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)unbindVariableName:(NSString *)name
|
|
||||||
{
|
|
||||||
[_variableBindings removeObjectForKey:name];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error
|
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error
|
||||||
{
|
{
|
||||||
return [self evaluateVariableDefinition:NO error:error];
|
return [self evaluateVariableDefinition:NO error:error];
|
||||||
@@ -68,14 +52,10 @@
|
|||||||
id<MPExpressionElement> element = [self.expression elementAtIndex:elementIndex];
|
id<MPExpressionElement> element = [self.expression elementAtIndex:elementIndex];
|
||||||
|
|
||||||
if ([element isString]) {
|
if ([element isString]) {
|
||||||
MPParsedFactor *nextFactor = nil;
|
id<MPParsedFactor> nextFactor = nil;
|
||||||
if (elementIndex < self.expression.numberOfElements - 1) {
|
if (elementIndex < self.expression.numberOfElements - 1) {
|
||||||
MPFunction *nextFunction = (MPFunction *)[self.expression elementAtIndex:elementIndex+1];
|
MPFunction *nextFunction = (MPFunction *)[self.expression elementAtIndex:elementIndex+1];
|
||||||
NSDecimalNumber *functionValue = [nextFunction evaluate:error];
|
nextFactor = nextFunction;
|
||||||
if (!functionValue) {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
nextFactor = [MPParsedFactor factorWithDecimalNumber:functionValue];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NSArray *newProducts;
|
NSArray *newProducts;
|
||||||
@@ -105,14 +85,10 @@
|
|||||||
|
|
||||||
elementIndex++;
|
elementIndex++;
|
||||||
} else {
|
} else {
|
||||||
NSDecimalNumber *functionValue = [(MPFunction *)element evaluate:error];
|
|
||||||
if (!functionValue) {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
if (!currentProduct) {
|
if (!currentProduct) {
|
||||||
currentProduct = [[MPParsedProduct alloc] init];
|
currentProduct = [[MPParsedProduct alloc] init];
|
||||||
}
|
}
|
||||||
[currentProduct addFactor:[MPParsedFactor factorWithDecimalNumber:functionValue]];
|
[currentProduct addFactor:(MPFunction *)element];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +96,11 @@
|
|||||||
|
|
||||||
NSDecimalNumber *value = [NSDecimalNumber zero];
|
NSDecimalNumber *value = [NSDecimalNumber zero];
|
||||||
for (MPParsedProduct *product in products) {
|
for (MPParsedProduct *product in products) {
|
||||||
value = [value decimalNumberByAdding:product.value];
|
NSDecimalNumber *productValue = [product evaluateWithError:error];
|
||||||
|
if (!productValue) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
value = [value decimalNumberByAdding:productValue];
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|||||||
14
MathPad/MPFunction+MPParsedFactor.h
Normal file
14
MathPad/MPFunction+MPParsedFactor.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// MPFunction+MPParsedFactor.h
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 13.09.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <MathKit/MathKit.h>
|
||||||
|
#import "MPParsedFactor.h"
|
||||||
|
|
||||||
|
@interface MPFunction (MPParsedFactor) <MPParsedFactor>
|
||||||
|
|
||||||
|
@end
|
||||||
30
MathPad/MPFunction+MPParsedFactor.m
Normal file
30
MathPad/MPFunction+MPParsedFactor.m
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// MPFunction+MPParsedFactor.m
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 13.09.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPFunction+MPParsedFactor.h"
|
||||||
|
|
||||||
|
@implementation MPFunction (MPParsedFactor)
|
||||||
|
|
||||||
|
- (instancetype)initWithRange:(NSRange)range
|
||||||
|
inString:(NSString *)string
|
||||||
|
{
|
||||||
|
return [self init];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)exists
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSRange)range
|
||||||
|
{
|
||||||
|
NSUInteger selfIndex = [self.parent indexOfElement:self];
|
||||||
|
return NSMakeRange([self.parent locationOfElementAtIndex:selfIndex], 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
- (id)elementAtIndexPath:(NSIndexPath *)indexPath;
|
- (id)elementAtIndexPath:(NSIndexPath *)indexPath;
|
||||||
|
|
||||||
#pragma mark Evaluating Functions
|
#pragma mark Evaluating Functions
|
||||||
- (NSDecimalNumber *)evaluate:(MPParseError *__autoreleasing *)error;
|
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error;
|
||||||
|
|
||||||
#pragma mark Messages
|
#pragma mark Messages
|
||||||
- (void)didChangeElementsInRangePath:(MPRangePath *)rangePath
|
- (void)didChangeElementsInRangePath:(MPRangePath *)rangePath
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark Evaluating Functions
|
#pragma mark Evaluating Functions
|
||||||
- (NSDecimalNumber *)evaluate:(MPParseError *__autoreleasing *)error
|
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error
|
||||||
{
|
{
|
||||||
return [NSDecimalNumber zero];
|
return [NSDecimalNumber zero];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,21 +2,19 @@
|
|||||||
// MPParsedFactor.h
|
// MPParsedFactor.h
|
||||||
// MathPad
|
// MathPad
|
||||||
//
|
//
|
||||||
// Created by Kim Wittenburg on 10.09.14.
|
// Created by Kim Wittenburg on 13.09.14.
|
||||||
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "MPParseError.h"
|
||||||
|
|
||||||
@interface MPParsedFactor : NSObject
|
@protocol MPParsedFactor <NSObject>
|
||||||
|
|
||||||
+ (MPParsedFactor *)factorWithDecimalNumber:(NSDecimalNumber *)number;
|
- (instancetype)initWithRange:(NSRange)range inString:(NSString *)string;
|
||||||
+ (MPParsedFactor *)sinFactorWithFactor:(MPParsedFactor *)factor;
|
|
||||||
+ (MPParsedFactor *)cosFactorWithFactor:(MPParsedFactor *)factor;
|
|
||||||
+ (MPParsedFactor *)tanFactorWithFactor:(MPParsedFactor *)factor;
|
|
||||||
|
|
||||||
- (instancetype)initWithDecimalNumber:(NSDecimalNumber *)number;
|
- (NSRange)range;
|
||||||
|
- (BOOL)exists;
|
||||||
- (NSDecimalNumber *)value;
|
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
16
MathPad/MPParsedNumber.h
Normal file
16
MathPad/MPParsedNumber.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// MPParsedNumber.h
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 13.09.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "MPParsedFactor.h"
|
||||||
|
|
||||||
|
@interface MPParsedNumber : NSObject <MPParsedFactor>
|
||||||
|
|
||||||
|
- (NSDecimalNumber *)number;
|
||||||
|
|
||||||
|
@end
|
||||||
42
MathPad/MPParsedNumber.m
Normal file
42
MathPad/MPParsedNumber.m
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
//
|
||||||
|
// MPParsedNumber.m
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 13.09.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPParsedNumber.h"
|
||||||
|
|
||||||
|
@interface MPParsedNumber ()
|
||||||
|
@property (nonatomic) NSRange range;
|
||||||
|
@property (nonatomic, strong) NSDecimalNumber *number;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MPParsedNumber
|
||||||
|
|
||||||
|
- (instancetype)initWithRange:(NSRange)range
|
||||||
|
inString:(NSString *)string
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
_range = range;
|
||||||
|
if (range.location != NSNotFound) {
|
||||||
|
NSString *stringValue = [string substringWithRange:range];
|
||||||
|
_number = [NSDecimalNumber decimalNumberWithString:stringValue];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)exists
|
||||||
|
{
|
||||||
|
return self.range.location != NSNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error
|
||||||
|
{
|
||||||
|
return self.number;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
17
MathPad/MPParsedOperator.h
Normal file
17
MathPad/MPParsedOperator.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// MPParsedOperator.h
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 13.09.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "MPParsedFactor.h"
|
||||||
|
|
||||||
|
@interface MPParsedOperator : NSObject <MPParsedFactor>
|
||||||
|
|
||||||
|
- (NSUInteger)numberOfOperators;
|
||||||
|
- (NSDecimalNumber *)multiplicator;
|
||||||
|
|
||||||
|
@end
|
||||||
54
MathPad/MPParsedOperator.m
Normal file
54
MathPad/MPParsedOperator.m
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// MPParsedOperator.m
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 13.09.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPParsedOperator.h"
|
||||||
|
|
||||||
|
@interface MPParsedOperator ()
|
||||||
|
@property (nonatomic) NSRange range;
|
||||||
|
@property (nonatomic) NSUInteger numberOfOperators;
|
||||||
|
@property (nonatomic, strong) NSDecimalNumber *multiplicator;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MPParsedOperator
|
||||||
|
|
||||||
|
- (instancetype)initWithRange:(NSRange)range
|
||||||
|
inString:(NSString *)string
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
_range = range;
|
||||||
|
if (range.location == NSNotFound) {
|
||||||
|
_multiplicator = [NSDecimalNumber one];
|
||||||
|
_numberOfOperators = 0;
|
||||||
|
} else {
|
||||||
|
NSString *stringValue = [string substringWithRange:range];
|
||||||
|
NSString *operators = [[stringValue componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsJoinedByString:@""];
|
||||||
|
NSInteger multiplicator = 1;
|
||||||
|
for (NSUInteger characterIndex = 0; characterIndex < operators.length; characterIndex++) {
|
||||||
|
if ([[operators substringWithRange:NSMakeRange(characterIndex, 1)] isEqualToString:@"-"]) {
|
||||||
|
multiplicator *= -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_multiplicator = [[NSDecimalNumber alloc] initWithInteger:multiplicator];
|
||||||
|
_numberOfOperators = operators.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)exists
|
||||||
|
{
|
||||||
|
return self.range.location != NSNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error
|
||||||
|
{
|
||||||
|
return self.multiplicator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -11,10 +11,12 @@
|
|||||||
|
|
||||||
@interface MPParsedProduct : NSObject
|
@interface MPParsedProduct : NSObject
|
||||||
|
|
||||||
|
- (instancetype)init; // designated initializer
|
||||||
|
- (instancetype)initWithFactor:(id<MPParsedFactor>)factor; // designated initializer.
|
||||||
|
|
||||||
@property (readonly, nonatomic, strong) NSArray *factors;
|
@property (readonly, nonatomic, strong) NSArray *factors;
|
||||||
|
- (void)addFactor:(id<MPParsedFactor>)factor;
|
||||||
|
|
||||||
- (void)addFactor:(MPParsedFactor *)factor;
|
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error;
|
||||||
|
|
||||||
- (NSDecimalNumber *)value;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -21,24 +21,37 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithFactor:(id<MPParsedFactor>)factor
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
_factors = [[NSMutableArray alloc] initWithObjects:factor, nil];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSArray *)factors
|
- (NSArray *)factors
|
||||||
{
|
{
|
||||||
return _factors;
|
return _factors;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addFactor:(MPParsedFactor *)factor
|
- (void)addFactor:(id<MPParsedFactor>)factor
|
||||||
{
|
{
|
||||||
[_factors addObject:factor];
|
[_factors addObject:factor];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDecimalNumber *)value
|
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error
|
||||||
{
|
{
|
||||||
if (_factors.count == 0) {
|
if (_factors.count == 0) {
|
||||||
return [NSDecimalNumber zero];
|
return [NSDecimalNumber zero];
|
||||||
}
|
}
|
||||||
NSDecimalNumber *value = [NSDecimalNumber one];
|
NSDecimalNumber *value = [NSDecimalNumber one];
|
||||||
for (MPParsedFactor *factor in _factors) {
|
for (id<MPParsedFactor> factor in _factors) {
|
||||||
value = [value decimalNumberByMultiplyingBy:factor.value];
|
NSDecimalNumber *factorValue = [factor evaluateWithError:error];
|
||||||
|
if (!factorValue) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
value = [value decimalNumberByMultiplyingBy:factorValue];
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|||||||
16
MathPad/MPParsedVariable.h
Normal file
16
MathPad/MPParsedVariable.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// MPParsedVariable.h
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 13.09.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "MPParsedFactor.h"
|
||||||
|
|
||||||
|
@interface MPParsedVariable : NSObject <MPParsedFactor>
|
||||||
|
|
||||||
|
- (NSString *)variableName;
|
||||||
|
|
||||||
|
@end
|
||||||
47
MathPad/MPParsedVariable.m
Normal file
47
MathPad/MPParsedVariable.m
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// MPParsedVariable.m
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 13.09.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPParsedVariable.h"
|
||||||
|
#import "MPEvaluationContext.h"
|
||||||
|
|
||||||
|
@interface MPParsedVariable ()
|
||||||
|
@property (nonatomic) NSRange range;
|
||||||
|
@property (nonatomic, strong) NSString *variableName;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MPParsedVariable
|
||||||
|
|
||||||
|
- (instancetype)initWithRange:(NSRange)range
|
||||||
|
inString:(NSString *)string
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
_range = range;
|
||||||
|
if (range.location != NSNotFound) {
|
||||||
|
_variableName = [string substringWithRange:range];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)exists
|
||||||
|
{
|
||||||
|
return self.range.location != NSNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error
|
||||||
|
{
|
||||||
|
NSDecimalNumber *value = [[MPEvaluationContext sharedContext] valueForVariableName:self.variableName];
|
||||||
|
if (!value) {
|
||||||
|
*error = MPParseError(self.range, @"Undefined Variable.");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
#import "MPExpression.h"
|
#import "MPExpression.h"
|
||||||
|
|
||||||
#import "MPExpressionEvaluator.h"
|
#import "MPExpressionEvaluator.h"
|
||||||
|
#import "MPEvaluationContext.h"
|
||||||
|
|
||||||
@implementation MPSumFunction
|
@implementation MPSumFunction
|
||||||
|
|
||||||
@@ -99,7 +100,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark Evaluating Functions
|
#pragma mark Evaluating Functions
|
||||||
- (NSDecimalNumber *)evaluate:(MPParseError *__autoreleasing *)error
|
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error
|
||||||
{
|
{
|
||||||
MPExpressionEvaluator *startEvaluator = self.startExpression.evaluator;
|
MPExpressionEvaluator *startEvaluator = self.startExpression.evaluator;
|
||||||
NSDecimalNumber *start = [startEvaluator evaluateVariableDefinition:YES error:error];
|
NSDecimalNumber *start = [startEvaluator evaluateVariableDefinition:YES error:error];
|
||||||
@@ -111,10 +112,12 @@
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[MPEvaluationContext sharedContext] push];
|
||||||
|
|
||||||
MPExpressionEvaluator *sumEvaluator = self.sumExpression.evaluator;
|
MPExpressionEvaluator *sumEvaluator = self.sumExpression.evaluator;
|
||||||
NSDecimalNumber *value = [NSDecimalNumber zero];
|
NSDecimalNumber *value = [NSDecimalNumber zero];
|
||||||
for (NSDecimalNumber *iterator = start; [iterator compare:target] <= 0; iterator = [iterator decimalNumberByAdding:[[NSDecimalNumber alloc] initWithInteger:1]]) {
|
for (NSDecimalNumber *iterator = start; [iterator compare:target] <= 0; iterator = [iterator decimalNumberByAdding:[[NSDecimalNumber alloc] initWithInteger:1]]) {
|
||||||
[sumEvaluator bindValue:iterator toVariableName:startEvaluator.definedVariable];
|
[[MPEvaluationContext sharedContext] bindValue:iterator toName:startEvaluator.definedVariable];
|
||||||
NSDecimalNumber *summand = [sumEvaluator evaluateWithError:error];
|
NSDecimalNumber *summand = [sumEvaluator evaluateWithError:error];
|
||||||
if (summand) {
|
if (summand) {
|
||||||
value = [value decimalNumberByAdding:summand];
|
value = [value decimalNumberByAdding:summand];
|
||||||
@@ -122,6 +125,9 @@
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[MPEvaluationContext sharedContext] pop];
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user