lang/include/basic_nodes.hpp
2023-07-29 12:19:37 +03:00

108 lines
2.3 KiB
C++

#pragma once
#include <optional>
#include <string>
#include <utility>
#include <variant>
namespace nodes {
enum class Modifier {
OUT, // -> x
IN, // <- x
REF, // <> x // IN and OUT
OR_OUT, // |-> // OUT or NONE
OR_IN, // <-| // IN or NONE
OPTIONAL, // x?
RESULT, // x!
NONE,
};
class Node {
public:
Node(std::pair<size_t, size_t> start_position,
std::pair<size_t, size_t> end_position)
: start_position_(start_position), end_position_(end_position) {}
std::pair<size_t, size_t> get_start_position() const {
return start_position_;
}
std::pair<size_t, size_t> get_end_position() const { return end_position_; }
protected:
std::pair<size_t, size_t> start_position_;
std::pair<size_t, size_t> end_position_;
};
struct unit {};
struct null {};
class Literal : public Node {
public:
template <typename T>
Literal(Node node, T &&value) : Node(node), value_(std::forward<T>(value)) {}
template <typename T> std::optional<T *> get() {
if (std::holds_alternative<T>(value_)) {
return &std::get<T>(value_);
}
return std::nullopt;
}
template <typename T> std::optional<const T *> get() const {
if (std::holds_alternative<T>(value_)) {
return &std::get<T>(value_);
}
return std::nullopt;
}
auto get_any() { return &value_; }
auto get_any() const { return &value_; }
private:
std::variant<double, long long, std::string, char, bool, unit, null> 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_; }
private:
IdentifierType type_;
std::string value_;
};
class EmptyLines : public Node {
public:
EmptyLines(Node node, size_t size) : Node(node), size_(size) {}
size_t size() const { return size_; }
private:
size_t size_;
};
} // namespace nodes