From 967be9e750221ab2ab783f95df79bb26d290a45e Mon Sep 17 00:00:00 2001 From: Martial Simon Date: Mon, 15 Sep 2025 01:07:58 +0200 Subject: add: added projects --- tiger-compiler/src/ast/dumper-dot.hxx | 214 ++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 tiger-compiler/src/ast/dumper-dot.hxx (limited to 'tiger-compiler/src/ast/dumper-dot.hxx') diff --git a/tiger-compiler/src/ast/dumper-dot.hxx b/tiger-compiler/src/ast/dumper-dot.hxx new file mode 100644 index 0000000..30a7b33 --- /dev/null +++ b/tiger-compiler/src/ast/dumper-dot.hxx @@ -0,0 +1,214 @@ +/** + ** \file ast/dumper-dot.hxx + ** \brief Implementation of ast::DumperDot. + */ + +#pragma once + +#include +#include +#include + +namespace ast +{ + + template + requires misc::ConstIterable + inline void DumperDot::dump_list(const std::string& field, const Container& l) + { + const std::string* old_parent_field = parent_field; + auto it = l.begin(); + unsigned n = 0; + while (it != l.end()) + { + std::ostringstream o; + o << field; + if (std::next(it) != l.end() || n > 0) + o << n++; + const std::string field_name = o.str(); + parent_field = &field_name; + (*it++)->accept(*this); + } + parent_field = old_parent_field; + } + + template inline void DumperDot::dump_def(const T& e) const + { + const ast::Ast* d = nullptr; + // FIXME: Some code was deleted here (set d using definition of e). + (void)e; + if (!d) + return; + ostr_ << parent_id << ":def:s -> " << reinterpret_cast(d) + << ":nodename [constraint=false, style=dashed, color=\"dimgray\"]" + << misc::iendl; + } + + inline void DumperDot::display_link(unsigned long old_parent_id) const + { + if (parent_field) + ostr_ << old_parent_id << ":" << *parent_field << ":s" + << " -> " << parent_id << ":nodename:n" << misc::iendl; + } + + inline void DumperDot::footer_and_link(unsigned long old_parent_id) const + { + node_html_footer(); + display_link(old_parent_id); + } + + template + inline void DumperDot::dump_chunk(const E& e, const std::string& name) + { + unsigned long old_parent_id = parent_id; + parent_id = reinterpret_cast(&e); + ostr_ << parent_id << " [label=<" << misc::incendl + << "" << misc::incendl << "" + << misc::incendl; + inner_fields = 0; + node_html_port_list(name, e, true); + ostr_ << misc::decendl << "" << misc::decendl << "
" + << misc::decendl << ">]" << misc::iendl; + display_link(old_parent_id); + dump_list("nodename", e); + parent_id = old_parent_id; + } + + namespace + { + inline void node_html_begin_inner(std::ostream& ostr, bool list = false) + { + ostr << "" << misc::incendl + << "" + << misc::incendl << "" << misc::incendl; + } + + inline void node_html_end_inner(std::ostream& ostr) + { + ostr << misc::decendl << "" << misc::decendl << "
" + << misc::decendl << ""; + } + + inline void node_html_separator(std::ostream& ostr) + { + node_html_end_inner(ostr); + ostr << misc::decendl << "" << misc::iendl << "" + << misc::incendl; + node_html_begin_inner(ostr); + } + inline void node_html_tr(std::ostream& ostr, + const std::string& port, + const std::string content) + { + ostr << "" << content << ""; + } + inline bool ends_with(const std::string& value, const std::string& ending) + { + if (ending.size() > value.size()) + return false; + return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); + } + inline std::string node_html_color(const std::string& type) + { + if (ends_with(type, "Dec")) + return "red1"; + else if (ends_with(type, "Var")) + return "orange1"; + else if (ends_with(type, "Ty")) + return "green3"; + else if (ends_with(type, "Exp")) + return "blue2"; + return "black"; + } + + template std::string html_escape(const T& input) + { + std::ostringstream i; + i << input; + const std::string& str = i.str(); + std::ostringstream o; + const std::string& specials = "&<>"; + for (const auto& p : str) + if (p == '\\') + o << '\\' << '\\'; + else if (specials.find(p) != std::string::npos) + o << "&#" << static_cast(static_cast(p)) << ";"; + else + o << p; + return o.str(); + } + } // namespace + + template + inline unsigned long DumperDot::node_html_header(const T& e, + const std::string& type) + { + unsigned long old_parent_id = parent_id; + parent_id = reinterpret_cast(&e); + ostr_ << parent_id << " [label=<" << misc::incendl + << "" << misc::incendl + << "" << misc::incendl; + node_html_begin_inner(ostr_); + node_html_tr(ostr_, "nodename", type); + node_html_separator(ostr_); + inner_fields = 0; + return old_parent_id; + } + template + inline void DumperDot::node_html_field(const std::string& name, + const T& content, + const std::string& sep) + { + std::ostringstream o; + o << name << ": " << sep << html_escape(content) << sep; + if (inner_fields++) + ostr_ << misc::iendl; + node_html_tr(ostr_, name, o.str()); + } + inline void DumperDot::node_html_one_port(const std::string& p) + { + if (inner_fields++) + ostr_ << misc::iendl; + node_html_tr(ostr_, p, p); + } + inline void DumperDot::node_html_ports(const std::vector& ports) + { + if (inner_fields) + node_html_separator(ostr_); + inner_fields = 0; + for (auto p : ports) + node_html_one_port(p); + } + template + inline void DumperDot::node_html_port_list(const std::string& name, + const T& list, + bool chunk) + { + if (inner_fields++) + ostr_ << misc::iendl; + const std::string ref = chunk ? "nodename" : name; + node_html_begin_inner(ostr_, true); + long int size = std::distance(list.begin(), list.end()); + ostr_ << ""; + if (size > 1) + { + ostr_ << misc::decendl << "" << misc::iendl << "" + << misc::incindent; + for (long int n = 0; n < size; n++) + ostr_ << misc::iendl << ""; + } + node_html_end_inner(ostr_); + } + inline void DumperDot::node_html_footer() const + { + if (!inner_fields) + ostr_ << ""; + node_html_end_inner(ostr_); + ostr_ << misc::decendl << "" << misc::decendl << "
" + << name << "
" << n + << "
" + << misc::decendl << ">]" << misc::iendl; + } +} // namespace ast -- cgit v1.2.3