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