Permalink
Browse files

added support for logical not

  • Loading branch information...
1 parent 34c91e5 commit 4ee87166178129c46460c5439aa9d466026d4efe @davedelong committed Oct 1, 2011
@@ -271,6 +271,7 @@ + (NSSet *) _standardFunctions {
//logical functions
@"l_and",
@"l_or",
+ @"l_not",
nil];
});
return standardFunctions;
@@ -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];
}
}
@@ -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
@@ -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;
@@ -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) {
@@ -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;
}
View
@@ -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;
}
@@ -25,6 +25,7 @@ typedef enum {
DDOperatorLogicalOr,
DDOperatorLogicalAnd,
+ DDOperatorLogicalNot,
DDOperatorBitwiseOr,
DDOperatorBitwiseXor,
@@ -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;
}
@@ -98,5 +98,6 @@
+ (DDMathFunction) l_andFunction;
+ (DDMathFunction) l_orFunction;
++ (DDMathFunction) l_notFunction;
@end
@@ -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
@@ -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++;

0 comments on commit 4ee8716

Please sign in to comment.