Archived
1

Cleaned Code & Fixed Some Errors

This commit is contained in:
Kim Wittenburg
2014-11-29 00:20:05 +01:00
parent b6973dc24a
commit 98e4a6dde6
13 changed files with 61 additions and 101 deletions

View File

@@ -20,8 +20,6 @@
- (BOOL)defineVariable:(NSString *)variable - (BOOL)defineVariable:(NSString *)variable
value:(NSDecimalNumber *)value; value:(NSDecimalNumber *)value;
- (BOOL)redefineVariable:(NSString *)variable
value:(NSDecimalNumber *)value;
- (void)undefineVariable:(NSString *)variable; - (void)undefineVariable:(NSString *)variable;
- (NSDecimalNumber *)valueForVariable:(NSString *)variable; - (NSDecimalNumber *)valueForVariable:(NSString *)variable;

View File

@@ -53,6 +53,7 @@ static MPEvaluationContext *sharedContext;
- (BOOL)defineVariable:(NSString *)variable - (BOOL)defineVariable:(NSString *)variable
value:(NSDecimalNumber *)value value:(NSDecimalNumber *)value
{ {
[self undefineVariable:variable];
if ([self isVariableDefined:variable]) { if ([self isVariableDefined:variable]) {
return NO; return NO;
} }
@@ -61,14 +62,6 @@ static MPEvaluationContext *sharedContext;
return YES; return YES;
} }
- (BOOL)redefineVariable:(NSString *)variable
value:(NSDecimalNumber *)value
{
[self undefineVariable:variable];
return [self defineVariable:variable
value:value];
}
- (void)undefineVariable:(NSString *)variable - (void)undefineVariable:(NSString *)variable
{ {
NSMutableDictionary *currentBindings = self.stack.lastObject; NSMutableDictionary *currentBindings = self.stack.lastObject;

View File

@@ -490,7 +490,7 @@ typedef NS_ENUM(NSUInteger, MPReferenceFrame) {
is restored. That basically means that subsequent strings are is restored. That basically means that subsequent strings are
joined and empty strings removed. After restoring integrity the joined and empty strings removed. After restoring integrity the
receiver sends a @c receiver sends a @c
-didChangeElementsInIndexedRangePath:replacementLength: to -changedElementsInIndexedRangePath:replacementLength: to
itself. For more information see the documentation on that itself. For more information see the documentation on that
method. method.
@@ -509,6 +509,30 @@ typedef NS_ENUM(NSUInteger, MPReferenceFrame) {
withElements:(NSArray *)elements; 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: @method subexpressionFromIndex:referenceFrame:
@brief Creates an expression from the items in the receiver from the @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 - (MPParsedExpression *)parseExpectingVariable:(BOOL)flag
errors:(NSArray *__autoreleasing *)errors; 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 @end

View File

@@ -561,7 +561,7 @@ NSString *const MPIllegalElementExceptionElementKey = @"MPIllegalElementExceptio
} }
[self fixElements]; [self fixElements];
[self didChangeElementsInRangePath:[[MPRangePath alloc] initWithRange:_editedRange] [self changedElementsInRangePath:[[MPRangePath alloc] initWithRange:_editedRange]
replacementLength:_replacementLength]; 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 - (MPExpression *)subexpressionFromIndex:(NSUInteger)from
referenceFrame:(MPReferenceFrame)referenceFrame 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 #pragma mark Basic NSObject Methods

View File

@@ -15,8 +15,6 @@
@interface MPExpressionStorage : MPExpression @interface MPExpressionStorage : MPExpression
- (instancetype)initWithElements:(NSArray *)elements;
@property (nonatomic, weak) MPExpressionView *expressionView; // Do not set @property (nonatomic, weak) MPExpressionView *expressionView; // Do not set
@property (nonatomic, strong) MPExpressionLayout *rootLayout; @property (nonatomic, strong) MPExpressionLayout *rootLayout;

View File

@@ -35,10 +35,10 @@
{ {
_expressionView = expressionView; _expressionView = expressionView;
self.rootLayout = [[MPExpressionLayout alloc] initWithExpression:self parent:nil]; 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 replacementLength:(NSUInteger)replacementLength
{ {
if (rangePath.location.length == 0) { if (rangePath.location.length == 0) {

View File

@@ -14,16 +14,18 @@
- (NSDecimalNumber *)doEvaluation:(NSError *__autoreleasing *)error - (NSDecimalNumber *)doEvaluation:(NSError *__autoreleasing *)error
{ {
NSDecimalNumber *nominator = [[self expressionAtIndex:0] evaluate:error]; MPEvaluateExpression(nominator, 0);
if (!nominator) { MPEvaluateExpression(denominator, 1);
if ([denominator isEqualToNumber:@0]) {
if (error) {
*error = [NSError errorWithDomain:MPMathKitErrorDomain
code:100
userInfo:@{NSLocalizedDescriptionKey: NSLocalizedString(@"Division by zero.", nil)}];
}
return 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 @end

View File

@@ -121,7 +121,7 @@
{ {
NSUInteger selfIndex = [self.parent indexOfElement:self]; NSUInteger selfIndex = [self.parent indexOfElement:self];
MPRangePath *newPath = MPMakeRangePath([rangePath.location indexPathByPreceedingIndex:selfIndex], rangePath.length); MPRangePath *newPath = MPMakeRangePath([rangePath.location indexPathByPreceedingIndex:selfIndex], rangePath.length);
[self.parent didChangeElementsInRangePath:newPath [self.parent changedElementsInRangePath:newPath
replacementLength:replacementLength]; replacementLength:replacementLength];
} }

View File

@@ -8,6 +8,8 @@
#import "MPTerm.h" #import "MPTerm.h"
#define MPEvaluateExpression(var, index) NSDecimalNumber *var = [[self expressionAtIndex:index] evaluate:error]; if (var == nil) return nil
@class MPFunctionTerm, MPFunction, MPParsedExpression; @class MPFunctionTerm, MPFunction, MPParsedExpression;

View File

@@ -13,14 +13,9 @@
- (NSDecimalNumber *)doEvaluation:(NSError *__autoreleasing *)error - (NSDecimalNumber *)doEvaluation:(NSError *__autoreleasing *)error
{ {
NSDecimalNumber *exponent = [[self expressionAtIndex:0] evaluate:error]; MPEvaluateExpression(exponent, 0);
if (!exponent) {
return nil;
}
NSDecimalNumber *base = [self.baseTerm evaluate:error]; NSDecimalNumber *base = [self.baseTerm evaluate:error];
if (!base) { ReturnNilIfNil(base);
return nil;
}
if ([base isEqualToNumber:@(0)] && [exponent isEqualToNumber:@(0)]) { if ([base isEqualToNumber:@(0)] && [exponent isEqualToNumber:@(0)]) {
// The C pow function returns 1 for pow(0, 0). Mathematically this should be undefined. // The C pow function returns 1 for pow(0, 0). Mathematically this should be undefined.
if (error) { if (error) {

View File

@@ -15,23 +15,21 @@
- (NSDecimalNumber *)doEvaluation:(NSError *__autoreleasing *)error - (NSDecimalNumber *)doEvaluation:(NSError *__autoreleasing *)error
{ {
MPParsedExpression *startExpression = [self expressionAtIndex:0]; MPParsedExpression *startExpression = [self expressionAtIndex:0];
MPParsedExpression *targetExpression = [self expressionAtIndex:1];
MPParsedExpression *sumExpression = [self expressionAtIndex:2]; MPParsedExpression *sumExpression = [self expressionAtIndex:2];
NSDecimalNumber *start = [startExpression evaluate:error]; NSDecimalNumber *start = [startExpression evaluate:error];
NSDecimalNumber *target = [targetExpression evaluate:error]; ReturnNilIfNil(start);
MPEvaluateExpression(target, 1);
NSDecimalNumber *value = [NSDecimalNumber zero]; NSDecimalNumber *value = [NSDecimalNumber zero];
for (NSDecimalNumber *current = start; for (NSDecimalNumber *current = start;
[current compare:target] <= 0; [current compare:target] <= 0;
current = [current decimalNumberByAdding:[[NSDecimalNumber alloc] initWithInteger:1]]) { 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; return nil;
} }
NSDecimalNumber *currentValue = [sumExpression evaluate:error]; NSDecimalNumber *currentValue = [sumExpression evaluate:error];
if (!currentValue) { ReturnNilIfNil(currentValue);
return nil;
}
value = [value decimalNumberByAdding:currentValue]; value = [value decimalNumberByAdding:currentValue];
} }
return value; return value;

View File

@@ -6,6 +6,9 @@
// Copyright (c) 2014 Kim Wittenburg. All rights reserved. // 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; @class MPTerm;
@@ -18,9 +21,6 @@
- (BOOL)defineVariable:(NSString *)variableName - (BOOL)defineVariable:(NSString *)variableName
value:(NSDecimalNumber *)value value:(NSDecimalNumber *)value
error:(NSError *__autoreleasing *)error; error:(NSError *__autoreleasing *)error;
- (BOOL)redefineVariable:(NSString *)variableName
value:(NSDecimalNumber *)value
error:(NSError *__autoreleasing *)error;
- (NSDecimalNumber *)valueForVariable:(NSString *)variableName - (NSDecimalNumber *)valueForVariable:(NSString *)variableName
error:(NSError *__autoreleasing *)error; error:(NSError *__autoreleasing *)error;
- (void)undefineVariable:(NSString *)variableName; // Should rarely be needed, defined variables are automatically undefined at the end of evaluation. - (void)undefineVariable:(NSString *)variableName; // Should rarely be needed, defined variables are automatically undefined at the end of evaluation.

View File

@@ -45,23 +45,6 @@
return couldDefineVariable; 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 - (NSDecimalNumber *)valueForVariable:(NSString *)variableName
error:(NSError *__autoreleasing *)error error:(NSError *__autoreleasing *)error
{ {