71 lines
1.8 KiB
Objective-C
Executable File
71 lines
1.8 KiB
Objective-C
Executable File
//
|
|
// Lexer.m
|
|
// Brainfuck
|
|
//
|
|
// Created by Kim Wittenburg on 20.05.13.
|
|
// Copyright (c) 2013 brainfuck. All rights reserved.
|
|
//
|
|
|
|
#import "Lexer.h"
|
|
|
|
@implementation Lexer {
|
|
NSString *script;
|
|
NSInteger pos;
|
|
NSInteger loopNestingLevel;
|
|
NSMutableArray *tokens;
|
|
}
|
|
|
|
+ (Lexer *)lexer
|
|
{
|
|
return [[self alloc] init];
|
|
}
|
|
|
|
- (id)init
|
|
{
|
|
self = [super init];
|
|
if (self) {
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (NSArray *)performLexingOnString:(NSString *)s error:(NSError *__autoreleasing *)error
|
|
{
|
|
pos = 0;
|
|
loopNestingLevel = -1;
|
|
script = s;
|
|
tokens = [[NSMutableArray alloc] init];
|
|
[self matchNextTokensInto:tokens error:error];
|
|
if (error) {
|
|
return nil;
|
|
}
|
|
return tokens;
|
|
}
|
|
|
|
- (void)matchNextTokensInto:(NSMutableArray *)target error:(NSError *__autoreleasing *)error;
|
|
{
|
|
while (pos < script.length) {
|
|
int c = [script characterAtIndex:pos++];
|
|
NSString *character = [NSString stringWithFormat:@"%c", c];
|
|
if (c == '-' || c == '+' || c == '<' || c == '>' || c == '.' || c == ',') {
|
|
[target addObject:character];
|
|
} else if (c == '[') {
|
|
loopNestingLevel++;
|
|
NSMutableArray *subTokens = [NSMutableArray new];
|
|
[self matchNextTokensInto:subTokens error:error];
|
|
[target addObject:subTokens];
|
|
} else if (c == ']') {
|
|
if (loopNestingLevel-- == -1) {
|
|
NSError *err = [NSError errorWithDomain:@"Lexer" code:101 userInfo:@{NSLocalizedDescriptionKey: @"] without mathcing ["}];
|
|
*error = err;
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
if (loopNestingLevel >= 0) {
|
|
*error = [NSError errorWithDomain:@"Lexer" code:102 userInfo:@{NSLocalizedDescriptionKey: @"unclosed loop"}];
|
|
}
|
|
}
|
|
|
|
@end
|