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);
 | |
| }
 |