15template<
class T> std::string escape(
const T& val) {
16 std::ostringstream oss;
26 Dot(std::ostream& ostream,
bool types,
const Def* root =
nullptr)
32 (tab_++).
println(os_,
"digraph {{");
33 tab_.println(os_,
"ordering=out;");
34 tab_.println(os_,
"splines=false;");
35 tab_.println(os_,
"node [shape=box,style=filled];");
38 void epilogue() { (tab_--).
println(os_,
"}}"); }
40 void run(
const Def* root, uint32_t max) {
46 void recurse(
const Def* def, uint32_t max) {
47 if (max == 0 || !done_.emplace(def).second)
return;
48 tab_.print(os_,
"_{}[", def->gid());
51 os_ <<
"style=\"filled,diagonals,bold\"";
53 os_ <<
"style=\"filled,diagonals\"";
54 else if (def == root_)
55 os_ <<
"style=\"filled,bold\"";
58 if (def->free_vars().empty()) os_ <<
"rank=min,";
59 tooltip(def) <<
"];\n";
61 if (!def->is_set())
return;
63 for (
size_t i = 0, e = def->num_ops(); i !=
e; ++i) {
66 tab_.print(os_,
"_{} -> _{}[taillabel=\"{}\",", def->gid(),
op->
gid(), i);
67 if (
op->isa<Lit>() ||
op->isa<Axiom>() || def->isa<Var>() || def->isa<Nat>() || def->isa<Idx>())
68 print(os_,
"fontcolor=\"#00000000\",color=\"#00000000\",constraint=false];\n");
73 if (
auto t = def->type();
t && types_) {
75 tab_.println(os_,
"_{} -> _{}[color=\"#00000000\",constraint=false,style=dashed];", def->gid(),
t->gid());
79 std::ostream& label(
const Def* def) {
80 print(os_,
"label=<{}<br/>", def->unique_name());
81 if (
auto lit = def->isa<Lit>())
84 os_ << def->node_name();
88 std::ostream& color(
const Def* def) {
92 std::ostream& tooltip(
const Def* def) {
93 static constexpr auto NL =
" ";
94 auto loc = escape(def->loc());
95 auto type = escape(def->type());
96 std::ostringstream oss;
97 oss <<
"0x" << std::hex << def->flags();
98 auto flags = oss.str();
100 print(os_,
"tooltip=\"");
101 print(os_,
"<b>expr:</b> {}{}", def, NL);
102 print(os_,
"<b>type:</b> {}{}", type, NL);
103 print(os_,
"<b>name:</b> {}{}", def->sym(), NL);
104 print(os_,
"<b>gid:</b> {}{}", def->gid(), NL);
105 print(os_,
"<b>flags:</b> {}{}", flags, NL);
106 print(os_,
"<b>free_vars:</b> {{{, }}}{}", def->free_vars(), NL);
107 print(os_,
"<b>local_vars:</b> {{{, }}}{}", def->local_vars(), NL);
108 print(os_,
"<b>local_muts:</b> {{{, }}}{}", def->local_muts(), NL);
109 if (
auto mut = def->isa_mut())
print(os_,
"<b>fv_consumers:</b> {{{, }}}{}", mut->fv_consumers(), NL);
110 print(os_,
"<b>loc:</b> {}", loc);
111 return print(os_,
"\"");
124void Def::dot(std::ostream& ostream, uint32_t max,
bool types)
const { Dot(ostream, types,
this).run(
this, max); }
126void Def::dot(
const char* file, uint32_t max,
bool types)
const {
128 dot(std::cout, max, types);
130 auto of = std::ofstream(file);
135void World::dot(
const char* file,
bool annexes,
bool types)
const {
139 auto of = std::ofstream(file);
144void World::dot(std::ostream& os,
bool anx,
bool types)
const {
const Def * op(size_t i) const
void dot(std::ostream &os, uint32_t max=0xFFFFFF, bool types=false) const
const auto & externals() const
void dot(std::ostream &os, bool annexes=false, bool types=false) const
Def * external(Sym name)
Lookup by name.
const Def * annex()
Get Axiom from a plugin.
const auto & annexes() const
Ref op(trait o, Ref type)
std::ostream & println(std::ostream &os, const char *fmt, Args &&... args)
As above but end with std::endl.
std::ostream & print(std::ostream &os, const char *s)
Base case.
GIDSet< const Def * > DefSet
void find_and_replace(std::string &str, std::string_view what, std::string_view repl)
Replaces all occurrences of what with repl.