From 368b7b42a8b66577a4068cac402c29a7433f4808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathana=C3=ABl=20Restori?= Date: Wed, 13 Aug 2014 22:53:13 +0200 Subject: [PATCH] Rewrite decoder --- qbrainfuck.cpp | 159 +++++++++++++++++++++++-------------------------- qbrainfuck.h | 4 +- qbrainfuck.ui | 76 +++++++++-------------- 3 files changed, 105 insertions(+), 134 deletions(-) diff --git a/qbrainfuck.cpp b/qbrainfuck.cpp index 517d051..19a2a67 100644 --- a/qbrainfuck.cpp +++ b/qbrainfuck.cpp @@ -20,11 +20,11 @@ void QBrainfuck::on_encodeButton_clicked() ui->debugTextEdit->setHtml(""); // First pass : find decades/steps - QList decades; // Store the decades for initial loop + QList decades; // Store the decades for initial loop decades.append(0); - QList array; // Store the program's memory - array.append(0); - QList steps; // Store the steps to construct the program + QList memory; // Store the program's memory + memory.append(0); + QList steps; // Store the steps to construct the program QString debugNumbers; QString debugChars; @@ -32,25 +32,25 @@ void QBrainfuck::on_encodeButton_clicked() QByteArray::const_iterator textIterator; for (textIterator = text.constBegin(); textIterator != text.constEnd(); ++textIterator) { int max_diff = ui->maxSignsSpinBox->value()+1; - QList::iterator index; + QList::iterator index; // Find nearest memory's case and store it - QList::iterator arrayIterator; - for (arrayIterator = array.begin(); arrayIterator != array.end(); ++arrayIterator) { - if (qAbs(*arrayIterator-*textIterator) < max_diff) { - max_diff = qAbs(*arrayIterator-*textIterator); - index = arrayIterator; + QList::iterator memoryIterator; + for (memoryIterator = memory.begin(); memoryIterator != memory.end(); ++memoryIterator) { + if (qAbs(*memoryIterator-*textIterator) < max_diff) { + max_diff = qAbs(*memoryIterator-*textIterator); + index = memoryIterator; } } - // Add step and insert current value in the array, else add a decade if we don't find a case nearer than max_diff + // Add step and insert current value in the memory, else add a decade if we don't find a case nearer than max_diff if (max_diff <= ui->maxSignsSpinBox->value()) { steps.append(*index); *index = *textIterator; } else { steps.append(qRound(*textIterator/(float)ui->decadesSpinBox->value())*ui->decadesSpinBox->value()); decades.append(qRound(*textIterator/(float)ui->decadesSpinBox->value())*ui->decadesSpinBox->value()); - array.append(*textIterator); + memory.append(*textIterator); } // Add current char to debug (with corresponding ASCII value) @@ -65,30 +65,30 @@ void QBrainfuck::on_encodeButton_clicked() ui->debugTextEdit->insertHtml("# The message

" + QString(text) + "

# In ASCII

" + debugNumbers + "
" + debugChars + "

# The memory

"); - for(int i = 0; i < ui->decadesSpinBox->value(); ++i) { + for (int i = 0; i < ui->decadesSpinBox->value(); ++i) { program += "+"; } program += "\["; - QList::iterator decadesIterator; + QList::iterator decadesIterator; for (decadesIterator = decades.begin()+1; decadesIterator != decades.end(); ++decadesIterator) { program += ">"; - for(int i = 0; i < *decadesIterator; i+=ui->decadesSpinBox->value()) { + for (int i = 0; i < *decadesIterator; i+=ui->decadesSpinBox->value()) { program += "+"; } } - for(int i = 0; i < decades.size()-1; ++i) { + for (int i = 0; i < decades.size()-1; ++i) { program += "<"; } program += "-]"; // Print initial loop to debug QString debugText; - for(int multiplier = 0; multiplier <= ui->decadesSpinBox->value(); ++multiplier) { + for (int multiplier = 0; multiplier <= ui->decadesSpinBox->value(); ++multiplier) { debugText += "  " + formatNumber(ui->decadesSpinBox->value()-multiplier) + ""; - for(int i = 1; i < decades.length(); ++i) { + for (int i = 1; i < decades.length(); ++i) { debugText += formatNumber(decades[i]/ui->decadesSpinBox->value()*multiplier); } @@ -99,27 +99,27 @@ void QBrainfuck::on_encodeButton_clicked() int prev_ptr = 0; - QList::const_iterator stepsIterator; + QList::const_iterator stepsIterator; textIterator = text.constBegin(); for (stepsIterator = steps.constBegin(); stepsIterator != steps.constEnd(); ++stepsIterator) { int next_ptr = decades.indexOf(*stepsIterator); - if(next_ptr > prev_ptr) { - for(int i = 0; i < next_ptr-prev_ptr; ++i) { + if (next_ptr > prev_ptr) { + for (int i = 0; i < next_ptr-prev_ptr; ++i) { program += ">"; } } else { - for(int i = 0; i < prev_ptr-next_ptr; ++i) { + for (int i = 0; i < prev_ptr-next_ptr; ++i) { program += "<"; } } - if(*textIterator > *stepsIterator) { - for(int i = 0; i < *textIterator-*stepsIterator; ++i) { + if (*textIterator > *stepsIterator) { + for (int i = 0; i < *textIterator-*stepsIterator; ++i) { program += "+"; } } else { - for(int i = 0; i < *stepsIterator-*textIterator; ++i) { + for (int i = 0; i < *stepsIterator-*textIterator; ++i) { program += "-"; } } @@ -129,7 +129,7 @@ void QBrainfuck::on_encodeButton_clicked() decades[next_ptr] = *textIterator; // Print current memory and current letter - printMemory(decades, decades.length(), next_ptr, " " + QString(*textIterator)); + printMemory(decades, next_ptr, " " + QString(*textIterator)); ++textIterator; } @@ -143,68 +143,74 @@ void QBrainfuck::on_decodeButton_clicked() ui->textTextEdit->setPlainText(""); ui->debugTextEdit->setHtml(""); - bool exit = false; int ptr = 0; - int maxPtr = 0; - QByteArray text = ui->programTextEdit->document()->toPlainText().toLatin1(); - QByteArray array = QByteArray(ui->arraySpinBox->value(), (char)0); + QByteArray program = ui->programTextEdit->document()->toPlainText().toLatin1(); QByteArray input = ui->inputLineEdit->text().toLatin1(); - QByteArray::const_iterator last_textIterator; QByteArray::const_iterator inputIterator = input.constBegin(); - QByteArray::const_iterator textIterator; - int loopCounter = 0; - for (textIterator = text.constBegin(); textIterator != text.constEnd() && exit == false; ++textIterator) { + QList memory; + QMap correspondingBraces; + QStack loopStack; - switch (*textIterator) { + memory.append(0); + + for (int i = 0; i < program.size(); ++i) { + switch (program.at(i)) { + case '[': + loopStack.push(i); + break; + case ']': + if(loopStack.isEmpty()) { + QMessageBox::critical(this, "QBrainfuck error", "Error: Unmatched end of loop"); + return; + } + int old_i = loopStack.pop(); + correspondingBraces.insert(i, old_i); + correspondingBraces.insert(old_i, i); + break; + } + } + if(!loopStack.isEmpty()) { + QMessageBox::critical(this, "QBrainfuck error", "Error: Unmatched begin of loop"); + return; + } + + for (int i = 0; i < program.size(); ++i) { + switch (program.at(i)) { case '>': ++ptr; - if (ptr >= ui->arraySpinBox->value()) { - ptr = 0; - } - if(maxPtr < ptr) { - maxPtr = ptr; + if(ptr == memory.size()) { + memory.append(0); } break; case '<': --ptr; if (ptr < 0) { - ptr = ui->arraySpinBox->value()-1; - maxPtr = ptr; + QMessageBox::critical(this, "QBrainfuck error", "Error: Pointer went under 0"); + return; } break; case '+': - array[ptr] = array.at(ptr) + 1; + ++memory[ptr]; break; case '-': - array[ptr] = array.at(ptr) - 1; + --memory[ptr]; break; case '.': - ui->textTextEdit->insertPlainText(QString(array.at(ptr))); - printMemory(array, maxPtr, ptr, "OUTPUT:     " + QString(array.at(ptr))); + ui->textTextEdit->insertPlainText(QString(memory.at(ptr))); break; case ',': - array[ptr] = *inputIterator; + memory[ptr] = *inputIterator; ++inputIterator; - printMemory(array, maxPtr, ptr, "INPUT:      " + QString(array.at(ptr))); break; case '[': - last_textIterator = textIterator; - loopCounter = 0; - printMemory(array, maxPtr, ptr, "LOOP BEG.    "); + if (memory.at(ptr) == 0) { + i = correspondingBraces.value(i); + } break; case ']': - if(array.at(ptr)!=0) { - textIterator = last_textIterator; - ++loopCounter; - - if (loopCounter >= ui->loopSpinBox->value()) { - QMessageBox::critical(this, "QBrainfuck", "Error: Loop too long"); - exit = true; - } - printMemory(array, maxPtr, ptr, "LOOP         "); - } else { - printMemory(array, maxPtr, ptr, "LOOP END     "); + if (memory.at(ptr) != 0) { + i = correspondingBraces.value(i); } break; } @@ -217,7 +223,7 @@ void QBrainfuck::on_motifButton_clicked() QByteArray program = ui->programTextEdit->document()->toPlainText().toLatin1(); if (motif.contains(QRegExp(">|<|\\+|-|\\.|,|\\[|\\]"))) { - QMessageBox::critical(this, "QBrainfuck", "Error: Motif contains Brainfuck characters"); + QMessageBox::critical(this, "QBrainfuck error", "Error: Motif contains Brainfuck characters"); return; } @@ -280,7 +286,7 @@ void QBrainfuck::on_saveButton_clicked() return; } - if(dialog.selectedNameFilter() == "Json Files (*.json)") { + if (dialog.selectedNameFilter() == "Json Files (*.json)") { QJsonObject jsonObject; jsonObject["text"] = ui->textTextEdit->document()->toPlainText(); @@ -329,7 +335,7 @@ void QBrainfuck::on_loadButton_clicked() QString QBrainfuck::formatNumber(int number) { - if(number < 10) { + if (number < 10) { return "   " + QString().setNum(number); } else if (number < 100) { return "  " + QString().setNum(number); @@ -338,27 +344,14 @@ QString QBrainfuck::formatNumber(int number) } } -void QBrainfuck::printMemory(QByteArray array, int maxPtr, int ptr, QString text) +void QBrainfuck::printMemory(QList memory, int ptr, QString text) { QString str; - for(int i = 0; i <= maxPtr; ++i) { - if(i == ptr) { - str += "" + formatNumber(array[i]) + ""; + for (int i = 0; i < memory.size(); ++i) { + if (i == ptr) { + str += "" + formatNumber(memory[i]) + ""; } else { - str += formatNumber(array[i]); - } - } - ui->debugTextEdit->insertHtml(text + str + "
"); -} - -void QBrainfuck::printMemory(QList array, int maxPtr, int ptr, QString text) -{ - QString str; - for(int i = 0; i < maxPtr; ++i) { - if(i == ptr) { - str += "" + formatNumber(array[i]) + ""; - } else { - str += formatNumber(array[i]); + str += formatNumber(memory[i]); } } ui->debugTextEdit->insertHtml(text + str + "
"); diff --git a/qbrainfuck.h b/qbrainfuck.h index 61ab2f9..a978f41 100644 --- a/qbrainfuck.h +++ b/qbrainfuck.h @@ -6,6 +6,7 @@ #include #include #include +#include namespace Ui { class QBrainfuck; @@ -42,8 +43,7 @@ private: Ui::QBrainfuck *ui; QString formatNumber(int number); - void printMemory(QByteArray array, int maxPtr, int ptr, QString text); - void printMemory(QList array, int maxPtr, int ptr, QString text); + void printMemory(QList memory, int ptr, QString text); }; #endif // QBRAINFUCK_H diff --git a/qbrainfuck.ui b/qbrainfuck.ui index 43384aa..694676e 100644 --- a/qbrainfuck.ui +++ b/qbrainfuck.ui @@ -176,50 +176,30 @@ QFormLayout::ExpandingFieldsGrow - - - - Max loop length - - - - - - - 100000 - - - 500 - - - - - - Array size - - - - - - - 100000 - - - 100 - - - - Input - + + + + + # + + + + + + + Motif regex + + + @@ -236,6 +216,12 @@ + + 1 + + + 255 + 10 @@ -248,22 +234,14 @@ - - - - Motif regex - - - - - - - # - - - + + 1 + + + 255 + 10