pass all expr tests
[ozulis.git] / src / ast / generator-browse-visitor.cc
blob8cc9827761cd3e81f4539a15ea0fafa67c6ee6b4
1 #include <iostream>
2 #include <fstream>
3 #include <boost/foreach.hpp>
5 #include <core/assert.hh>
6 #include "generator.hh"
8 namespace ag = ast::generator;
10 static void
11 generateBrowseVisitorHeader(const char * working_directory)
13 assert(working_directory);
15 std::fstream out;
16 std::string path(working_directory);
18 path.append("/browse-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_BROWSE_VISITOR_HH" NL
26 << "# define AST_BROWSE_VISITOR_HH" NL
28 << "#include <ast/visitor.hh>" NL
30 << "namespace ast" NL
31 << "{" NL;
33 #define BROWSE_VISITOR_HH(Prefix, Const) \
34 out << " /** @defgroup Visitors */" NL \
35 << " /**" NL \
36 << " * @brief A visitor which browse the AST from the top to the bottom." NL \
37 << " * @ingroup Visitors" NL \
38 << " */" NL \
39 << " class "Prefix"BrowseVisitor : public "Prefix"Visitor" NL \
40 << " {" NL \
41 << " public:" NL \
42 << " virtual ~"Prefix"BrowseVisitor();" NL \
43 NL; \
45 for (node = ag::nodes; !node->name.empty() > 0; node++) \
46 out << " virtual void visit("Const << node->name << " & node);" \
47 NL NL; \
49 out << " protected:" NL \
50 << " "Const"Node * parent_;" \
51 << " Node *"Const"* this_;" \
52 << " };" NL NL;
54 BROWSE_VISITOR_HH("", "");
55 BROWSE_VISITOR_HH("Const", "const ");
57 out << "} // namespace ast" NL
58 << "#endif // !AST_BROWSE_VISITOR_HH" NL;
59 out.close();
62 static void
63 generateBrowseVisitorSource(const char * working_directory)
65 assert(working_directory);
67 std::fstream out;
68 std::string path(working_directory);
70 path.append("/browse-visitor.cc");
71 out.open(path.c_str(), std::fstream::out | std::fstream::trunc);
72 assert(out.is_open() && out.good());
74 const ag::Node *node;
76 ag::appendGeneratedWarning(out);
77 out << "#include <boost/foreach.hpp>" NL
78 << "#include <core/assert.hh>" NL
79 << "#include <ast/browse-visitor.hh>" NL
80 << "#include <ast/ast.hh>" NL NL
81 << "#define NL << std::endl" NL NL
82 << "namespace ast" NL
83 << "{" NL;
85 #define BROWSE_VISITOR_CC(Name, Const) \
86 out << " "Name"::~"Name"() {}" NL NL; \
88 for (node = ag::nodes; !node->name.empty() > 0; node++) \
89 { \
90 out << " void "Name"::visit("Const << node->name \
91 << " & node __attribute__((unused)))" NL \
92 << " {" NL; \
94 BOOST_FOREACH(const ag::Attribute * attr, allAttributes(node)) \
95 { \
96 if (ag::isNode(attr->type)) \
97 out << " if (node." << attr->name << ")" NL \
98 << " node." << attr->name << "->accept(*this);" NL; \
99 else if (ag::isVectorOfNode(attr->type)) \
100 out << " if (node." << attr->name << ")" NL \
101 << " BOOST_FOREACH(Node * n, (*node." << attr->name \
102 << ")) {" NL \
103 << " assert(n);" NL \
104 << " parent_ = &node;" NL \
105 << " this_ = &n;" NL \
106 << " n->accept(*this);" NL \
107 << " }" NL; \
110 out << " }" NL NL; \
113 BROWSE_VISITOR_CC("BrowseVisitor", "");
114 BROWSE_VISITOR_CC("ConstBrowseVisitor", "const ");
116 out << "} // namespace ast" NL;
117 out.close();
120 int main(int argc, char **argv)
122 assert(argc == 2);
123 generateBrowseVisitorHeader(argv[1]);
124 generateBrowseVisitorSource(argv[1]);
125 return 0;