Generates llvm assembly code for additions :-)
[ozulis.git] / src / ast / generator-ascii-visitor.cc
blob44e65c8f397c328769faf61a6f9e639c6b254fa2
1 #include <core/assert.hh>
2 #include <iostream>
3 #include <fstream>
4 #include <boost/foreach.hpp>
6 #include "generator.hh"
8 namespace ag = ast::generator;
10 static void
11 generateAsciiVisitorHeader(const char * working_directory)
13 assert(working_directory);
15 std::fstream out;
16 std::string path(working_directory);
18 path.append("/ascii-visitor.hh");
19 out.open(path.c_str(), std::fstream::out | std::fstream::trunc);
20 assert(out.is_open() && out.good());
22 const ag::Node *node;
24 ag::appendGeneratedWarning(out);
25 out << "#ifndef AST_ASCII_VISITOR_HH" NL
26 << "# define AST_ASCII_VISITOR_HH" NL NL
27 << "#include <ast/browse-visitor.hh>" NL NL
28 << "namespace ast" NL
29 << "{" NL;
31 out << " /** @defgroup Visitors */" NL
32 << " /**" NL
33 << " * @brief A visitor which dump the AST on the standard output." NL
34 << " * @ingroup Visitors" NL
35 << " */" NL
36 << " class AsciiVisitor : public ConstBrowseVisitor" NL
37 << " {" NL
38 << " public:" NL
39 << " AsciiVisitor();" NL
40 << " virtual ~AsciiVisitor();" NL NL;
42 for (node = ag::nodes; !node->name.empty() > 0; node++)
43 out << " virtual void visit(const " << node->name << " & node);" NL;
45 out << " protected:" NL
46 << " int depth_; ///< The depht in the ast." NL
47 << " std::string name_; ///< The name of the node." NL
48 << " std::string prefix_; ///< The name of the node." NL
49 << " };" NL NL;
51 out << "} // namespace ast" NL
52 << "#endif // !AST_ASCII_VISITOR_HH" NL;
53 out.close();
56 #define cclear "\e[m"
57 #define ctype "\e[34m"
58 #define cchev "\e[33m"
59 #define cbrack "\e[35m"
61 static void
62 generateAsciiVisitorSource(const char * working_directory)
64 assert(working_directory);
66 std::fstream out;
67 std::string path(working_directory);
69 path.append("/ascii-visitor.cc");
70 out.open(path.c_str(), std::fstream::out | std::fstream::trunc);
71 assert(out.is_open() && out.good());
73 const ag::Node *node;
75 ag::appendGeneratedWarning(out);
76 out << "#include <iostream>" NL
77 << "#include <sstream>" NL
78 << "#include <boost/foreach.hpp>" NL
79 << "#include <ast/ascii-visitor.hh>" NL NL
80 << "#define NL << std::endl" NL NL
81 << "namespace ast" NL
82 << "{" NL;
84 out << " AsciiVisitor::AsciiVisitor()" NL
85 << " : depth_(-1), name_(), prefix_()"
86 << "{}" NL NL
87 << " AsciiVisitor::~AsciiVisitor() {}" NL NL;
89 for (node = ag::nodes; !node->name.empty() > 0; node++)
91 out << " void AsciiVisitor::visit(const " << node->name << " & node)" NL
92 << " {" NL
93 << " int i;" NL
94 << " std::string oldName = name_;" NL
95 << " std::string oldPrefix = prefix_;" NL NL
96 << " ++depth_;" NL
97 << " std::cout << prefix_ << \"`- \";" NL
98 << " if (!name_.empty())" NL
99 << " std::cout << name_ << \" \";" NL
100 << " std::cout << \""cchev"<"ctype << node->name << cchev">\e[m\" NL;" NL;
102 int i = 0;
103 std::vector<const ag::Attribute *> allAttrs = ag::allAttributes(node);
104 BOOST_FOREACH(const ag::Attribute * attr, allAttrs)
106 ++i;
107 out << " name_ = \"" << attr->name << "\";" NL;
108 if (ag::isNode(attr->type))
109 out << " prefix_ = oldPrefix;" NL
110 << " prefix_.append(\" "
111 << (i < allAttrs.size() ? "|" : " ") << "\");" NL
112 << " node." << attr->name << "->accept(*this);" NL;
113 else if (ag::isVectorOfNode(attr->type))
115 out << " i = 0;" NL
116 << " if (node." << attr->name << ")" NL
117 << " BOOST_FOREACH(Node * n, (*node." << attr->name << "))" NL
118 << " {" NL
119 << " std::stringstream ss;" NL
120 << " ss << \""cbrack"["cclear"\" << i << \""cbrack"]"cclear"\";" NL
121 << " name_ = \"" << attr->name << "\";" NL
122 << " name_.append(ss.str());" NL
123 << " prefix_ = oldPrefix;" NL;
125 if (i < allAttrs.size())
126 out << " prefix_.append(\" |\");" NL;
127 else
128 out << " if (i == node." << attr->name << "->size() - 1)"
129 << " prefix_.append(\" \");" NL
130 << " else" NL
131 << " prefix_.append(\" |\");" NL;
132 out << " n->accept(*this);" NL
133 << " i++;" NL
134 << " }" NL;
136 else if (ag::isPrintable(attr->type))
137 out << " std::cout << oldPrefix << \" "
138 << (i < allAttrs.size() ? "|" : " ") << "\";" NL
139 << " std::cout << \"`- " << attr->name << cchev" <" ctype << attr->type
140 << cchev">\e[m = \" << node." << attr->name << " NL;" NL;
142 out << " --depth_;" NL
143 << " name_ = oldName;" NL;
145 out << " }" NL NL;
148 out << "} // namespace ast" NL;
149 out.close();
152 int main(int argc, char **argv)
154 assert(argc == 2);
155 generateAsciiVisitorHeader(argv[1]);
156 generateAsciiVisitorSource(argv[1]);
157 return 0;