[ozulis] now deleting some fields in AST's destructors
[ozulis.git] / src / ozulis / generators / ast.cc
blobbe451555fd183629612d0f1d7a203b7f406d7996
1 #include "generator.hh"
2 #include <ozulis/core/assert.hh>
3 #include <iostream>
4 #include <fstream>
6 namespace ag = ozulis::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 <vector>" NL
27 << "# include <string>" NL NL
28 << "# include <boost/filesystem/path.hpp>" NL NL
29 << "# include <ozulis/core/ref-counted-object.hh>" NL
30 << "# include <ozulis/core/id.hh>" NL NL
31 << "namespace ozulis" NL
32 << "{" NL
33 << "namespace ast" NL
34 << "{" NL
35 << " class Scope;" NL
36 << " /// @defgroup AST" NL;
38 for (node = ag::nodes; node->name.length() > 0; node++)
39 out << " struct " << node->name << ";" NL;
41 for (node = ag::nodes; node->name.length() > 0; node++)
42 out << " typedef core::RefCountedObject::Ptr<" << node->name
43 << "> " << node->name << "Ptr;" NL;
45 out NL
46 << "# define AST_IS_FLOATING_POINT_TYPE(Type) \\" NL
47 << " ((Type)->nodeType == ::ozulis::ast::FloatType::nodeTypeId() || \\" NL
48 << " (Type)->nodeType == ::ozulis::ast::DoubleType::nodeTypeId())" NL NL
50 << "# define AST_PTR_CAST(Type, Value) \\" NL
51 << " reinterpret_cast< ::ozulis::ast::Type *> (Value.ptr())" NL NL;
53 for (node = ag::nodes; !node->name.empty() > 0; node++)
55 out << " /// @ingroup AST" NL
56 << " /// @brief " << node->description NL
57 << " struct " << node->name;
58 if (!node->parent.empty())
59 out << " : public " << node->parent;
60 out NL << " {" NL
61 << " public:" NL NL
62 << " " << node->name << "();" NL
63 << " virtual ~" << node->name << "();" NL NL
64 << " /// Returns the node name" NL
65 << " virtual const std::string & nodeName() const;" NL
66 << " /// Returns the node type" NL
67 << " static inline core::id_t nodeTypeId() { return core::Id<Node, "
68 << node->name << ">::id(); }" NL NL;
70 for (attr = node->attrs; !attr->type.empty(); attr++)
72 out << " " << attr->type << " " << attr->name << ";" NL
73 << " typedef " << ag::deref(attr->type) << " " << attr->name << "_t;" NL;
75 out << " };" NL NL;
78 out << "} // namespace ast" NL
79 << "} // namespace ozulis" NL NL
80 << "extern template class std::vector<ozulis::ast::Node *>;" NL
81 << "extern template class std::vector<ozulis::ast::Type *>;" NL
82 << "extern template class std::vector<ozulis::ast::VarDecl *>;" NL
83 << "#endif // !AST_AST_HH" NL;
84 out.close();
87 static void
88 generateAstSource(const char * working_directory)
90 assert(working_directory);
92 std::fstream out;
93 std::string path(working_directory);
95 path.append("/ast.cc");
96 out.open(path.c_str(), std::fstream::out | std::fstream::trunc);
97 assert(out.is_open() && out.good());
99 ag::appendGeneratedWarning(out);
100 out << "#include <ozulis/ast/ast.hh>" NL
101 << "#include <ozulis/core/id.cxx>" NL NL
102 << "#define NL << std::endl" NL NL
103 << "namespace ozulis" NL
104 << "{" NL
105 << "namespace ast" NL
106 << "{" NL;
108 const ag::Node *node;
109 for (node = ag::nodes; !node->name.empty() > 0; node++)
111 bool hasParent = !node->parent.empty();
112 out << " " << node->name << "::" << node->name << "()";
113 if (hasParent)
114 out NL << " : " << node->parent << "()";
115 for (const ag::Attribute * attr = node->attrs; !attr->type.empty(); ++attr)
116 if (hasParent++)
117 out << ", " << attr->name << "()";
118 else
119 out << ": " << attr->name << "()";
121 out NL
122 << " {" NL
123 << " nodeType = core::IdP<Node, "
124 << (node->name == "Node" ? "Node" : node->parent) << ", "
125 << node->name << ">::id();" NL
126 << " }" NL NL;
128 out << " " << node->name << "::~" << node->name << "()" NL
129 << " {" NL;
130 for (const ag::Attribute * attr = node->attrs; !attr->type.empty(); ++attr)
131 if (ag::needsDelete(attr->type))
132 out << " delete " << attr->name << ";" NL;
133 out << " }" NL NL;
135 out << " const std::string & " << node->name << "::nodeName() const" NL
136 << " {" NL
137 << " static const std::string name__ = \"" << node->name << "\";" NL
138 << " return name__;" NL
139 << " }" NL NL;
142 out << "} // namespace ast" NL
143 << "} // namespace ozulis" NL
144 << "template class std::vector<ozulis::ast::Node *>;" NL
145 << "template class std::vector<ozulis::ast::Type *>;" NL
146 << "template class std::vector<ozulis::ast::VarDecl *>;" NL;
147 out.close();
151 int main(int argc, char **argv)
153 assert(argc == 2);
154 generateAstHeader(argv[1]);
155 generateAstSource(argv[1]);
156 return 0;