113 lines
2.7 KiB
C++
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);
|
|
}
|