#pragma once #include #include #include #include namespace nodes { enum class ReferenceType { REF, IN, OUT, NONE }; class Node { public: Node(std::pair start_position, std::pair end_position) : start_position_(start_position), end_position_(end_position) {} std::pair get_start_position() { return start_position_; } std::pair get_end_position() { return end_position_; } protected: std::pair start_position_; std::pair end_position_; }; struct unit {}; struct null {}; class Literal : public Node { public: template Literal(Node node, T &&value) : Node(node), value_(std::forward(value)) {} template std::optional get() { if (std::holds_alternative(value_)) { return &std::get(value_); } return std::nullopt; } template std::optional get() const { if (std::holds_alternative(value_)) { return &std::get(value_); } return std::nullopt; } private: std::variant value_; }; class Identifier : public Node { public: enum IdentifierType { SIMPLE_NAME, SIMPLE_TYPE, TYPECLASS, ARGUMENT_NAME, ARGUMENT_TYPE, // ANNOTATION, used as std::string OPERATOR, PLACEHOLDER, }; Identifier(Node node, IdentifierType type, std::string &&value) : Node(node), type_(type), value_(std::move(value)) {} Identifier(Node node, IdentifierType type, const std::string &value) : Node(node), type_(type), value_(value) {} IdentifierType get_type() { return type_; } std::string *get() { return &value_; } const std::string *get() const { return &value_; } private: IdentifierType type_; std::string value_; }; } // namespace nodes