#pragma once #include #include #include #include namespace nodes { // replace enum with structure ?? enum class Modifier { IN, // <- x REF, // <> x CONST, // -- x (or nothing sometimes) OUT, // -> x // IN_OR_REF, // <-|<> x IN_OR_CONST, // <-|-- x REF_OR_OUT, // <>|-> x CONST_OR_OUT, // --|-> x REF_OR_CONST, // <>|-- x IN_OR_OUT, // <-|-> x // IN_OR_REF_OR_OUT, // <-|<>|-> x IN_OR_CONST_OR_OUT, // <-|--|-> x IN_OR_REF_OR_CONST, // <-|<>|-- x REF_OR_CONST_OR_OUT, //<>|--|-> x // IN_OR_REF_OR_CONST_OR_OUT, //<-|<>|--|-> x OPTIONAL, // x? RESULT, // x! 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() const { return start_position_; } std::pair get_end_position() const { 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; } auto get_any() { return &value_; } auto get_any() const { return &value_; } 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() const { return type_; } // std::string *get() { return &value_; } const std::string *get() const { return &value_; } // void append_before(const std::string &name) { value_ = name + "." + value_; } void append_after(const std::string &name) { value_ += "."; value_ += name; } private: IdentifierType type_; std::string value_; }; class Extra : public Node { public: Extra(Node node, std::string &&content) : Node(node), content_(std::move(content)) {} Extra(Node node, const std::string &content) : Node(node), content_(content) {} std::string *content() { return &content_; } const std::string *content() const { return &content_; } private: std::string content_; }; class EmptyLines : public Node { public: EmptyLines(Node node, size_t line_count) : Node(node), line_count_(line_count) {} size_t line_count() const { return line_count_; } private: size_t line_count_; }; } // namespace nodes