147 lines
3.6 KiB
C++
147 lines
3.6 KiB
C++
|
#include "tree.hpp"
|
||
|
#include <string>
|
||
|
|
||
|
template <typename T>
|
||
|
std::string label(T v) {
|
||
|
return std::to_string(v);
|
||
|
}
|
||
|
|
||
|
template <>
|
||
|
std::string label<std::string>(std::string v) {
|
||
|
return v;
|
||
|
}
|
||
|
|
||
|
template <>
|
||
|
std::string label<const char*>(const char* v) {
|
||
|
return v;
|
||
|
}
|
||
|
|
||
|
template <>
|
||
|
std::string label<binop>(binop op) {
|
||
|
switch(op) {
|
||
|
case binop::plus:
|
||
|
return "+";
|
||
|
case binop::minus:
|
||
|
return "-";
|
||
|
case binop::times:
|
||
|
return "*";
|
||
|
case binop::divide:
|
||
|
return "/";
|
||
|
case binop::land:
|
||
|
return "&&";
|
||
|
case binop::lor:
|
||
|
return "||";
|
||
|
case binop::eq:
|
||
|
return "==";
|
||
|
case binop::neq:
|
||
|
return "!=";
|
||
|
case binop::lt:
|
||
|
return "<";
|
||
|
case binop::lte:
|
||
|
return "<=";
|
||
|
case binop::gt:
|
||
|
return ">";
|
||
|
case binop::gte:
|
||
|
return ">=";
|
||
|
default:
|
||
|
return "";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
template <>
|
||
|
std::string label<unop>(unop op) {
|
||
|
switch(op) {
|
||
|
case unop::lnot:
|
||
|
return "!";
|
||
|
default:
|
||
|
return "";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
std::string wrap_label(T v) {
|
||
|
return std::string(" [label=\"") + label(v) + "\"]";
|
||
|
}
|
||
|
|
||
|
void expr_id::print_dot(dot& into, std::string prefix) {
|
||
|
into.push_back(prefix + wrap_label(id));
|
||
|
}
|
||
|
|
||
|
void expr_int::print_dot(dot& into, std::string prefix) {
|
||
|
into.push_back(prefix + wrap_label(val));
|
||
|
}
|
||
|
|
||
|
void expr_float::print_dot(dot& into, std::string prefix) {
|
||
|
into.push_back(prefix + wrap_label(val));
|
||
|
}
|
||
|
|
||
|
void expr_binop::print_dot(dot& into, std::string prefix) {
|
||
|
into.push_back(prefix + wrap_label(op));
|
||
|
std::string lp = prefix + "_left";
|
||
|
std::string rp = prefix + "_right";
|
||
|
left->print_dot(into, lp);
|
||
|
right->print_dot(into, rp);
|
||
|
into.push_back(prefix + "->" + lp);
|
||
|
into.push_back(prefix + "->" + rp);
|
||
|
}
|
||
|
|
||
|
void expr_unop::print_dot(dot& into, std::string prefix) {
|
||
|
into.push_back(prefix + wrap_label(op));
|
||
|
std::string cp = prefix + "_child";
|
||
|
child->print_dot(into, cp);
|
||
|
into.push_back(prefix + "->" + cp);
|
||
|
}
|
||
|
|
||
|
void expr_assign::print_dot(dot& into, std::string prefix) {
|
||
|
into.push_back(prefix + wrap_label(var + "="));
|
||
|
std::string cp = prefix + "_child";
|
||
|
child->print_dot(into, cp);
|
||
|
into.push_back(prefix + "->" + cp);
|
||
|
}
|
||
|
|
||
|
void stmt_block::print_dot(dot& into, std::string prefix) {
|
||
|
into.push_back(prefix + wrap_label("block"));
|
||
|
int index = 0;
|
||
|
for(auto& child : children) {
|
||
|
std::string cp = prefix + "_" + std::to_string(index);
|
||
|
child->print_dot(into, cp);
|
||
|
into.push_back(prefix + "->" + cp);
|
||
|
index++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void stmt_if::print_dot(dot& into, std::string prefix) {
|
||
|
into.push_back(prefix + wrap_label("if"));
|
||
|
std::string cp = prefix + "_cond";
|
||
|
std::string tp = prefix + "_then";
|
||
|
std::string ep = prefix + "_else";
|
||
|
|
||
|
cond->print_dot(into, cp);
|
||
|
then->print_dot(into, tp);
|
||
|
if(els) els->print_dot(into, ep);
|
||
|
|
||
|
into.push_back(prefix + "->" + cp);
|
||
|
into.push_back(prefix + "->" + tp);
|
||
|
if(els) into.push_back(prefix + "->" + ep);
|
||
|
}
|
||
|
|
||
|
void stmt_while::print_dot(dot& into, std::string prefix) {
|
||
|
into.push_back(prefix + wrap_label("while"));
|
||
|
std::string cp = prefix + "_cond";
|
||
|
std::string bp = prefix + "_body";
|
||
|
|
||
|
cond->print_dot(into, cp);
|
||
|
body->print_dot(into, bp);
|
||
|
|
||
|
into.push_back(prefix + "->" + cp);
|
||
|
into.push_back(prefix + "->" + bp);
|
||
|
}
|
||
|
|
||
|
void stmt_break::print_dot(dot& into, std::string prefix) {
|
||
|
into.push_back(prefix + wrap_label("break"));
|
||
|
}
|
||
|
|
||
|
void stmt_expr::print_dot(dot& into, std::string prefix) {
|
||
|
child->print_dot(into, prefix);
|
||
|
}
|