#pragma once #include "utils.hpp" #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, }; namespace utils { inline bool is_suffix_modifier(nodes::Modifier modifier) { return modifier == nodes::Modifier::OPTIONAL || modifier == nodes::Modifier::RESULT; } } // namespace utils class Node { public: Node() : undefined_(true) {} Node(std::pair start_position, std::pair end_position) : undefined_(false), start_position_(start_position), end_position_(end_position) {} std::pair get_start_position() const { if (undefined_) { error_handling::handle_general_error( "Get start position from undefined node"); } return start_position_; } std::pair get_end_position() const { if (undefined_) { error_handling::handle_general_error( "Get end position from undefined node"); } return end_position_; } protected: bool undefined_ = false; std::pair start_position_ = {0, 0}; std::pair end_position_ = {0, 0}; }; struct unit {}; struct null {}; struct unicode_string { std::string str; }; struct unicode { std::string ch; }; 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; } // bool operator==(const Identifier &other_identifier) const { return type_ == other_identifier.type_ && value_ == other_identifier.value_; } bool operator!=(const Identifier &other_identifier) const { return !(*this == other_identifier); } bool operator<(const Identifier &other_identifier) const { return type_ < other_identifier.type_ || (type_ == other_identifier.type_ && value_ < other_identifier.value_); } 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