aboutsummaryrefslogtreecommitdiffstats
path: root/src/diagram
diff options
context:
space:
mode:
Diffstat (limited to 'src/diagram')
-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
4 files changed, 199 insertions, 24 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 */