src
go_emit.cc
Go to the documentation of this file.
1 #include <stddef.h>
2 #include "src/util/c99_stdint.h"
3 #include <string>
4 #include <utility>
5 #include <vector>
6 
7 #include "src/codegen/bitmap.h"
8 #include "src/codegen/go.h"
10 #include "src/codegen/label.h"
11 #include "src/codegen/output.h"
12 #include "src/codegen/print.h"
13 #include "src/conf/opt.h"
14 #include "src/globals.h"
15 #include "src/ir/adfa/adfa.h"
17 
18 namespace re2c
19 {
20 
21 static void output_if (OutputFile & o, uint32_t ind, bool & readCh, const std::string & compare, uint32_t value);
22 static void output_goto (OutputFile & o, uint32_t ind, bool & readCh, label_t to);
23 static std::string output_yych (bool & readCh);
24 static std::string output_hgo (OutputFile & o, uint32_t ind, bool & readCh, SwitchIf * hgo);
25 
26 std::string output_yych (bool & readCh)
27 {
28  if (readCh)
29  {
30  readCh = false;
31  return "(" + opts->input_api.expr_peek_save () + ")";
32  }
33  else
34  {
35  return opts->yych;
36  }
37 }
38 
39 void output_if (OutputFile & o, uint32_t ind, bool & readCh, const std::string & compare, uint32_t value)
40 {
41  o.wind(ind).ws("if (").wstring(output_yych (readCh)).ws(" ").wstring(compare).ws(" ").wc_hex (value).ws(") ");
42 }
43 
44 void output_goto (OutputFile & o, uint32_t ind, bool & readCh, label_t to)
45 {
46  if (readCh)
47  {
48  o.wstring(opts->input_api.stmt_peek (ind));
49  readCh = false;
50  }
51  o.wind(ind).ws("goto ").wstring(opts->labelPrefix).wlabel(to).ws(";\n");
52 }
53 
54 std::string output_hgo (OutputFile & o, uint32_t ind, bool & readCh, SwitchIf * hgo)
55 {
56  std::string yych = output_yych (readCh);
57  if (hgo != NULL)
58  {
59  o.wind(ind).ws("if (").wstring(yych).ws(" & ~0xFF) {\n");
60  hgo->emit (o, ind + 1, readCh);
61  o.wind(ind).ws("} else ");
62  yych = opts->yych;
63  }
64  else
65  {
66  o.wind(ind);
67  }
68  return yych;
69 }
70 
71 void Case::emit (OutputFile & o, uint32_t ind)
72 {
73  for (uint32_t i = 0; i < ranges.size (); ++i)
74  {
75  for (uint32_t b = ranges[i].first; b < ranges[i].second; ++b)
76  {
77  o.wind(ind).ws("case ").wc_hex (b).ws(":");
78  if (opts->dFlag && opts->encoding.type () == Enc::EBCDIC)
79  {
80  const uint32_t c = opts->encoding.decodeUnsafe (b);
81  if (is_print (c))
82  o.ws(" /* ").wc(static_cast<char> (c)).ws(" */");
83  }
84  bool last_case = i == ranges.size () - 1 && b == ranges[i].second - 1;
85  if (!last_case)
86  {
87  o.ws("\n");
88  }
89  }
90  }
91 }
92 
93 void Cases::emit (OutputFile & o, uint32_t ind, bool & readCh)
94 {
95  o.wind(ind).ws("switch (").wstring(output_yych (readCh)).ws(") {\n");
96  for (uint32_t i = 0; i < cases_size; ++i)
97  {
98  if (cases[i].to != def)
99  {
100  cases[i].emit (o, ind);
101  output_goto (o, 1, readCh, cases[i].to->label);
102  }
103  }
104  o.wind(ind).ws("default:");
105  output_goto (o, 1, readCh, def->label);
106  o.wind(ind).ws("}\n");
107 }
108 
109 void Binary::emit (OutputFile & o, uint32_t ind, bool & readCh)
110 {
111  output_if (o, ind, readCh, cond->compare, cond->value);
112  o.ws("{\n");
113  thn->emit (o, ind + 1, readCh);
114  o.wind(ind).ws("} else {\n");
115  els->emit (o, ind + 1, readCh);
116  o.wind(ind).ws("}\n");
117 }
118 
119 void Linear::emit (OutputFile & o, uint32_t ind, bool & readCh)
120 {
121  for (uint32_t i = 0; i < branches.size (); ++i)
122  {
123  if (branches[i].first != NULL)
124  {
125  output_if (o, ind, readCh, branches[i].first->compare, branches[i].first->value);
126  output_goto (o, 0, readCh, branches[i].second->label);
127  }
128  else
129  {
130  output_goto (o, ind, readCh, branches[i].second->label);
131  }
132  }
133 }
134 
135 void If::emit (OutputFile & o, uint32_t ind, bool & readCh)
136 {
137  switch (type)
138  {
139  case BINARY:
140  info.binary->emit (o, ind, readCh);
141  break;
142  case LINEAR:
143  info.linear->emit (o, ind, readCh);
144  break;
145  }
146 }
147 
148 void SwitchIf::emit (OutputFile & o, uint32_t ind, bool & readCh)
149 {
150  switch (type)
151  {
152  case SWITCH:
153  info.cases->emit (o, ind, readCh);
154  break;
155  case IF:
156  info.ifs->emit (o, ind, readCh);
157  break;
158  }
159 }
160 
161 void GoBitmap::emit (OutputFile & o, uint32_t ind, bool & readCh)
162 {
163  std::string yych = output_hgo (o, ind, readCh, hgo);
164  o.ws("if (").wstring(opts->yybm).ws("[").wu32(bitmap->i).ws("+").wstring(yych).ws("] & ");
165  if (opts->yybmHexTable)
166  {
167  o.wu32_hex(bitmap->m);
168  }
169  else
170  {
171  o.wu32(bitmap->m);
172  }
173  o.ws(") {\n");
174  output_goto (o, ind + 1, readCh, bitmap_state->label);
175  o.wind(ind).ws("}\n");
176  if (lgo != NULL)
177  {
178  lgo->emit (o, ind, readCh);
179  }
180 }
181 
182 label_t CpgotoTable::max_label () const
183 {
184  label_t max = label_t::first ();
185  for (uint32_t i = 0; i < TABLE_SIZE; ++i)
186  {
187  if (max < table[i]->label)
188  {
189  max = table[i]->label;
190  };
191  }
192  return max;
193 }
194 
195 void CpgotoTable::emit (OutputFile & o, uint32_t ind)
196 {
197  o.wind(ind).ws("static void *").wstring(opts->yytarget).ws("[256] = {\n");
198  o.wind(++ind);
199  const uint32_t max_digits = max_label ().width ();
200  for (uint32_t i = 0; i < TABLE_SIZE; ++i)
201  {
202  o.ws("&&").wstring(opts->labelPrefix).wlabel(table[i]->label);
203  if (i == TABLE_SIZE - 1)
204  {
205  o.ws("\n");
206  }
207  else if (i % 8 == 7)
208  {
209  o.ws(",\n").wind(ind);
210  }
211  else
212  {
213  const uint32_t padding = max_digits - table[i]->label.width () + 1;
214  o.ws(",").wstring(std::string (padding, ' '));
215  }
216  }
217  o.wind(--ind).ws("};\n");
218 }
219 
220 void Cpgoto::emit (OutputFile & o, uint32_t ind, bool & readCh)
221 {
222  std::string yych = output_hgo (o, ind, readCh, hgo);
223  o.ws("{\n");
224  table->emit (o, ++ind);
225  o.wind(ind).ws("goto *").wstring(opts->yytarget).ws("[").wstring(yych).ws("];\n");
226  o.wind(--ind).ws("}\n");
227 }
228 
230 {
231  const uint32_t n = cases->cases_size;
232  if (n == 1)
233  {
234  o.wlabel(from->label).ws(" -> ").wlabel(cases->cases[0].to->label).ws("\n");
235  }
236  else
237  {
238  for (uint32_t i = 0; i < n; ++i)
239  {
240  o.wlabel(from->label).ws(" -> ").wlabel(cases->cases[i].to->label).ws(" [label=\"");
241  for (uint32_t j = 0; j < cases->cases[i].ranges.size (); ++j)
242  {
243  o.wrange(cases->cases[i].ranges[j].first, cases->cases[i].ranges[j].second);
244  }
245  o.ws("\"]\n");
246  }
247  }
248 }
249 
250 void Go::emit (OutputFile & o, uint32_t ind, bool & readCh)
251 {
252  switch (type)
253  {
254  case EMPTY:
255  break;
256  case SWITCH_IF:
257  info.switchif->emit (o, ind, readCh);
258  break;
259  case BITMAP:
260  info.bitmap->emit (o, ind, readCh);
261  break;
262  case CPGOTO:
263  info.cpgoto->emit (o, ind, readCh);
264  break;
265  case DOT:
266  info.dot->emit (o);
267  break;
268  }
269 }
270 
271 } // namespace re2c
If * thn
Definition: go.h:65
void emit(OutputFile &o, uint32_t ind, bool &readCh)
Definition: go_emit.cc:135
static const uint32_t TABLE_SIZE
Definition: go.h:136
SwitchIf * hgo
Definition: go.h:124
CpgotoTable * table
Definition: go.h:152
enum re2c::Go::@3 type
void emit(OutputFile &o, uint32_t ind, bool &readCh)
Definition: go_emit.cc:119
SwitchIf * hgo
Definition: go.h:151
const State * def
Definition: go.h:43
uint32_t width() const
Definition: label.cc:28
std::string yytarget
Definition: opt.h:118
type_t type() const
Definition: enc.h:185
std::string compare
Definition: go.h:57
uint32_t value
Definition: go.h:58
InputAPI input_api
Definition: opt.h:118
std::string yych
Definition: opt.h:118
OutputFile & ws(const char *s)
Definition: output.cc:173
static std::string output_hgo(OutputFile &o, uint32_t ind, bool &readCh, SwitchIf *hgo)
Definition: go_emit.cc:54
OutputFile & wu32(uint32_t n)
Definition: output.cc:155
std::string yybm
Definition: opt.h:118
void emit(OutputFile &o, uint32_t ind)
Definition: go_emit.cc:195
OutputFile & wind(uint32_t ind)
Definition: output.cc:191
std::string expr_peek_save() const
Definition: input_api.cc:40
OutputFile & wlabel(label_t l)
Definition: output.cc:179
enum re2c::SwitchIf::@1 type
void emit(OutputFile &o, uint32_t ind, bool &readCh)
Definition: go_emit.cc:93
OutputFile & wc(char c)
Definition: output.cc:149
const State ** table
Definition: go.h:137
bool dFlag
Definition: opt.h:118
OutputFile & wc_hex(uint32_t n)
Definition: output.cc:108
OutputFile & wrange(uint32_t u, uint32_t l)
Definition: output.cc:114
uint32_t cases_size
Definition: go.h:45
void emit(OutputFile &o, uint32_t ind, bool &readCh)
Definition: go_emit.cc:161
static std::string output_yych(bool &readCh)
Definition: go_emit.cc:26
void emit(OutputFile &o, uint32_t ind, bool &readCh)
Definition: go_emit.cc:220
bool is_print(uint32_t c)
Definition: print.cc:11
uint32_t m
Definition: bitmap.h:25
void emit(OutputFile &o, uint32_t ind, bool &readCh)
Definition: go_emit.cc:109
void emit(OutputFile &o, uint32_t ind)
Definition: go_emit.cc:71
uint32_t i
Definition: bitmap.h:24
Enc encoding
Definition: opt.h:118
Case * cases
Definition: go.h:44
Cond * cond
Definition: go.h:64
SwitchIf * lgo
Definition: go.h:125
std::string labelPrefix
Definition: opt.h:118
label_t label
Definition: adfa.h:25
const State * to
Definition: go.h:30
std::vector< std::pair< const Cond *, const State * > > branches
Definition: go.h:77
const State * bitmap_state
Definition: go.h:123
Opt opts
Definition: opt.cc:7
static label_t first()
Definition: label.cc:18
static void output_goto(OutputFile &o, uint32_t ind, bool &readCh, label_t to)
Definition: go_emit.cc:44
std::string stmt_peek(uint32_t ind) const
Definition: input_api.cc:45
Cases * cases
Definition: go.h:164
union re2c::If::@0 info
const BitMap * bitmap
Definition: go.h:122
bool yybmHexTable
Definition: opt.h:118
uint32_t decodeUnsafe(uint32_t c) const
Definition: enc.cc:103
OutputFile & wu32_hex(uint32_t n)
Definition: output.cc:102
union re2c::SwitchIf::@2 info
If * els
Definition: go.h:66
union re2c::Go::@4 info
void emit(OutputFile &o, uint32_t ind, bool &readCh)
Definition: go_emit.cc:250
void emit(OutputFile &o)
Definition: go_emit.cc:229
enum re2c::If::type_t type
static void output_if(OutputFile &o, uint32_t ind, bool &readCh, const std::string &compare, uint32_t value)
Definition: go_emit.cc:39
std::vector< std::pair< uint32_t, uint32_t > > ranges
Definition: go.h:29
Definition: bitmap.cc:10
const State * from
Definition: go.h:163
OutputFile & wstring(const std::string &s)
Definition: output.cc:167
void emit(OutputFile &o, uint32_t ind, bool &readCh)
Definition: go_emit.cc:148