Cleaned Code & Fixed Some Errors
This commit is contained in:
@@ -20,8 +20,6 @@
|
||||
|
||||
- (BOOL)defineVariable:(NSString *)variable
|
||||
value:(NSDecimalNumber *)value;
|
||||
- (BOOL)redefineVariable:(NSString *)variable
|
||||
value:(NSDecimalNumber *)value;
|
||||
- (void)undefineVariable:(NSString *)variable;
|
||||
|
||||
- (NSDecimalNumber *)valueForVariable:(NSString *)variable;
|
||||
|
||||
@@ -53,6 +53,7 @@ static MPEvaluationContext *sharedContext;
|
||||
- (BOOL)defineVariable:(NSString *)variable
|
||||
value:(NSDecimalNumber *)value
|
||||
{
|
||||
[self undefineVariable:variable];
|
||||
if ([self isVariableDefined:variable]) {
|
||||
return NO;
|
||||
}
|
||||
@@ -61,14 +62,6 @@ static MPEvaluationContext *sharedContext;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)redefineVariable:(NSString *)variable
|
||||
value:(NSDecimalNumber *)value
|
||||
{
|
||||
[self undefineVariable:variable];
|
||||
return [self defineVariable:variable
|
||||
value:value];
|
||||
}
|
||||
|
||||
- (void)undefineVariable:(NSString *)variable
|
||||
{
|
||||
NSMutableDictionary *currentBindings = self.stack.lastObject;
|
||||
|
||||
@@ -490,7 +490,7 @@ typedef NS_ENUM(NSUInteger, MPReferenceFrame) {
|
||||
is restored. That basically means that subsequent strings are
|
||||
joined and empty strings removed. After restoring integrity the
|
||||
receiver sends a @c
|
||||
-didChangeElementsInIndexedRangePath:replacementLength: to
|
||||
-changedElementsInIndexedRangePath:replacementLength: to
|
||||
itself. For more information see the documentation on that
|
||||
method.
|
||||
|
||||
@@ -509,6 +509,30 @@ typedef NS_ENUM(NSUInteger, MPReferenceFrame) {
|
||||
withElements:(NSArray *)elements;
|
||||
|
||||
|
||||
/*!
|
||||
@method changedElementsInRangePath:replacementLength:
|
||||
@brief Called after the receiver has been mutated.
|
||||
|
||||
@discussion This method does nothing more than notify it's parent that it has
|
||||
been mutated at the receiver's index. If you need to know about
|
||||
changes in an expression you should override this method instead
|
||||
of @c -replaceSymbolsInRange:withElements: because this method
|
||||
gives you information about the number of elements changed during
|
||||
the mutation.
|
||||
|
||||
@param rangePath
|
||||
The range path at which the receiver was changed starting at the
|
||||
receiver. The range addressed by @c rangePath is expressed in the
|
||||
element reference frame.
|
||||
|
||||
@param replacementLength
|
||||
The number of elements replacing the elements specified by @c
|
||||
rangePath (also specified in the element reference frame).
|
||||
*/
|
||||
- (void)changedElementsInRangePath:(MPRangePath *)rangePath
|
||||
replacementLength:(NSUInteger)replacementLength;
|
||||
|
||||
|
||||
/*!
|
||||
@method subexpressionFromIndex:referenceFrame:
|
||||
@brief Creates an expression from the items in the receiver from the
|
||||
@@ -651,36 +675,6 @@ typedef NS_ENUM(NSUInteger, MPReferenceFrame) {
|
||||
- (MPParsedExpression *)parseExpectingVariable:(BOOL)flag
|
||||
errors:(NSArray *__autoreleasing *)errors;
|
||||
|
||||
|
||||
#pragma mark Notifications
|
||||
/*!
|
||||
@methodgroup Notifications
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
@method didChangeElementsInRangePath:replacementLength:
|
||||
@brief Called after the receiver has been mutated.
|
||||
|
||||
@discussion This method does nothing more than notify it's parent that it has
|
||||
been mutated at the receiver's index. If you need to know about
|
||||
changes in an expression you should override this method instead
|
||||
of @c -replaceSymbolsInRange:withElements: because this method
|
||||
gives you information about the number of elements changed during
|
||||
the mutation.
|
||||
|
||||
@param rangePath
|
||||
The range path at which the receiver was changed starting at the
|
||||
receiver. The range addressed by @c rangePath is expressed in the
|
||||
element reference frame.
|
||||
|
||||
@param replacementLength
|
||||
The number of elements replacing the elements specified by @c
|
||||
rangePath (also specified in the element reference frame).
|
||||
*/
|
||||
- (void)didChangeElementsInRangePath:(MPRangePath *)rangePath
|
||||
replacementLength:(NSUInteger)replacementLength;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@@ -561,7 +561,7 @@ NSString *const MPIllegalElementExceptionElementKey = @"MPIllegalElementExceptio
|
||||
}
|
||||
|
||||
[self fixElements];
|
||||
[self didChangeElementsInRangePath:[[MPRangePath alloc] initWithRange:_editedRange]
|
||||
[self changedElementsInRangePath:[[MPRangePath alloc] initWithRange:_editedRange]
|
||||
replacementLength:_replacementLength];
|
||||
}
|
||||
|
||||
@@ -592,6 +592,16 @@ NSString *const MPIllegalElementExceptionElementKey = @"MPIllegalElementExceptio
|
||||
}
|
||||
|
||||
|
||||
- (void)changedElementsInRangePath:(MPRangePath *)rangePath
|
||||
replacementLength:(NSUInteger)replacementLength
|
||||
{
|
||||
NSUInteger selfIndex = [self.parent indexOfChild:self];
|
||||
MPRangePath *newPath = MPMakeRangePath([rangePath.location indexPathByPreceedingIndex:selfIndex], rangePath.length);
|
||||
[self.parent didChangeElementsInRangePath:newPath
|
||||
replacementLength:replacementLength];
|
||||
}
|
||||
|
||||
|
||||
- (MPExpression *)subexpressionFromIndex:(NSUInteger)from
|
||||
referenceFrame:(MPReferenceFrame)referenceFrame
|
||||
{
|
||||
@@ -661,19 +671,6 @@ NSString *const MPIllegalElementExceptionElementKey = @"MPIllegalElementExceptio
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Notifications
|
||||
|
||||
|
||||
- (void)didChangeElementsInRangePath:(MPRangePath *)rangePath
|
||||
replacementLength:(NSUInteger)replacementLength
|
||||
{
|
||||
NSUInteger selfIndex = [self.parent indexOfChild:self];
|
||||
MPRangePath *newPath = MPMakeRangePath([rangePath.location indexPathByPreceedingIndex:selfIndex], rangePath.length);
|
||||
[self.parent didChangeElementsInRangePath:newPath
|
||||
replacementLength:replacementLength];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Basic NSObject Methods
|
||||
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
|
||||
@interface MPExpressionStorage : MPExpression
|
||||
|
||||
- (instancetype)initWithElements:(NSArray *)elements;
|
||||
|
||||
@property (nonatomic, weak) MPExpressionView *expressionView; // Do not set
|
||||
@property (nonatomic, strong) MPExpressionLayout *rootLayout;
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
{
|
||||
_expressionView = expressionView;
|
||||
self.rootLayout = [[MPExpressionLayout alloc] initWithExpression:self parent:nil];
|
||||
self.rootLayout.flipped = expressionView.isFlipped;
|
||||
self.rootLayout.flipped = expressionView.flipped;
|
||||
}
|
||||
|
||||
- (void)didChangeElementsInRangePath:(MPRangePath *)rangePath
|
||||
- (void)changedElementsInRangePath:(MPRangePath *)rangePath
|
||||
replacementLength:(NSUInteger)replacementLength
|
||||
{
|
||||
if (rangePath.location.length == 0) {
|
||||
|
||||
@@ -14,16 +14,18 @@
|
||||
|
||||
- (NSDecimalNumber *)doEvaluation:(NSError *__autoreleasing *)error
|
||||
{
|
||||
NSDecimalNumber *nominator = [[self expressionAtIndex:0] evaluate:error];
|
||||
if (!nominator) {
|
||||
MPEvaluateExpression(nominator, 0);
|
||||
MPEvaluateExpression(denominator, 1);
|
||||
if ([denominator isEqualToNumber:@0]) {
|
||||
if (error) {
|
||||
*error = [NSError errorWithDomain:MPMathKitErrorDomain
|
||||
code:100
|
||||
userInfo:@{NSLocalizedDescriptionKey: NSLocalizedString(@"Division by zero.", nil)}];
|
||||
}
|
||||
return nil;
|
||||
} else {
|
||||
return [nominator decimalNumberByDividingBy:denominator];
|
||||
}
|
||||
NSDecimalNumber *denominator = [[self expressionAtIndex:1] evaluate:error];
|
||||
if (!denominator) {
|
||||
return nil;
|
||||
}
|
||||
#warning Division by zero ahead
|
||||
return [nominator decimalNumberByDividingBy:denominator];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
{
|
||||
NSUInteger selfIndex = [self.parent indexOfElement:self];
|
||||
MPRangePath *newPath = MPMakeRangePath([rangePath.location indexPathByPreceedingIndex:selfIndex], rangePath.length);
|
||||
[self.parent didChangeElementsInRangePath:newPath
|
||||
[self.parent changedElementsInRangePath:newPath
|
||||
replacementLength:replacementLength];
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#import "MPTerm.h"
|
||||
|
||||
#define MPEvaluateExpression(var, index) NSDecimalNumber *var = [[self expressionAtIndex:index] evaluate:error]; if (var == nil) return nil
|
||||
|
||||
|
||||
|
||||
@class MPFunctionTerm, MPFunction, MPParsedExpression;
|
||||
|
||||
@@ -13,14 +13,9 @@
|
||||
|
||||
- (NSDecimalNumber *)doEvaluation:(NSError *__autoreleasing *)error
|
||||
{
|
||||
NSDecimalNumber *exponent = [[self expressionAtIndex:0] evaluate:error];
|
||||
if (!exponent) {
|
||||
return nil;
|
||||
}
|
||||
MPEvaluateExpression(exponent, 0);
|
||||
NSDecimalNumber *base = [self.baseTerm evaluate:error];
|
||||
if (!base) {
|
||||
return nil;
|
||||
}
|
||||
ReturnNilIfNil(base);
|
||||
if ([base isEqualToNumber:@(0)] && [exponent isEqualToNumber:@(0)]) {
|
||||
// The C pow function returns 1 for pow(0, 0). Mathematically this should be undefined.
|
||||
if (error) {
|
||||
|
||||
@@ -15,23 +15,21 @@
|
||||
- (NSDecimalNumber *)doEvaluation:(NSError *__autoreleasing *)error
|
||||
{
|
||||
MPParsedExpression *startExpression = [self expressionAtIndex:0];
|
||||
MPParsedExpression *targetExpression = [self expressionAtIndex:1];
|
||||
MPParsedExpression *sumExpression = [self expressionAtIndex:2];
|
||||
|
||||
NSDecimalNumber *start = [startExpression evaluate:error];
|
||||
NSDecimalNumber *target = [targetExpression evaluate:error];
|
||||
ReturnNilIfNil(start);
|
||||
MPEvaluateExpression(target, 1);
|
||||
NSDecimalNumber *value = [NSDecimalNumber zero];
|
||||
|
||||
for (NSDecimalNumber *current = start;
|
||||
[current compare:target] <= 0;
|
||||
current = [current decimalNumberByAdding:[[NSDecimalNumber alloc] initWithInteger:1]]) {
|
||||
if (![self redefineVariable:startExpression.definedVariable value:current error:error]) {
|
||||
if (![self defineVariable:startExpression.definedVariable value:current error:error]) {
|
||||
return nil;
|
||||
}
|
||||
NSDecimalNumber *currentValue = [sumExpression evaluate:error];
|
||||
if (!currentValue) {
|
||||
return nil;
|
||||
}
|
||||
ReturnNilIfNil(currentValue);
|
||||
value = [value decimalNumberByAdding:currentValue];
|
||||
}
|
||||
return value;
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||
//
|
||||
|
||||
#define ReturnIfNil(test, value) if (test == nil) return value
|
||||
#define ReturnNilIfNil(test) if (test == nil) return nil
|
||||
|
||||
|
||||
@class MPTerm;
|
||||
|
||||
@@ -18,9 +21,6 @@
|
||||
- (BOOL)defineVariable:(NSString *)variableName
|
||||
value:(NSDecimalNumber *)value
|
||||
error:(NSError *__autoreleasing *)error;
|
||||
- (BOOL)redefineVariable:(NSString *)variableName
|
||||
value:(NSDecimalNumber *)value
|
||||
error:(NSError *__autoreleasing *)error;
|
||||
- (NSDecimalNumber *)valueForVariable:(NSString *)variableName
|
||||
error:(NSError *__autoreleasing *)error;
|
||||
- (void)undefineVariable:(NSString *)variableName; // Should rarely be needed, defined variables are automatically undefined at the end of evaluation.
|
||||
|
||||
@@ -45,23 +45,6 @@
|
||||
return couldDefineVariable;
|
||||
}
|
||||
|
||||
- (BOOL)redefineVariable:(NSString *)variableName
|
||||
value:(NSDecimalNumber *)value
|
||||
error:(NSError *__autoreleasing *)error
|
||||
{
|
||||
BOOL couldDefineVariable = [[MPEvaluationContext sharedContext] redefineVariable:variableName
|
||||
value:value];
|
||||
if (!couldDefineVariable) {
|
||||
if (error) {
|
||||
NSString *localizedDescription = [NSString stringWithFormat:NSLocalizedString(@"Redifinition of variable \"%@\".", nil), variableName];
|
||||
*error = [NSError errorWithDomain:MPMathKitErrorDomain
|
||||
code:100
|
||||
userInfo:@{NSLocalizedDescriptionKey: localizedDescription}];
|
||||
}
|
||||
}
|
||||
return couldDefineVariable;
|
||||
}
|
||||
|
||||
- (NSDecimalNumber *)valueForVariable:(NSString *)variableName
|
||||
error:(NSError *__autoreleasing *)error
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user