mirror of
https://github.com/djcb/mu.git
synced 2024-06-29 07:51:04 +02:00
ed4a640c39
- Move the lib/query/ stuff up a level into lib/ - Associate directly with the Query object - Rework the Query object to be C++ rather than mixed with C - Update all dependencies, tests
112 lines
2.6 KiB
C++
112 lines
2.6 KiB
C++
/*
|
|
** Copyright (C) 2017 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
|
**
|
|
** This library is free software; you can redistribute it and/or
|
|
** modify it under the terms of the GNU Lesser General Public License
|
|
** as published by the Free Software Foundation; either version 2.1
|
|
** of the License, or (at your option) any later version.
|
|
**
|
|
** This library is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
** Lesser General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU Lesser General Public
|
|
** License along with this library; if not, write to the Free
|
|
** Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|
** 02110-1301, USA.
|
|
*/
|
|
|
|
#ifndef TREE_HH__
|
|
#define TREE_HH__
|
|
|
|
#include <vector>
|
|
#include <string>
|
|
#include <iostream>
|
|
|
|
#include <mu-data.hh>
|
|
#include <utils/mu-error.hh>
|
|
|
|
namespace Mu {
|
|
|
|
// A node in the parse tree
|
|
struct Node {
|
|
enum class Type {
|
|
Empty, // only for empty trees
|
|
OpAnd,
|
|
OpOr,
|
|
OpXor,
|
|
OpAndNot,
|
|
OpNot,
|
|
Value,
|
|
Range,
|
|
Invalid
|
|
};
|
|
|
|
Node(Type _type, std::unique_ptr<Data>&& _data):
|
|
type{_type}, data{std::move(_data)} {}
|
|
Node(Type _type): type{_type} {}
|
|
Node(Node&& rhs) = default;
|
|
|
|
Type type;
|
|
std::unique_ptr<Data> data;
|
|
|
|
static const char* type_name (Type t) {
|
|
switch (t) {
|
|
case Type::Empty: return ""; break;
|
|
case Type::OpAnd: return "and"; break;
|
|
case Type::OpOr: return "or"; break;
|
|
case Type::OpXor: return "xor"; break;
|
|
case Type::OpAndNot: return "andnot"; break;
|
|
case Type::OpNot: return "not"; break;
|
|
case Type::Value: return "value"; break;
|
|
case Type::Range: return "range"; break;
|
|
case Type::Invalid: return "<invalid>"; break;
|
|
default:
|
|
throw Mu::Error(Error::Code::Internal, "unexpected type");
|
|
}
|
|
}
|
|
|
|
static constexpr bool is_binop(Type t) {
|
|
return t == Type::OpAnd || t == Type::OpAndNot ||
|
|
t == Type::OpOr || t == Type::OpXor;
|
|
}
|
|
};
|
|
|
|
inline std::ostream&
|
|
operator<< (std::ostream& os, const Node& t)
|
|
{
|
|
os << Node::type_name(t.type);
|
|
if (t.data)
|
|
os << t.data;
|
|
|
|
return os;
|
|
}
|
|
|
|
struct Tree {
|
|
Tree(Node&& _node): node(std::move(_node)) {}
|
|
Tree(Tree&& rhs) = default;
|
|
|
|
void add_child (Tree&& child) { children.emplace_back(std::move(child)); }
|
|
bool empty() const { return node.type == Node::Type::Empty; }
|
|
|
|
Node node;
|
|
std::vector<Tree> children;
|
|
};
|
|
|
|
inline std::ostream&
|
|
operator<< (std::ostream& os, const Tree& tree)
|
|
{
|
|
os << '(' << tree.node;
|
|
for (const auto& subtree : tree.children)
|
|
os << subtree;
|
|
os << ')';
|
|
|
|
return os;
|
|
}
|
|
|
|
} // namespace Mu
|
|
|
|
|
|
#endif /* TREE_HH__ */
|