// Nodes in flow graph: Abstract Operations #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: Node(){} Node(std::vector operands): mOperands(operands) {} std::vector& operands() { return mOperands; } virtual ~Node() {}; // force class to be polymorphic (e.g. in a container) private: std::vector mOperands; }; // 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 MakeConstantInt(int i); Data MakeLocalPointer(const std::string& name); Data MakeLocalSize(const std::string& name); Data MakeTemporaryInt(LocalScope& scope); 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 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 m_destination; // successor on branch }; // Call Subroutine class Call: public Node { public: Call(std::shared_ptr destination, std::vector arguments): m_destination(destination), m_arguments(arguments) {} private: std::shared_ptr m_destination; std::vector m_arguments; }; // Return from Subroutine class Return: public Node { public: Return(std::vector returnValues): m_returnValues(returnValues) {} private: std::vector m_returnValues; }; enum class UnaryOperationType { Increment, Decrement, Negate }; class UnaryOperation: public Node { public: UnaryOperation(UnaryOperationType type, Data& destination, Data& source): m_type(type), m_destination(destination), m_source(source) {} private: UnaryOperationType m_type; 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(BinaryOperationType type, Data& destination, Data& source0, Data& source1): Node(std::vector({destination, source0, source1})), m_type(type) {} BinaryOperationType type() {return m_type;} private: BinaryOperationType m_type; }; } // namespace FlowGraph