diff options
Diffstat (limited to 'flowgraph')
-rw-r--r-- | flowgraph/data.cpp | 1 | ||||
-rw-r--r-- | flowgraph/data.h | 51 | ||||
-rw-r--r-- | flowgraph/graph.cpp | 1 | ||||
-rw-r--r-- | flowgraph/graph.h | 20 | ||||
-rw-r--r-- | flowgraph/node.cpp | 9 | ||||
-rw-r--r-- | flowgraph/node.h | 150 | ||||
-rw-r--r-- | flowgraph/storage.cpp | 8 | ||||
-rw-r--r-- | flowgraph/storage.h | 85 |
8 files changed, 325 insertions, 0 deletions
diff --git a/flowgraph/data.cpp b/flowgraph/data.cpp new file mode 100644 index 0000000..9dd6ef8 --- /dev/null +++ b/flowgraph/data.cpp @@ -0,0 +1 @@ +#include "data.h" diff --git a/flowgraph/data.h b/flowgraph/data.h new file mode 100644 index 0000000..353567c --- /dev/null +++ b/flowgraph/data.h @@ -0,0 +1,51 @@ +#pragma once + +#include <cstdint> +#include <vector> + +namespace FlowGraph { + + // Explicitely not including size + enum class DataType + { + Size, + Int, + UInt, + Pointer, + Bool, + Char, + UChar, + }; + + class Storage; ///< forward declaration + + // Argument for Operations + // -> includes identity of data point, e.g. a local int variable + // Built up as a list of Data instances for global and local data points in parallel to FlowGraph + class Data + { + public: + Data(DataType type, std::shared_ptr<Storage> storage):m_type(type) {} + DataType type() const { return m_type; } + private: + const DataType m_type; + std::shared_ptr<Storage> m_storage; + }; + +} + +namespace GlobalData { + + // variable of simple or struct type + class Element + { + private: + size_t size; + std::vector<uint8_t> data; // may be empty if uninitialized + }; + + class Segment: public std::vector<Element> + { + }; + +} diff --git a/flowgraph/graph.cpp b/flowgraph/graph.cpp new file mode 100644 index 0000000..e8b6b5e --- /dev/null +++ b/flowgraph/graph.cpp @@ -0,0 +1 @@ +#include "graph.h" diff --git a/flowgraph/graph.h b/flowgraph/graph.h new file mode 100644 index 0000000..265a3bd --- /dev/null +++ b/flowgraph/graph.h @@ -0,0 +1,20 @@ +#pragma once + +#include "node.h" + +#include <exception> +#include <memory> +#include <string> +#include <stdexcept> +#include <vector> + +namespace FlowGraph { + + class Graph: public std::vector<std::shared_ptr<Node>> + { + public: + Graph() {} + }; + +} + diff --git a/flowgraph/node.cpp b/flowgraph/node.cpp new file mode 100644 index 0000000..fc55ef6 --- /dev/null +++ b/flowgraph/node.cpp @@ -0,0 +1,9 @@ +#include "node.h" + +#include "data.h" + +using namespace FlowGraph; + +Data FlowGraph::MakeLocalPointer(const std::string& name) { return Data(DataType::Pointer, std::make_shared<LocalStorage>(name)); } +Data FlowGraph::MakeLocalSize(const std::string& name) { return Data(DataType::Size, std::make_shared<LocalStorage>(name)); } + diff --git a/flowgraph/node.h b/flowgraph/node.h new file mode 100644 index 0000000..37af95a --- /dev/null +++ b/flowgraph/node.h @@ -0,0 +1,150 @@ +#pragma once + +#include "data.h" +#include "storage.h" + +namespace FlowGraph { + + // Node in Graph: Building block of the graph + // Abstracts actions of program flow, yet machine independent, + // to be converted later into machine code + // Basic elements: + // - Subroutine calls + // - Arithmetic/logical operations + // Arguments (Data instances) will be provided explicitly from outside + class Node + { + public: + virtual ~Node() {}; // force class to be polymorphic + }; + + // Memory on Heap: new and delete + class AllocateDynamic: public Node + { + public: + AllocateDynamic(Data& location, Data& size): m_location(location), m_size(size) {} + private: + Data m_location; // in/out: Pointer + Data m_size; // in: Size + }; + + class DeallocateDynamic: public Node + { + public: + DeallocateDynamic(Data& location) : m_location(location) {} // in + private: + Data m_location; // in: Pointer + }; + + Data MakeLocalPointer(const std::string& name); + Data MakeLocalSize(const std::string& name); + + class MemCopy: public Node + { + public: + MemCopy(Data& destination, Data& source, Data& size): m_destination(destination), m_source(source), m_size(size) {} + private: + Data m_destination; // Pointer + Data m_source; // Pointer + Data m_size; // in bytes + }; + + class Move: public Node + { + public: + Move(Data& destination, Data& source): m_destination(destination), m_source(source) {} + private: + Data m_destination; + Data m_source; + }; + + enum class JumpVariant + { + Unconditional, + GT, + LT, + GE, + LE, + EQ, + NE + }; + + // Unconditional Jump, conditional Jump + class Jump: public Node + { + public: + Jump(JumpVariant variant, Data& source0, Data& source1, std::shared_ptr<Node> destination): + m_variant(variant), + m_source0(source0), + m_source1(source1), + m_destination(destination) + {} + private: + JumpVariant m_variant; + Data m_source0; + Data m_source1; + std::shared_ptr<Node> m_destination; // successor on branch + }; + + // Call Subroutine + class Call: public Node + { + public: + Call(std::shared_ptr<Node> destination, std::vector<Data> arguments): m_destination(destination), m_arguments(arguments) {} + private: + std::shared_ptr<Node> m_destination; + std::vector<Data> m_arguments; + }; + + // Return from Subroutine + class Return: public Node + { + public: + Return(std::vector<Data> returnValues): m_returnValues(returnValues) {} + private: + std::vector<Data> m_returnValues; + }; + + enum class UnaryOperationType { + Increment, + Decrement, + Negate + }; + + class UnaryOperation: public Node + { + public: + UnaryOperation(Data& destination, Data& source): m_destination(destination), m_source(source) {} + private: + Data m_destination; + Data m_source; + }; + + enum class BinaryOperationType { + Add, + Subtract, + Multiply, + Divide, + Modulo, + ShiftRight, + ShiftLeft, + BitwiseAnd, + BitwiseOr, + BitwiseXor, + BitwiseNot, + LogicalAnd, + LogicalOr, + LogicalNot + }; + + class BinaryOperation: public Node + { + public: + BinaryOperation(Data& destination, Data& source0, Data& source1): m_destination(destination), m_source0(source0), m_source1(source1) {} + private: + Data m_destination; + Data m_source0; + Data m_source1; + }; + +} diff --git a/flowgraph/storage.cpp b/flowgraph/storage.cpp new file mode 100644 index 0000000..f78a65d --- /dev/null +++ b/flowgraph/storage.cpp @@ -0,0 +1,8 @@ +#include "storage.h" + +using namespace std::string_literals; + +FlowGraph::TemporaryStorage::TemporaryStorage(LocalScope& scope): + m_name("__local_"s + std::to_string(scope.getNewIndex())) +{} + diff --git a/flowgraph/storage.h b/flowgraph/storage.h new file mode 100644 index 0000000..c2fa7c5 --- /dev/null +++ b/flowgraph/storage.h @@ -0,0 +1,85 @@ +#pragma once + +#include "data.h" + +#include <cstdint> +#include <string> +#include <vector> + +namespace FlowGraph { + + // Parameter to Data class, defining where the data is stored + // Explicitely not including size + // But including label/data/pointer + // -> includes identity of certain data point + class Storage + { + public: + virtual ~Storage() {} // force class to be polymorphic + }; + + class Constant: public Storage + { + public: + Constant(std::vector<uint8_t> value) {} // little endian data + const std::vector<uint8_t>& value() const { return m_value; } + private: + std::vector<uint8_t> m_value; + }; + + class GlobalStorage : public Storage + { + public: + GlobalStorage(const std::string& name): m_name(name) {} + const std::string& name() const { return m_name; } + private: + std::string m_name; + }; + + class LocalStorage : public Storage + { + public: + LocalStorage(const std::string& name): m_name(name) {} + const std::string& name() const { return m_name; } + private: + std::string m_name; + }; + + // Provide a context for local temporaries name generation + class LocalScope + { + public: + size_t getNewIndex() { return m_index++; } + private: + size_t m_index{ 0 }; + }; + + // intermediate results, anonymous values + // use generated name + class TemporaryStorage : public Storage + { + public: + TemporaryStorage(LocalScope& scope); + const std::string& name() const { return m_name; } + private: + std::string m_name; + }; + + // dereferenced pointer + class PointeeStorage : public Storage + { + public: + PointeeStorage(const Data& pointer, const Data& offset): m_pointer(pointer), m_offset(offset) { + if (pointer.type() != DataType::Pointer) + throw std::runtime_error("Pointer argument must be a DataType::Pointer"); + if (offset.type() != DataType::Size) + throw std::runtime_error("Offset argument must be a DataType::Size"); + } + Data pointer() { return m_pointer; } + Data offset() { return m_offset; } + private: + Data m_pointer; + Data m_offset; + }; + +} |