[llvm generator] correctly generate function's prototype
[ozulis.git] / src / ast / generator-ast.cc
blob06cf9b75ea80bc865f2804fbb9914c94013cbfc4
1 #include "generator.hh"
2 #include <core/assert.hh>
3 #include <iostream>
4 #include <fstream>
6 namespace ag = ast::generator;
8 void
9 generateAstHeader(const char * working_directory)
11 assert(working_directory);
13 std::fstream out;
14 std::string path(working_directory);
16 path.append("/ast.hh");
17 out.open(path.c_str(), std::fstream::out | std::fstream::trunc);
18 assert(out.is_open() && out.good());
20 const ag::Node * node;
21 const ag::Attribute * attr;
23 ag::appendGeneratedWarning(out);
24 out << "#ifndef AST_AST_HH" NL
25 << "# define AST_AST_HH" NL NL
26 << "# include <gc/gc_cpp.h>" NL
27 << "# include <vector>" NL
28 << "# include <string>" NL NL
29 << "# include <core/id.hh>" NL NL
30 << "namespace ast" NL
31 << "{" NL NL
32 << " /// @defgroup AST" NL;
34 out << " struct Visitor;" NL
35 << " struct ConstVisitor;" NL
36 << " struct Symbol;" NL
37 << " struct Scope;" NL NL;
39 for (node = ag::nodes; node->name.length() > 0; node++)
40 out << " struct " << node->name << ";" NL;
42 out NL
43 << "# define AST_IS_FLOATING_POINT_TYPE(Type) \\" NL
44 << " ((Type)->nodeType == ::ast::FloatType::nodeTypeId() || \\" NL
45 << " (Type)->nodeType == ::ast::DoubleType::nodeTypeId())" NL NL;
47 for (node = ag::nodes; !node->name.empty() > 0; node++)
49 out << " /// @ingroup AST" NL
50 << " /// @brief " << node->description NL
51 << " struct " << node->name;
52 if (!node->parent.empty())
53 out << " : public " << node->parent;
54 out NL << " {" NL
55 << " public:" NL NL
56 << " " << node->name << "();" NL
57 << " virtual ~" << node->name << "();" NL NL
58 << " /// The accept method for the visitor design pattern." NL
59 << " virtual void accept(Visitor & visitor);" NL
60 << " /// The accept method for the const visitor design pattern." NL
61 << " virtual void accept(ConstVisitor & visitor) const;" NL NL
62 << " /// Returns the node type" NL
63 << " static inline core::id_t nodeTypeId() { return core::Id<ast::Node, ast::"
64 << node->name << ">::id(); }" NL NL;
66 if (!node->attrs->type.empty())
67 out NL;
69 for (attr = node->attrs; !attr->type.empty(); attr++)
71 out << " " << attr->type << " " << attr->name << ";" NL
72 << " typedef " << attr->type << " " << attr->name << "_t;" NL;
74 out << " };" NL NL;
77 out << "} // namespace ast" NL NL
78 << "extern template class std::vector<ast::Node *>;" NL
79 << "extern template class std::vector<ast::Type *>;" NL
80 << "extern template class std::vector<ast::VarDecl *>;" NL
81 << "#endif // !AST_AST_HH" NL;
82 out.close();
85 static void
86 generateAstSource(const char * working_directory)
88 assert(working_directory);
90 std::fstream out;
91 std::string path(working_directory);
93 path.append("/ast.cc");
94 out.open(path.c_str(), std::fstream::out | std::fstream::trunc);
95 assert(out.is_open() && out.good());
97 ag::appendGeneratedWarning(out);
98 out << "#include <ast/ast.hh>" NL
99 << "#include <ast/visitor.hh>" NL
100 << "#include <core/id.hh>" NL NL
101 << "#define NL << std::endl" NL NL
102 << "namespace ast" NL
103 << "{" NL;
105 const ag::Node *node;
106 for (node = ag::nodes; !node->name.empty() > 0; node++)
108 bool hasParent = !node->parent.empty();
109 out << " " << node->name << "::" << node->name << "()";
110 if (hasParent)
111 out NL << " : " << node->parent << "()";
112 for (const ag::Attribute * attr = node->attrs; !attr->type.empty(); ++attr)
113 if (hasParent++)
114 out << ", " << attr->name << "()";
115 else
116 out << ": " << attr->name << "()";
118 out NL
119 << " {" NL
120 << " nodeType = core::Id<ast::Node, ast::" << node->name
121 << ">::id();" NL
122 << " }" NL NL;
124 out << " " << node->name << "::~" << node->name << "()" NL
125 << " {" NL
126 << " }" NL NL;
128 out << " void " << node->name << "::accept(Visitor & visitor)" NL
129 << " {" NL
130 << " visitor.visit(*this);" NL
131 << " }" NL NL;
133 out << " void " << node->name << "::accept(ConstVisitor & visitor) const" NL
134 << " {" NL
135 << " visitor.visit(*this);" NL
136 << " }" NL NL;
139 out << "} // namespace ast" NL
140 << "template class std::vector<ast::Node *>;" NL
141 << "template class std::vector<ast::Type *>;" NL
142 << "template class std::vector<ast::VarDecl *>;" NL;
143 out.close();
147 int main(int argc, char **argv)
149 assert(argc == 2);
150 generateAstHeader(argv[1]);
151 generateAstSource(argv[1]);
152 return 0;