23 #include <hilti/ast/meta.h> 24 #include <hilti/ast/node_ref.h> 25 #include <hilti/ast/scope.h> 26 #include <hilti/base/type_erase.h> 27 #include <hilti/base/util.h> 38 using PropertyValue = std::variant<bool, const char*, double, int, int64_t, unsigned int, uint64_t, std::string>;
41 inline std::string to_string(PropertyValue v) {
43 auto operator()(
bool s) {
return std::string(s ?
"true" :
"false"); }
44 auto operator()(
const char* s) {
return util::escapeUTF8(s); }
45 auto operator()(
double d) {
return util::fmt(
"%.6f", d); }
46 auto operator()(
int i) {
return util::fmt(
"%d", i); }
47 auto operator()(int64_t i) {
return util::fmt(
"%" PRId64, i); }
48 auto operator()(std::string s) {
return util::escapeUTF8(s); }
49 auto operator()(
unsigned int u) {
return util::fmt(
"%u", u); }
50 auto operator()(uint64_t u) {
return util::fmt(
"%" PRIu64, u); }
53 return std::visit(
Visitor(), v);
73 bool operator<(
const Error& other)
const {
74 return std::tie(message, location) < std::tie(other.
message, other.
location);
83 using Properties = std::map<std::string, node::detail::PropertyValue>;
86 #include <hilti/autogen/__node.h> 97 class Node final :
public node::detail::Node {
100 template<typename T, typename std::enable_if_t<std::is_base_of<trait::isNode, T>::value>* =
nullptr>
103 Node(
const Node& other) : node::detail::Node::Node(other), _scope(other._scope) {}
106 : node::detail::Node::Node(std::move(other)),
107 _control_ptr(std::move(other._control_ptr)),
108 _scope(std::move(other._scope)),
109 _errors(std::move(other._errors)) {
111 _control_ptr->_node =
this;
120 _control_ptr->_node =
nullptr;
130 uint64_t
rid()
const {
return _control_ptr ? _control_ptr->_rid : 0; }
147 _scope = make_intrusive<Scope>();
164 std::vector<node::Error>
errors()
const {
172 bool hasErrors()
const {
return _errors && _errors->size(); }
188 void addError(std::string msg, std::vector<std::string> context = {}) {
189 addError(std::move(msg),
location(), std::move(context));
214 error.
message = std::move(msg);
216 error.
context = std::move(context);
220 _errors = std::make_unique<std::vector<node::Error>>();
222 _errors->push_back(std::move(error));
232 std::string render(
bool include_location =
true)
const;
243 void print(std::ostream& out,
bool compact =
false)
const;
252 std::cerr <<
"Assertion failure: Node expected to be a " <<
typeid(T).name() <<
" but is a " 253 << typeid_().name() << std::endl;
259 operator std::string()
const {
260 std::stringstream buf;
271 node::detail::ErasedBase::operator=(n);
280 _scope = std::move(n._scope);
281 node::detail::ErasedBase::operator=(std::move(n));
292 node::detail::ErasedBase::operator=(to_node(t));
302 if ( ! _control_ptr )
303 _control_ptr = make_intrusive<node_ref::detail::Control>(
this);
310 std::unique_ptr<std::vector<node::Error>> _errors =
nullptr;
334 for (
auto& c : childs )
335 addChild(std::move(c));
349 return _childs[i].as<T>();
360 _childs[i].template assertIsA<T>();
373 std::vector<T>
childs(
int begin,
int end)
const {
377 end = _childs.size();
379 for (
auto i = begin; i < end; i++ )
380 n.emplace_back(_childs[i].as<T>());
394 for (
auto& c : _childs ) {
395 if (
auto x = c.tryAs<T>() )
410 std::vector<std::reference_wrapper<const Node>> n;
411 for (
const auto& c : _childs ) {
421 std::vector<std::reference_wrapper<Node>> n;
422 for (
auto& c : _childs ) {
435 if ( _meta.location() && ! n.
location() ) {
437 m.setLocation(_meta.location());
438 n.setMeta(std::move(m));
441 _childs.push_back(std::move(n));
449 auto&
meta()
const {
return _meta; }
460 std::vector<::hilti::Node> _childs;
494 template<
typename T, IF_SAME(T, Node)>
495 inline Node to_node(
const T& n) {
501 Node to_node(std::optional<T> t) {
503 return to_node(std::move(*t));
513 std::vector<Node> nodes(std::vector<T> t) {
516 for (
const auto& i : t )
517 v.emplace_back(std::move(i));
526 std::vector<Node> nodes(std::list<T> t) {
528 for (
const auto& i : t )
529 v.emplace_back(std::move(i));
538 std::vector<Node> nodes(std::set<T> t) {
541 for (
const auto& i : t )
542 v.emplace_back(std::move(i));
550 template<
typename T,
typename U>
551 std::vector<Node> nodes(std::vector<std::pair<T, U>> t) {
553 v.reserve(t.size() * 2);
554 for (
const auto& i : t ) {
555 v.emplace_back(std::move(i.first));
556 v.emplace_back(std::move(i.second));
563 std::vector<Node> nodes(T t) {
564 return {to_node(std::move(t))};
571 template<
typename T,
typename... Ts>
572 std::vector<Node> nodes(T t, Ts... ts) {
573 return util::concat(std::move(nodes(t)), nodes(std::move(ts)...));
583 template<
typename T,
typename Other, IF_DERIVED_FROM(T, trait::isNode), IF_DERIVED_FROM(Other, trait::isNode)>
584 bool isEqual(
const T* this_,
const Other& other) {
585 if (
auto o = other.template tryAs<T>() )
594 inline std::ostream& operator<<(std::ostream& out,
const Node& n) {
603 void flattenedChilds(
const Node& n, std::vector<T>* dst) {
604 for (
const auto& c : n.childs() ) {
605 if (
auto t = c.tryAs<T>() )
608 flattenedChilds(c, dst);
619 std::vector<T> flattenedChilds(
const Node& n) {
621 detail::flattenedChilds<T>(n, &dst);
Definition: global-optimizer.cc:45
ErrorPriority priority
Definition: node.h:69
std::vector< std::string > context
Definition: node.h:68
void setOriginalNode(const NodeRef &n)
Definition: node.h:455
uint64_t rid() const
Definition: node.h:130
IntrusivePtr< Scope > scope() const
Definition: node.h:145
NodeBase(Meta meta)
Definition: node.h:325
auto & childs() const
Definition: node.h:445
std::vector< T > childs(int begin, int end) const
Definition: node.h:373
void assertIsA()
Definition: node.h:250
Node & operator=(const T &t)
Definition: node.h:291
void addError(std::string msg, Location l, std::vector< std::string > context={})
Definition: node.h:200
const Node none
Definition: node.cc:12
void abort_with_backtrace()
Definition: util.cc:180
bool hasErrors() const
Definition: node.h:172
auto & childs()
Definition: node.h:447
Definition: optional.h:79
std::vector< T > childsOfType() const
Definition: node.h:392
static None create()
Definition: node.h:477
void addChild(Node n)
Definition: node.h:434
std::vector< T > concat(std::vector< T > v1, const std::vector< T > &v2)
Definition: util.h:571
void clearScope()
Definition: node.h:158
void addError(std::string msg, std::vector< std::string > context={})
Definition: node.h:188
void setScope(IntrusivePtr< Scope > new_scope)
Definition: node.h:155
const Location & location() const
Definition: node.h:246
Location location
Definition: node.h:67
Node & operator=(Node &&n) noexcept
Definition: node.h:279
std::string renderedRid() const
Definition: node.h:137
void clearErrors()
Definition: node.h:175
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:212
auto properties() const
Definition: node.h:471
std::vector< node::Error > errors() const
Definition: node.h:164
const NodeRef & originalNode() const
Definition: node.h:453
Definition: intrusive-ptr.h:69
Definition: type_erase.h:30
void setMeta(Meta m)
Definition: node.h:451
void print(std::ostream &out, bool compact=false) const
Definition: node.cc:84
std::map< std::string, node::detail::PropertyValue > Properties
Definition: node.h:83
std::string message
Definition: node.h:66
const T & child(int i) const
Definition: node.h:348
auto nodesOfType() const
Definition: node.h:409
Definition: node_ref.h:44
Definition: location.h:17
Node & operator=(const Node &n)
Definition: node.h:269
ErrorPriority
Definition: node.h:59
auto & meta() const
Definition: node.h:449
Definition: location.h:86
Node(T t)
Definition: node.h:101
void assertChildIsA(int i)
Definition: node.h:359
NodeBase(std::vector< Node > childs, Meta meta)
Definition: node.h:333
void clearCache()
Definition: node.h:457