Archive Project
This commit is contained in:
130
Brainfuck/Interpreter.m
Executable file
130
Brainfuck/Interpreter.m
Executable file
@@ -0,0 +1,130 @@
|
||||
//
|
||||
// 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
|
||||
Reference in New Issue
Block a user