131 lines
2.4 KiB
Objective-C
Executable File
131 lines
2.4 KiB
Objective-C
Executable File
//
|
|
// Interpreter.m
|
|
// Brainfuck
|
|
//
|
|
// Created by Kim Wittenburg on 20.05.13.
|
|
// Copyright (c) 2013 brainfuck. All rights reserved.
|
|
//
|
|
|
|
#import "Interpreter.h"
|
|
|
|
#import "Lexer.h"
|
|
|
|
@implementation Interpreter {
|
|
NSMutableArray *a;
|
|
NSInteger level;
|
|
NSString *input;
|
|
NSInteger inPos;
|
|
}
|
|
|
|
@synthesize printer;
|
|
|
|
+ (Interpreter *)interpreter
|
|
{
|
|
return [[self alloc] init];
|
|
}
|
|
|
|
- (id)init
|
|
{
|
|
self = [super init];
|
|
if (self) {
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)execute:(NSString *)script withInput:(NSString *)i error:(NSError *__autoreleasing *)error
|
|
{
|
|
input = i;
|
|
inPos = 0;
|
|
Lexer *lexer = [Lexer lexer];
|
|
NSArray *cmds = [lexer performLexingOnString:script error:error];
|
|
level = 0;
|
|
a = [NSMutableArray new];
|
|
[a addObject:[NSNumber numberWithInt:0]];
|
|
[self executeCommands:cmds];
|
|
}
|
|
|
|
- (void)executeCommands:(NSArray *)cmds
|
|
{
|
|
for (id cmd in cmds) {
|
|
if ([cmd isKindOfClass:[NSArray class]]) {
|
|
[self loop:cmd];
|
|
} else {
|
|
[self executeCommand:cmd];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)executeCommand:(NSString *)cmd
|
|
{
|
|
int c = [cmd characterAtIndex:0];
|
|
if (c == '+') {
|
|
[self increment];
|
|
} else if (c == '-') {
|
|
[self decrement];
|
|
} else if (c == '<') {
|
|
[self previousCell];
|
|
} else if (c == '>') {
|
|
[self nextCell];
|
|
} else if (c == '.') {
|
|
[self printCellValue];
|
|
} else if (c == ',') {
|
|
[self readNextInput];
|
|
}
|
|
}
|
|
|
|
- (void)increment
|
|
{
|
|
NSNumber *number = a[level];
|
|
number = [NSNumber numberWithInt:number.intValue+1];
|
|
a[level] = number;
|
|
}
|
|
|
|
- (void)decrement
|
|
{
|
|
NSNumber *number = a[level];
|
|
number = [NSNumber numberWithInt:number.intValue-1];
|
|
a[level] = number;
|
|
}
|
|
|
|
- (void)nextCell
|
|
{
|
|
if (++level == a.count) {
|
|
[a addObject:[NSNumber numberWithInt:0]];
|
|
}
|
|
}
|
|
|
|
- (void)previousCell
|
|
{
|
|
if (--level == -1) {
|
|
[a insertObject:[NSNumber numberWithInt:0] atIndex:0];
|
|
level++;
|
|
}
|
|
}
|
|
|
|
- (void)printCellValue
|
|
{
|
|
NSNumber *ascii = a[level];
|
|
NSString *text = [NSString stringWithFormat:@"%c", ascii.intValue];
|
|
[self.printer print:text];
|
|
}
|
|
|
|
- (void)readNextInput
|
|
{
|
|
int ascii;
|
|
if (inPos == input.length) {
|
|
ascii = 0;
|
|
} else {
|
|
ascii = [input characterAtIndex:inPos++];
|
|
}
|
|
a[level] = [NSNumber numberWithInt:ascii];
|
|
}
|
|
|
|
- (void)loop:(NSArray *)cmds
|
|
{
|
|
while (((NSNumber *)a[level]).intValue != 0) {
|
|
[self executeCommands:cmds];
|
|
}
|
|
}
|
|
|
|
@end
|