Initial commit
This commit is contained in:
commit
ec66620ad8
20
QBrainfuck.pro
Normal file
20
QBrainfuck.pro
Normal file
@ -0,0 +1,20 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2014-07-28T15:14:32
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = QBrainfuck
|
||||
TEMPLATE = app
|
||||
|
||||
|
||||
SOURCES += main.cpp\
|
||||
qbrainfuck.cpp
|
||||
|
||||
HEADERS += qbrainfuck.h
|
||||
|
||||
FORMS += qbrainfuck.ui
|
11
main.cpp
Normal file
11
main.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "qbrainfuck.h"
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
QBrainfuck w;
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
286
qbrainfuck.cpp
Normal file
286
qbrainfuck.cpp
Normal file
@ -0,0 +1,286 @@
|
||||
#include "qbrainfuck.h"
|
||||
#include "ui_qbrainfuck.h"
|
||||
|
||||
QBrainfuck::QBrainfuck(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::QBrainfuck)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
QBrainfuck::~QBrainfuck()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void QBrainfuck::on_encodeButton_clicked()
|
||||
{
|
||||
QByteArray text = ui->textTextEdit->document()->toPlainText().toLatin1();
|
||||
|
||||
// First pass : find decades/steps
|
||||
QList<char> decades; // Store the decades for initial loop
|
||||
decades.append(0);
|
||||
QList<char> array; // Store the program's memory
|
||||
array.append(0);
|
||||
QList<char> steps; // Store the steps to construct the program
|
||||
|
||||
QByteArray::const_iterator textIterator;
|
||||
for (textIterator = text.constBegin(); textIterator != text.constEnd(); ++textIterator) {
|
||||
int max_diff = ui->maxSignsSpinBox->value()+1;
|
||||
QList<char>::iterator index;
|
||||
|
||||
// Find nearest memory's case and store it
|
||||
QList<char>::iterator arrayIterator;
|
||||
for (arrayIterator = array.begin(); arrayIterator != array.end(); ++arrayIterator) {
|
||||
if (qAbs(*arrayIterator-*textIterator) < max_diff) {
|
||||
max_diff = qAbs(*arrayIterator-*textIterator);
|
||||
index = arrayIterator;
|
||||
}
|
||||
}
|
||||
|
||||
// Add step and insert current value in the array, 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);
|
||||
}
|
||||
}
|
||||
qSort(decades);
|
||||
|
||||
// Second pass : write program
|
||||
QString program = "";
|
||||
|
||||
for(int i = 0; i < ui->decadesSpinBox->value(); ++i) {
|
||||
program += "+";
|
||||
}
|
||||
|
||||
program += "\[";
|
||||
|
||||
QList<char>::iterator decadesIterator;
|
||||
for (decadesIterator = decades.begin()+1; decadesIterator != decades.end(); ++decadesIterator) {
|
||||
program += ">";
|
||||
for(int i = 0; i < *decadesIterator; i+=ui->decadesSpinBox->value()) {
|
||||
program += "+";
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < decades.size()-1; ++i) {
|
||||
program += "<";
|
||||
}
|
||||
program += "-]";
|
||||
|
||||
int prev_ptr = 0;
|
||||
|
||||
QList<char>::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) {
|
||||
program += ">";
|
||||
}
|
||||
} else {
|
||||
for(int i = 0; i < prev_ptr-next_ptr; ++i) {
|
||||
program += "<";
|
||||
}
|
||||
}
|
||||
|
||||
if(*textIterator > *stepsIterator) {
|
||||
for(int i = 0; i < *textIterator-*stepsIterator; ++i) {
|
||||
program += "+";
|
||||
}
|
||||
} else {
|
||||
for(int i = 0; i < *stepsIterator-*textIterator; ++i) {
|
||||
program += "-";
|
||||
}
|
||||
}
|
||||
|
||||
program += ".";
|
||||
prev_ptr = next_ptr;
|
||||
decades[next_ptr] = *textIterator;
|
||||
++textIterator;
|
||||
}
|
||||
|
||||
ui->programTextEdit->setPlainText(program);
|
||||
}
|
||||
|
||||
void QBrainfuck::on_decodeButton_clicked()
|
||||
{
|
||||
ui->textTextEdit->setPlainText("");
|
||||
|
||||
int ptr = 0;
|
||||
QByteArray text = ui->programTextEdit->document()->toPlainText().toLatin1();
|
||||
QByteArray array = QByteArray(ui->arraySpinBox->value(), (char)0);
|
||||
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(); ++textIterator) {
|
||||
|
||||
switch (*textIterator) {
|
||||
case '>':
|
||||
ptr++;
|
||||
if (ptr >= ui->arraySpinBox->value()) {
|
||||
QMessageBox::critical(this, "QBrainfuck", "Error: Pointer went upper than array's length");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case '<':
|
||||
ptr--;
|
||||
if (ptr < 0) {
|
||||
QMessageBox::critical(this, "QBrainfuck", "Error: Pointer went under 0");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case '+':
|
||||
array[ptr] = array.at(ptr) + 1;
|
||||
break;
|
||||
case '-':
|
||||
array[ptr] = array.at(ptr) - 1;
|
||||
break;
|
||||
case '.':
|
||||
ui->textTextEdit->insertPlainText(QString(array.at(ptr)));
|
||||
break;
|
||||
case ',':
|
||||
array[ptr] = *inputIterator;
|
||||
inputIterator++;
|
||||
break;
|
||||
case '[':
|
||||
last_textIterator = textIterator;
|
||||
loopCounter = 0;
|
||||
break;
|
||||
case ']':
|
||||
if(array.at(ptr)!=0) {
|
||||
textIterator = last_textIterator;
|
||||
loopCounter++;
|
||||
|
||||
if (loopCounter >= ui->loopSpinBox->value()) {
|
||||
QMessageBox::critical(this, "QBrainfuck", "Error: Loop too long");
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QBrainfuck::on_motifButton_clicked()
|
||||
{
|
||||
QString motif = ui->motifTextEdit->document()->toPlainText();
|
||||
QByteArray program = ui->programTextEdit->document()->toPlainText().toLatin1();
|
||||
|
||||
if (motif.contains(QRegExp(">|<|\\+|-|\\.|,|\\[|\\]"))) {
|
||||
QMessageBox::critical(this, "QBrainfuck", "Error: Motif contains Brainfuck characters");
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray::const_iterator programIterator;
|
||||
for (programIterator = program.constBegin(); programIterator != program.constEnd(); ++programIterator) {
|
||||
switch (*programIterator) {
|
||||
case '>':
|
||||
case '<':
|
||||
case '+':
|
||||
case '-':
|
||||
case '.':
|
||||
case ',':
|
||||
case '[':
|
||||
case ']':
|
||||
int index = motif.indexOf(QRegExp(ui->regexLineEdit->text()));
|
||||
if (index==-1) {
|
||||
motif += *programIterator;
|
||||
} else {
|
||||
motif.replace(index, 1, *programIterator);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ui->resultTextEdit->setPlainText(motif);
|
||||
}
|
||||
|
||||
void QBrainfuck::on_textTextEdit_textChanged()
|
||||
{
|
||||
ui->textLabel->setText("Text length: " + QString().setNum(ui->textTextEdit->document()->toPlainText().length()));
|
||||
}
|
||||
|
||||
void QBrainfuck::on_programTextEdit_textChanged()
|
||||
{
|
||||
ui->programLabel->setText("Program length: " + QString().setNum(ui->programTextEdit->document()->toPlainText().count(QRegExp(">|<|\\+|-|\\.|,|\\[|\\]"))));
|
||||
}
|
||||
|
||||
void QBrainfuck::on_motifTextEdit_textChanged()
|
||||
{
|
||||
ui->motifLabel->setText("Motif length: " + QString().setNum(ui->motifTextEdit->document()->toPlainText().count(QRegExp(ui->regexLineEdit->text()))));
|
||||
}
|
||||
|
||||
void QBrainfuck::on_regexLineEdit_textChanged(const QString &arg1)
|
||||
{
|
||||
on_motifTextEdit_textChanged();
|
||||
}
|
||||
|
||||
void QBrainfuck::on_saveButton_clicked()
|
||||
{
|
||||
QFileDialog dialog(this);
|
||||
dialog.setFileMode(QFileDialog::AnyFile);
|
||||
dialog.setNameFilter("Json Files (*.json);;Txt Files (*.txt)");
|
||||
dialog.setDefaultSuffix("json");
|
||||
dialog.setAcceptMode(QFileDialog::AcceptSave);
|
||||
|
||||
if (dialog.exec()) {
|
||||
QFile saveFile(dialog.selectedFiles().first());
|
||||
|
||||
if (!saveFile.open(QIODevice::WriteOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(dialog.selectedNameFilter() == "Json Files (*.json)") {
|
||||
QJsonObject jsonObject;
|
||||
|
||||
jsonObject["text"] = ui->textTextEdit->document()->toPlainText();
|
||||
jsonObject["program"] = ui->programTextEdit->document()->toPlainText();
|
||||
jsonObject["motif"] = ui->motifTextEdit->document()->toPlainText();
|
||||
jsonObject["result"] = ui->resultTextEdit->document()->toPlainText();
|
||||
|
||||
QJsonDocument jsonDoc(jsonObject);
|
||||
saveFile.write(jsonDoc.toJson());
|
||||
} else {
|
||||
saveFile.write(ui->textTextEdit->document()->toPlainText().toUtf8() + "\n\n");
|
||||
saveFile.write(ui->programTextEdit->document()->toPlainText().toUtf8() + "\n\n");
|
||||
saveFile.write(ui->motifTextEdit->document()->toPlainText().toUtf8() + "\n\n");
|
||||
saveFile.write(ui->resultTextEdit->document()->toPlainText().toUtf8() + "\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QBrainfuck::on_loadButton_clicked()
|
||||
{
|
||||
QFileDialog dialog(this);
|
||||
dialog.setFileMode(QFileDialog::AnyFile);
|
||||
dialog.setNameFilter("Json Files (*.json)");
|
||||
dialog.setDefaultSuffix("json");
|
||||
dialog.setAcceptMode(QFileDialog::AcceptOpen);
|
||||
|
||||
if (dialog.exec()) {
|
||||
QFile loadFile(dialog.selectedFiles().first());
|
||||
|
||||
if (!loadFile.open(QIODevice::ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray saveData = loadFile.readAll();
|
||||
|
||||
QJsonDocument jsonDoc(QJsonDocument::fromJson(saveData));
|
||||
QJsonObject jsonObject = jsonDoc.object();
|
||||
|
||||
ui->textTextEdit->setPlainText(jsonObject["text"].toString());
|
||||
ui->programTextEdit->setPlainText(jsonObject["program"].toString());
|
||||
ui->motifTextEdit->setPlainText(jsonObject["motif"].toString());
|
||||
ui->resultTextEdit->setPlainText(jsonObject["result"].toString());
|
||||
}
|
||||
}
|
45
qbrainfuck.h
Normal file
45
qbrainfuck.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef QBRAINFUCK_H
|
||||
#define QBRAINFUCK_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace Ui {
|
||||
class QBrainfuck;
|
||||
}
|
||||
|
||||
class QBrainfuck : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QBrainfuck(QWidget *parent = 0);
|
||||
~QBrainfuck();
|
||||
|
||||
private slots:
|
||||
void on_encodeButton_clicked();
|
||||
|
||||
void on_decodeButton_clicked();
|
||||
|
||||
void on_motifButton_clicked();
|
||||
|
||||
void on_textTextEdit_textChanged();
|
||||
|
||||
void on_programTextEdit_textChanged();
|
||||
|
||||
void on_motifTextEdit_textChanged();
|
||||
|
||||
void on_regexLineEdit_textChanged(const QString &arg1);
|
||||
|
||||
void on_saveButton_clicked();
|
||||
|
||||
void on_loadButton_clicked();
|
||||
|
||||
private:
|
||||
Ui::QBrainfuck *ui;
|
||||
};
|
||||
|
||||
#endif // QBRAINFUCK_H
|
265
qbrainfuck.ui
Normal file
265
qbrainfuck.ui
Normal file
@ -0,0 +1,265 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QBrainfuck</class>
|
||||
<widget class="QMainWindow" name="QBrainfuck">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1187</width>
|
||||
<height>585</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>QBrainfuck</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="1">
|
||||
<widget class="QGroupBox" name="resultGroupBox">
|
||||
<property name="title">
|
||||
<string>Result</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="resultTextEdit">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Monospace</family>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="saveButton">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="loadButton">
|
||||
<property name="text">
|
||||
<string>Load</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QGroupBox" name="programGroupBox">
|
||||
<property name="title">
|
||||
<string>Brainfuck program</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="programTextEdit">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Monospace</family>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="programLabel">
|
||||
<property name="text">
|
||||
<string>Program length: 0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="decodeButton">
|
||||
<property name="text">
|
||||
<string>Decode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="motifGoupBox">
|
||||
<property name="title">
|
||||
<string>Motif</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="motifTextEdit">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Monospace</family>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="motifLabel">
|
||||
<property name="text">
|
||||
<string>Motif length: 0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="motifButton">
|
||||
<property name="text">
|
||||
<string>Motif</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="textGroupBox">
|
||||
<property name="title">
|
||||
<string>Plain text</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="textTextEdit">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Monospace</family>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="textLabel">
|
||||
<property name="text">
|
||||
<string>Text length: 0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="encodeButton">
|
||||
<property name="text">
|
||||
<string>Encode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="optionsGroupBox">
|
||||
<property name="title">
|
||||
<string>Options</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="2">
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="loopSpinBox">
|
||||
<property name="maximum">
|
||||
<number>5000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>500</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="loopLabel">
|
||||
<property name="text">
|
||||
<string>Max loop length</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="arrayLabel">
|
||||
<property name="text">
|
||||
<string>Array size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="inputLineEdit"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="inputLabel">
|
||||
<property name="text">
|
||||
<string>Input</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="arraySpinBox">
|
||||
<property name="maximum">
|
||||
<number>5000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="maxSignsLabel">
|
||||
<property name="text">
|
||||
<string>Max signs (+/-)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="maxSignsSpinBox">
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="decadesLabel">
|
||||
<property name="text">
|
||||
<string>Decades size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="regexLabel">
|
||||
<property name="text">
|
||||
<string>Motif regex</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="regexLineEdit">
|
||||
<property name="text">
|
||||
<string>#</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="decadesSpinBox">
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Loading…
Reference in New Issue
Block a user