Skip to content

Commit

Permalink
added support for logical not
Browse files Browse the repository at this point in the history
  • Loading branch information
davedelong committed Oct 1, 2011
1 parent 34c91e5 commit 4ee8716
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 9 deletions.
1 change: 1 addition & 0 deletions DDMathParser/DDMathEvaluator.m
Expand Up @@ -271,6 +271,7 @@ + (NSSet *) _standardFunctions {
//logical functions
@"l_and",
@"l_or",
@"l_not",
nil];
});
return standardFunctions;
Expand Down
27 changes: 20 additions & 7 deletions DDMathParser/DDMathStringTokenizer.m
Expand Up @@ -92,12 +92,12 @@ - (id)initWithString:(NSString *)expressionString error:(NSError **)error {
return nil;
}
}

[self _processToken:nil withError:error];

if (error && *error) {
DD_RELEASE(self);
self = nil;
} else {
[self _processToken:nil withError:nil];
}
}

Expand All @@ -119,10 +119,7 @@ - (void)dealloc {

- (BOOL)_processToken:(DDMathStringToken *)token withError:(NSError **)error {
//figure out if "-" and "+" are unary or binary
BOOL shouldContinue = [self _processUnknownOperatorToken:token withError:error];
if (!shouldContinue) {
return NO;
}
(void)[self _processUnknownOperatorToken:token withError:error];

if ([token operatorType] == DDOperatorUnaryPlus) {
// the unary + operator is a no-op operator. It does nothing, so we'll throw it out
Expand All @@ -140,8 +137,8 @@ - (BOOL)_processToken:(DDMathStringToken *)token withError:(NSError **)error {
}

- (BOOL)_processUnknownOperatorToken:(DDMathStringToken *)token withError:(NSError **)error {
DDMathStringToken *previousToken = [_tokens lastObject];
if ([token tokenType] == DDTokenTypeOperator && [token operatorType] == DDOperatorInvalid) {
DDMathStringToken *previousToken = [_tokens lastObject];
DDOperator resolvedOperator = DDOperatorInvalid;

BOOL shouldBeUnary = NO;
Expand All @@ -168,6 +165,14 @@ - (BOOL)_processUnknownOperatorToken:(DDMathStringToken *)token withError:(NSErr
}
}

if ([[token token] isEqual:@"!"]) {
if (previousToken == nil) {
resolvedOperator = DDOperatorLogicalNot;
} else if ([previousToken tokenType] == DDTokenTypeOperator && [previousToken operatorType] != DDOperatorParenthesisClose) {
resolvedOperator = DDOperatorLogicalNot;
}
}

[token resolveToOperator:resolvedOperator];

if ([token operatorType] == DDOperatorInvalid) {
Expand All @@ -177,6 +182,14 @@ - (BOOL)_processUnknownOperatorToken:(DDMathStringToken *)token withError:(NSErr
return NO;
}
}

if (token == nil && [[previousToken token] isEqual:@"!"]) {
[previousToken resolveToOperator:DDOperatorFactorial];
if (error != nil) {
*error = nil;
}
}

return YES;
}

Expand Down
2 changes: 2 additions & 0 deletions DDMathParser/DDParser.m
Expand Up @@ -145,6 +145,8 @@ - (DDOperatorAssociativity) associativityForOperator:(DDOperator)operatorType {

// factorial is always left associative
case DDOperatorFactorial: return DDOperatorAssociativityLeft;
// logical not is always right associative
case DDOperatorLogicalNot: return DDOperatorAssociativityRight;

default: return DDOperatorAssociativityLeft;
}
Expand Down
1 change: 1 addition & 0 deletions DDMathParser/DDParserTypes.h
Expand Up @@ -25,6 +25,7 @@ typedef enum {

DDOperatorLogicalOr,
DDOperatorLogicalAnd,
DDOperatorLogicalNot,

DDOperatorBitwiseOr,
DDOperatorBitwiseXor,
Expand Down
3 changes: 1 addition & 2 deletions DDMathParser/NSString+DDMathParsing.m
Expand Up @@ -18,9 +18,8 @@ - (NSNumber *) numberByEvaluatingString {
- (NSNumber *) numberByEvaluatingStringWithSubstitutions:(NSDictionary *)substitutions {
NSError *error = nil;
NSNumber *returnValue = [self numberByEvaluatingStringWithSubstitutions:substitutions error:&error];
if (error != nil) {
if (returnValue == nil) {
NSLog(@"error: %@", error);
return nil;
}
return returnValue;
}
Expand Down
1 change: 1 addition & 0 deletions DDMathParser/_DDFunctionUtilities.h
Expand Up @@ -98,5 +98,6 @@

+ (DDMathFunction) l_andFunction;
+ (DDMathFunction) l_orFunction;
+ (DDMathFunction) l_notFunction;

@end
12 changes: 12 additions & 0 deletions DDMathParser/_DDFunctionUtilities.m
Expand Up @@ -1097,4 +1097,16 @@ + (DDMathFunction) l_orFunction {
return DD_AUTORELEASE([function copy]);
}

+ (DDMathFunction) l_notFunction {
DDMathFunction function = ^ DDExpression* (NSArray *arguments, NSDictionary *variables, DDMathEvaluator *evaluator, NSError **error) {
#pragma unused(variables, evaluator)
REQUIRE_N_ARGS(1);
NSNumber *n = [[arguments objectAtIndex:0] evaluateWithSubstitutions:variables evaluator:evaluator error:error];
NSNumber *result = [NSNumber numberWithBool:![n boolValue]];
return [DDExpression numberExpressionWithNumber:result];

};
return DD_AUTORELEASE([function copy]);
}

@end
3 changes: 3 additions & 0 deletions DDMathParser/_DDOperatorInfo.m
Expand Up @@ -50,6 +50,9 @@ + (NSArray *)_buildOperators {
[operators addObject:[self infoForOperator:DDOperatorLogicalAnd arity:DDOperatorArityBinary precedence:precedence token:@"&&" function:@"l_and"]];
precedence++;

[operators addObject:[self infoForOperator:DDOperatorLogicalNot arity:DDOperatorArityUnary precedence:precedence token:@"!" function:@"l_not"]];
precedence++;

[operators addObject:[self infoForOperator:DDOperatorBitwiseOr arity:DDOperatorArityBinary precedence:precedence token:@"|" function:@"or"]];
precedence++;

Expand Down

0 comments on commit 4ee8716

Please sign in to comment.