Added the MPExpressionTree Classes
This commit is contained in:
@@ -9,7 +9,12 @@
|
||||
#import "MPTokenStream.h"
|
||||
|
||||
@implementation MPTokenStream {
|
||||
NSUInteger _currentTokenIndex;
|
||||
NSUInteger eofLocation;
|
||||
|
||||
BOOL *whitespaceIgnores;
|
||||
NSUInteger maxWhitespaceIgnores;
|
||||
NSUInteger currentWhitespaceState;
|
||||
}
|
||||
|
||||
- (instancetype)initWithTokens:(NSArray *)tokens
|
||||
@@ -17,65 +22,96 @@
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.tokens = tokens;
|
||||
self.ignoringWhitespaceTokens = YES;
|
||||
whitespaceIgnores = malloc(10 * sizeof(BOOL));
|
||||
maxWhitespaceIgnores = 10;
|
||||
currentWhitespaceState = 0;
|
||||
[self beginAcceptingWhitespaceTokens];
|
||||
_currentTokenIndex = 0;
|
||||
if (tokens.count > 0) {
|
||||
eofLocation = NSMaxRange([tokens.lastObject range]);
|
||||
} else {
|
||||
eofLocation = 0;
|
||||
}
|
||||
[self reset];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)beginAcceptingWhitespaceTokens
|
||||
{
|
||||
[self pushWhitespaceState:YES];
|
||||
}
|
||||
|
||||
- (void)beginIgnoringWhitespaceTokens
|
||||
{
|
||||
[self pushWhitespaceState:NO];
|
||||
}
|
||||
|
||||
- (void)pushWhitespaceState:(BOOL)state
|
||||
{
|
||||
currentWhitespaceState++;
|
||||
if (currentWhitespaceState >= maxWhitespaceIgnores) {
|
||||
maxWhitespaceIgnores += 10;
|
||||
BOOL *reallocatedWhitespaceIgnores = realloc(whitespaceIgnores, maxWhitespaceIgnores);
|
||||
if (reallocatedWhitespaceIgnores) {
|
||||
whitespaceIgnores = reallocatedWhitespaceIgnores;
|
||||
} else {
|
||||
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Realloc Failed" userInfo:nil];
|
||||
}
|
||||
}
|
||||
whitespaceIgnores[currentWhitespaceState] = state;
|
||||
}
|
||||
|
||||
- (void)endIgnoringOrAcceptingWhitespaceTokens
|
||||
{
|
||||
currentWhitespaceState--;
|
||||
}
|
||||
|
||||
- (void)skipWhitespaces
|
||||
{
|
||||
if (!self.isIgnoringWhitespaceTokens) {
|
||||
if (whitespaceIgnores[currentWhitespaceState]) {
|
||||
return;
|
||||
}
|
||||
while (self.currentTokenIndex < self.tokens.count) {
|
||||
MPToken *token = self.tokens[self.currentTokenIndex];
|
||||
while (_currentTokenIndex < self.tokens.count) {
|
||||
MPToken *token = self.tokens[_currentTokenIndex];
|
||||
if (token.tokenType != MPWhitespaceToken) {
|
||||
return;
|
||||
}
|
||||
++self.currentTokenIndex;
|
||||
[self currentTokenConsumed];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)reset
|
||||
{
|
||||
self.currentTokenIndex = 0;
|
||||
[self skipWhitespaces];
|
||||
}
|
||||
|
||||
- (BOOL)hasMoreTokens
|
||||
{
|
||||
[self skipWhitespaces];
|
||||
return self.currentTokenIndex < self.tokens.count;
|
||||
return _currentTokenIndex < self.tokens.count;
|
||||
}
|
||||
|
||||
- (MPToken *)nextToken
|
||||
- (MPToken *)currentToken
|
||||
{
|
||||
[self skipWhitespaces];
|
||||
if (self.currentTokenIndex >= self.tokens.count) {
|
||||
if (_currentTokenIndex >= _tokens.count) {
|
||||
return [[MPToken alloc] initEOFTokenAtLocation:eofLocation];
|
||||
} else {
|
||||
MPToken *token = self.tokens[self.currentTokenIndex++];
|
||||
return token;
|
||||
}
|
||||
return _tokens[_currentTokenIndex];
|
||||
}
|
||||
|
||||
- (MPToken *)nextTokenOfType:(MPTokenType)type
|
||||
- (MPToken *)peekNextToken
|
||||
{
|
||||
[self skipWhitespaces];
|
||||
if (self.currentTokenIndex >= self.tokens.count) {
|
||||
return nil;
|
||||
} else {
|
||||
MPToken *token = self.tokens[self.currentTokenIndex];
|
||||
if (token.tokenType != type) {
|
||||
return nil;
|
||||
}
|
||||
++self.currentTokenIndex;
|
||||
return token;
|
||||
}
|
||||
NSUInteger currentTokenIndex = _currentTokenIndex;
|
||||
[self currentTokenConsumed]; // Pretend the current token has been consumed
|
||||
MPToken *token = [self currentToken];
|
||||
_currentTokenIndex = currentTokenIndex; // Undo the lookahead
|
||||
return token;
|
||||
}
|
||||
|
||||
- (void)currentTokenConsumed
|
||||
{
|
||||
++_currentTokenIndex;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
free(whitespaceIgnores);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user