aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/diagram/Statement.cpp15
-rw-r--r--src/diagram/Statement.hpp44
-rw-r--r--src/diagram/Structogram.cpp111
-rw-r--r--src/diagram/Structogram.hpp53
-rw-r--r--src/main.cpp26
-rw-r--r--src/ui/AsciiRenderer.cpp23
-rw-r--r--src/ui/AsciiRenderer.hpp (renamed from src/ui/AsciiRenderer.h)12
-rw-r--r--src/ui/Window.cpp21
-rw-r--r--src/ui/Window.hpp27
9 files changed, 290 insertions, 42 deletions
diff --git a/src/diagram/Statement.cpp b/src/diagram/Statement.cpp
index 75770db..60be094 100644
--- a/src/diagram/Statement.cpp
+++ b/src/diagram/Statement.cpp
@@ -5,8 +5,21 @@
* Author: naopross
*/
-#include "../diagram/Statement.h"
+#include "Statement.hpp"
namespace samb {
+Statement::pointer Statement::makeStatement(Statement::Type t) {
+ return std::make_shared<Statement>(Statement(t, "", nullptr, nullptr));
+}
+
+bool Statement::operator==(const Statement& other) {
+ return (this->type == other.type) && (this->text == other.text) &&
+ (this->next == other.next) && (this->scope == other.scope);
+}
+
+
+Statement::Statement(Type t, std::string txt, Statement::pointer p, Statement::pointer s): type(t), text(txt), next(p), scope(s) {}
+Statement::~Statement() {}
+
} /* namespace samb */
diff --git a/src/diagram/Statement.hpp b/src/diagram/Statement.hpp
index a90e88d..8c41714 100644
--- a/src/diagram/Statement.hpp
+++ b/src/diagram/Statement.hpp
@@ -9,6 +9,7 @@
#define SRC_STATEMENT_H_
#include <string>
+#include <memory>
namespace samb {
@@ -24,24 +25,23 @@ namespace samb {
* PARALLEL,
*/
-/* this class should behave like a std::list, or a std::map storing the data
- * with a tree structure, BUT it is not a tree because allows 2 notes to point
+/* this struct is a link for linked list that stores the data in a tree-like
+ * structure, BUT it is not a tree because it allows 2 or more nodes to point
* at a single node
*
- * Normal Tree: Statements:
+ * Tree: Statements:
* A - B - C - D A - B - C - D - G
* \ \ /
* E - F E - F
*
- * Because a statement contains branching elmeents. (if / switch)
+ * Because a statements can be branching elements. (if / switch)
+ *
+ * This class is also a *Factory* to make statements.
*/
-class Statement {
-private:
- Statement *next;
- Statement *prev;
+struct Statement {
+ using pointer = std::shared_ptr<Statement>;
-public:
- const enum Type {
+ enum Type {
PROCESS,
DECISION,
SWITCH,
@@ -49,10 +49,30 @@ public:
UNTIL,
SCOPE,
PARALLEL,
- } m_type;
- Statement(Type type, Statement *prev): m_type(type), m_prev(prev);
+ /* this type of statement indicates the end of the program
+ * and it is used only internally
+ *
+ * TODO: think of something more elegant to solve this
+ */
+ END
+ } type;
+
+ std::string text;
+
+ pointer next;
+ pointer scope; // TODO: make iterator look for this
+
+ static Statement::pointer makeStatement(Type t);
+// static Statement::pointer makeProcess();
+// static Statement::pointer makeLoop(Type t, std::string condition);
+// static Statement::pointer makeBranching(Type t, std::string condition);
+
virtual ~Statement();
+ bool operator==(const Statement& other);
+
+private:
+ Statement(Type type, std::string txt, pointer next, pointer scope);
};
} /* namespace samb */
diff --git a/src/diagram/Structogram.cpp b/src/diagram/Structogram.cpp
index dae9028..a21c62d 100644
--- a/src/diagram/Structogram.cpp
+++ b/src/diagram/Structogram.cpp
@@ -5,23 +5,126 @@
* Author: naopross
*/
-#include "../diagram/Structogram.h"
+#include "../diagram/Structogram.hpp"
#include <memory>
+#include <exception>
namespace samb {
-Structogram::Structogram(std::string title): m_title(title) {
+/* iterator nested class */
+Structogram::iterator::iterator(Statement::pointer first) {
+ m_current = first;
+}
+
+Structogram::iterator::~iterator() {}
+
+Structogram::iterator& Structogram::iterator::operator++() {
+ if (m_current->next != nullptr) {
+ m_current = m_current->next;
+ }
+
+ return *this;
+}
+
+Structogram::iterator& Structogram::iterator::operator++(int) {
+ static iterator old(*this);
+ old = *this;
+
+ operator++();
+ return old;
+}
+
+bool Structogram::iterator::operator==(const iterator& other) const {
+ if (*this->m_current == *other.m_current) {
+ return true;
+ }
+
+ return false;
+}
+
+bool Structogram::iterator::operator!=(const iterator& other) const {
+ return !(other == *this);
+}
+
+Statement& Structogram::iterator::operator*() const {
+ if (m_current == nullptr) {
+ throw std::logic_error("structogram iterator: m_current is nullptr");
+ }
+
+ return *m_current;
+}
+
+Statement::pointer Structogram::iterator::operator->() const {
+ return m_current;
+}
+
+/**
+ * Structogram class methods
+ */
+Structogram::Structogram(std::string title) {
+
+ m_size = 0;
+ m_title = title;
+
+ m_head = Statement::makeStatement(Statement::Type::SCOPE);
+ m_tail = Statement::makeStatement(Statement::Type::END);
+
+ m_head->next = m_tail;
+ m_head->text = m_title;
}
Structogram::~Structogram() {
+ /* no need to destroy anything because of smart pointers */
+}
+std::size_t Structogram::size() const {
+ return m_size;
}
-const std::list<Statement>& Structogram::getStatements() const {
- return m_statements;
+Structogram::iterator Structogram::insert_after(Structogram::iterator it, Statement::pointer statement) {
+
+ if (statement == nullptr) {
+ throw std::invalid_argument("structogram: attempt to insert a null statement");
+ }
+
+ statement->next = it->next;
+ it->next = statement;
+ m_size++;
+
+ return ++it;
}
+//Structogram::iterator Structogram::insert_after(Structogram::iterator it, Statement::pointer statement) {
+// return insert(++it, statement);
+//}
+
+Structogram::iterator Structogram::erase_after(iterator it) {
+
+ // TODO: error handling IE return a std::pair<iterator, bool>
+
+ /* the first statement (scope of the program) cannot be deleted */
+ if ((*it) == *m_head) {
+ return it;
+ }
+
+ if (it->next == nullptr) {
+ return it;
+ }
+
+ it->next = it->next->next;
+
+ return it;
+}
+
+/* iterator related methods */
+Structogram::iterator Structogram::begin() const {
+ return iterator(m_head);
+}
+
+const Structogram::iterator Structogram::end() const {
+ return iterator(m_tail);
+}
} /* namespace structograms */
diff --git a/src/diagram/Structogram.hpp b/src/diagram/Structogram.hpp
index 2234142..9318ee4 100644
--- a/src/diagram/Structogram.hpp
+++ b/src/diagram/Structogram.hpp
@@ -10,21 +10,60 @@
#include <iostream>
#include <list>
-#include "../diagram/Statement.h"
+
+#include "Statement.hpp"
namespace samb {
-/* object that holds statements */
+/* A Structogram is a Nassi-Schneiderman diagram, in this implementation it is
+ * simply and iterable object that holds statements.
+ *
+ * The first statement inside a structogram (m_head) is a SCOPE
+ * statement that holds the entire program inside it.
+ */
class Structogram {
-private:
- std::list<Statement> m_statements;
- std::string m_title;
-
public:
+ /* forward only iterator */
+ class iterator {
+ public:
+ iterator(Statement::pointer first);
+ ~iterator();
+
+ iterator& operator++();
+ iterator& operator++(int);
+
+ bool operator==(const iterator& other) const;
+ bool operator!=(const iterator& other) const;
+ Statement& operator*() const;
+ Statement::pointer operator->() const;
+
+ private:
+ Statement::pointer m_current;
+ };
+
Structogram(std::string title);
virtual ~Structogram();
- const std::list<Statement>& getStatements() const;
+ std::size_t size() const;
+
+ // cannot be implemented because iter is forward only
+// iterator insert(iterator it, Statement::pointer statement);
+// iterator erase(iterator it);
+
+ iterator insert_after(iterator it, Statement::pointer statement);
+ iterator erase_after(iterator it);
+
+ /* iterator */
+ iterator begin() const;
+ const iterator end() const;
+ const Statement& operator[](const Statement& it) = delete;
+
+private:
+ std::size_t m_size;
+ std::string m_title;
+
+ Statement::pointer m_head;
+ Statement::pointer m_tail;
};
} /* namespace structograms */
diff --git a/src/main.cpp b/src/main.cpp
index 5ea2172..7f70de6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,10 +1,28 @@
-#include "diagram/Structogram.h"
+#include "diagram/Structogram.hpp"
+#include "diagram/Statement.hpp"
+#include "ui/AsciiRenderer.hpp"
+
#include <iostream>
-#include "ui/AsciiRenderer.h"
+#include <memory>
+
+using namespace samb;
int main(int argc, char *argv[]) {
- samb::Structogram st("Demo");
- samb::AsciiRenderer renderer(st, 60);
+ Structogram st("Demo");
+ AsciiRenderer renderer(st, 60);
+
+ Structogram::iterator it = st.begin();
+
+ auto first = Statement::makeStatement(Statement::Type::PROCESS);
+ first->text = "Hello World";
+
+ auto second = Statement::makeStatement(Statement::Type::PROCESS);
+ second->text = "Hello World Again!";
+
+ st.insert_after(it, first);
+ ++it;
+
+ st.insert_after(it, second);
renderer.render();
diff --git a/src/ui/AsciiRenderer.cpp b/src/ui/AsciiRenderer.cpp
index 0f17d85..d06dadb 100644
--- a/src/ui/AsciiRenderer.cpp
+++ b/src/ui/AsciiRenderer.cpp
@@ -5,7 +5,7 @@
* Author: naopross
*/
-#include "AsciiRenderer.h"
+#include "AsciiRenderer.hpp"
#include <memory>
@@ -38,10 +38,9 @@ void AsciiRenderer::drawText(std::string text, unsigned int width, std::string b
unsigned int textWidth = width - before.length() - after.length();
-
std::cout << before;
- for (unsigned int i = 0; i < text.length(); i++) {
- if (i % textWidth == 0) {
+ for (std::size_t i = 0; i < text.length(); i++) {
+ if (i % textWidth == 0 && i != 0) {
std::cout << after << "\n" << before;
}
@@ -62,24 +61,24 @@ void AsciiRenderer::drawDecision(std::string condition, std::string trueText, st
}
void AsciiRenderer::render() {
- const std::list<Statement>& statements = m_structogram.getStatements();
- for (std::list<Statement>::const_iterator it = statements.begin(); it != statements.end(); it++) {
- Statement st = *it;
- switch (st.type) {
+ for (Structogram::iterator it = m_structogram.begin(); it != m_structogram.end(); ++it) {
+
+ switch (it->type) {
case Statement::Type::PROCESS:
drawLine();
- drawText(st.text);
+ drawText(it->text);
+ drawLine();
break;
case Statement::Type::DECISION:
- drawLine();
break;
case Statement::Type::SWITCH:
break;
case Statement::Type::SCOPE:
+ std::cout << "Title: " << it->text << std::endl;
break;
case Statement::Type::WHILE:
@@ -90,6 +89,10 @@ void AsciiRenderer::render() {
case Statement::Type::PARALLEL:
break;
+
+ case Statement::END:
+ // do nothing
+ break;
}
}
}
diff --git a/src/ui/AsciiRenderer.h b/src/ui/AsciiRenderer.hpp
index 4f9020a..76d6ff5 100644
--- a/src/ui/AsciiRenderer.h
+++ b/src/ui/AsciiRenderer.hpp
@@ -5,13 +5,17 @@
* Author: naopross
*/
-#ifndef SRC_UI_ASCIIRENDERER_H_
-#define SRC_UI_ASCIIRENDERER_H_
+#ifndef SRC_UI_ASCIIRENDERER_HPP_
+#define SRC_UI_ASCIIRENDERER_HPP_
-#include "../diagram/Structogram.h"
+#include "../diagram/Structogram.hpp"
namespace samb {
+/* Sample renderer for debug,
+ *
+ * TODO: implement PdfRenderer, UiRenderer with a common interface
+ */
class AsciiRenderer {
private:
Structogram m_structogram;
@@ -30,4 +34,4 @@ public:
} /* namespace samb */
-#endif /* SRC_UI_ASCIIRENDERER_H_ */
+#endif /* SRC_UI_ASCIIRENDERER_HPP_ */
diff --git a/src/ui/Window.cpp b/src/ui/Window.cpp
new file mode 100644
index 0000000..4572766
--- /dev/null
+++ b/src/ui/Window.cpp
@@ -0,0 +1,21 @@
+/*
+ * Window.cpp
+ *
+ * Created on: Nov 26, 2017
+ * Author: naopross
+ */
+
+#include "Window.hpp"
+
+namespace samb {
+
+Window::Window() {
+ // TODO Auto-generated constructor stub
+
+}
+
+Window::~Window() {
+ // TODO Auto-generated destructor stub
+}
+
+} /* namespace samb */
diff --git a/src/ui/Window.hpp b/src/ui/Window.hpp
new file mode 100644
index 0000000..5afad8c
--- /dev/null
+++ b/src/ui/Window.hpp
@@ -0,0 +1,27 @@
+/*
+ * Window.hpp
+ *
+ * Created on: Nov 26, 2017
+ * Author: naopross
+ */
+
+#ifndef SRC_UI_WINDOW_HPP_
+#define SRC_UI_WINDOW_HPP_
+
+#include <QWidget>
+
+namespace samb {
+
+class Window : public QWidget {
+Q_OBJECT
+public:
+ Window();
+ virtual ~Window();
+
+signals:
+public slots:
+};
+
+} /* namespace samb */
+
+#endif /* SRC_UI_WINDOW_HPP_ */