QBrainfuck/decoderthread.cpp

113 lines
2.7 KiB
C++

#include "decoderthread.h"
DecoderThread::DecoderThread(QObject *parent) :
QThread(parent)
{
}
DecoderThread::~DecoderThread()
{
wait();
}
void DecoderThread::decode(QByteArray program, QByteArray input)
{
this->program = program;
this->input = input;
start();
}
void DecoderThread::run()
{
char* program = new char[this->program.size() + 1];
strcpy(program, this->program.data());
int programLength = this->program.size();
char* input = new char[this->input.size() + 1];
strcpy(input, this->input.data());
int inputLength = this->program.size();
actualDecode(program, programLength, input, inputLength);
delete program;
delete input;
}
void DecoderThread::actualDecode(char* program, int programLength, char* input, int inputLength)
{
// Don't use QList or QByteArray, it's too slow
char memory[65536];
int ptr = 0;
QString text;
QMap<int,int> correspondingBraces;
QStack<int> loopStack;
int programIndex = 0;
int inputIndex = 0;
for (programIndex = 0; programIndex < programLength; ++programIndex) {
switch (program[programIndex]) {
case '[':
loopStack.push(programIndex);
break;
case ']':
if(loopStack.isEmpty()) {
emit errorMessage("Unmatched end of loop");
return;
}
int old_i = loopStack.pop();
correspondingBraces.insert(programIndex, old_i);
correspondingBraces.insert(old_i, programIndex);
break;
}
}
if(!loopStack.isEmpty()) {
emit errorMessage("Unmatched begin of loop");
return;
}
for (programIndex = 0; programIndex < programLength; ++programIndex) {
switch (program[programIndex]) {
case '>':
++ptr;
break;
case '<':
--ptr;
break;
case '+':
++memory[ptr];
break;
case '-':
--memory[ptr];
break;
case '.':
text += (QString(memory[ptr]));
if (memory[ptr] == '\n') {
emit programDecoded(text);
}
break;
case ',':
if (inputIndex < inputLength) {
memory[ptr] = input[inputIndex];
++inputIndex;
} else {
memory[ptr] = 0;
}
break;
case '[':
if (memory[ptr] == 0) {
programIndex = correspondingBraces.value(programIndex);
}
break;
case ']':
if (memory[ptr] != 0) {
programIndex = correspondingBraces.value(programIndex);
}
break;
}
}
emit programDecoded(text);
}