Skip to content

Commit

Permalink
New operators cannot be ambiguous or conflict with existing operators
Browse files Browse the repository at this point in the history
  • Loading branch information
davedelong committed Jan 4, 2014
1 parent 0438a26 commit 07bc615
Showing 1 changed file with 20 additions and 6 deletions.
26 changes: 20 additions & 6 deletions DDMathParser/DDMathOperator.m
Expand Up @@ -15,6 +15,9 @@
@implementation DDMathOperator

- (id)initWithOperatorFunction:(NSString *)function tokens:(NSArray *)tokens arity:(DDOperatorArity)arity associativity:(DDOperatorAssociativity)associativity {
if (arity == DDOperatorArityUnknown) {
[NSException raise:NSInvalidArgumentException format:@"Unable to create operator with unknown arity"];
}
return [self initWithOperatorFunction:function tokens:tokens arity:arity precedence:0 associativity:associativity];
}

Expand Down Expand Up @@ -46,7 +49,7 @@ + (instancetype)infoForOperatorFunction:(NSString *)function {

+ (NSArray *)infosForOperatorToken:(NSString *)token {
[self _buildOperators];
return [_operatorsByToken objectForKey:token];
return [_operatorsByToken objectForKey:[token lowercaseString]];
}

+ (void)_processNewOperator:(DDMathOperator *)newOperator relative:(NSComparisonResult)relative {
Expand All @@ -60,6 +63,15 @@ + (void)_processNewOperator:(DDMathOperator *)newOperator relative:(NSComparison
[existingOperatorForFunction addTokens:newOperator.tokens];
} else {
// there is not. this is a genuinely new operator

// first, make sure the tokens involved in this new operator are unique
for (NSString *token in newOperator.tokens) {
DDMathOperator *existing = [_operatorsByToken objectForKey:[token lowercaseString]];
if (existing != nil) {
[NSException raise:NSInvalidArgumentException format:@"An operator is already defined for '%@'", token];
}
}

[_allOperators addObject:newOperator];

if (relative != NSOrderedSame) {
Expand Down Expand Up @@ -90,17 +102,18 @@ + (void)_processNewOperator:(DDMathOperator *)newOperator relative:(NSComparison
}

for (NSString *token in newOperator.tokens) {
NSMutableArray *operatorsForToken = [_operatorsByToken objectForKey:token];
NSString *lowercaseToken = [token lowercaseString];
NSMutableArray *operatorsForToken = [_operatorsByToken objectForKey:lowercaseToken];
if (operatorsForToken == nil) {
operatorsForToken = [NSMutableArray array];
[_operatorsByToken setObject:operatorsForToken forKey:token];
[_operatorsByToken setObject:operatorsForToken forKey:lowercaseToken];
}
[operatorsForToken addObject:resolvedOperator];
}
}

+ (void)addTokens:(NSArray *)tokens forOperatorFunction:(NSString *)operatorFunction {
DDMathOperator *newOperator = [[DDMathOperator alloc] initWithOperatorFunction:operatorFunction tokens:tokens arity:0 associativity:0];
DDMathOperator *newOperator = [[DDMathOperator alloc] initWithOperatorFunction:operatorFunction tokens:tokens arity:0 precedence:0 associativity:0];
DDMathOperator *existing = [self infoForOperatorFunction:operatorFunction];
if (existing == nil) {
[NSException raise:NSInvalidArgumentException format:@"No operator is defined for function '%@'", operatorFunction];
Expand Down Expand Up @@ -236,10 +249,11 @@ + (void)_buildOperators {
for (DDMathOperator *op in _allOperators) {
NSArray *tokens = [op tokens];
for (NSString *token in tokens) {
NSMutableArray *operatorsForThisToken = [_operatorsByToken objectForKey:token];
NSString *lowercaseToken = [token lowercaseString];
NSMutableArray *operatorsForThisToken = [_operatorsByToken objectForKey:lowercaseToken];
if (operatorsForThisToken == nil) {
operatorsForThisToken = [NSMutableArray array];
[_operatorsByToken setObject:operatorsForThisToken forKey:token];
[_operatorsByToken setObject:operatorsForThisToken forKey:lowercaseToken];
}
[operatorsForThisToken addObject:op];
}
Expand Down

0 comments on commit 07bc615

Please sign in to comment.