simple.cc - generated code example
[prop.git] / prop-src / codegen.cc
blobdcc93b3e9948764508f3711e3c75a1bda8398189
1 ///////////////////////////////////////////////////////////////////////////////
2 // This file is generated automatically using Prop (version 2.3.6),
3 // last updated on Nov 2, 1999.
4 // The original source file is "codegen.pcc".
5 ///////////////////////////////////////////////////////////////////////////////
7 #line 1 "codegen.pcc"
8 ///////////////////////////////////////////////////////////////////////////////
9 //
10 // This file implements the low level routine for generating C++ output->
12 ///////////////////////////////////////////////////////////////////////////////
13 #include <iostream>
14 #include <string.h>
15 #include <AD/strings/charesc.h>
16 #include "codegen.h"
17 #include "ir.h"
18 #include "ast.h"
19 #include "type.h"
20 #include "matchcom.h"
21 #include "options.h"
23 ///////////////////////////////////////////////////////////////////////////////
25 // Code generator constructor and destructor
27 ///////////////////////////////////////////////////////////////////////////////
28 CodeGen:: CodeGen()
29 : output(&std::cerr), anchored(true), tabbing(0), tab_unit(3) {}
30 CodeGen::~CodeGen() {}
31 void CodeGen::set_stream(std::ostream& s) { output = &s; }
33 ///////////////////////////////////////////////////////////////////////////////
35 // Convert literals to a type string.
37 ///////////////////////////////////////////////////////////////////////////////
38 #line 31 "codegen.pcc"
39 #line 38 "codegen.pcc"
40 Id literal_type_of (Literal x_1);
41 Id literal_type_of (Literal x_1)
43 switch (x_1->tag__) {
44 case a_Literal::tag_INTlit: {
45 #line 31 "codegen.pcc"
46 return "integer";
47 #line 31 "codegen.pcc"
48 } break;
49 case a_Literal::tag_BOOLlit: {
50 #line 34 "codegen.pcc"
51 return "boolean";
52 #line 34 "codegen.pcc"
53 } break;
54 case a_Literal::tag_CHARlit: {
55 #line 33 "codegen.pcc"
56 return "character";
57 #line 33 "codegen.pcc"
58 } break;
59 case a_Literal::tag_REALlit: {
60 #line 32 "codegen.pcc"
61 return "real";
62 #line 32 "codegen.pcc"
63 } break;
64 case a_Literal::tag_QUARKlit: {
65 #line 36 "codegen.pcc"
66 return "Quark";
67 #line 36 "codegen.pcc"
68 } break;
69 case a_Literal::tag_BIGINTlit: {
70 #line 37 "codegen.pcc"
71 return "BigInt";
72 #line 37 "codegen.pcc"
73 } break;
74 default: {
75 #line 35 "codegen.pcc"
76 return "string";
77 #line 35 "codegen.pcc"
78 } break;
81 #line 38 "codegen.pcc"
82 #line 38 "codegen.pcc"
85 ///////////////////////////////////////////////////////////////////////////////
87 // Emit a string with indenting.
89 ///////////////////////////////////////////////////////////////////////////////
90 void CodeGen::gen_code(const char * code)
91 { const char * p, * q;
92 int line_no = 1;
93 int my_tab = -1;
94 for (p = code; *p; ) {
95 if (anchored) {
96 int t;
97 if (line_no == 2) {
98 if (tabbing == 0) my_tab = 0;
99 else for (my_tab = 0, q = p; *q == ' '; q++) my_tab++;
101 if (line_no >= 2) {
102 for (t = my_tab; *p == ' ' && t > 0; p++) t--;
103 for (t = tabbing; t > 0; t--) output->put(' ');
104 } else {
105 for (t = tabbing; *p == ' ' && t > 0; p++) t--;
106 for ( ; t > 0; t--) output->put(' ');
108 } else {
109 for ( ; *p == ' '; p++); output->put(' ');
111 anchored = false;
112 for (;;) {
113 if (*p == '\0') break;
114 output->put(*p);
115 if (*p == '\n') { line_no++; anchored = true; p++; break; }
116 p++;
121 ///////////////////////////////////////////////////////////////////////////////
123 // Decode a format string and dispatch to various printing routines.
125 ///////////////////////////////////////////////////////////////////////////////
126 std::ostream& CodeGen::outv(const char * fmt, va_list arg)
127 { unsigned char c;
128 while ((c = *fmt++) != 0)
129 { if (c == '%') {
130 switch (*fmt++) {
131 case 'i': (*output)<< va_arg(arg,int); anchored = false; break;
132 case 'c': c = (unsigned char)va_arg(arg,int);
133 output->put(c); anchored = (c == '\n'); break;
134 case 'C': gen_code(va_arg(arg,const char *)); break;
135 case 's': { const char * s = va_arg(arg,const char *);
136 int len = strlen(s);
137 (*output)<< s;
138 anchored = (s[len-1] == '\n');
139 } break;
140 case 'S': (*output)<< mangle(va_arg(arg,const char *));
141 anchored = false;
142 break;
143 case 'q': (*output)<< va_arg(arg,QualId); anchored = false; break;
144 case 'e': (*output)<< va_arg(arg,Exp); anchored = false; break;
145 case 'f': { Bool save = pretty_print_exp;
146 pretty_print_exp = true;
147 (*output)<< va_arg(arg,Exp); anchored = false;
148 pretty_print_exp = save;
149 } break;
150 case 'E': { Exp e = va_arg(arg,Exp);
152 #line 106 "codegen.pcc"
153 #line 109 "codegen.pcc"
155 if (e) {
156 switch (e->tag__) {
157 case a_Exp::tag_MARKEDexp: {
158 #line 108 "codegen.pcc"
159 pr ("%D", MARKEDdecl(((Exp_MARKEDexp *)e)->_1, EXPdecl(((Exp_MARKEDexp *)e)->_2)));
160 #line 108 "codegen.pcc"
161 } break;
162 default: {
163 L1:;
164 #line 109 "codegen.pcc"
165 (*output)<< e;
166 #line 109 "codegen.pcc"
167 } break;
169 } else { goto L1; }
171 #line 110 "codegen.pcc"
172 #line 110 "codegen.pcc"
174 anchored = false;
175 } break;
176 case 'l': (*output)<< va_arg(arg,Literal); anchored = false; break;
177 case 'p': (*output)<< va_arg(arg,Pat); anchored = false; break;
178 case 'r': (*output)<< va_arg(arg,MatchRule); anchored = false; break;
179 case 'b': { Ty ty = va_arg (arg,Ty);
180 Id name = va_arg (arg,Id);
181 Id id = mangle(name);
182 Parameter p = (Parameter)va_arg (arg,int);
183 Bool is_array = is_array_constructor(name);
184 if (is_array)
185 { Ty body_ty = NOty;
186 if (p == TYbody)
187 { pr ("%^const int len_;%^");
188 body_ty = mkarrayty(ty,LITERALexp(INTlit(0)));
189 } else
190 { body_ty =
191 mkrecordty(
193 #line 129 "codegen.pcc"
194 #line 129 "codegen.pcc"
195 list_1_(Id("_len_"),list_1_(id))
196 #line 129 "codegen.pcc"
197 #line 129 "codegen.pcc"
200 #line 130 "codegen.pcc"
201 #line 130 "codegen.pcc"
202 list_1_(integer_ty,list_1_(mkptrty(QUALty(QUALconst,ty))))
203 #line 130 "codegen.pcc"
204 #line 130 "codegen.pcc"
206 false);
208 print_parameter(*output, body_ty, id, p);
209 if (p == TYbody)
210 { pr ("\n"
211 "%^inline int len() const { return len_; }"
212 "%^inline %t const& at(int i) const { return %S[i]; }"
213 "%^inline %t& at(int i) { return %S[i]; }"
214 "%^inline %t const * array() const { return %S; }"
215 "%^inline %t * array() { return %S; }",
216 ty, "", name, ty, "", name,
217 ty, "", name, ty, "", name);
219 } else {
220 print_parameter(*output, ty, id, p);
222 anchored = false;
223 } break;
224 case 'T': (*output)<< va_arg(arg,Ty); anchored = false; break;
225 case 't': { Bool save = pretty_print_ty;
226 pretty_print_ty = false;
227 Ty ty = va_arg(arg,Ty);
228 ty_id = va_arg(arg,Id);
229 (*output)<< ty;
230 anchored = false;
231 pretty_print_ty = save;
232 } break;
233 case 'V': print_tyvars(*output,va_arg(arg,TyVars), '<', '>', false);
234 anchored = false; break;
235 case 'P': { Tys tys = va_arg(arg,Tys);
236 Bool save = pretty_print_ty;
237 pretty_print_ty = false;
238 if (tys)(*output)<< '<' << tys << '>';
239 pretty_print_ty = save;
240 anchored = false;
241 } break;
242 case 'Q': (*output)<< va_arg(arg,Pid); anchored = false; break;
243 case 'H': print_tyvars(*output,va_arg(arg,TyVars), '<', '>', true);
244 anchored = false; break;
245 case 'v': print_tyvars(*output,va_arg(arg,TyVars), '(', ')', false);
246 anchored = false; break;
247 case '#': { int l = va_arg(arg,int);
248 const char * f = va_arg(arg,const char *);
249 if (options.line_directives)
250 { if (! anchored)(*output)<< '\n';
251 (*output)<< "#line " << l << " \"" << f << "\"\n";
252 anchored = true;
254 } break;
255 case '!': { const Loc * l = va_arg(arg, const Loc *);
256 if (! anchored)(*output)<< '\n';
257 if (options.GNU_style_message)
258 (*output)<< l->file_name << ':'
259 << l->begin_line << ": ";
260 else
261 (*output)<< '"' << l->file_name << "\", line "
262 << l->begin_line << ": ";
263 anchored = true;
264 } break;
265 case 'L': if (options.GNU_style_message)
266 (*output)<< file << ':' << line << ": ";
267 else
268 (*output)<< '"' << file << "\", line " << line << ": ";
269 anchored = false;
270 break;
271 case 'w': if (options.strict_checking) errors++;
272 else(*output)<< "warning: ";
273 anchored = false;
274 break;
275 case 'M': (*output)<< va_arg(arg,Match); anchored = false; break;
276 case 'n': if (! anchored)(*output)<< '\n'; anchored = true; break;
277 case 'I': { Inherits i = va_arg(arg,Inherits);
278 (*output)<< i;
279 anchored = false;
280 } break;
281 case 'U': { Exp exp = va_arg(arg,Exp);
282 Ty ty = va_arg(arg,Ty);
283 (*output) << MatchCompiler::untag(exp,ty);
284 } break;
285 case '*': { Cons cons = va_arg(arg,Cons);
286 Bool normalized = va_arg(arg,int);
287 (*output) << MatchCompiler::tag_name_of(cons,
288 normalized);
289 } break;
290 case '%': (*output)<< '%'; anchored = false; break;
291 case '?': if (! anchored) break;
292 case '^': { if (! anchored)(*output)<< '\n';
293 if (tabbing < 0) error ("Tab = %i\n", tabbing);
294 for (int i = tabbing; i > 0; i--)(*output)<< ' ';
295 anchored = (tabbing == 0);
296 } break;
297 case '+': tabbing += tab_unit; break;
298 case '-': tabbing -= tab_unit; break;
299 case '/': { for (int i = 79 - tabbing; i > 0; i--)(*output)<< '/';
300 (*output)<< '\n'; anchored = true;
301 } break;
302 case '=': (*output)<< "_equal_" << literal_type_of(va_arg(arg,Literal)); break;
303 case '<': (*output)<< "_less_" << literal_type_of(va_arg(arg,Literal)); break;
304 default: arg = printer(fmt[-1],arg); break;
307 else { output->put(c); anchored = (c == '\n'); }
309 return *output;
312 ///////////////////////////////////////////////////////////////////////////////
314 // Entry point.
316 ///////////////////////////////////////////////////////////////////////////////
317 std::ostream& CodeGen::pr(const char * fmt, ...)
318 { va_list arg;
319 va_start(arg,fmt);
320 outv(fmt,arg);
321 va_end(arg);
322 return *output;
324 #line 249 "codegen.pcc"
326 ------------------------------- Statistics -------------------------------
327 Merge matching rules = yes
328 Number of DFA nodes merged = 37
329 Number of ifs generated = 1
330 Number of switches generated = 2
331 Number of labels = 1
332 Number of gotos = 1
333 Adaptive matching = enabled
334 Fast string matching = disabled
335 Inline downcasts = enabled
336 --------------------------------------------------------------------------