Vcsn  2.2
Be Rational
context-printer.cc
Go to the documentation of this file.
2 
3 #include <map>
4 
5 #include <boost/algorithm/string/predicate.hpp>
6 
7 #include <vcsn/dyn/type-ast.hh>
8 #include <vcsn/misc/getargs.hh>
9 #include <vcsn/misc/indent.hh>
10 #include <vcsn/misc/raise.hh>
11 
12 
13 namespace vcsn
14 {
15  namespace ast
16  {
17  void context_printer::header(const std::string& h)
18  {
19  headers_.insert(h);
20  }
21 
22  void context_printer::linkflags(const std::string& flags)
23  {
24  // We rely on this initial space when not empty.
25  linkflags_ += ' ';
26  linkflags_ += flags;
27  }
28 
29  const std::string& context_printer::linkflags() const
30  {
31  return linkflags_;
32  }
33 
34  std::ostream& context_printer::print(std::ostream& o)
35  {
36  //o << "// " << is.str() << "\n";
37  o <<
38  "#define BUILD_LIBVCSN 1\n"
39  "#define VCSN_INSTANTIATION 1\n"
40  "#define MAYBE_EXTERN\n"
41  "\n";
42  for (const auto& h: headers_)
43  o << "#include <" << h << ">\n";
44  o << '\n';
45  for (const auto& h: headers_late_)
46  o << "#include <" << h << ">\n";
47  o << "\n"
48  << os_.str();
49  return o;
50  }
51 
52 #define DEFINE(Type) \
53  void context_printer::visit(const Type& t)
54 
56  {
57  static const auto map = getarg<std::string>
58  {
59  "automaton type",
60  {
61  {"compose_automaton" , "vcsn/algos/compose.hh"},
62  {"delay_automaton" , "vcsn/algos/is-synchronized.hh"},
63  {"derived_term_automaton" , "vcsn/algos/derived-term.hh"},
64  {"determinized_automaton" , "vcsn/algos/determinize.hh"},
65  {"expression_automaton" , "vcsn/core/expression-automaton.hh"},
66  {"filter_automaton" , "vcsn/algos/filter.hh"},
67  {"focus_automaton" , "vcsn/algos/focus.hh"},
68  {"insplit_automaton" , "vcsn/algos/insplit.hh"},
69  {"lazy_proper_automaton" , "vcsn/algos/epsilon-remover-lazy.hh"},
70  {"mutable_automaton" , "vcsn/core/mutable-automaton.hh"},
71  {"name_automaton" , "vcsn/core/name-automaton.hh"},
72  {"pair_automaton" , "vcsn/algos/synchronizing-word.hh"},
73  {"partition_automaton" , "vcsn/core/partition-automaton.hh"},
74  {"permutation_automaton" , "vcsn/core/permutation-automaton.hh"},
75  {"product_automaton" , "vcsn/algos/conjunction.hh"},
76  {"scc_automaton" , "vcsn/algos/scc.hh"},
77  {"synchronized_automaton" , "vcsn/algos/synchronize.hh"},
78  {"transpose_automaton" , "vcsn/algos/transpose.hh"},
79  {"tuple_automaton" , "vcsn/core/tuple-automaton.hh"},
80  },
81  };
82  auto type = t.get_type();
83  header(map[type]);
84  os_ << "vcsn::" << type << '<' << incendl;
85  bool first = true;
86  for (auto c: t.get_content())
87  {
88  if (!first)
89  os_ << ',' << iendl;
90  first = false;
91  c->accept(*this);
92  }
93  os_ << decendl << '>';
94  }
95 
96  DEFINE(context)
97  {
98  header("vcsn/ctx/context.hh");
99  os_ << "vcsn::context<" << incendl;
100  t.get_labelset()->accept(*this);
101  os_ << ',' << iendl;
102  t.get_weightset()->accept(*this);
103  os_ << decendl << '>';
104  }
105 
106  DEFINE(tuple)
107  {
108  header("tuple");
109  os_ << "std::tuple<" << incendl;
110  bool first = true;
111  for (auto v: t.get_sets())
112  {
113  if (!first)
114  os_ << ',' << iendl;
115  first = false;
116  v->accept(*this);
117  }
118  os_ << decendl << '>';
119  }
120 
121  DEFINE(tupleset)
122  {
123  headers_late_.insert("vcsn/labelset/tupleset.hh");
124  os_ << "vcsn::tupleset<" << incendl;
125  bool first = true;
126  for (auto v: t.get_sets())
127  {
128  if (!first)
129  os_ << ',' << iendl;
130  first = false;
131  v->accept(*this);
132  }
133  os_ << decendl << '>';
134  }
135 
136  DEFINE(nullableset)
137  {
138  header("vcsn/labelset/nullableset.hh");
139  os_ << "vcsn::nullableset<" << incendl;
140  t.get_labelset()->accept(*this);
141  os_ << decendl << ">";
142  }
143 
144  DEFINE(oneset)
145  {
146  (void) t;
147  header("vcsn/labelset/oneset.hh");
148  os_ << "vcsn::oneset";
149  }
150 
151  DEFINE(genset)
152  {
153  header("vcsn/alphabets/setalpha.hh"); // set_alphabet
154  if (t.letter_type() == "char_letters")
155  header("vcsn/alphabets/char.hh");
156  else if (t.letter_type() == "string_letters")
157  header("vcsn/alphabets/string.hh");
158  os_ << "vcsn::set_alphabet<vcsn::" << t.letter_type() << '>';
159  }
160 
161  DEFINE(letterset)
162  {
163  header("vcsn/labelset/letterset.hh");
164  os_ << "vcsn::letterset<";
165  t.genset()->accept(*this);
166  os_ << '>';
167  }
168 
169  DEFINE(expressionset)
170  {
171  os_ << "vcsn::expressionset<" << incendl;
172  t.get_context()->accept(*this);
173  os_ << decendl << '>';
174  header("vcsn/core/rat/expressionset.hh");
175  }
176 
177  DEFINE(expansionset)
178  {
179  os_ << "vcsn::rat::expansionset<" << incendl;
180  t.get_expressionset()->accept(*this);
181  os_ << decendl << '>';
182  header("vcsn/core/rat/expansionset.hh");
183  }
184 
185  DEFINE(weightset)
186  {
187  header("vcsn/weightset/" + t.get_type() + ".hh");
188  if (t.get_type() == "qmp")
189  linkflags("-lgmp -lgmpxx");
190  os_ << "vcsn::" << t.get_type();
191  }
192 
193  DEFINE(wordset)
194  {
195  header("vcsn/labelset/wordset.hh");
196  os_ << "vcsn::wordset<";
197  t.genset()->accept(*this);
198  os_ << '>';
199  }
200 
201  DEFINE(other)
202  {
203  if (boost::ends_with(t.get_type(), "_tag"))
204  os_ << "vcsn::";
205  os_ << t.get_type();
206  }
207 
208  DEFINE(polynomialset)
209  {
210  os_ << "vcsn::polynomialset<" << incendl;
211  t.get_content()->accept(*this);
212  os_ << decendl << '>';
213  header("vcsn/weightset/polynomialset.hh");
214  }
215 #undef DEFINE
216  }
217 }
void header(const std::string &h)
Record that we need an include for this header.
std::ostream & incendl(std::ostream &o)
Increment the indentation, print an end of line, and set the indentation.
Definition: indent.cc:54
Definition: a-star.hh:8
std::set< std::string > headers_
Headers to include.
Indentation relative functions.
std::ostream & iendl(std::ostream &o)
Print an end of line, then set the indentation.
Definition: indent.cc:49
A mapping from strings to Values.
Definition: getargs.hh:33
const std::string & linkflags() const
Get the link flags.
std::set< std::string > headers_late_
std::ostringstream & os_
#define DEFINE(Type)
std::ostream & print(std::ostream &o)
Generate the code to compile on o.
std::string linkflags_
Flags to pass to the linker.