From a382b1f10bde6a28de3f7cbe9ed74e15f48bef9b Mon Sep 17 00:00:00 2001 From: Kim Wittenburg Date: Tue, 30 Sep 2014 22:18:51 +0200 Subject: [PATCH] Added Factorial, added parts of exponents --- MathPad/Base.lproj/MPDocument.xib | 18 +++++++----------- MathPad/MPExpressionEvaluator.m | 25 ++++++++++++++++++++++--- MathPad/MPExpressionTokenizer.m | 9 +++++++-- MathPad/MPTerm.h | 2 ++ MathPad/MPTerm.m | 21 +++++++++++++++------ MathPad/MPToken.h | 1 + MathPad/MPTokenStream.h | 2 +- MathPad/MPTokenStream.m | 4 ---- 8 files changed, 55 insertions(+), 27 deletions(-) diff --git a/MathPad/Base.lproj/MPDocument.xib b/MathPad/Base.lproj/MPDocument.xib index c4c828d..1627610 100644 --- a/MathPad/Base.lproj/MPDocument.xib +++ b/MathPad/Base.lproj/MPDocument.xib @@ -1,7 +1,7 @@ - + - + @@ -13,22 +13,20 @@ - + - + - + - - + - @@ -40,7 +38,6 @@ - @@ -52,7 +49,6 @@ - @@ -61,7 +57,6 @@ - @@ -89,6 +84,7 @@ + diff --git a/MathPad/MPExpressionEvaluator.m b/MathPad/MPExpressionEvaluator.m index 410921e..e07ffb3 100644 --- a/MathPad/MPExpressionEvaluator.m +++ b/MathPad/MPExpressionEvaluator.m @@ -15,6 +15,7 @@ #import "MPTokenStream.h" #import "MPEvaluationContext.h" +#import "MPPowerFunction.h" @@ -171,7 +172,7 @@ switch (token.tokenType) { case MPNumberToken: { - return [[MPTerm alloc] initWithNumber:token.number]; + return [self decoratedTerm:[[MPTerm alloc] initWithNumber:token.number]]; } case MPVariableToken: @@ -180,12 +181,12 @@ self.error = MPParseError(token.range, @"Undefined Variable"); return nil; } - return [[MPTerm alloc] initWithVariable:token.variable]; + return [self decoratedTerm:[[MPTerm alloc] initWithVariable:token.variable]]; } case MPGenericFunctionToken: { - return [((MPFunction *)token) parseWithError:_error]; + return [self decoratedTerm:[((MPFunction *)token) parseWithError:_error]]; } case MPSinToken: @@ -241,4 +242,22 @@ } } +- (MPTerm *)decoratedTerm:(MPTerm *)term +{ + MPTerm *decoratedTerm = term; + MPToken *facultyToken = [tokenStream nextTokenOfType:MPFactorialToken]; + if (facultyToken) { + decoratedTerm = [[MPTerm alloc] initWithFactorialOfTerm:term]; + } + MPToken *powerToken = [tokenStream nextTokenOfType:MPGenericFunctionToken]; + if ([powerToken isKindOfClass:[MPPowerFunction class]]) { + MPPowerFunction *powerFunction = (MPPowerFunction *)powerToken; + powerFunction.baseTerm = decoratedTerm; + return [powerFunction parseWithError:_error]; + } else { + tokenStream.currentLocation--; + } + return decoratedTerm; +} + @end diff --git a/MathPad/MPExpressionTokenizer.m b/MathPad/MPExpressionTokenizer.m index 126f3e0..77d5577 100644 --- a/MathPad/MPExpressionTokenizer.m +++ b/MathPad/MPExpressionTokenizer.m @@ -45,6 +45,7 @@ @"(cos)|" @"(tan)|" @"([A-Za-z])|" + @"(!)|" @"(=)|" @"(\\s)" @")"; @@ -66,8 +67,9 @@ NSRange cosRange = [match rangeAtIndex:5]; NSRange tanRange = [match rangeAtIndex:6]; NSRange variableRange = [match rangeAtIndex:7]; - NSRange equalsRange = [match rangeAtIndex:8]; - NSRange whitespaceRange = [match rangeAtIndex:9]; + NSRange factorialRange = [match rangeAtIndex:8]; + NSRange equalsRange = [match rangeAtIndex:9]; + NSRange whitespaceRange = [match rangeAtIndex:10]; if (MPRangeExists(multiplicationSymbolRange)) { range = multiplicationSymbolRange; @@ -90,6 +92,9 @@ } else if (MPRangeExists(variableRange)) { range = variableRange; tokenType = MPVariableToken; + } else if (MPRangeExists(factorialRange)) { + range = factorialRange; + tokenType = MPFactorialToken; } else if (MPRangeExists(equalsRange)) { range = equalsRange; tokenType = MPEqualsToken; diff --git a/MathPad/MPTerm.h b/MathPad/MPTerm.h index 6b69acd..09dfe4c 100644 --- a/MathPad/MPTerm.h +++ b/MathPad/MPTerm.h @@ -17,6 +17,8 @@ - (instancetype)initWithFactors:(NSArray *)factors; // array of MPTerms - (instancetype)initWithVariable:(NSString *)variable; +- (instancetype)initWithFactorialOfTerm:(MPTerm *)term; + - (instancetype)initWithSinOfTerm:(MPTerm *)term; - (instancetype)initWithCosOfTerm:(MPTerm *)term; - (instancetype)initWithTanOfTerm:(MPTerm *)term; diff --git a/MathPad/MPTerm.m b/MathPad/MPTerm.m index 20e9d9e..6549787 100644 --- a/MathPad/MPTerm.m +++ b/MathPad/MPTerm.m @@ -62,27 +62,36 @@ }]; } +- (instancetype)initWithFactorialOfTerm:(MPTerm *)term +{ + return [self initWithBlock:^NSDecimalNumber *{ + NSDecimalNumber *termValue = [term evaluate]; + NSLog(@"Factorial of %@ = %f", termValue, tgamma(termValue.doubleValue + 1)); + return [[NSDecimalNumber alloc] initWithDouble:tgamma(termValue.doubleValue + 1)]; + }]; +} + - (instancetype)initWithSinOfTerm:(MPTerm *)term { return [self initWithBlock:^NSDecimalNumber *{ - NSDecimalNumber *sinValue = [term evaluate]; - return [[NSDecimalNumber alloc] initWithDouble:sin(sinValue.doubleValue)]; + NSDecimalNumber *termValue = [term evaluate]; + return [[NSDecimalNumber alloc] initWithDouble:sin(termValue.doubleValue)]; }]; } - (instancetype)initWithCosOfTerm:(MPTerm *)term { return [self initWithBlock:^NSDecimalNumber *{ - NSDecimalNumber *cosValue = [term evaluate]; - return [[NSDecimalNumber alloc] initWithDouble:cos(cosValue.doubleValue)]; + NSDecimalNumber *termValue = [term evaluate]; + return [[NSDecimalNumber alloc] initWithDouble:cos(termValue.doubleValue)]; }]; } - (instancetype)initWithTanOfTerm:(MPTerm *)term { return [self initWithBlock:^NSDecimalNumber *{ - NSDecimalNumber *tanValue = [term evaluate]; - return [[NSDecimalNumber alloc] initWithDouble:tan(tanValue.doubleValue)]; + NSDecimalNumber *termValue = [term evaluate]; + return [[NSDecimalNumber alloc] initWithDouble:tan(termValue.doubleValue)]; }]; } diff --git a/MathPad/MPToken.h b/MathPad/MPToken.h index fbeb113..0ab11d2 100644 --- a/MathPad/MPToken.h +++ b/MathPad/MPToken.h @@ -17,6 +17,7 @@ typedef NS_ENUM(NSUInteger, MPTokenType) { MPTanToken, MPNumberToken, MPVariableToken, + MPFactorialToken, MPEqualsToken, MPGenericFunctionToken, diff --git a/MathPad/MPTokenStream.h b/MathPad/MPTokenStream.h index 05fc9f6..3e0e54f 100644 --- a/MathPad/MPTokenStream.h +++ b/MathPad/MPTokenStream.h @@ -16,7 +16,7 @@ @property (nonatomic, copy) NSArray *tokens; @property (nonatomic, getter=isIgnoringWhitespaceTokens) BOOL ignoringWhitespaceTokens; // Default: YES -@property (readonly, nonatomic) NSUInteger currentLocation; +@property (nonatomic) NSUInteger currentLocation; - (void)reset; - (BOOL)hasMoreTokens; diff --git a/MathPad/MPTokenStream.m b/MathPad/MPTokenStream.m index 37f0ebe..99f3f9f 100644 --- a/MathPad/MPTokenStream.m +++ b/MathPad/MPTokenStream.m @@ -8,10 +8,6 @@ #import "MPTokenStream.h" -@interface MPTokenStream () -@property (readwrite, nonatomic) NSUInteger currentLocation; -@end - @implementation MPTokenStream { NSUInteger currentTokenIndex; NSUInteger eofLocation;