Permalink
Browse files

Parity with the old term system

  • Loading branch information...
1 parent 74d8f6d commit 33bbe840ec9b7cf5db417ba8bf1f0d3b42f2c34a @davedelong committed Jul 14, 2011
@@ -19,10 +19,11 @@
+ (id) mathStringTokenWithToken:(NSString *)t type:(DDTokenType)type;
-@property (readonly) NSString * token;
-@property (readonly) DDTokenType tokenType;
-@property (readonly) DDOperator operatorType;
-@property DDPrecedence operatorPrecedence;
+@property (nonatomic,readonly) NSString * token;
+@property (nonatomic,readonly) DDTokenType tokenType;
+@property (nonatomic,readonly) DDOperator operatorType;
+@property (nonatomic,readonly) DDOperatorArity operatorArity;
+@property (nonatomic) DDPrecedence operatorPrecedence;
- (NSNumber *) numberValue;
@@ -9,7 +9,7 @@
#import "DDMathStringToken.h"
@implementation DDMathStringToken
-@synthesize token, tokenType, operatorType, operatorPrecedence;
+@synthesize token, tokenType, operatorType, operatorPrecedence, operatorArity;
- (void) dealloc {
[token release];
@@ -24,27 +24,33 @@ - (id) initWithToken:(NSString *)t type:(DDTokenType)type {
tokenType = type;
operatorType = DDOperatorInvalid;
operatorPrecedence = DDPrecedenceNone;
+ operatorArity = DDOperatorArityUnknown;
if (tokenType == DDTokenTypeOperator) {
if ([token isEqual:@"|"]) {
operatorType = DDOperatorBitwiseOr;
operatorPrecedence = DDPrecedenceBitwiseOr;
+ operatorArity = DDOperatorArityBinary;
}
if ([token isEqual:@"^"]) {
operatorType = DDOperatorBitwiseXor;
operatorPrecedence = DDPrecedenceBitwiseXor;
+ operatorArity = DDOperatorArityBinary;
}
if ([token isEqual:@"&"]) {
operatorType = DDOperatorBitwiseAnd;
operatorPrecedence = DDPrecedenceBitwiseAnd;
+ operatorArity = DDOperatorArityBinary;
}
if ([token isEqual:@"<<"]) {
operatorType = DDOperatorLeftShift;
operatorPrecedence = DDPrecedenceLeftShift;
+ operatorArity = DDOperatorArityBinary;
}
if ([token isEqual:@">>"]) {
operatorType = DDOperatorRightShift;
operatorPrecedence = DDPrecedenceRightShift;
+ operatorArity = DDOperatorArityBinary;
}
if ([token isEqual:@"-"]) {
operatorType = DDOperatorMinus;
@@ -57,26 +63,32 @@ - (id) initWithToken:(NSString *)t type:(DDTokenType)type {
if ([token isEqual:@"/"]) {
operatorType = DDOperatorDivide;
operatorPrecedence = DDPrecedenceDivision;
+ operatorArity = DDOperatorArityBinary;
}
if ([token isEqual:@"*"]) {
operatorType = DDOperatorMultiply;
operatorPrecedence = DDPrecedenceMultiplication;
+ operatorArity = DDOperatorArityBinary;
}
if ([token isEqual:@"%"]) {
operatorType = DDOperatorModulo;
operatorPrecedence = DDPrecedenceModulo;
+ operatorArity = DDOperatorArityBinary;
}
if ([token isEqual:@"~"]) {
operatorType = DDOperatorBitwiseNot;
operatorPrecedence = DDPrecedenceUnary;
+ operatorArity = DDOperatorArityUnary;
}
if ([token isEqual:@"!"]) {
operatorType = DDOperatorFactorial;
operatorPrecedence = DDPrecedenceFactorial;
+ operatorArity = DDOperatorArityUnary;
}
if ([token isEqual:@"**"]) {
operatorType = DDOperatorPower;
operatorPrecedence = DDPrecedencePower;
+ operatorArity = DDOperatorArityBinary;
}
if ([token isEqual:@"("]) {
operatorType = DDOperatorParenthesisOpen;
@@ -128,4 +140,15 @@ - (DDOperator) operatorType {
return operatorType;
}
+- (void)setOperatorPrecedence:(DDPrecedence)precedence {
+ if (operatorArity == DDOperatorArityUnknown) {
+ if (precedence == DDPrecedenceUnary || precedence == DDPrecedenceFactorial) {
+ operatorArity = DDOperatorArityUnary;
+ } else if (precedence != DDPrecedenceNone) {
+ operatorArity = DDOperatorArityBinary;
+ }
+ }
+ operatorPrecedence = precedence;
+}
+
@end
View
@@ -122,6 +122,7 @@ - (void) dealloc {
- (DDOperatorAssociativity) associativityForOperator:(DDOperator)operatorType {
switch (operatorType) {
+ // binary operators can have customizable associativity
case DDOperatorBitwiseOr: return bitwiseOrAssociativity;
case DDOperatorBitwiseXor: return bitwiseXorAssociativity;
case DDOperatorBitwiseAnd: return bitwiseAndAssociativity;
@@ -134,8 +135,14 @@ - (DDOperatorAssociativity) associativityForOperator:(DDOperator)operatorType {
case DDOperatorModulo: return modAssociativity;
case DDOperatorPower: return powerAssociativity;
- //unary operators are right associative (factorial doesn't really count)
+ // unary operators are always right associative (except for factorial)
+ case DDOperatorUnaryPlus:
+ case DDOperatorUnaryMinus:
case DDOperatorBitwiseNot: return DDOperatorAssociativityRight;
+
+ // factorial is always left associative
+ case DDOperatorFactorial: return DDOperatorAssociativityLeft;
+
default: return DDOperatorAssociativityLeft;
}
return DDOperatorAssociativityLeft;
@@ -44,6 +44,13 @@ typedef enum {
DDOperatorUnaryPlus
} DDOperator;
+typedef enum {
+ DDOperatorArityUnknown = 0,
+
+ DDOperatorArityUnary,
+ DDOperatorArityBinary
+} DDOperatorArity;
+
enum {
DDPrecedenceBitwiseOr = 0,
DDPrecedenceBitwiseXor,
@@ -12,4 +12,6 @@
@property (nonatomic,readonly) NSString *functionName;
+- (id)_initWithFunction:(NSString *)function subterms:(NSArray *)terms error:(NSError **)error;
+
@end
@@ -12,9 +12,19 @@
#import "DDMathParserMacros.h"
#import "_DDOperatorTerm.h"
+#import "DDExpression.h"
+
@implementation _DDFunctionTerm
@synthesize functionName;
+- (id)_initWithFunction:(NSString *)function subterms:(NSArray *)terms error:(NSError **)error {
+ self = [super _initWithSubterms:terms error:error];
+ if (self) {
+ functionName = [function copy];
+ }
+ return self;
+}
+
- (id)_initWithTokenizer:(DDMathStringTokenizer *)tokenizer error:(NSError **)error {
DDMathStringToken *token = [tokenizer nextToken];
@@ -29,18 +39,37 @@ - (id)_initWithTokenizer:(DDMathStringTokenizer *)tokenizer error:(NSError **)er
if ([term type] == DDParserTermTypeOperator && [(_DDOperatorTerm *)term operatorType] == DDOperatorComma) {
NSArray *parameterGroupTerms = [[self subterms] subarrayWithRange:subrange];
- NSError *error = nil;
- _DDGroupTerm *parameterGroup = [[_DDGroupTerm alloc] _initWithSubterms:parameterGroupTerms error:&error];
- if (parameterGroup) {
- [newSubterms addObject:parameterGroup];
+ if ([parameterGroupTerms count] != 1) {
+ _DDGroupTerm *parameterGroup = [[_DDGroupTerm alloc] _initWithSubterms:parameterGroupTerms error:error];
+ if (parameterGroup) {
+ [newSubterms addObject:parameterGroup];
+ }
+ [parameterGroup release];
+ } else {
+ // there's only one term in this parameter; no need to group it in parentheses
+ [newSubterms addObject:[parameterGroupTerms objectAtIndex:0]];
}
- [parameterGroup release];
+
subrange.location = NSMaxRange(subrange)+1;
subrange.length = 0;
} else {
subrange.length++;
}
}
+
+ // get the last parameter
+ NSRange rangeOfLastParameter;
+ rangeOfLastParameter.location = subrange.location;
+ rangeOfLastParameter.length = [[self subterms] count]-rangeOfLastParameter.location;
+ if (rangeOfLastParameter.length > 1) {
+ NSArray *lastParameters = [[self subterms] subarrayWithRange:rangeOfLastParameter];
+ _DDGroupTerm *parameterGroup = [[_DDGroupTerm alloc] _initWithSubterms:lastParameters error:error];
+ [newSubterms addObject:parameterGroup];
+ [parameterGroup release];
+ } else {
+ [newSubterms addObject:[[self subterms] objectAtIndex:rangeOfLastParameter.location]];
+ }
+
[self _setSubterms:newSubterms];
}
return self;
@@ -53,6 +82,12 @@ - (void)dealloc {
- (DDParserTermType)type { return DDParserTermTypeFunction; }
+- (NSString *)description {
+ NSArray *parameterDescriptions = [[self subterms] valueForKey:@"description"];
+ NSString *parameters = [parameterDescriptions componentsJoinedByString:@","];
+ return [NSString stringWithFormat:@"%@(%@)", functionName, parameters];
+}
+
- (BOOL)resolveWithParser:(DDParser *)parser error:(NSError **)error {
if ([self isResolved]) { return YES; }
@@ -66,4 +101,18 @@ - (BOOL)resolveWithParser:(DDParser *)parser error:(NSError **)error {
return YES;
}
+- (DDExpression *)expressionWithError:(NSError **)error {
+ ERR_ASSERT(error);
+
+ NSMutableArray *parameters = [NSMutableArray array];
+ for (_DDParserTerm *term in [self subterms]) {
+ DDExpression *parameter = [term expressionWithError:error];
+ if (!parameter) { return nil; }
+
+ [parameters addObject:parameter];
+ }
+
+ return [DDExpression functionExpressionWithFunction:functionName arguments:parameters error:error];
+}
+
@end
Oops, something went wrong.

0 comments on commit 33bbe84

Please sign in to comment.