New directory tree, with preprocessor/ inside interpretor/.
[Faustine.git] / interpretor / preprocessor / faust-0.9.47mr3 / compiler / boxes / boxes.cpp
diff --git a/interpretor/preprocessor/faust-0.9.47mr3/compiler/boxes/boxes.cpp b/interpretor/preprocessor/faust-0.9.47mr3/compiler/boxes/boxes.cpp
new file mode 100644 (file)
index 0000000..7bf6529
--- /dev/null
@@ -0,0 +1,614 @@
+/************************************************************************
+ ************************************************************************
+    FAUST compiler
+       Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+
+
+
+/*****************************************************************************
+******************************************************************************
+
+
+                                                           The Box Language
+
+
+******************************************************************************
+*****************************************************************************/
+
+
+/**\file boxes.cpp
+ * \author Yann Orlarey
+ * \version 1.0
+ * \date 2003
+ * \brief Implementation of block diagram expressions.
+ *  Boxes are created using five main connection operations : sequential (:),
+ *  parallel (,), split (<:), merge (:>), and recursive (~).
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "boxes.hh"
+#include "ppbox.hh"
+#include "prim2.hh"
+#include "xtended.hh"
+
+
+/*****************************************************************************
+                                                               Identifiers
+*****************************************************************************/
+Sym BOXIDENT = symbol ("BoxIdent");
+
+Tree boxIdent(const char* name)                { return tree(BOXIDENT, tree(symbol(name)) ); }
+bool isBoxIdent(Tree t)                                { return t->node() == Node(BOXIDENT); }
+bool isBoxIdent(Tree t0, const char** str)
+{
+       Tree t1; Sym s;
+       if ( isTree(t0, BOXIDENT, t1) && isSym(t1->node(), &s) ) {
+               *str = name(s);
+               return true;
+       } else {
+               return false;
+       }
+}
+
+
+/*****************************************************************************
+                                                               Numbers
+*****************************************************************************/
+
+Tree boxInt(int n)                                     { return tree(n);       }
+Tree boxReal(double n)                                 { return tree(n);       }
+
+bool isBoxInt(Tree t)                          { return isInt(t->node());      }
+bool isBoxReal(Tree t)                         { return isDouble(t->node()); }
+
+bool isBoxInt(Tree t, int* i)          { return isInt(t->node(), i);   }
+bool isBoxReal(Tree t, double* r)      { return isDouble(t->node(), r); }
+
+
+/*****************************************************************************
+                                                               Wire and Cut
+*****************************************************************************/
+
+Sym BOXCUT = symbol ("BoxCut");
+Tree boxCut()                                          { return tree(BOXCUT); }
+bool isBoxCut(Tree t)                          { return isTree(t, BOXCUT); }
+
+Sym BOXWIRE = symbol ("BoxWire");
+Tree boxWire()                                         { return tree(BOXWIRE); }
+bool isBoxWire(Tree t)                         { return isTree(t, BOXWIRE); }
+
+
+/*****************************************************************************
+                                               Symbolic Boxes with symbolic slots
+*****************************************************************************/
+
+Sym BOXSLOT = symbol ("BoxSlot");
+
+Tree boxSlot(int id)                           { return tree(BOXSLOT,tree(id)); }
+bool isBoxSlot(Tree t)                         { Tree w; return isTree(t, BOXSLOT,w); }
+bool isBoxSlot(Tree t, int* id)                { Tree w; return isTree(t, BOXSLOT,w) && isInt(w->node(),id); }
+
+
+Sym BOXSYMBOLIC = symbol ("BoxSymbolic");
+
+Tree boxSymbolic(Tree slot, Tree body)                         { return tree(BOXSYMBOLIC,slot, body); }
+bool isBoxSymbolic(Tree t)                                                     { Tree slot, body; return isTree(t, BOXSYMBOLIC, slot, body); }
+bool isBoxSymbolic(Tree t, Tree& slot, Tree& body)     { return isTree(t, BOXSYMBOLIC, slot, body); }
+
+
+/*****************************************************************************
+                                                         Composition of Boxes
+*****************************************************************************/
+
+Sym BOXSEQ = symbol ("BoxSeq");
+Tree boxSeq(Tree x, Tree y)                            { return tree(BOXSEQ, x, y);            }
+bool isBoxSeq(Tree t, Tree& x, Tree& y)        { return isTree(t, BOXSEQ, x, y);       }
+
+Sym BOXPAR = symbol ("BoxPar");
+Tree boxPar(Tree x, Tree y)                            { return tree(BOXPAR, x, y);            }
+bool isBoxPar(Tree t, Tree& x, Tree& y)                { return isTree(t, BOXPAR, x, y);       }
+
+Sym BOXREC = symbol ("BoxRec");
+Tree boxRec(Tree x, Tree y)                            { return tree(BOXREC, x, y);            }
+bool isBoxRec(Tree t, Tree& x, Tree& y)                { return isTree(t, BOXREC, x, y);       }
+
+Sym BOXSPLIT = symbol ("BoxSplit");
+Tree boxSplit(Tree x, Tree y)                          { return tree(BOXSPLIT, x, y);          }
+bool isBoxSplit(Tree t, Tree& x, Tree& y)      { return isTree(t, BOXSPLIT, x, y); }
+
+Sym BOXMERGE = symbol ("BoxMerge");
+Tree boxMerge(Tree x, Tree y)                          { return tree(BOXMERGE, x, y); }
+bool isBoxMerge(Tree t, Tree& x, Tree& y)      { return isTree(t, BOXMERGE, x, y); }
+
+
+/*****************************************************************************
+                                               Algorithmic Composition of Boxes
+*****************************************************************************/
+
+Sym BOXIPAR = symbol ("BoxIPar");
+Sym BOXISEQ = symbol ("BoxISeq");
+Sym BOXISUM = symbol ("BoxISum");
+Sym BOXIPROD = symbol ("BoxIProd");
+
+Tree boxIPar(Tree x, Tree y, Tree z)                                   { return tree(BOXIPAR, x, y, z);                }
+Tree boxISeq(Tree x, Tree y, Tree z)                                   { return tree(BOXISEQ, x, y, z);                }
+Tree boxISum(Tree x, Tree y, Tree z)                                   { return tree(BOXISUM, x, y, z);                }
+Tree boxIProd(Tree x, Tree y, Tree z)                                  { return tree(BOXIPROD, x, y, z);               }
+
+bool isBoxIPar(Tree t, Tree& x, Tree& y, Tree& z)              { return isTree(t, BOXIPAR,  x, y, z);   }
+bool isBoxISeq(Tree t, Tree& x, Tree& y, Tree& z)              { return isTree(t, BOXISEQ,  x, y, z);   }
+bool isBoxISum(Tree t, Tree& x, Tree& y, Tree& z)              { return isTree(t, BOXISUM,  x, y, z);   }
+bool isBoxIProd(Tree t, Tree& x, Tree& y, Tree& z)             { return isTree(t, BOXIPROD, x, y, z);   }
+
+
+
+/*****************************************************************************
+                                                         Lambda-Calculus of Boxes
+*****************************************************************************/
+Sym BOXABSTR   = symbol ("BoxAbstr");
+Sym BOXAPPL    = symbol ("BoxAppl");
+Sym CLOSURE    = symbol ("Closure");
+Sym BOXERROR   = symbol ("BoxError");
+Sym BOXACCESS  = symbol ("BoxAccess");
+
+Tree boxAbstr  (Tree x, Tree y)                        { return tree(BOXABSTR, x, y); }
+Tree boxAppl   (Tree x, Tree y)                        { return tree(BOXAPPL, x, y); }
+
+bool isBoxAbstr        (Tree t)                                        { return t->node() == Node(BOXABSTR); }
+bool isBoxAppl (Tree t)                                        { return t->node() == Node(BOXAPPL); }
+
+bool isBoxAbstr        (Tree t, Tree& x, Tree& y)      { return isTree(t, BOXABSTR, x, y); }
+bool isBoxAppl (Tree t, Tree& x, Tree& y)      { return isTree(t, BOXAPPL, x, y); }
+
+Tree buildBoxAbstr     (Tree largs, Tree body)
+{
+       if (isNil(largs)) {
+               return body;
+       } else {
+               return buildBoxAbstr(tl(largs), boxAbstr(hd(largs), body));
+       }
+}
+#if 0
+Tree buildBoxAppl      (Tree fun, Tree revarglist)
+{
+       if (isNil(revarglist)) {
+               return fun;
+       } else {
+               return  boxAppl(buildBoxAppl(fun, tl(revarglist)), hd(revarglist));
+       }
+}
+#else
+Tree buildBoxAppl      (Tree fun, Tree revarglist)
+{
+       if (isNil (revarglist)) exit(1); // a revoir !!!!!!
+       return  boxAppl(fun, revarglist);
+}
+#endif
+
+Tree closure (Tree abstr, Tree genv, Tree vis, Tree lenv)
+{
+       return  tree(CLOSURE, abstr, genv, vis, lenv);
+}
+
+bool isClosure (Tree t, Tree& abstr, Tree& genv, Tree& vis, Tree& lenv)
+{
+       return isTree(t, CLOSURE, abstr, genv, vis, lenv);
+}
+
+Tree boxError()
+{
+       return  tree(BOXERROR);
+}
+
+bool isBoxError(Tree t)
+{
+       return isTree(t, BOXERROR);
+}
+
+
+Tree boxAccess (Tree exp, Tree id)                             { return tree(BOXACCESS, exp, id); }
+bool isBoxAccess(Tree t, Tree& exp, Tree& id)  { return isTree(t, BOXACCESS, exp, id); }
+
+
+/*****************************************************************************
+                                               Boxes with local definitions
+*****************************************************************************/
+Sym BOXWITHLOCALDEF    = symbol ("BoxWithLocalDef");
+
+Tree boxWithLocalDef (Tree body, Tree ldef)                                    { return tree(BOXWITHLOCALDEF, body, ldef); }
+bool isBoxWithLocalDef (Tree t, Tree& body, Tree& ldef)                { return isTree(t, BOXWITHLOCALDEF, body, ldef); }
+
+
+/*****************************************************************************
+                        Boxes modif local definitions
+*****************************************************************************/
+Sym BOXMODIFLOCALDEF   = symbol ("BoxModifLocalDef");
+
+
+Tree boxModifLocalDef (Tree body, Tree ldef)                { return tree(BOXMODIFLOCALDEF, body, ldef); }
+bool isBoxModifLocalDef (Tree t, Tree& body, Tree& ldef)       { return isTree(t, BOXMODIFLOCALDEF, body, ldef); }
+
+
+/*****************************************************************************
+                                                        Modules
+*****************************************************************************/
+
+Sym BOXENVIRONMENT  = symbol ("BoxEnvironment");
+
+Tree boxEnvironment ()                                      { return tree(BOXENVIRONMENT); }
+bool isBoxEnvironment (Tree s)                              { return isTree(s, BOXENVIRONMENT); }
+
+Sym BOXCOMPONENT    = symbol ("BoxComponent");
+
+Tree boxComponent (Tree filename)                           { return tree(BOXCOMPONENT, filename); }
+bool isBoxComponent (Tree s, Tree& filename)                { return isTree(s, BOXCOMPONENT, filename); }
+
+Sym BOXLIBRARY      = symbol ("BoxLibrary");
+
+Tree boxLibrary (Tree filename)                             { return tree(BOXLIBRARY, filename); }
+bool isBoxLibrary (Tree s, Tree& filename)                  { return isTree(s, BOXLIBRARY, filename); }
+
+
+Sym IMPORTFILE      = symbol ("ImportFile");
+
+Tree importFile(Tree filename)                                                         { return tree(IMPORTFILE, filename); }
+bool isImportFile(Tree s, Tree& filename)                                      { return isTree(s, IMPORTFILE, filename); }
+
+
+/*****************************************************************************
+                                                       External Primitive Boxes (n -> 1)
+*****************************************************************************/
+
+Sym BOXPRIM0 = symbol ("BoxPrim0");
+Tree boxPrim0(prim0 foo)                                       { return tree(BOXPRIM0, tree((void*)foo)); }
+bool isBoxPrim0        (Tree s)                                        { Tree t; return isTree(s, BOXPRIM0, t);        }
+bool isBoxPrim0        (Tree s, prim0* p)                      { Tree t; return isTree(s, BOXPRIM0, t) && isPointer(t->node(),(void**)p);      }
+
+Sym BOXPRIM1 = symbol ("BoxPrim1");
+Tree boxPrim1(prim1 foo)                                       { return tree(BOXPRIM1, tree((void*)foo)); }
+bool isBoxPrim1        (Tree s)                                        { Tree t; return isTree(s, BOXPRIM1, t);        }
+bool isBoxPrim1        (Tree s, prim1* p)                      { Tree t; return isTree(s, BOXPRIM1, t) && isPointer(t->node(),(void**)p);      }
+
+Sym BOXPRIM2 = symbol ("BoxPrim2");
+Tree boxPrim2(prim2 foo)                                       { return tree(BOXPRIM2, tree((void*)foo)); }
+bool isBoxPrim2        (Tree s)                                        { Tree t; return isTree(s, BOXPRIM2, t);        }
+bool isBoxPrim2        (Tree s, prim2* p)                      { Tree t; return isTree(s, BOXPRIM2, t) && isPointer(t->node(),(void**)p);      }
+
+Sym BOXPRIM3 = symbol ("BoxPrim3");
+Tree boxPrim3(prim3 foo)                                       { return tree(BOXPRIM3, tree((void*)foo)); }
+bool isBoxPrim3        (Tree s)                                        { Tree t; return isTree(s, BOXPRIM3, t);        }
+bool isBoxPrim3        (Tree s, prim3* p)                      { Tree t; return isTree(s, BOXPRIM3, t) && isPointer(t->node(),(void**)p);      }
+
+Sym BOXPRIM4 = symbol ("BoxPrim4");
+Tree boxPrim4(prim4 foo)                                       { return tree(BOXPRIM4, tree((void*)foo)); }
+bool isBoxPrim4        (Tree s)                                        { Tree t; return isTree(s, BOXPRIM4, t);        }
+bool isBoxPrim4        (Tree s, prim4* p)                      { Tree t; return isTree(s, BOXPRIM4, t) && isPointer(t->node(),(void**)p);      }
+
+Sym BOXPRIM5 = symbol ("BoxPrim5");
+Tree boxPrim5(prim5 foo)                                       { return tree(BOXPRIM5, tree((void*)foo)); }
+bool isBoxPrim5        (Tree s)                                        { Tree t; return isTree(s, BOXPRIM5, t);        }
+bool isBoxPrim5        (Tree s, prim5* p)                      { Tree t; return isTree(s, BOXPRIM5, t) && isPointer(t->node(),(void**)p);      }
+
+/*****************************************************************************
+                                                        Foreign Functions
+*****************************************************************************/
+
+Sym BOXFFUN = symbol ("BoxFFun");
+Tree boxFFun (Tree ff)                                         { return tree(BOXFFUN, ff);                             }
+bool isBoxFFun (Tree s)                                        { Tree ff; return isTree(s, BOXFFUN, ff);       }
+bool isBoxFFun (Tree s, Tree& ff)                      { return isTree(s, BOXFFUN, ff);                        }
+
+
+Sym BOXFCONST = symbol ("BoxFConst");
+Tree boxFConst      (Tree type, Tree name, Tree file)               { return tree(BOXFCONST, type, name, file);             }
+bool isBoxFConst    (Tree s)                                        { Tree t,n,f; return isTree(s, BOXFCONST, t, n, f); }
+bool isBoxFConst    (Tree s, Tree& type, Tree& name, Tree& file)    { return isTree(s, BOXFCONST,type, name, file);     }
+
+
+Sym BOXFVAR = symbol ("BoxFVar");
+Tree boxFVar      (Tree type, Tree name, Tree file)                 { return tree(BOXFVAR, type, name, file);             }
+bool isBoxFVar    (Tree s)                                          { Tree t,n,f; return isTree(s, BOXFVAR, t, n, f); }
+bool isBoxFVar    (Tree s, Tree& type, Tree& name, Tree& file)      { return isTree(s, BOXFVAR,type, name, file);     }
+
+
+/*****************************************************************************
+                                                        User Interface Elements
+*****************************************************************************/
+
+Sym BOXBUTTON = symbol ("BoxButton");
+Tree boxButton          (Tree lbl)                                     { return tree(BOXBUTTON, lbl);                                  }
+bool isBoxButton (Tree s)                                      { Tree lbl; return isTree(s, BOXBUTTON, lbl);   }
+bool isBoxButton (Tree s, Tree& lbl)           { return isTree(s, BOXBUTTON, lbl);                             }
+
+
+Sym BOXCHECKBOX = symbol ("BoxCheckbox");
+Tree boxCheckbox   (Tree lbl)                          { return tree(BOXCHECKBOX, lbl);                                        }
+bool isBoxCheckbox (Tree s)                                    { Tree lbl; return isTree(s, BOXCHECKBOX, lbl); }
+bool isBoxCheckbox (Tree s, Tree& lbl)         { return isTree(s, BOXCHECKBOX, lbl);                           }
+
+
+Sym BOXHSLIDER = symbol ("BoxHSlider");
+Tree boxHSlider   (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
+                                                                                       { return tree(BOXHSLIDER, lbl, list4(cur,min,max,step));                }
+bool isBoxHSlider (Tree s)                                     { Tree lbl, params; return isTree(s, BOXHSLIDER, lbl, params);  }
+
+bool isBoxHSlider (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
+{
+       Tree params;
+       if (isTree(s, BOXHSLIDER, lbl, params)) {
+               cur = nth(params, 0);
+               min = nth(params, 1);
+               max = nth(params, 2);
+               step= nth(params, 3);
+               return true;
+       } else {
+               return false;
+       }
+}
+
+
+Sym BOXVSLIDER = symbol ("BoxVSlider");
+Tree boxVSlider   (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
+                                                                                       { return tree(BOXVSLIDER, lbl, list4(cur,min,max,step));                }
+bool isBoxVSlider (Tree s)                                     { Tree lbl, params; return isTree(s, BOXVSLIDER, lbl, params);  }
+
+bool isBoxVSlider (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
+{
+       Tree params;
+       if (isTree(s, BOXVSLIDER, lbl, params)) {
+               cur = nth(params, 0);
+               min = nth(params, 1);
+               max = nth(params, 2);
+               step= nth(params, 3);
+               return true;
+       } else {
+               return false;
+       }
+}
+
+Sym BOXNUMENTRY = symbol ("BoxNumEntry");
+Tree boxNumEntry   (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
+                                                                                       { return tree(BOXNUMENTRY, lbl, list4(cur,min,max,step));               }
+bool isBoxNumEntry (Tree s)                                    { Tree lbl, params; return isTree(s, BOXNUMENTRY, lbl, params); }
+
+bool isBoxNumEntry (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
+{
+       Tree params;
+       if (isTree(s, BOXNUMENTRY, lbl, params)) {
+               cur = nth(params, 0);
+               min = nth(params, 1);
+               max = nth(params, 2);
+               step= nth(params, 3);
+               return true;
+       } else {
+               return false;
+       }
+}
+
+
+Sym BOXHGROUP = symbol ("BoxHGroup");
+Tree boxHGroup   (Tree lbl, Tree x)                            { return tree(BOXHGROUP, lbl, x);                               }
+bool isBoxHGroup (Tree s)                                              { Tree lbl, x; return isTree(s, BOXHGROUP, lbl, x);     }
+bool isBoxHGroup (Tree s, Tree& lbl, Tree& x)  { return isTree(s, BOXHGROUP, lbl, x);                          }
+
+
+Sym BOXVGROUP = symbol ("BoxVGroup");
+Tree boxVGroup   (Tree lbl, Tree x)                            { return tree(BOXVGROUP, lbl, x);                               }
+bool isBoxVGroup (Tree s)                                              { Tree lbl, x; return isTree(s, BOXVGROUP, lbl, x);     }
+bool isBoxVGroup (Tree s, Tree& lbl, Tree& x)  { return isTree(s, BOXVGROUP, lbl, x);                          }
+
+
+Sym BOXTGROUP = symbol ("BoxTGroup");
+Tree boxTGroup   (Tree lbl, Tree x)                            { return tree(BOXTGROUP, lbl, x);                               }
+bool isBoxTGroup (Tree s)                                              { Tree lbl, x; return isTree(s, BOXTGROUP, lbl, x);     }
+bool isBoxTGroup (Tree s, Tree& lbl, Tree& x)  { return isTree(s, BOXTGROUP, lbl, x);                          }
+
+
+Sym BOXHBARGRAPH = symbol ("BoxHBargraph");
+Tree boxHBargraph(Tree lbl, Tree min, Tree max)                                        { return tree(BOXHBARGRAPH, lbl, min, max);             }
+bool isBoxHBargraph (Tree s)                                                                   { Tree lbl, min, max; return isTree(s, BOXHBARGRAPH, lbl, min, max);    }
+bool isBoxHBargraph (Tree s, Tree& lbl, Tree& min, Tree& max)  { return isTree(s, BOXHBARGRAPH, lbl, min, max); }
+
+
+Sym BOXVBARGRAPH = symbol ("BoxVBargraph");
+Tree boxVBargraph(Tree lbl, Tree min, Tree max)                                        { return tree(BOXVBARGRAPH, lbl, min, max);             }
+bool isBoxVBargraph (Tree s)                                                                   { Tree lbl, min, max; return isTree(s, BOXVBARGRAPH, lbl, min, max);    }
+bool isBoxVBargraph (Tree s, Tree& lbl, Tree& min, Tree& max)  { return isTree(s, BOXVBARGRAPH, lbl, min, max); }
+
+
+/*****************************************************************************
+                                                        pattern lmatching case
+*****************************************************************************/
+
+Sym BOXCASE            = symbol ("BoxCase");
+Sym BOXPATMATCHER      = symbol ("BoxPatMatcher");
+Sym BOXPATVAR          = symbol ("BoxPatVar");
+
+/**
+ * Prepare a "pattern" by replacing variables x by special
+ * pattern variables ?x.
+ *
+ * P[x]     -> ?x
+ * P[x(e)]  -> x(P[e])
+ * P[e(f)]  -> P[e](P[f])
+ * P[e:f]   -> P[e]:P[f]
+ * etc.
+ */
+static Tree preparePattern(Tree box)
+{
+//    cerr << "preparePattern(" << boxpp(box) << ")" << endl;
+
+        int            id;
+        double r;
+        prim0  p0;
+        prim1  p1;
+        prim2  p2;
+        prim3  p3;
+        prim4  p4;
+        prim5  p5;
+
+        Tree   t1, t2, t3, ff, label, cur, min, max, step, type, name, file, arg,
+                body, fun, args, ldef, slot,
+                ident, rules;
+
+        xtended* xt = (xtended*) getUserData(box);
+
+
+        // primitive elements
+             if (xt)                                           return box;
+        else if (isBoxIdent(box))           return boxPatternVar(box);
+        else if (isBoxAppl(box, fun, args))    {
+                if (isBoxIdent(fun))        return boxAppl( fun, lmap(preparePattern,args));
+                else                        return boxAppl( preparePattern(fun), lmap(preparePattern,args));
+            }
+        else if (isBoxAbstr(box,arg,body))     return box;
+        else if (isBoxInt(box))             return box;
+        else if (isBoxReal(box, &r))           return box;
+        else if (isBoxCut(box))                                return box;
+        else if (isBoxWire(box))                       return box;
+        else if (isBoxPrim0(box, &p0))         return box;
+        else if (isBoxPrim1(box, &p1))         return box;
+        else if (isBoxPrim2(box, &p2))         return box;
+        else if (isBoxPrim3(box, &p3))         return box;
+        else if (isBoxPrim4(box, &p4))         return box;
+        else if (isBoxPrim5(box, &p5))         return box;
+
+        else if (isBoxWithLocalDef(box, body, ldef))   return boxWithLocalDef(preparePattern(body), ldef);
+
+
+        // foreign elements
+        else if (isBoxFFun(box, ff))           return box;
+        else if (isBoxFConst(box, type, name, file))
+                                            return box;
+        else if (isBoxFVar(box, type, name, file))
+                                            return box;
+
+        // block diagram binary operator
+        else if (isBoxSeq(box, t1, t2))                return boxSeq( preparePattern(t1), preparePattern(t2) );
+        else if (isBoxSplit(box, t1, t2))      return boxSplit( preparePattern(t1), preparePattern(t2) );
+        else if (isBoxMerge(box, t1, t2))      return boxMerge( preparePattern(t1), preparePattern(t2) );
+        else if (isBoxPar(box, t1, t2))        return boxPar( preparePattern(t1), preparePattern(t2) );
+        else if (isBoxRec(box, t1, t2))        return boxRec( preparePattern(t1), preparePattern(t2) );
+
+        // iterative block diagram construction
+        else if (isBoxIPar(box, t1, t2, t3))   return boxIPar ( t1, t2, preparePattern(t3) );
+        else if (isBoxISeq(box, t1, t2, t3))   return boxISeq ( t1, t2, preparePattern(t3) );
+        else if (isBoxISum(box, t1, t2, t3))   return boxISum ( t1, t2, preparePattern(t3) );
+        else if (isBoxIProd(box, t1, t2, t3))  return boxIProd( t1, t2, preparePattern(t3) );
+
+        // user interface
+        else if (isBoxButton(box, label))       return box;
+        else if (isBoxCheckbox(box, label))     return box;
+
+        else if (isBoxVSlider(box, label, cur, min, max, step))        return box;
+        else if (isBoxHSlider(box, label, cur, min, max, step))        return box;
+
+        else if (isBoxVGroup(box, label, t1))   return boxVGroup(label, preparePattern(t1));
+        else if (isBoxHGroup(box, label, t1))   return boxHGroup(label, preparePattern(t1));
+        else if (isBoxTGroup(box, label, t1))   return boxTGroup(label, preparePattern(t1));
+
+        else if (isBoxHBargraph(box, label, min, max))              return box;
+        else if (isBoxVBargraph(box, label, min, max))              return box;
+        else if (isBoxNumEntry(box, label, cur, min, max, step))    return box;
+
+        else if (isNil(box))                    return box;
+        else if (isList(box))                   return lmap(preparePattern, box);
+        else if (isBoxEnvironment(box))         return box;
+        /* not expected
+        else if (isClosure(box, abstr, genv, vis, lenv)) {
+            fout << "closure[" << boxpp(abstr)
+                << ", genv = " << envpp(genv)
+                << ", lenv = " << envpp(lenv)
+                << "]";
+        }
+        */
+        else if (isBoxComponent(box, label))        return box;
+        else if (isBoxAccess(box, t1, t2))          return box;
+
+        /* not expected
+        else if (isImportFile(box, label)) {
+            fout << "import("
+                << tree2str(label) << ')';
+        }
+        */
+
+
+        else if (isBoxSlot(box, &id))               return box;
+        else if (isBoxSymbolic(box, slot, body))    return box;
+
+        // Pattern Matching Extensions
+        else if (isBoxCase(box, rules))             return box;
+        else if (isBoxPatternVar(box, ident))       return box;
+
+
+        // None of the previous tests succeded, then it is not a valid box
+        else {
+            cerr << "Error in preparePattern() : " << *box << " is not a valid box" << endl;
+            exit(1);
+        }
+
+
+   return box;
+}
+
+static Tree prepareRule(Tree rule)
+{
+    return cons (lmap(preparePattern,hd(rule)), tl(rule));
+}
+
+static Tree prepareRules(Tree rules) {
+    return lmap(prepareRule, rules);
+}
+
+Tree boxCaseInternal    (Tree rules)       { return tree(BOXCASE, rules);                                      }
+Tree boxCase    (Tree rules)                           { return boxCaseInternal(prepareRules(rules));  }
+
+bool isBoxCase (Tree s)                                                { Tree rules; return isTree(s, BOXCASE, rules); }
+bool isBoxCase (Tree s, Tree& rules)           { return isTree(s, BOXCASE, rules);                             }
+
+
+Tree boxPatternVar     (Tree id)                               { return tree(BOXPATVAR, id);                                   }
+bool isBoxPatternVar(Tree s, Tree& id)         { return isTree(s, BOXPATVAR, id);                              }
+
+
+Tree boxPatternMatcher         (Automaton* a, int state, Tree env, Tree origRules, Tree revParamList)  
+{ 
+       return tree(BOXPATMATCHER, tree((void*)a), tree(state), env, origRules, revParamList); 
+}                                      
+
+bool isBoxPatternMatcher       (Tree s)
+{
+       Tree ta, ts, env, orig, rpl;
+       return isTree(s, BOXPATMATCHER, ta, ts, env, orig, rpl);
+}
+
+bool isBoxPatternMatcher       (Tree s, Automaton*& a, int& state, Tree& env, Tree& origRules, Tree& revParamList)
+{
+       Tree ta, ts;
+       if (isTree(s, BOXPATMATCHER, ta, ts, env, origRules, revParamList)) {
+               a = (Automaton*)tree2ptr(ta);
+               state = tree2int(ts);
+               return true;
+       } else {
+               return false;
+       }
+}
+
+