Bug fixed for unix error "readlink /proc/self/fd/0" on MacOS.
[Faustine.git] / interpreter / preprocessor / faust-0.9.47mr3 / compiler / boxes / ppbox.cpp
1 /************************************************************************
2 ************************************************************************
3 FAUST compiler
4 Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
21
22
23
24 #include "list.hh"
25 #include "boxes.hh"
26 #include "ppbox.hh"
27 #include "signals.hh"
28 #include "prim2.hh"
29 #include "xtended.hh"
30
31
32 const char * prim0name(CTree *(*ptr) ())
33 {
34 return "prim0???";
35 }
36
37 const char * prim1name(CTree *(*ptr) (CTree *))
38 {
39 if (ptr == sigDelay1) return "mem";
40 if (ptr == sigIntCast) return "int";
41 if (ptr == sigFloatCast) return "float";
42 if (ptr == sigSerialize) return "serialize";
43
44 return "prim1???";
45 }
46
47 const char * prim2name(CTree *(*ptr) (CTree *, CTree *))
48 {
49 if (ptr == sigAdd) return "+";
50 if (ptr == sigSub) return "-";
51 if (ptr == sigMul) return "*";
52 if (ptr == sigDiv) return "/";
53 if (ptr == sigRem) return "%";
54
55 if (ptr == sigAND) return "&";
56 if (ptr == sigOR ) return "|";
57 if (ptr == sigXOR) return "^";
58
59 if (ptr == sigLeftShift ) return "<< ";
60 if (ptr == sigRightShift) return " >>";
61
62 if (ptr == sigLT) return "< ";
63 if (ptr == sigLE) return "<=";
64 if (ptr == sigGT) return " >";
65 if (ptr == sigGE) return " >=";
66 if (ptr == sigEQ) return "==";
67 if (ptr == sigNE) return "!=";
68
69 if (ptr == sigFixDelay) return "@";
70 if (ptr == sigPrefix) return "prefix";
71 if (ptr == sigAttach) return "attach";
72
73 if (ptr == sigVectorize) return "vectorize";
74 if (ptr == sigVectorAt) return "[]";
75 if (ptr == sigConcat) return "#";
76
77
78
79
80 return "prim2???";
81 }
82
83 const char * prim3name(CTree *(*ptr) (CTree *, CTree *, CTree *))
84 {
85 if (ptr == sigReadOnlyTable) return "rdtable";
86 if (ptr == sigSelect2) return "selecttwo";
87 return "prim3???";
88 }
89
90 const char * prim4name(CTree *(*ptr) (CTree *, CTree *, CTree *, CTree *))
91 {
92 if (ptr == sigSelect3) return "selectthree";
93 return "prim4???";
94 }
95
96 const char * prim5name(CTree *(*ptr) (CTree *, CTree *, CTree *, CTree *, CTree *))
97 {
98 if (ptr == sigWriteReadTable) return "wrtable";
99 return "prim5???";
100 }
101
102
103 static void streambinop(ostream& fout, Tree t1, const char* op, Tree t2, int curPriority, int upPriority)
104 {
105 if (upPriority > curPriority) fout << '(';
106 fout << boxpp(t1,curPriority) << op << boxpp(t2,curPriority);
107 if (upPriority > curPriority) fout << ')';
108 }
109
110 static void printRule(ostream& fout, Tree rule)
111 {
112 Tree lhs = left(rule);
113 Tree rhs = right(rule);
114 char sep = '('; while (!isNil(lhs)) { fout << sep << boxpp(hd(lhs)); sep=','; lhs=tl(lhs); }
115 fout << ") => " << boxpp(rhs) << "; ";
116 }
117
118 /*****************************************************************************
119 affichage d'une expression box comme en entree
120 *****************************************************************************/
121
122 ostream& boxpp::print (ostream& fout) const
123 {
124 int i, id;
125 double r;
126 prim0 p0;
127 prim1 p1;
128 prim2 p2;
129 prim3 p3;
130 prim4 p4;
131 prim5 p5;
132
133 Tree t1, t2, t3, ff, label, cur, min, max, step, type, name, file, arg,
134 body, fun, args, abstr, genv, vis, lenv, ldef, slot,
135 ident, rules;
136
137 const char* str;
138
139 xtended* xt = (xtended*) getUserData(box);
140
141
142 // primitive elements
143 if (xt) fout << xt->name();
144 else if (isBoxInt(box, &i)) fout << i;
145 else if (isBoxReal(box, &r))
146 {
147 fout.setf( ios_base::fixed );
148 fout.precision(16);
149 fout << r;
150 //fout.setf( ios_base::fixed);
151 }
152
153 else if (isBoxCut(box)) fout << '!';
154 else if (isBoxWire(box)) fout << '_';
155 else if (isBoxIdent(box, &str)) fout << str;
156 else if (isBoxPrim0(box, &p0)) fout << prim0name(p0);
157 else if (isBoxPrim1(box, &p1)) fout << prim1name(p1);
158 else if (isBoxPrim2(box, &p2)) fout << prim2name(p2);
159 else if (isBoxPrim3(box, &p3)) fout << prim3name(p3);
160 else if (isBoxPrim4(box, &p4)) fout << prim4name(p4);
161 else if (isBoxPrim5(box, &p5)) fout << prim5name(p5);
162
163 else if (isBoxAbstr(box,arg,body)) fout << "\\" << boxpp(arg) << ".(" << boxpp(body) << ")";
164 else if (isBoxAppl(box, fun, args)) fout << boxpp(fun) << boxpp(args) ;
165
166 else if (isBoxWithLocalDef(box, body, ldef)) fout << boxpp(body) << " with { " << envpp(ldef) << " }";
167
168 // foreign elements
169 else if (isBoxFFun(box, ff)) fout << "ffunction(" << ffname(ff) << ')';
170 else if (isBoxFConst(box, type, name, file))
171 fout << "fconstant(" /*<< tree2str(type) */<< tree2str(name) << ')';
172 else if (isBoxFVar(box, type, name, file))
173 fout << "fvariable(" << tree2str(name) << ')';
174
175 // block diagram binary operator
176 else if (isBoxSeq(box, t1, t2)) streambinop(fout, t1, ":", t2, 1, priority);
177 else if (isBoxSplit(box, t1, t2)) streambinop(fout, t1, "<:", t2, 1, priority);
178 else if (isBoxMerge(box, t1, t2)) streambinop(fout, t1, ":>", t2, 1, priority);
179 else if (isBoxPar(box, t1, t2)) streambinop(fout, t1,",",t2, 2, priority);
180 else if (isBoxRec(box, t1, t2)) streambinop(fout, t1,"~",t2, 4, priority);
181
182 // iterative block diagram construction
183 else if (isBoxIPar(box, t1, t2, t3)) fout << "par(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
184 else if (isBoxISeq(box, t1, t2, t3)) fout << "seq(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
185 else if (isBoxISum(box, t1, t2, t3)) fout << "sum(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
186 else if (isBoxIProd(box, t1, t2, t3)) fout << "prod(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
187
188 /*
189 // user interface
190 else if (isBoxButton(box, label)) fout << "button(" << tree2str(label) << ')';
191 else if (isBoxCheckbox(box, label)) fout << "checkbox(" << tree2str(label) << ')';
192 else if (isBoxVSlider(box, label, cur, min, max, step)) {
193 fout << "vslider("
194 << tree2str(label) << ", "
195 << boxpp(cur) << ", "
196 << boxpp(min) << ", "
197 << boxpp(max) << ", "
198 << boxpp(step)<< ')';
199 }
200 else if (isBoxHSlider(box, label, cur, min, max, step)) {
201 fout << "hslider("
202 << tree2str(label) << ", "
203 << boxpp(cur) << ", "
204 << boxpp(min) << ", "
205 << boxpp(max) << ", "
206 << boxpp(step)<< ')';
207 }
208 else if (isBoxVGroup(box, label, t1)) {
209 fout << "vgroup(" << tree2str(label) << ", " << boxpp(t1, 0) << ')';
210 }
211 else if (isBoxHGroup(box, label, t1)) {
212 fout << "hgroup(" << tree2str(label) << ", " << boxpp(t1, 0) << ')';
213 }
214 else if (isBoxTGroup(box, label, t1)) {
215 fout << "tgroup(" << tree2str(label) << ", " << boxpp(t1, 0) << ')';
216 }
217 else if (isBoxHBargraph(box, label, min, max)) {
218 fout << "hbargraph("
219 << tree2str(label) << ", "
220 << boxpp(min) << ", "
221 << boxpp(max) << ')';
222 }
223 else if (isBoxVBargraph(box, label, min, max)) {
224 fout << "vbargraph("
225 << tree2str(label) << ", "
226 << boxpp(min) << ", "
227 << boxpp(max) << ')';
228 }
229 else if (isBoxNumEntry(box, label, cur, min, max, step)) {
230 fout << "nentry("
231 << tree2str(label) << ", "
232 << boxpp(cur) << ", "
233 << boxpp(min) << ", "
234 << boxpp(max) << ", "
235 << boxpp(step)<< ')';
236 }
237 */
238
239 // user interface ----------- Edited by Haisheng WANG for Faustine, 16/09/2013.
240 else if (isBoxButton(box, label)) fout << "button";
241 else if (isBoxCheckbox(box, label)) fout << "checkbox";
242 else if (isBoxVSlider(box, label, cur, min, max, step)) {
243 fout << "vslider";
244 }
245 else if (isBoxHSlider(box, label, cur, min, max, step)) {
246 fout << "hslider";
247 }
248 else if (isBoxVGroup(box, label, t1)) {
249 fout << "vgroup";
250 }
251 else if (isBoxHGroup(box, label, t1)) {
252 fout << "hgroup";
253 }
254 else if (isBoxTGroup(box, label, t1)) {
255 fout << "tgroup";
256 }
257 else if (isBoxHBargraph(box, label, min, max)) {
258 fout << "hbargraph";
259 }
260 else if (isBoxVBargraph(box, label, min, max)) {
261 fout << "vbargraph";
262 }
263 else if (isBoxNumEntry(box, label, cur, min, max, step)) {
264 fout << "nentry";
265 }
266 // end user interface
267
268 else if (isNil(box)) {
269 fout << "()" ;
270 }
271 else if (isList(box)) {
272
273 Tree l = box;
274 char sep = '(';
275
276 do {
277 fout << sep << boxpp(hd(l));
278 sep = ',';
279 l = tl(l);
280 } while (isList(l));
281
282 fout << ')';
283
284 }
285 else if (isBoxEnvironment(box)) {
286 fout << "environment";
287 }
288 else if (isClosure(box, abstr, genv, vis, lenv)) {
289 fout << "closure[" << boxpp(abstr)
290 << ", genv = " << envpp(genv)
291 << ", lenv = " << envpp(lenv)
292 << "]";
293 }
294 else if (isBoxComponent(box, label)) {
295 fout << "component("
296 << tree2str(label) << ')';
297 }
298 else if (isBoxAccess(box, t1, t2)) {
299 fout << boxpp(t1) << '.' << boxpp(t2);
300 }
301 else if (isImportFile(box, label)) {
302 fout << "import("
303 << tree2str(label) << ')';
304 }
305 else if (isBoxSlot(box, &id)) {
306 fout << "#" << id;
307 }
308 else if (isBoxSymbolic(box, slot, body)) {
309 fout << "[" << boxpp(slot) << ">" << boxpp(body) << "]";
310 }
311
312 // Pattern Matching Extensions
313 else if (isBoxCase(box, rules)) {
314 fout << "case {";
315 while (!isNil(rules)) { printRule(fout, hd(rules)); rules = tl(rules); }
316 fout << "}";
317 }
318 #if 1
319 // more useful for debugging output
320 else if (isBoxPatternVar(box, ident)) {
321 fout << "<" << boxpp(ident) << ">";
322 }
323 #else
324 // beautify messages involving lhs patterns
325 else if (isBoxPatternVar(box, ident)) {
326 fout << boxpp(ident);
327 }
328 #endif
329
330 else if (isBoxPatternMatcher(box)) {
331 fout << "PM[" << box << "]";
332 }
333
334 else if (isBoxError(box)) {
335 fout << "ERROR";
336 }
337
338
339 // None of the previous tests succeded, then it is not a valid box
340 else {
341 cerr << "Error in box::print() : " << *box << " is not a valid box" << endl;
342 exit(1);
343 }
344
345 return fout;
346 }
347
348
349 /*****************************************************************************
350 affichage d'un environnement
351 *****************************************************************************/
352
353 ostream& envpp::print (ostream& fout) const
354 {
355 const char* sep = "";
356 Tree l = fEnv;
357
358 fout << '{';
359 while (isList(l)) {
360 fout << sep << boxpp(hd(hd(l))) << "=" << boxpp(tl(hd(l)));
361 sep = ", ";
362 l = tl(l);
363 }
364 fout << '}';
365 return fout;
366 }
367