From 7f7e6fe30ef4f9ba4507b89174676f57c42c0000 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Sun, 26 Nov 2017 23:36:26 +0100 Subject: Implementation for Structogram iterator and Statement type The interator is not (yet) aware of the scope in which it is iterating. --- src/diagram/Statement.cpp | 15 +++++- src/diagram/Statement.hpp | 44 +++++++++++++----- src/diagram/Structogram.cpp | 111 ++++++++++++++++++++++++++++++++++++++++++-- src/diagram/Structogram.hpp | 53 ++++++++++++++++++--- src/main.cpp | 26 +++++++++-- src/ui/AsciiRenderer.cpp | 23 +++++---- src/ui/AsciiRenderer.h | 33 ------------- src/ui/AsciiRenderer.hpp | 37 +++++++++++++++ src/ui/Window.cpp | 21 +++++++++ src/ui/Window.hpp | 27 +++++++++++ 10 files changed, 319 insertions(+), 71 deletions(-) delete mode 100644 src/ui/AsciiRenderer.h create mode 100644 src/ui/AsciiRenderer.hpp create mode 100644 src/ui/Window.cpp create mode 100644 src/ui/Window.hpp (limited to 'src') 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(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 +#include 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; -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 +#include 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& 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 + + /* 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 #include -#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 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& 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 -#include "ui/AsciiRenderer.h" +#include + +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 @@ -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& statements = m_structogram.getStatements(); - for (std::list::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.h deleted file mode 100644 index 4f9020a..0000000 --- a/src/ui/AsciiRenderer.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Renderer.h - * - * Created on: Nov 23, 2017 - * Author: naopross - */ - -#ifndef SRC_UI_ASCIIRENDERER_H_ -#define SRC_UI_ASCIIRENDERER_H_ - -#include "../diagram/Structogram.h" - -namespace samb { - -class AsciiRenderer { -private: - Structogram m_structogram; - const unsigned int m_width; - - void drawPadding(unsigned int amt); - void drawLine() const; - void drawText(std::string text, unsigned int width = 0, std::string before = "|", std::string after = "|") const; - void drawDecision(std::string condition, std::string trueText, std::string falseText, unsigned int width = 0) const; -public: - AsciiRenderer(Structogram& structogram, unsigned int width); - ~AsciiRenderer(); - - void render(); -}; - -} /* namespace samb */ - -#endif /* SRC_UI_ASCIIRENDERER_H_ */ diff --git a/src/ui/AsciiRenderer.hpp b/src/ui/AsciiRenderer.hpp new file mode 100644 index 0000000..76d6ff5 --- /dev/null +++ b/src/ui/AsciiRenderer.hpp @@ -0,0 +1,37 @@ +/* + * Renderer.h + * + * Created on: Nov 23, 2017 + * Author: naopross + */ + +#ifndef SRC_UI_ASCIIRENDERER_HPP_ +#define SRC_UI_ASCIIRENDERER_HPP_ + +#include "../diagram/Structogram.hpp" + +namespace samb { + +/* Sample renderer for debug, + * + * TODO: implement PdfRenderer, UiRenderer with a common interface + */ +class AsciiRenderer { +private: + Structogram m_structogram; + const unsigned int m_width; + + void drawPadding(unsigned int amt); + void drawLine() const; + void drawText(std::string text, unsigned int width = 0, std::string before = "|", std::string after = "|") const; + void drawDecision(std::string condition, std::string trueText, std::string falseText, unsigned int width = 0) const; +public: + AsciiRenderer(Structogram& structogram, unsigned int width); + ~AsciiRenderer(); + + void render(); +}; + +} /* namespace samb */ + +#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 + +namespace samb { + +class Window : public QWidget { +Q_OBJECT +public: + Window(); + virtual ~Window(); + +signals: +public slots: +}; + +} /* namespace samb */ + +#endif /* SRC_UI_WINDOW_HPP_ */ -- cgit v1.2.1