1 #include "generator.hh"
2 #include <core/assert.hh>
6 namespace ag
= ast::generator
;
9 generateAstHeader(const char * working_directory
)
11 assert(working_directory
);
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
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
;
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
;
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())
69 for (attr
= node
->attrs
; !attr
->type
.empty(); attr
++)
71 out
<< " " << attr
->type
<< " " << attr
->name
<< ";" NL
72 << " typedef " << attr
->type
<< " " << attr
->name
<< "_t;" 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
;
86 generateAstSource(const char * working_directory
)
88 assert(working_directory
);
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
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
<< "()";
111 out NL
<< " : " << node
->parent
<< "()";
112 for (const ag::Attribute
* attr
= node
->attrs
; !attr
->type
.empty(); ++attr
)
114 out
<< ", " << attr
->name
<< "()";
116 out
<< ": " << attr
->name
<< "()";
120 << " nodeType = core::Id<ast::Node, ast::" << node
->name
124 out
<< " " << node
->name
<< "::~" << node
->name
<< "()" NL
128 out
<< " void " << node
->name
<< "::accept(Visitor & visitor)" NL
130 << " visitor.visit(*this);" NL
133 out
<< " void " << node
->name
<< "::accept(ConstVisitor & visitor) const" NL
135 << " visitor.visit(*this);" 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
;
147 int main(int argc
, char **argv
)
150 generateAstHeader(argv
[1]);
151 generateAstSource(argv
[1]);