1 /************************************************************************
2 ************************************************************************
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.
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.
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 ************************************************************************/
24 /*****************************************************************************
25 ******************************************************************************
31 ******************************************************************************
32 *****************************************************************************/
36 * \author Yann Orlarey
39 * \brief Implementation of block diagram expressions.
40 * Boxes are created using five main connection operations : sequential (:),
41 * parallel (,), split (<:), merge (:>), and recursive (~).
52 /*****************************************************************************
54 *****************************************************************************/
55 Sym BOXIDENT
= symbol ("BoxIdent");
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
)
62 if ( isTree(t0
, BOXIDENT
, t1
) && isSym(t1
->node(), &s
) ) {
71 /*****************************************************************************
73 *****************************************************************************/
75 Tree
boxInt(int n
) { return tree(n
); }
76 Tree
boxReal(double n
) { return tree(n
); }
78 bool isBoxInt(Tree t
) { return isInt(t
->node()); }
79 bool isBoxReal(Tree t
) { return isDouble(t
->node()); }
81 bool isBoxInt(Tree t
, int* i
) { return isInt(t
->node(), i
); }
82 bool isBoxReal(Tree t
, double* r
) { return isDouble(t
->node(), r
); }
85 /*****************************************************************************
87 *****************************************************************************/
89 Sym BOXCUT
= symbol ("BoxCut");
90 Tree
boxCut() { return tree(BOXCUT
); }
91 bool isBoxCut(Tree t
) { return isTree(t
, BOXCUT
); }
93 Sym BOXWIRE
= symbol ("BoxWire");
94 Tree
boxWire() { return tree(BOXWIRE
); }
95 bool isBoxWire(Tree t
) { return isTree(t
, BOXWIRE
); }
98 /*****************************************************************************
99 Symbolic Boxes with symbolic slots
100 *****************************************************************************/
102 Sym BOXSLOT
= symbol ("BoxSlot");
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
); }
109 Sym BOXSYMBOLIC
= symbol ("BoxSymbolic");
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
); }
116 /*****************************************************************************
118 *****************************************************************************/
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
); }
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
); }
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
); }
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
); }
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
); }
141 /*****************************************************************************
142 Algorithmic Composition of Boxes
143 *****************************************************************************/
145 Sym BOXIPAR
= symbol ("BoxIPar");
146 Sym BOXISEQ
= symbol ("BoxISeq");
147 Sym BOXISUM
= symbol ("BoxISum");
148 Sym BOXIPROD
= symbol ("BoxIProd");
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
); }
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
); }
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");
171 Tree
boxAbstr (Tree x
, Tree y
) { return tree(BOXABSTR
, x
, y
); }
172 Tree
boxAppl (Tree x
, Tree y
) { return tree(BOXAPPL
, x
, y
); }
174 bool isBoxAbstr (Tree t
) { return t
->node() == Node(BOXABSTR
); }
175 bool isBoxAppl (Tree t
) { return t
->node() == Node(BOXAPPL
); }
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
); }
180 Tree
buildBoxAbstr (Tree largs
, Tree body
)
185 return buildBoxAbstr(tl(largs
), boxAbstr(hd(largs
), body
));
189 Tree
buildBoxAppl (Tree fun
, Tree revarglist
)
191 if (isNil(revarglist
)) {
194 return boxAppl(buildBoxAppl(fun
, tl(revarglist
)), hd(revarglist
));
198 Tree
buildBoxAppl (Tree fun
, Tree revarglist
)
200 if (isNil (revarglist
)) exit(1); // a revoir !!!!!!
201 return boxAppl(fun
, revarglist
);
205 Tree
closure (Tree abstr
, Tree genv
, Tree vis
, Tree lenv
)
207 return tree(CLOSURE
, abstr
, genv
, vis
, lenv
);
210 bool isClosure (Tree t
, Tree
& abstr
, Tree
& genv
, Tree
& vis
, Tree
& lenv
)
212 return isTree(t
, CLOSURE
, abstr
, genv
, vis
, lenv
);
217 return tree(BOXERROR
);
220 bool isBoxError(Tree t
)
222 return isTree(t
, BOXERROR
);
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
); }
230 /*****************************************************************************
231 Boxes with local definitions
232 *****************************************************************************/
233 Sym BOXWITHLOCALDEF
= symbol ("BoxWithLocalDef");
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
); }
239 /*****************************************************************************
240 Boxes modif local definitions
241 *****************************************************************************/
242 Sym BOXMODIFLOCALDEF
= symbol ("BoxModifLocalDef");
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
); }
249 /*****************************************************************************
251 *****************************************************************************/
253 Sym BOXENVIRONMENT
= symbol ("BoxEnvironment");
255 Tree
boxEnvironment () { return tree(BOXENVIRONMENT
); }
256 bool isBoxEnvironment (Tree s
) { return isTree(s
, BOXENVIRONMENT
); }
258 Sym BOXCOMPONENT
= symbol ("BoxComponent");
260 Tree
boxComponent (Tree filename
) { return tree(BOXCOMPONENT
, filename
); }
261 bool isBoxComponent (Tree s
, Tree
& filename
) { return isTree(s
, BOXCOMPONENT
, filename
); }
263 Sym BOXLIBRARY
= symbol ("BoxLibrary");
265 Tree
boxLibrary (Tree filename
) { return tree(BOXLIBRARY
, filename
); }
266 bool isBoxLibrary (Tree s
, Tree
& filename
) { return isTree(s
, BOXLIBRARY
, filename
); }
269 Sym IMPORTFILE
= symbol ("ImportFile");
271 Tree
importFile(Tree filename
) { return tree(IMPORTFILE
, filename
); }
272 bool isImportFile(Tree s
, Tree
& filename
) { return isTree(s
, IMPORTFILE
, filename
); }
275 /*****************************************************************************
276 External Primitive Boxes (n -> 1)
277 *****************************************************************************/
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
); }
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
); }
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
); }
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
); }
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
); }
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
); }
309 /*****************************************************************************
311 *****************************************************************************/
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
); }
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
); }
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
); }
331 /*****************************************************************************
332 User Interface Elements
333 *****************************************************************************/
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
); }
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
); }
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
); }
352 bool isBoxHSlider (Tree s
, Tree
& lbl
, Tree
& cur
, Tree
& min
, Tree
& max
, Tree
& step
)
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);
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
); }
372 bool isBoxVSlider (Tree s
, Tree
& lbl
, Tree
& cur
, Tree
& min
, Tree
& max
, Tree
& step
)
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);
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
); }
391 bool isBoxNumEntry (Tree s
, Tree
& lbl
, Tree
& cur
, Tree
& min
, Tree
& max
, Tree
& step
)
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);
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
); }
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
); }
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
); }
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
); }
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
); }
436 /*****************************************************************************
437 pattern lmatching case
438 *****************************************************************************/
440 Sym BOXCASE
= symbol ("BoxCase");
441 Sym BOXPATMATCHER
= symbol ("BoxPatMatcher");
442 Sym BOXPATVAR
= symbol ("BoxPatVar");
445 * Prepare a "pattern" by replacing variables x by special
446 * pattern variables ?x.
450 * P[e(f)] -> P[e](P[f])
451 * P[e:f] -> P[e]:P[f]
454 static Tree
preparePattern(Tree box
)
456 // cerr << "preparePattern(" << boxpp(box) << ")" << endl;
467 Tree t1
, t2
, t3
, ff
, label
, cur
, min
, max
, step
, type
, name
, file
, arg
,
468 body
, fun
, args
, ldef
, slot
,
471 xtended
* xt
= (xtended
*) getUserData(box
);
474 // primitive elements
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
));
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
;
493 else if (isBoxWithLocalDef(box
, body
, ldef
)) return boxWithLocalDef(preparePattern(body
), ldef
);
497 else if (isBoxFFun(box
, ff
)) return box
;
498 else if (isBoxFConst(box
, type
, name
, file
))
500 else if (isBoxFVar(box
, type
, name
, file
))
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
) );
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
) );
517 else if (isBoxButton(box
, label
)) return box
;
518 else if (isBoxCheckbox(box
, label
)) return box
;
520 else if (isBoxVSlider(box
, label
, cur
, min
, max
, step
)) return box
;
521 else if (isBoxHSlider(box
, label
, cur
, min
, max
, step
)) return box
;
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
));
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
;
531 else if (isNil(box
)) return box
;
532 else if (isList(box
)) return lmap(preparePattern
, box
);
533 else if (isBoxEnvironment(box
)) return box
;
535 else if (isClosure(box, abstr, genv, vis, lenv)) {
536 fout << "closure[" << boxpp(abstr)
537 << ", genv = " << envpp(genv)
538 << ", lenv = " << envpp(lenv)
542 else if (isBoxComponent(box
, label
)) return box
;
543 else if (isBoxAccess(box
, t1
, t2
)) return box
;
546 else if (isImportFile(box, label)) {
548 << tree2str(label) << ')';
553 else if (isBoxSlot(box
, &id
)) return box
;
554 else if (isBoxSymbolic(box
, slot
, body
)) return box
;
556 // Pattern Matching Extensions
557 else if (isBoxCase(box
, rules
)) return box
;
558 else if (isBoxPatternVar(box
, ident
)) return box
;
561 // None of the previous tests succeded, then it is not a valid box
563 cerr
<< "Error in preparePattern() : " << *box
<< " is not a valid box" << endl
;
571 static Tree
prepareRule(Tree rule
)
573 return cons (lmap(preparePattern
,hd(rule
)), tl(rule
));
576 static Tree
prepareRules(Tree rules
) {
577 return lmap(prepareRule
, rules
);
580 Tree
boxCaseInternal (Tree rules
) { return tree(BOXCASE
, rules
); }
581 Tree
boxCase (Tree rules
) { return boxCaseInternal(prepareRules(rules
)); }
583 bool isBoxCase (Tree s
) { Tree rules
; return isTree(s
, BOXCASE
, rules
); }
584 bool isBoxCase (Tree s
, Tree
& rules
) { return isTree(s
, BOXCASE
, rules
); }
587 Tree
boxPatternVar (Tree id
) { return tree(BOXPATVAR
, id
); }
588 bool isBoxPatternVar(Tree s
, Tree
& id
) { return isTree(s
, BOXPATVAR
, id
); }
591 Tree
boxPatternMatcher (Automaton
* a
, int state
, Tree env
, Tree origRules
, Tree revParamList
)
593 return tree(BOXPATMATCHER
, tree((void*)a
), tree(state
), env
, origRules
, revParamList
);
596 bool isBoxPatternMatcher (Tree s
)
598 Tree ta
, ts
, env
, orig
, rpl
;
599 return isTree(s
, BOXPATMATCHER
, ta
, ts
, env
, orig
, rpl
);
602 bool isBoxPatternMatcher (Tree s
, Automaton
*& a
, int& state
, Tree
& env
, Tree
& origRules
, Tree
& revParamList
)
605 if (isTree(s
, BOXPATMATCHER
, ta
, ts
, env
, origRules
, revParamList
)) {
606 a
= (Automaton
*)tree2ptr(ta
);
607 state
= tree2int(ts
);