// 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): Node(std::vector({location, size})) // in/out: Pointer; in: Size {} }; class DeallocateDynamic: public Node { public: DeallocateDynamic(Data& location): Node(std::vector({location})) // in: Pointer {} }; Data MakeConstantInt(int i); Data MakeLocalPointer(FlowGraph::LocalScope& scope, const std::string& name); Data MakeLocalSize(FlowGraph::LocalScope& scope, const std::string& name); Data MakeTemporaryInt(LocalScope& scope); class MemCopy: public Node { public: MemCopy(Data& destination, Data& source, Data& size): // Pointer, Pointer, size in bytes Node(std::vector({destination, source, size})) {} }; class Move: public Node { public: Move(Data& destination, Data& source): Node(std::vector({destination, source})) {} }; enum class JumpVariant: int { 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): Node(std::vector({source0, source1})), m_variant(variant), m_destination(destination) {} JumpVariant variant() { return m_variant; } private: JumpVariant m_variant; std::shared_ptr m_destination; // successor on branch }; // Call Subroutine class Call: public Node { public: Call(std::shared_ptr destination, std::vector arguments): Node(arguments), m_destination(destination) {} private: std::shared_ptr m_destination; }; // Return from Subroutine class Return: public Node { public: Return(std::vector returnValues): Node(returnValues) {} }; enum class UnaryOperationType: int { Increment, Decrement, Negate, Store // just take Data as-is to store it at destination }; class UnaryOperation: public Node { public: UnaryOperation(UnaryOperationType type, Data& destination, Data& source): Node(std::vector({destination, source})), m_type(type) {} UnaryOperationType type() { return m_type; } private: UnaryOperationType m_type; }; enum class BinaryOperationType: int { 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; }; // Open a new scope, with stack frame class CreateScopeOp: public Node { public: CreateScopeOp() {} LocalScope& scope(); private: LocalScope m_scope; }; // Close current scope, closing stack frame class DestroyScopeOp: public Node { public: DestroyScopeOp() {} }; } // namespace FlowGraph