Bug fixed for unix error "readlink /proc/self/fd/0" on MacOS.
[Faustine.git] / interpreter / preprocessor / faust-0.9.47mr3 / compiler / boxes / boxes.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 /*****************************************************************************
25 ******************************************************************************
26
27
28 The Box Language
29
30
31 ******************************************************************************
32 *****************************************************************************/
33
34
35 /**\file boxes.cpp
36 * \author Yann Orlarey
37 * \version 1.0
38 * \date 2003
39 * \brief Implementation of block diagram expressions.
40 * Boxes are created using five main connection operations : sequential (:),
41 * parallel (,), split (<:), merge (:>), and recursive (~).
42 */
43
44 #include <stdio.h>
45 #include <string.h>
46 #include "boxes.hh"
47 #include "ppbox.hh"
48 #include "prim2.hh"
49 #include "xtended.hh"
50
51
52 /*****************************************************************************
53 Identifiers
54 *****************************************************************************/
55 Sym BOXIDENT = symbol ("BoxIdent");
56
57 Tree boxIdent(const char* name) { return tree(BOXIDENT, tree(symbol(name)) ); }
58 bool isBoxIdent(Tree t) { return t->node() == Node(BOXIDENT); }
59 bool isBoxIdent(Tree t0, const char** str)
60 {
61 Tree t1; Sym s;
62 if ( isTree(t0, BOXIDENT, t1) && isSym(t1->node(), &s) ) {
63 *str = name(s);
64 return true;
65 } else {
66 return false;
67 }
68 }
69
70
71 /*****************************************************************************
72 Numbers
73 *****************************************************************************/
74
75 Tree boxInt(int n) { return tree(n); }
76 Tree boxReal(double n) { return tree(n); }
77
78 bool isBoxInt(Tree t) { return isInt(t->node()); }
79 bool isBoxReal(Tree t) { return isDouble(t->node()); }
80
81 bool isBoxInt(Tree t, int* i) { return isInt(t->node(), i); }
82 bool isBoxReal(Tree t, double* r) { return isDouble(t->node(), r); }
83
84
85 /*****************************************************************************
86 Wire and Cut
87 *****************************************************************************/
88
89 Sym BOXCUT = symbol ("BoxCut");
90 Tree boxCut() { return tree(BOXCUT); }
91 bool isBoxCut(Tree t) { return isTree(t, BOXCUT); }
92
93 Sym BOXWIRE = symbol ("BoxWire");
94 Tree boxWire() { return tree(BOXWIRE); }
95 bool isBoxWire(Tree t) { return isTree(t, BOXWIRE); }
96
97
98 /*****************************************************************************
99 Symbolic Boxes with symbolic slots
100 *****************************************************************************/
101
102 Sym BOXSLOT = symbol ("BoxSlot");
103
104 Tree boxSlot(int id) { return tree(BOXSLOT,tree(id)); }
105 bool isBoxSlot(Tree t) { Tree w; return isTree(t, BOXSLOT,w); }
106 bool isBoxSlot(Tree t, int* id) { Tree w; return isTree(t, BOXSLOT,w) && isInt(w->node(),id); }
107
108
109 Sym BOXSYMBOLIC = symbol ("BoxSymbolic");
110
111 Tree boxSymbolic(Tree slot, Tree body) { return tree(BOXSYMBOLIC,slot, body); }
112 bool isBoxSymbolic(Tree t) { Tree slot, body; return isTree(t, BOXSYMBOLIC, slot, body); }
113 bool isBoxSymbolic(Tree t, Tree& slot, Tree& body) { return isTree(t, BOXSYMBOLIC, slot, body); }
114
115
116 /*****************************************************************************
117 Composition of Boxes
118 *****************************************************************************/
119
120 Sym BOXSEQ = symbol ("BoxSeq");
121 Tree boxSeq(Tree x, Tree y) { return tree(BOXSEQ, x, y); }
122 bool isBoxSeq(Tree t, Tree& x, Tree& y) { return isTree(t, BOXSEQ, x, y); }
123
124 Sym BOXPAR = symbol ("BoxPar");
125 Tree boxPar(Tree x, Tree y) { return tree(BOXPAR, x, y); }
126 bool isBoxPar(Tree t, Tree& x, Tree& y) { return isTree(t, BOXPAR, x, y); }
127
128 Sym BOXREC = symbol ("BoxRec");
129 Tree boxRec(Tree x, Tree y) { return tree(BOXREC, x, y); }
130 bool isBoxRec(Tree t, Tree& x, Tree& y) { return isTree(t, BOXREC, x, y); }
131
132 Sym BOXSPLIT = symbol ("BoxSplit");
133 Tree boxSplit(Tree x, Tree y) { return tree(BOXSPLIT, x, y); }
134 bool isBoxSplit(Tree t, Tree& x, Tree& y) { return isTree(t, BOXSPLIT, x, y); }
135
136 Sym BOXMERGE = symbol ("BoxMerge");
137 Tree boxMerge(Tree x, Tree y) { return tree(BOXMERGE, x, y); }
138 bool isBoxMerge(Tree t, Tree& x, Tree& y) { return isTree(t, BOXMERGE, x, y); }
139
140
141 /*****************************************************************************
142 Algorithmic Composition of Boxes
143 *****************************************************************************/
144
145 Sym BOXIPAR = symbol ("BoxIPar");
146 Sym BOXISEQ = symbol ("BoxISeq");
147 Sym BOXISUM = symbol ("BoxISum");
148 Sym BOXIPROD = symbol ("BoxIProd");
149
150 Tree boxIPar(Tree x, Tree y, Tree z) { return tree(BOXIPAR, x, y, z); }
151 Tree boxISeq(Tree x, Tree y, Tree z) { return tree(BOXISEQ, x, y, z); }
152 Tree boxISum(Tree x, Tree y, Tree z) { return tree(BOXISUM, x, y, z); }
153 Tree boxIProd(Tree x, Tree y, Tree z) { return tree(BOXIPROD, x, y, z); }
154
155 bool isBoxIPar(Tree t, Tree& x, Tree& y, Tree& z) { return isTree(t, BOXIPAR, x, y, z); }
156 bool isBoxISeq(Tree t, Tree& x, Tree& y, Tree& z) { return isTree(t, BOXISEQ, x, y, z); }
157 bool isBoxISum(Tree t, Tree& x, Tree& y, Tree& z) { return isTree(t, BOXISUM, x, y, z); }
158 bool isBoxIProd(Tree t, Tree& x, Tree& y, Tree& z) { return isTree(t, BOXIPROD, x, y, z); }
159
160
161
162 /*****************************************************************************
163 Lambda-Calculus of Boxes
164 *****************************************************************************/
165 Sym BOXABSTR = symbol ("BoxAbstr");
166 Sym BOXAPPL = symbol ("BoxAppl");
167 Sym CLOSURE = symbol ("Closure");
168 Sym BOXERROR = symbol ("BoxError");
169 Sym BOXACCESS = symbol ("BoxAccess");
170
171 Tree boxAbstr (Tree x, Tree y) { return tree(BOXABSTR, x, y); }
172 Tree boxAppl (Tree x, Tree y) { return tree(BOXAPPL, x, y); }
173
174 bool isBoxAbstr (Tree t) { return t->node() == Node(BOXABSTR); }
175 bool isBoxAppl (Tree t) { return t->node() == Node(BOXAPPL); }
176
177 bool isBoxAbstr (Tree t, Tree& x, Tree& y) { return isTree(t, BOXABSTR, x, y); }
178 bool isBoxAppl (Tree t, Tree& x, Tree& y) { return isTree(t, BOXAPPL, x, y); }
179
180 Tree buildBoxAbstr (Tree largs, Tree body)
181 {
182 if (isNil(largs)) {
183 return body;
184 } else {
185 return buildBoxAbstr(tl(largs), boxAbstr(hd(largs), body));
186 }
187 }
188 #if 0
189 Tree buildBoxAppl (Tree fun, Tree revarglist)
190 {
191 if (isNil(revarglist)) {
192 return fun;
193 } else {
194 return boxAppl(buildBoxAppl(fun, tl(revarglist)), hd(revarglist));
195 }
196 }
197 #else
198 Tree buildBoxAppl (Tree fun, Tree revarglist)
199 {
200 if (isNil (revarglist)) exit(1); // a revoir !!!!!!
201 return boxAppl(fun, revarglist);
202 }
203 #endif
204
205 Tree closure (Tree abstr, Tree genv, Tree vis, Tree lenv)
206 {
207 return tree(CLOSURE, abstr, genv, vis, lenv);
208 }
209
210 bool isClosure (Tree t, Tree& abstr, Tree& genv, Tree& vis, Tree& lenv)
211 {
212 return isTree(t, CLOSURE, abstr, genv, vis, lenv);
213 }
214
215 Tree boxError()
216 {
217 return tree(BOXERROR);
218 }
219
220 bool isBoxError(Tree t)
221 {
222 return isTree(t, BOXERROR);
223 }
224
225
226 Tree boxAccess (Tree exp, Tree id) { return tree(BOXACCESS, exp, id); }
227 bool isBoxAccess(Tree t, Tree& exp, Tree& id) { return isTree(t, BOXACCESS, exp, id); }
228
229
230 /*****************************************************************************
231 Boxes with local definitions
232 *****************************************************************************/
233 Sym BOXWITHLOCALDEF = symbol ("BoxWithLocalDef");
234
235 Tree boxWithLocalDef (Tree body, Tree ldef) { return tree(BOXWITHLOCALDEF, body, ldef); }
236 bool isBoxWithLocalDef (Tree t, Tree& body, Tree& ldef) { return isTree(t, BOXWITHLOCALDEF, body, ldef); }
237
238
239 /*****************************************************************************
240 Boxes modif local definitions
241 *****************************************************************************/
242 Sym BOXMODIFLOCALDEF = symbol ("BoxModifLocalDef");
243
244
245 Tree boxModifLocalDef (Tree body, Tree ldef) { return tree(BOXMODIFLOCALDEF, body, ldef); }
246 bool isBoxModifLocalDef (Tree t, Tree& body, Tree& ldef) { return isTree(t, BOXMODIFLOCALDEF, body, ldef); }
247
248
249 /*****************************************************************************
250 Modules
251 *****************************************************************************/
252
253 Sym BOXENVIRONMENT = symbol ("BoxEnvironment");
254
255 Tree boxEnvironment () { return tree(BOXENVIRONMENT); }
256 bool isBoxEnvironment (Tree s) { return isTree(s, BOXENVIRONMENT); }
257
258 Sym BOXCOMPONENT = symbol ("BoxComponent");
259
260 Tree boxComponent (Tree filename) { return tree(BOXCOMPONENT, filename); }
261 bool isBoxComponent (Tree s, Tree& filename) { return isTree(s, BOXCOMPONENT, filename); }
262
263 Sym BOXLIBRARY = symbol ("BoxLibrary");
264
265 Tree boxLibrary (Tree filename) { return tree(BOXLIBRARY, filename); }
266 bool isBoxLibrary (Tree s, Tree& filename) { return isTree(s, BOXLIBRARY, filename); }
267
268
269 Sym IMPORTFILE = symbol ("ImportFile");
270
271 Tree importFile(Tree filename) { return tree(IMPORTFILE, filename); }
272 bool isImportFile(Tree s, Tree& filename) { return isTree(s, IMPORTFILE, filename); }
273
274
275 /*****************************************************************************
276 External Primitive Boxes (n -> 1)
277 *****************************************************************************/
278
279 Sym BOXPRIM0 = symbol ("BoxPrim0");
280 Tree boxPrim0(prim0 foo) { return tree(BOXPRIM0, tree((void*)foo)); }
281 bool isBoxPrim0 (Tree s) { Tree t; return isTree(s, BOXPRIM0, t); }
282 bool isBoxPrim0 (Tree s, prim0* p) { Tree t; return isTree(s, BOXPRIM0, t) && isPointer(t->node(),(void**)p); }
283
284 Sym BOXPRIM1 = symbol ("BoxPrim1");
285 Tree boxPrim1(prim1 foo) { return tree(BOXPRIM1, tree((void*)foo)); }
286 bool isBoxPrim1 (Tree s) { Tree t; return isTree(s, BOXPRIM1, t); }
287 bool isBoxPrim1 (Tree s, prim1* p) { Tree t; return isTree(s, BOXPRIM1, t) && isPointer(t->node(),(void**)p); }
288
289 Sym BOXPRIM2 = symbol ("BoxPrim2");
290 Tree boxPrim2(prim2 foo) { return tree(BOXPRIM2, tree((void*)foo)); }
291 bool isBoxPrim2 (Tree s) { Tree t; return isTree(s, BOXPRIM2, t); }
292 bool isBoxPrim2 (Tree s, prim2* p) { Tree t; return isTree(s, BOXPRIM2, t) && isPointer(t->node(),(void**)p); }
293
294 Sym BOXPRIM3 = symbol ("BoxPrim3");
295 Tree boxPrim3(prim3 foo) { return tree(BOXPRIM3, tree((void*)foo)); }
296 bool isBoxPrim3 (Tree s) { Tree t; return isTree(s, BOXPRIM3, t); }
297 bool isBoxPrim3 (Tree s, prim3* p) { Tree t; return isTree(s, BOXPRIM3, t) && isPointer(t->node(),(void**)p); }
298
299 Sym BOXPRIM4 = symbol ("BoxPrim4");
300 Tree boxPrim4(prim4 foo) { return tree(BOXPRIM4, tree((void*)foo)); }
301 bool isBoxPrim4 (Tree s) { Tree t; return isTree(s, BOXPRIM4, t); }
302 bool isBoxPrim4 (Tree s, prim4* p) { Tree t; return isTree(s, BOXPRIM4, t) && isPointer(t->node(),(void**)p); }
303
304 Sym BOXPRIM5 = symbol ("BoxPrim5");
305 Tree boxPrim5(prim5 foo) { return tree(BOXPRIM5, tree((void*)foo)); }
306 bool isBoxPrim5 (Tree s) { Tree t; return isTree(s, BOXPRIM5, t); }
307 bool isBoxPrim5 (Tree s, prim5* p) { Tree t; return isTree(s, BOXPRIM5, t) && isPointer(t->node(),(void**)p); }
308
309 /*****************************************************************************
310 Foreign Functions
311 *****************************************************************************/
312
313 Sym BOXFFUN = symbol ("BoxFFun");
314 Tree boxFFun (Tree ff) { return tree(BOXFFUN, ff); }
315 bool isBoxFFun (Tree s) { Tree ff; return isTree(s, BOXFFUN, ff); }
316 bool isBoxFFun (Tree s, Tree& ff) { return isTree(s, BOXFFUN, ff); }
317
318
319 Sym BOXFCONST = symbol ("BoxFConst");
320 Tree boxFConst (Tree type, Tree name, Tree file) { return tree(BOXFCONST, type, name, file); }
321 bool isBoxFConst (Tree s) { Tree t,n,f; return isTree(s, BOXFCONST, t, n, f); }
322 bool isBoxFConst (Tree s, Tree& type, Tree& name, Tree& file) { return isTree(s, BOXFCONST,type, name, file); }
323
324
325 Sym BOXFVAR = symbol ("BoxFVar");
326 Tree boxFVar (Tree type, Tree name, Tree file) { return tree(BOXFVAR, type, name, file); }
327 bool isBoxFVar (Tree s) { Tree t,n,f; return isTree(s, BOXFVAR, t, n, f); }
328 bool isBoxFVar (Tree s, Tree& type, Tree& name, Tree& file) { return isTree(s, BOXFVAR,type, name, file); }
329
330
331 /*****************************************************************************
332 User Interface Elements
333 *****************************************************************************/
334
335 Sym BOXBUTTON = symbol ("BoxButton");
336 Tree boxButton (Tree lbl) { return tree(BOXBUTTON, lbl); }
337 bool isBoxButton (Tree s) { Tree lbl; return isTree(s, BOXBUTTON, lbl); }
338 bool isBoxButton (Tree s, Tree& lbl) { return isTree(s, BOXBUTTON, lbl); }
339
340
341 Sym BOXCHECKBOX = symbol ("BoxCheckbox");
342 Tree boxCheckbox (Tree lbl) { return tree(BOXCHECKBOX, lbl); }
343 bool isBoxCheckbox (Tree s) { Tree lbl; return isTree(s, BOXCHECKBOX, lbl); }
344 bool isBoxCheckbox (Tree s, Tree& lbl) { return isTree(s, BOXCHECKBOX, lbl); }
345
346
347 Sym BOXHSLIDER = symbol ("BoxHSlider");
348 Tree boxHSlider (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
349 { return tree(BOXHSLIDER, lbl, list4(cur,min,max,step)); }
350 bool isBoxHSlider (Tree s) { Tree lbl, params; return isTree(s, BOXHSLIDER, lbl, params); }
351
352 bool isBoxHSlider (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
353 {
354 Tree params;
355 if (isTree(s, BOXHSLIDER, lbl, params)) {
356 cur = nth(params, 0);
357 min = nth(params, 1);
358 max = nth(params, 2);
359 step= nth(params, 3);
360 return true;
361 } else {
362 return false;
363 }
364 }
365
366
367 Sym BOXVSLIDER = symbol ("BoxVSlider");
368 Tree boxVSlider (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
369 { return tree(BOXVSLIDER, lbl, list4(cur,min,max,step)); }
370 bool isBoxVSlider (Tree s) { Tree lbl, params; return isTree(s, BOXVSLIDER, lbl, params); }
371
372 bool isBoxVSlider (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
373 {
374 Tree params;
375 if (isTree(s, BOXVSLIDER, lbl, params)) {
376 cur = nth(params, 0);
377 min = nth(params, 1);
378 max = nth(params, 2);
379 step= nth(params, 3);
380 return true;
381 } else {
382 return false;
383 }
384 }
385
386 Sym BOXNUMENTRY = symbol ("BoxNumEntry");
387 Tree boxNumEntry (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
388 { return tree(BOXNUMENTRY, lbl, list4(cur,min,max,step)); }
389 bool isBoxNumEntry (Tree s) { Tree lbl, params; return isTree(s, BOXNUMENTRY, lbl, params); }
390
391 bool isBoxNumEntry (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
392 {
393 Tree params;
394 if (isTree(s, BOXNUMENTRY, lbl, params)) {
395 cur = nth(params, 0);
396 min = nth(params, 1);
397 max = nth(params, 2);
398 step= nth(params, 3);
399 return true;
400 } else {
401 return false;
402 }
403 }
404
405
406 Sym BOXHGROUP = symbol ("BoxHGroup");
407 Tree boxHGroup (Tree lbl, Tree x) { return tree(BOXHGROUP, lbl, x); }
408 bool isBoxHGroup (Tree s) { Tree lbl, x; return isTree(s, BOXHGROUP, lbl, x); }
409 bool isBoxHGroup (Tree s, Tree& lbl, Tree& x) { return isTree(s, BOXHGROUP, lbl, x); }
410
411
412 Sym BOXVGROUP = symbol ("BoxVGroup");
413 Tree boxVGroup (Tree lbl, Tree x) { return tree(BOXVGROUP, lbl, x); }
414 bool isBoxVGroup (Tree s) { Tree lbl, x; return isTree(s, BOXVGROUP, lbl, x); }
415 bool isBoxVGroup (Tree s, Tree& lbl, Tree& x) { return isTree(s, BOXVGROUP, lbl, x); }
416
417
418 Sym BOXTGROUP = symbol ("BoxTGroup");
419 Tree boxTGroup (Tree lbl, Tree x) { return tree(BOXTGROUP, lbl, x); }
420 bool isBoxTGroup (Tree s) { Tree lbl, x; return isTree(s, BOXTGROUP, lbl, x); }
421 bool isBoxTGroup (Tree s, Tree& lbl, Tree& x) { return isTree(s, BOXTGROUP, lbl, x); }
422
423
424 Sym BOXHBARGRAPH = symbol ("BoxHBargraph");
425 Tree boxHBargraph(Tree lbl, Tree min, Tree max) { return tree(BOXHBARGRAPH, lbl, min, max); }
426 bool isBoxHBargraph (Tree s) { Tree lbl, min, max; return isTree(s, BOXHBARGRAPH, lbl, min, max); }
427 bool isBoxHBargraph (Tree s, Tree& lbl, Tree& min, Tree& max) { return isTree(s, BOXHBARGRAPH, lbl, min, max); }
428
429
430 Sym BOXVBARGRAPH = symbol ("BoxVBargraph");
431 Tree boxVBargraph(Tree lbl, Tree min, Tree max) { return tree(BOXVBARGRAPH, lbl, min, max); }
432 bool isBoxVBargraph (Tree s) { Tree lbl, min, max; return isTree(s, BOXVBARGRAPH, lbl, min, max); }
433 bool isBoxVBargraph (Tree s, Tree& lbl, Tree& min, Tree& max) { return isTree(s, BOXVBARGRAPH, lbl, min, max); }
434
435
436 /*****************************************************************************
437 pattern lmatching case
438 *****************************************************************************/
439
440 Sym BOXCASE = symbol ("BoxCase");
441 Sym BOXPATMATCHER = symbol ("BoxPatMatcher");
442 Sym BOXPATVAR = symbol ("BoxPatVar");
443
444 /**
445 * Prepare a "pattern" by replacing variables x by special
446 * pattern variables ?x.
447 *
448 * P[x] -> ?x
449 * P[x(e)] -> x(P[e])
450 * P[e(f)] -> P[e](P[f])
451 * P[e:f] -> P[e]:P[f]
452 * etc.
453 */
454 static Tree preparePattern(Tree box)
455 {
456 // cerr << "preparePattern(" << boxpp(box) << ")" << endl;
457
458 int id;
459 double r;
460 prim0 p0;
461 prim1 p1;
462 prim2 p2;
463 prim3 p3;
464 prim4 p4;
465 prim5 p5;
466
467 Tree t1, t2, t3, ff, label, cur, min, max, step, type, name, file, arg,
468 body, fun, args, ldef, slot,
469 ident, rules;
470
471 xtended* xt = (xtended*) getUserData(box);
472
473
474 // primitive elements
475 if (xt) return box;
476 else if (isBoxIdent(box)) return boxPatternVar(box);
477 else if (isBoxAppl(box, fun, args)) {
478 if (isBoxIdent(fun)) return boxAppl( fun, lmap(preparePattern,args));
479 else return boxAppl( preparePattern(fun), lmap(preparePattern,args));
480 }
481 else if (isBoxAbstr(box,arg,body)) return box;
482 else if (isBoxInt(box)) return box;
483 else if (isBoxReal(box, &r)) return box;
484 else if (isBoxCut(box)) return box;
485 else if (isBoxWire(box)) return box;
486 else if (isBoxPrim0(box, &p0)) return box;
487 else if (isBoxPrim1(box, &p1)) return box;
488 else if (isBoxPrim2(box, &p2)) return box;
489 else if (isBoxPrim3(box, &p3)) return box;
490 else if (isBoxPrim4(box, &p4)) return box;
491 else if (isBoxPrim5(box, &p5)) return box;
492
493 else if (isBoxWithLocalDef(box, body, ldef)) return boxWithLocalDef(preparePattern(body), ldef);
494
495
496 // foreign elements
497 else if (isBoxFFun(box, ff)) return box;
498 else if (isBoxFConst(box, type, name, file))
499 return box;
500 else if (isBoxFVar(box, type, name, file))
501 return box;
502
503 // block diagram binary operator
504 else if (isBoxSeq(box, t1, t2)) return boxSeq( preparePattern(t1), preparePattern(t2) );
505 else if (isBoxSplit(box, t1, t2)) return boxSplit( preparePattern(t1), preparePattern(t2) );
506 else if (isBoxMerge(box, t1, t2)) return boxMerge( preparePattern(t1), preparePattern(t2) );
507 else if (isBoxPar(box, t1, t2)) return boxPar( preparePattern(t1), preparePattern(t2) );
508 else if (isBoxRec(box, t1, t2)) return boxRec( preparePattern(t1), preparePattern(t2) );
509
510 // iterative block diagram construction
511 else if (isBoxIPar(box, t1, t2, t3)) return boxIPar ( t1, t2, preparePattern(t3) );
512 else if (isBoxISeq(box, t1, t2, t3)) return boxISeq ( t1, t2, preparePattern(t3) );
513 else if (isBoxISum(box, t1, t2, t3)) return boxISum ( t1, t2, preparePattern(t3) );
514 else if (isBoxIProd(box, t1, t2, t3)) return boxIProd( t1, t2, preparePattern(t3) );
515
516 // user interface
517 else if (isBoxButton(box, label)) return box;
518 else if (isBoxCheckbox(box, label)) return box;
519
520 else if (isBoxVSlider(box, label, cur, min, max, step)) return box;
521 else if (isBoxHSlider(box, label, cur, min, max, step)) return box;
522
523 else if (isBoxVGroup(box, label, t1)) return boxVGroup(label, preparePattern(t1));
524 else if (isBoxHGroup(box, label, t1)) return boxHGroup(label, preparePattern(t1));
525 else if (isBoxTGroup(box, label, t1)) return boxTGroup(label, preparePattern(t1));
526
527 else if (isBoxHBargraph(box, label, min, max)) return box;
528 else if (isBoxVBargraph(box, label, min, max)) return box;
529 else if (isBoxNumEntry(box, label, cur, min, max, step)) return box;
530
531 else if (isNil(box)) return box;
532 else if (isList(box)) return lmap(preparePattern, box);
533 else if (isBoxEnvironment(box)) return box;
534 /* not expected
535 else if (isClosure(box, abstr, genv, vis, lenv)) {
536 fout << "closure[" << boxpp(abstr)
537 << ", genv = " << envpp(genv)
538 << ", lenv = " << envpp(lenv)
539 << "]";
540 }
541 */
542 else if (isBoxComponent(box, label)) return box;
543 else if (isBoxAccess(box, t1, t2)) return box;
544
545 /* not expected
546 else if (isImportFile(box, label)) {
547 fout << "import("
548 << tree2str(label) << ')';
549 }
550 */
551
552
553 else if (isBoxSlot(box, &id)) return box;
554 else if (isBoxSymbolic(box, slot, body)) return box;
555
556 // Pattern Matching Extensions
557 else if (isBoxCase(box, rules)) return box;
558 else if (isBoxPatternVar(box, ident)) return box;
559
560
561 // None of the previous tests succeded, then it is not a valid box
562 else {
563 cerr << "Error in preparePattern() : " << *box << " is not a valid box" << endl;
564 exit(1);
565 }
566
567
568 return box;
569 }
570
571 static Tree prepareRule(Tree rule)
572 {
573 return cons (lmap(preparePattern,hd(rule)), tl(rule));
574 }
575
576 static Tree prepareRules(Tree rules) {
577 return lmap(prepareRule, rules);
578 }
579
580 Tree boxCaseInternal (Tree rules) { return tree(BOXCASE, rules); }
581 Tree boxCase (Tree rules) { return boxCaseInternal(prepareRules(rules)); }
582
583 bool isBoxCase (Tree s) { Tree rules; return isTree(s, BOXCASE, rules); }
584 bool isBoxCase (Tree s, Tree& rules) { return isTree(s, BOXCASE, rules); }
585
586
587 Tree boxPatternVar (Tree id) { return tree(BOXPATVAR, id); }
588 bool isBoxPatternVar(Tree s, Tree& id) { return isTree(s, BOXPATVAR, id); }
589
590
591 Tree boxPatternMatcher (Automaton* a, int state, Tree env, Tree origRules, Tree revParamList)
592 {
593 return tree(BOXPATMATCHER, tree((void*)a), tree(state), env, origRules, revParamList);
594 }
595
596 bool isBoxPatternMatcher (Tree s)
597 {
598 Tree ta, ts, env, orig, rpl;
599 return isTree(s, BOXPATMATCHER, ta, ts, env, orig, rpl);
600 }
601
602 bool isBoxPatternMatcher (Tree s, Automaton*& a, int& state, Tree& env, Tree& origRules, Tree& revParamList)
603 {
604 Tree ta, ts;
605 if (isTree(s, BOXPATMATCHER, ta, ts, env, origRules, revParamList)) {
606 a = (Automaton*)tree2ptr(ta);
607 state = tree2int(ts);
608 return true;
609 } else {
610 return false;
611 }
612 }
613
614