forked from davedelong/DDMathParser
/
DDMathStringToken.m
134 lines (111 loc) · 3.43 KB
/
DDMathStringToken.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//
// DDMathStringToken.m
// DDMathParser
//
// Created by Dave DeLong on 11/16/10.
// Copyright 2010 Home. All rights reserved.
//
#import "DDMathParser.h"
#import "DDMathStringToken.h"
#import "_DDOperatorInfo.h"
@implementation DDMathStringToken
@synthesize token, tokenType;
#if !DD_HAS_ARC
- (void) dealloc {
[token release];
[numberValue release];
[super dealloc];
}
#endif
- (id) initWithToken:(NSString *)t type:(DDTokenType)type {
self = [super init];
if (self) {
token = [t copy];
tokenType = type;
operatorType = DDOperatorInvalid;
if (tokenType == DDTokenTypeOperator) {
NSArray *matching = [_DDOperatorInfo infosForOperatorToken:t];
if ([matching count] == 0) {
DD_RELEASE(self);
return nil;
} else if ([matching count] == 1) {
operatorInfo = DD_RETAIN([matching objectAtIndex:0]);
} else {
ambiguous = YES;
}
}
}
return self;
}
+ (id) mathStringTokenWithToken:(NSString *)t type:(DDTokenType)type {
return DD_AUTORELEASE([[self alloc] initWithToken:t type:type]);
}
- (NSNumber *) numberValue {
if ([self tokenType] != DDTokenTypeNumber) { return nil; }
if (numberValue == nil) {
numberValue = [[NSDecimalNumber alloc] initWithString:[self token]];
if (numberValue == nil) {
NSLog(@"supposedly invalid number: %@", [self token]);
numberValue = [[NSNumber alloc] initWithInt:0];
}
}
return numberValue;
}
- (NSString *) description {
NSMutableString * d = [NSMutableString string];
if (tokenType == DDTokenTypeVariable) {
[d appendString:@"$"];
}
[d appendString:token];
return d;
}
- (NSString *)debugDescription {
NSMutableString *d = [NSMutableString stringWithString:[self description]];
if (tokenType == DDTokenTypeOperator) {
[d appendString:@" ("];
DDOperatorArity arity = [self operatorArity];
NSString *arityNames[3] = { @"UNK", @"UN", @"BIN" };
[d appendFormat:@"arity:%@, ", arityNames[arity]];
NSInteger precedence = [self operatorPrecedence];
[d appendFormat:@"precedence:%d, ", precedence];
DDOperatorAssociativity assoc = [self operatorAssociativity];
NSString *assocNames[2] = { @"LEFT", @"RIGHT" };
[d appendFormat:@"associativity:%@, ", assocNames[assoc]];
[d appendFormat:@"function:%@", [self operatorFunction]];
[d appendString:@")"];
}
return d;
}
- (NSString *)token {
return token;
}
- (NSString *)operatorType {
if (ambiguous) { return DDOperatorInvalid; }
return [operatorInfo function];
}
- (NSInteger)operatorPrecedence {
if (ambiguous) { return -1; }
return [operatorInfo precedence];
}
- (DDOperatorArity)operatorArity {
if (ambiguous) { return DDOperatorArityUnknown; }
return [operatorInfo arity];
}
- (NSString *)operatorFunction {
if (ambiguous) { return @""; }
return [operatorInfo function];
}
- (DDOperatorAssociativity)operatorAssociativity {
if (ambiguous) { return 0; }
return [operatorInfo defaultAssociativity];
}
- (void)resolveToOperator:(NSString *)operator {
DD_RELEASE(operatorInfo);
operatorInfo = nil;
NSArray *matching = [_DDOperatorInfo infosForOperatorFunction:operator];
if ([matching count] > 0) {
ambiguous = NO;
operatorInfo = DD_RETAIN([matching objectAtIndex:0]);
}
}
@end