Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

adding conditions to rewrite rules

  • Loading branch information...
commit 77c91a4eedb226c40c4e2fa14f0a7eae4b4cd159 1 parent 979d36e
@davedelong authored
View
2  DDMathParser.xcodeproj/project.pbxproj
@@ -598,6 +598,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ CLANG_ENABLE_OBJC_ARC = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
@@ -620,6 +621,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ CLANG_ENABLE_OBJC_ARC = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
View
2  DDMathParser/DDMathEvaluator.h
@@ -30,7 +30,7 @@
- (BOOL) addAlias:(NSString *)alias forFunctionName:(NSString *)functionName;
- (void) removeAlias:(NSString *)alias;
-- (void)addRewriteRule:(NSString *)rule forExpressionsMatchingTemplate:(NSString *)template;
+- (void)addRewriteRule:(NSString *)rule forExpressionsMatchingTemplate:(NSString *)template condition:(NSString *)condition;
- (DDExpression *)expressionByRewritingExpression:(DDExpression *)expression;
@end
View
26 DDMathParser/DDMathEvaluator.m
@@ -137,8 +137,8 @@ - (void) removeAlias:(NSString *)alias {
[self unregisterFunctionWithName:alias];
}
-- (void)addRewriteRule:(NSString *)rule forExpressionsMatchingTemplate:(NSString *)template {
- _DDRewriteRule *rewriteRule = [_DDRewriteRule rewriteRuleWithTemplate:template replacementPattern:rule];
+- (void)addRewriteRule:(NSString *)rule forExpressionsMatchingTemplate:(NSString *)template condition:(NSString *)condition {
+ _DDRewriteRule *rewriteRule = [_DDRewriteRule rewriteRuleWithTemplate:template replacementPattern:rule condition:condition];
[rewriteRules addObject:rewriteRule];
}
@@ -339,12 +339,6 @@ + (NSDictionary *)_standardRewriteRules {
@"pow(__exp1, 2)", @"__exp1 * __exp1",
@"multiply(__var1, __num1)", @"multiply(__num1, __var1)",
- //division
- @"1", @"__exp1 / __exp1",
- @"__exp1", @"__exp2 * __exp1 / __exp2",
- @"1/__exp1", @"__exp2 / (__exp2 * __exp1)",
- @"1/__exp1", @"__exp2 / (__exp1 * __exp2)",
-
//other stuff
@"__exp1", @"--__exp1",
@"exp(__exp1 + __exp2)", @"exp(__exp1) * exp(__exp2)",
@@ -352,7 +346,6 @@ + (NSDictionary *)_standardRewriteRules {
@"1", @"pow(__exp1, 0)",
@"__exp1", @"pow(__exp1, 1)",
@"abs(__exp1)", @"sqrt(pow(__exp1, 2))",
- @"abs(__exp1)", @"nthroot(pow(__exp1, __exp2), __exp2)",
//
@"__exp1", @"dtor(rtod(__exp1))",
@@ -391,12 +384,23 @@ - (void)_registerStandardRewriteRules {
for (NSString *template in templates) {
NSString *replacement = [templates objectForKey:template];
- [self addRewriteRule:replacement forExpressionsMatchingTemplate:template];
+ [self addRewriteRule:replacement forExpressionsMatchingTemplate:template condition:nil];
}
+
+ //division
+ [self addRewriteRule:@"1" forExpressionsMatchingTemplate:@"__exp1 / __exp1" condition:@"__exp1 != 0"];
+ [self addRewriteRule:@"__exp1" forExpressionsMatchingTemplate:@"(__exp1 * __exp2) / __exp2" condition:@"__exp2 != 0"];
+ [self addRewriteRule:@"__exp1" forExpressionsMatchingTemplate:@"(__exp2 * __exp1) / __exp2" condition:@"__exp2 != 0"];
+ [self addRewriteRule:@"1/__exp1" forExpressionsMatchingTemplate:@"__exp2 / (__exp2 * __exp1)" condition:@"__exp2 != 0"];
+ [self addRewriteRule:@"1/__exp1" forExpressionsMatchingTemplate:@"__exp2 / (__exp1 * __exp2)" condition:@"__exp2 != 0"];
+
+ //exponents and roots
+ [self addRewriteRule:@"abs(__exp1)" forExpressionsMatchingTemplate:@"nthroot(pow(__exp1, __exp2), __exp2)" condition:@"__exp2 % 2 == 0"];
+ [self addRewriteRule:@"__exp1" forExpressionsMatchingTemplate:@"nthroot(pow(__exp1, __exp2), __exp2)" condition:@"__exp2 % 2 == 1"];
}
- (DDExpression *)_rewriteExpression:(DDExpression *)expression usingRule:(_DDRewriteRule *)rule {
- DDExpression *rewritten = [rule expressionByRewritingExpression:expression];
+ DDExpression *rewritten = [rule expressionByRewritingExpression:expression withEvaluator:self];
// if the rule did not match, return the expression
if (rewritten == expression && [expression expressionType] == DDExpressionTypeFunction) {
View
7 DDMathParser/_DDRewriteRule.h
@@ -13,13 +13,14 @@
@interface _DDRewriteRule : NSObject {
DDExpression *predicate;
DDExpression *pattern;
+ DDExpression *condition;
}
-+ (_DDRewriteRule *)rewriteRuleWithTemplate:(NSString *)string replacementPattern:(NSString *)replacement;
++ (_DDRewriteRule *)rewriteRuleWithTemplate:(NSString *)string replacementPattern:(NSString *)replacement condition:(NSString *)condition;
-- (BOOL)ruleMatchesExpression:(DDExpression *)target;
+- (BOOL)ruleMatchesExpression:(DDExpression *)target withEvaluator:(DDMathEvaluator *)evaluator;
// returns nil if the rule does not match the target expression
-- (DDExpression *)expressionByRewritingExpression:(DDExpression *)target;
+- (DDExpression *)expressionByRewritingExpression:(DDExpression *)target withEvaluator:(DDMathEvaluator *)evaluator;
@end
View
36 DDMathParser/_DDRewriteRule.m
@@ -12,17 +12,17 @@
@interface _DDRewriteRule ()
-- (id)initWithTemplate:(NSString *)string replacementPattern:(NSString *)pattern;
+- (id)initWithTemplate:(NSString *)string replacementPattern:(NSString *)pattern condition:(NSString *)condition;
@end
@implementation _DDRewriteRule
-+ (_DDRewriteRule *)rewriteRuleWithTemplate:(NSString *)string replacementPattern:(NSString *)replacement {
- return DD_AUTORELEASE([[self alloc] initWithTemplate:string replacementPattern:replacement]);
++ (_DDRewriteRule *)rewriteRuleWithTemplate:(NSString *)string replacementPattern:(NSString *)replacement condition:(NSString *)condition {
+ return DD_AUTORELEASE([[self alloc] initWithTemplate:string replacementPattern:replacement condition:condition]);
}
-- (id)initWithTemplate:(NSString *)string replacementPattern:(NSString *)patternFormat {
+- (id)initWithTemplate:(NSString *)string replacementPattern:(NSString *)patternFormat condition:(NSString *)conditionFormat {
self = [super init];
if (self) {
NSError *error = nil;
@@ -34,6 +34,10 @@ - (id)initWithTemplate:(NSString *)string replacementPattern:(NSString *)pattern
DD_RELEASE(self);
return nil;
}
+
+ if (conditionFormat) {
+ condition = DD_RETAIN([DDExpression expressionFromString:conditionFormat error:&error]);
+ }
}
return self;
}
@@ -42,6 +46,7 @@ - (id)initWithTemplate:(NSString *)string replacementPattern:(NSString *)pattern
- (void)dealloc {
[predicate release];
[pattern release];
+ [condition release];
[super dealloc];
}
#endif
@@ -115,10 +120,6 @@ - (BOOL)_ruleExpression:(DDExpression *)rule matchesExpression:(DDExpression *)t
return argsMatch;
}
-- (BOOL)ruleMatchesExpression:(DDExpression *)target {
- return [self _ruleExpression:predicate matchesExpression:target withReplacements:[NSMutableDictionary dictionary]];
-}
-
- (DDExpression *)_expressionByApplyingReplacements:(NSDictionary *)replacements toPattern:(DDExpression *)p {
if ([p expressionType] == DDExpressionTypeVariable) { return p; }
if ([p expressionType] == DDExpressionTypeNumber) { return p; }
@@ -139,9 +140,24 @@ - (DDExpression *)_expressionByApplyingReplacements:(NSDictionary *)replacements
return [DDExpression functionExpressionWithFunction:pFunction arguments:replacedArguments error:nil];
}
-- (DDExpression *)expressionByRewritingExpression:(DDExpression *)target {
+- (BOOL)matchExpression:(DDExpression *)target replacements:(NSMutableDictionary *)replacements evaluator:(DDMathEvaluator *)evaluator {
+ BOOL matches = [self _ruleExpression:predicate matchesExpression:target withReplacements:replacements];
+ if (matches && condition) {
+ DDExpression *resolvedCondition = [self _expressionByApplyingReplacements:replacements toPattern:condition];
+ NSError *evalError = nil;
+ NSNumber *result = [resolvedCondition evaluateWithSubstitutions:replacements evaluator:evaluator error:&evalError];
+ matches &= [result boolValue];
+ }
+ return matches;
+}
+
+- (BOOL)ruleMatchesExpression:(DDExpression *)target withEvaluator:(DDMathEvaluator *)evaluator {
+ return [self matchExpression:target replacements:[NSMutableDictionary dictionary] evaluator:evaluator];
+}
+
+- (DDExpression *)expressionByRewritingExpression:(DDExpression *)target withEvaluator:(DDMathEvaluator *)evaluator {
NSMutableDictionary *replacements = [NSMutableDictionary dictionary];
- if (![self _ruleExpression:predicate matchesExpression:target withReplacements:replacements]) { return target; }
+ if (![self matchExpression:target replacements:replacements evaluator:evaluator]) { return target; }
return [self _expressionByApplyingReplacements:replacements toPattern:pattern];
}
Please sign in to comment.
Something went wrong with that request. Please try again.