#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 correspondingBraces; QStack 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); }