Archived
1

Added the MPExpressionTree Classes

This commit is contained in:
Kim Wittenburg
2014-10-13 23:53:04 +02:00
parent 82259f87e2
commit 5592128926
60 changed files with 1981 additions and 725 deletions

View File

@@ -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