15 #include <type_traits> 26 #include <hilti/ast/meta.h> 27 #include <hilti/ast/node-ref.h> 28 #include <hilti/ast/scope.h> 29 #include <hilti/base/type_erase.h> 30 #include <hilti/base/util.h> 47 using PropertyValue = std::variant<bool, const char*, double, int, int64_t, unsigned int, uint64_t, std::string>;
50 inline std::string to_string(PropertyValue v) {
52 auto operator()(
bool s) {
return std::string(s ?
"true" :
"false"); }
53 auto operator()(
const char* s) {
return util::escapeUTF8(s); }
54 auto operator()(
double d) {
return util::fmt(
"%.6f", d); }
55 auto operator()(
int i) {
return util::fmt(
"%d", i); }
56 auto operator()(int64_t i) {
return util::fmt(
"%" PRId64, i); }
57 auto operator()(std::string s) {
return util::escapeUTF8(s); }
58 auto operator()(
unsigned int u) {
return util::fmt(
"%u", u); }
59 auto operator()(uint64_t u) {
return util::fmt(
"%" PRIu64, u); }
62 return std::visit(Visitor(), v);
76 return static_cast<std::underlying_type_t<ErrorPriority>
>(x) <
77 static_cast<std::underlying_type_t<ErrorPriority>
>(y);
89 bool operator<(
const Error& other)
const {
90 return std::tie(message, location) < std::tie(other.
message, other.
location);
99 using Properties = std::map<std::string, node::detail::PropertyValue>;
102 #include <hilti/autogen/__node.h> 113 class Node final :
public node::detail::Node {
116 template<typename T, typename std::enable_if_t<std::is_base_of<trait::isNode, T>::value>* =
nullptr>
119 Node(
const Node& other) : node::detail::Node::Node(other), _scope(other._scope) {}
122 : node::detail::Node::Node(std::move(other)),
123 _control_ptr(std::move(other._control_ptr)),
124 _scope(std::move(other._scope)),
125 _errors(std::move(other._errors)) {
127 _control_ptr->_node =
this;
134 _control_ptr->_node =
nullptr;
144 uint64_t
rid()
const {
return _control_ptr ? _control_ptr->_rid : 0; }
161 _scope = make_intrusive<Scope>();
178 _scope = make_intrusive<Scope>();
182 std::vector<node::Error>
errors()
const {
190 bool hasErrors()
const {
return _errors && _errors->size(); }
206 void addError(std::string msg, std::vector<std::string> context = {}) {
207 addError(std::move(msg),
location(), std::move(context));
220 addError(std::move(msg),
location(), priority, std::move(context));
245 error.
message = std::move(msg);
247 error.
context = std::move(context);
251 _errors = std::make_unique<std::vector<node::Error>>();
253 _errors->push_back(std::move(error));
260 void destroyChilds();
269 std::string render(
bool include_location =
true)
const;
281 void print(std::ostream& out,
bool compact =
false)
const;
287 std::string print()
const;
296 std::cerr <<
"Assertion failure: Node expected to be a " <<
typeid(T).name() <<
" but is a " 297 << typeid_().name() << std::endl;
303 operator std::string()
const {
return print(); }
311 node::detail::ErasedBase::operator=(n);
320 _scope = std::move(n._scope);
321 node::detail::ErasedBase::operator=(std::move(n));
332 node::detail::ErasedBase::operator=(to_node(t));
342 if ( ! _control_ptr )
343 _control_ptr = make_intrusive<node_ref::detail::Control>(
this);
350 std::unique_ptr<std::vector<node::Error>> _errors =
nullptr;
374 for (
auto& c : childs )
375 addChild(std::move(c));
389 return _childs[i].as<T>();
400 _childs[i].template assertIsA<T>();
414 auto end_ = (end < 0) ? _childs.end() : _childs.begin() + end;
427 auto end_ = (end < 0) ? _childs.end() : _childs.begin() + end;
429 std::vector<NodeRef> refs;
430 for (
auto c = _childs.begin(); c != end_; c = std::next(c) )
453 std::vector<NodeRef> childRefsOfType()
const;
460 if ( _meta.location() && ! n.
location() ) {
462 m.setLocation(_meta.location());
463 n.setMeta(std::move(m));
466 _childs.push_back(std::move(n));
470 const auto&
childs()
const {
return _childs; }
474 auto&
meta()
const {
return _meta; }
481 std::vector<::hilti::Node> _childs;
514 using BaseIterator = std::vector<Node>::const_iterator;
517 using value_type = BaseIterator::value_type;
518 using difference_type = BaseIterator::difference_type;
519 using pointer = BaseIterator::pointer;
520 using reference = BaseIterator::reference;
521 using iterator_category = BaseIterator::iterator_category;
523 explicit RangeIterator(BaseIterator i) : _iter(std::move(i)) {}
529 const Node& node()
const {
return *_iter; }
533 const T& operator*()
const {
return value(); }
534 const T* operator->()
const {
return &value(); }
535 bool operator==(
const RangeIterator& other)
const {
return _iter == other._iter; }
536 bool operator!=(
const RangeIterator& other)
const {
return ! (*
this == other); }
559 difference_type operator-(
const RangeIterator& other)
const {
return _iter - other._iter; }
564 const T& value()
const {
return (*_iter).template as<std::remove_const_t<T>>(); }
581 Range(std::vector<Node>::const_iterator begin, std::vector<Node>::const_iterator end)
582 : _begin(std::move(begin)), _end(std::move(end)) {}
584 explicit Range(
const std::vector<Node>& nodes) :
Range(nodes.begin(), nodes.end()) {}
590 auto begin()
const {
return const_iterator(_begin); }
591 auto end()
const {
return const_iterator(_end); }
592 size_t size()
const {
return static_cast<size_t>(_end - _begin); }
593 const T& front()
const {
return *_begin; }
594 bool empty()
const {
return _begin == _end; }
602 for (
auto i = _begin; i != _end; i++ )
608 const T& operator[](
size_t i)
const {
609 assert(i < std::distance(_begin, _end));
610 return *(_begin + i);
613 bool operator==(
const Range& other)
const {
614 if (
this == &other )
617 if ( size() != other.size() )
621 auto y = other._begin;
622 while ( x != _end ) {
623 if ( ! (*x++ == *y++) )
630 Range& operator=(
const Range& other) =
default;
646 using BaseIterator =
typename std::vector<std::reference_wrapper<const T>>::const_iterator;
650 using value_type = T;
651 using difference_type =
typename BaseIterator::difference_type;
652 using pointer =
typename BaseIterator::pointer;
653 using reference =
typename BaseIterator::reference;
654 using iterator_category =
typename BaseIterator::iterator_category;
656 explicit SetIterator(BaseIterator i) : _iter(std::move(i)) {}
662 const Node& node()
const {
return *_iter; }
666 const T& operator*()
const {
return value(); }
667 const T* operator->()
const {
return &value(); }
668 bool operator==(
const SetIterator& other)
const {
return _iter == other._iter; }
669 bool operator!=(
const SetIterator& other)
const {
return ! (*
this == other); }
692 difference_type operator-(
const SetIterator& other)
const {
return _iter - other._iter; }
697 const T& value()
const {
return ((*_iter).get()); }
715 Set(
const Set& other) =
default;
716 Set(
Set&& other) =
default;
719 auto begin()
const {
return const_iterator(_set.begin()); }
720 auto end()
const {
return const_iterator(_set.end()); }
721 size_t size()
const {
return _set.size(); }
722 bool empty()
const {
return _set.empty(); }
723 void insert(
const T& t) { _set.push_back(t); }
731 for (
auto i = begin(); i != end(); i++ )
737 const T& operator[](
size_t i)
const {
return *(begin() + i); }
739 bool operator==(
const Set& other)
const {
740 if (
this == &other )
743 if ( size() != other.size() )
747 auto y = other.begin();
748 while ( x != end() ) {
749 if ( ! (*x++ == *y++) )
756 Set& operator=(
const Set& other) =
default;
757 Set& operator=(
Set&& other) =
default;
760 std::vector<std::reference_wrapper<const T>> _set;
772 template<
typename T, IF_SAME(T, Node)>
773 inline Node to_node(
const T& n) {
779 Node to_node(std::optional<T> t) {
781 return to_node(std::move(*t));
791 std::vector<Node> nodes(std::vector<T> t) {
794 for (
const auto& i : t )
795 v.emplace_back(std::move(i));
805 std::vector<Node> nodes(std::list<T> t) {
807 for (
const auto& i : t )
808 v.emplace_back(std::move(i));
821 for (
const auto& i : t )
822 v.emplace_back(std::move(i));
829 std::vector<Node> nodes(T t) {
830 return {to_node(std::move(t))};
837 template<
typename T,
typename... Ts>
838 std::vector<Node> nodes(T t, Ts... ts) {
839 return util::concat(std::move(nodes(t)), nodes(std::move(ts)...));
849 template<
typename T,
typename Other, IF_DERIVED_FROM(T, trait::isNode), IF_DERIVED_FROM(Other, trait::isNode)>
850 bool isEqual(
const T* this_,
const Other& other) {
851 if (
const auto o = other.template tryAs<T>() )
861 template<
typename X,
typename F>
864 for (
const auto& i : x ) {
876 template<
typename X,
typename F>
879 for (
const auto& i : x ) {
891 template<
typename X,
typename F>
893 using Y =
typename std::result_of<F(X&)>::type;
896 for (
const auto& i : x )
906 template<
typename X,
typename F>
908 using Y =
typename std::result_of<F(X&)>::type;
911 for (
const auto& i : x )
921 inline std::ostream& operator<<(std::ostream& out,
const Node& n) {
929 for (
auto c = _childs.begin(); c != _childs.end(); c = std::next(c) ) {
930 if (
auto t = c->tryAs<T>() )
939 typename std::vector<NodeRef> n;
940 for (
auto c = _childs.begin(); c != _childs.end(); c = std::next(c) ) {
960 detail::flattenedChilds(n, &dst);
std::vector< T > copy() const
Definition: node.h:600
ErrorPriority priority
Definition: node.h:85
std::vector< std::string > context
Definition: node.h:84
uint64_t rid() const
Definition: node.h:144
bool pruneWalk() const
Definition: node.h:478
IntrusivePtr< Scope > scope() const
Definition: node.h:159
NodeBase(Meta meta)
Definition: node.h:365
void assertIsA()
Definition: node.h:294
Node & operator=(const T &t)
Definition: node.h:331
void addError(std::string msg, Location l, std::vector< std::string > context={})
Definition: node.h:231
const Node none
Definition: node.cc:14
auto filter(const hilti::node::Range< X > &x, F f)
Definition: node.h:862
void abort_with_backtrace()
Definition: util.cc:179
auto childRefs(int begin, int end)
Definition: node.h:426
bool hasErrors() const
Definition: node.h:190
auto & childs()
Definition: node.h:472
Definition: optional.h:79
hilti::node::Set< T > childsOfType() const
Definition: node.h:927
static None create()
Definition: node.h:498
void addChild(Node n)
Definition: node.h:459
std::vector< T > concat(std::vector< T > v1, const std::vector< T > &v2)
Definition: util.h:530
void clearScope()
Definition: node.h:172
void addError(std::string msg, std::vector< std::string > context={})
Definition: node.h:206
void setScope(IntrusivePtr< Scope > new_scope)
Definition: node.h:169
const Location & location() const
Definition: node.h:290
Location location
Definition: node.h:83
Node & operator=(Node &&n) noexcept
Definition: node.h:319
std::vector< NodeRef > childRefsOfType() const
Definition: node.h:938
std::vector< T > copy() const
Definition: node.h:729
std::string renderedRid() const
Definition: node.h:151
auto childs(int begin, int end) const
Definition: node.h:413
void clearErrors()
Definition: node.h:193
std::string fmt(const char *fmt, const Args &... args)
Definition: util.h:80
void addError(std::string msg, Location l, node::ErrorPriority priority, std::vector< std::string > context={})
Definition: node.h:243
auto properties() const
Definition: node.h:492
std::vector< node::Error > errors() const
Definition: node.h:182
Definition: intrusive-ptr.h:69
Definition: type_erase.h:30
void setMeta(Meta m)
Definition: node.h:476
void print(std::ostream &out, bool compact=false) const
Definition: node.cc:103
std::map< std::string, node::detail::PropertyValue > Properties
Definition: node.h:99
std::string message
Definition: node.h:82
const T & child(int i) const
Definition: node.h:388
Definition: node-ref.h:44
Definition: location.h:17
void addError(std::string msg, node::ErrorPriority priority, std::vector< std::string > context={})
Definition: node.h:219
const auto & childs() const
Definition: node.h:470
Node & operator=(const Node &n)
Definition: node.h:309
ErrorPriority
Definition: node.h:68
auto & meta() const
Definition: node.h:474
Definition: location.h:93
Node(T t)
Definition: node.h:117
void assertChildIsA(int i)
Definition: node.h:399
NodeBase(std::vector< Node > childs, Meta meta)
Definition: node.h:373