96 lines
1.5 KiB
C++
96 lines
1.5 KiB
C++
#ifndef code__query__expression_hxx_
|
|
#define code__query__expression_hxx_
|
|
|
|
#include <code/query/concepts.hxx>
|
|
#include <code/query/error.hxx>
|
|
#include <code/query/source-location.hxx>
|
|
#include <code/query/types.hxx>
|
|
#include <code/query/visitor.hxx>
|
|
|
|
namespace code::query
|
|
{
|
|
|
|
class expression_t
|
|
{
|
|
public:
|
|
template<Expression E>
|
|
expression_t(E e)
|
|
: container_{make_shared<container_t<E>>(move(e))}
|
|
{}
|
|
|
|
source_location_t const&
|
|
origin() const;
|
|
|
|
friend
|
|
void
|
|
accept(expression_t const& e, visitor_t& v);
|
|
|
|
friend
|
|
string
|
|
to_string(expression_t const& e);
|
|
|
|
private:
|
|
struct abstract_t
|
|
{
|
|
virtual
|
|
~abstract_t() noexcept = default;
|
|
|
|
virtual
|
|
source_location_t const&
|
|
origin_() const = 0;
|
|
|
|
virtual
|
|
void
|
|
accept_(visitor_t& v) const = 0;
|
|
|
|
virtual
|
|
string
|
|
to_string_() const = 0;
|
|
|
|
};
|
|
|
|
template<Expression E>
|
|
struct container_t
|
|
: abstract_t
|
|
{
|
|
explicit
|
|
container_t(E e)
|
|
: e{move(e)}
|
|
{}
|
|
|
|
~container_t() noexcept override
|
|
{}
|
|
|
|
source_location_t const&
|
|
origin_() const override
|
|
{
|
|
return e.origin();
|
|
}
|
|
|
|
void
|
|
accept_(visitor_t& v) const override
|
|
{
|
|
if (auto c = dynamic_cast<basic_visitor_t<E>*>(&v); c) {
|
|
c->visit(e);
|
|
return;
|
|
}
|
|
|
|
v.visit_default();
|
|
}
|
|
|
|
string
|
|
to_string_() const override
|
|
{
|
|
return to_string(e);
|
|
}
|
|
|
|
E e;
|
|
};
|
|
|
|
shared_ptr<abstract_t const> container_;
|
|
};
|
|
|
|
} // namespace code::query
|
|
|
|
#endif
|