FAUST compiler  0.9.9.6b8
ppbox.cpp
Go to the documentation of this file.
00001 /************************************************************************
00002  ************************************************************************
00003     FAUST compiler
00004     Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
00005     ---------------------------------------------------------------------
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  ************************************************************************
00020  ************************************************************************/
00021 
00022 
00023 
00024 #include "list.hh"
00025 #include "boxes.hh"
00026 #include "ppbox.hh"
00027 #include "signals.hh"
00028 #include "prim2.hh"
00029 #include "xtended.hh"
00030 
00031 
00032 const char * prim0name(CTree *(*ptr) ())
00033 {
00034     return "prim0???";
00035 }
00036 
00037 const char * prim1name(CTree *(*ptr) (CTree *))
00038 {
00039     if (ptr == sigDelay1) return "mem";
00040     if (ptr == sigIntCast) return "int";
00041     if (ptr == sigFloatCast) return "float";
00042     return "prim1???";
00043 }
00044 
00045 const char * prim2name(CTree *(*ptr) (CTree *, CTree *))
00046 {
00047     if (ptr == sigAdd) return "+";
00048     if (ptr == sigSub) return "-";
00049     if (ptr == sigMul) return "*";
00050     if (ptr == sigDiv) return "/";
00051     if (ptr == sigRem) return "%";
00052 
00053     if (ptr == sigAND) return "&";
00054     if (ptr == sigOR ) return "|";
00055     if (ptr == sigXOR) return "^";
00056 
00057     if (ptr == sigLeftShift ) return "<<";
00058     if (ptr == sigRightShift) return ">>";
00059 
00060     if (ptr == sigLT) return "<";
00061     if (ptr == sigLE) return "<=";
00062     if (ptr == sigGT) return ">";
00063     if (ptr == sigGE) return ">=";
00064     if (ptr == sigEQ) return "==";
00065     if (ptr == sigNE) return "!=";
00066 
00067     if (ptr == sigFixDelay) return "@";
00068     if (ptr == sigPrefix)   return "prefix";
00069     if (ptr == sigAttach)   return "attach";
00070 
00071     return "prim2???";
00072 }
00073 
00074 const char * prim3name(CTree *(*ptr) (CTree *, CTree *, CTree *))
00075 {
00076     if (ptr == sigReadOnlyTable)    return "rdtable";
00077     if (ptr == sigSelect2)          return "select2";
00078     return "prim3???";
00079 }
00080 
00081 const char * prim4name(CTree *(*ptr) (CTree *, CTree *, CTree *, CTree *))
00082 {
00083     if (ptr == sigSelect3)          return "select3";
00084     return "prim4???";
00085 }
00086 
00087 const char * prim5name(CTree *(*ptr) (CTree *, CTree *, CTree *, CTree *, CTree *))
00088 {
00089     if (ptr == sigWriteReadTable)   return "wrtable";
00090     return "prim5???";
00091 }
00092 
00093 
00094 static void streambinop(ostream& fout, Tree t1, const char* op, Tree t2, int curPriority, int upPriority)
00095 {
00096     if (upPriority > curPriority) fout << '(';
00097     fout << boxpp(t1,curPriority) << op << boxpp(t2,curPriority);
00098     if (upPriority > curPriority) fout << ')';
00099 }
00100 
00101 static void printRule(ostream& fout, Tree rule)
00102 {
00103     Tree lhs = left(rule);
00104     Tree rhs = right(rule);
00105     char sep = '('; while (!isNil(lhs)) { fout << sep << boxpp(hd(lhs)); sep=','; lhs=tl(lhs); }
00106     fout << ") => " << boxpp(rhs) << "; ";
00107 }
00108 
00109 /*****************************************************************************
00110      affichage d'une expression box comme en entree
00111 *****************************************************************************/
00112 
00113 ostream& boxpp::print (ostream& fout) const
00114 {
00115     int     i, id;
00116     double  r;
00117     prim0   p0;
00118     prim1   p1;
00119     prim2   p2;
00120     prim3   p3;
00121     prim4   p4;
00122     prim5   p5;
00123 
00124     Tree    t1, t2, t3, ff, label, cur, min, max, step, type, name, file, arg,
00125             body, fun, args, abstr, genv, vis, lenv, ldef, slot,
00126             ident, rules;
00127 
00128     const char* str;
00129 
00130     xtended* xt = (xtended*) getUserData(box);
00131 
00132 
00133     // primitive elements
00134          if (xt)                        fout << xt->name();
00135     else if (isBoxInt(box, &i))         fout << i;
00136     else if (isBoxReal(box, &r))        fout << r;
00137     else if (isBoxCut(box))             fout << '!';
00138     else if (isBoxWire(box))            fout << '_';
00139     else if (isBoxIdent(box, &str))     fout << str;
00140     else if (isBoxPrim0(box, &p0))      fout << prim0name(p0);
00141     else if (isBoxPrim1(box, &p1))      fout << prim1name(p1);
00142     else if (isBoxPrim2(box, &p2))      fout << prim2name(p2);
00143     else if (isBoxPrim3(box, &p3))      fout << prim3name(p3);
00144     else if (isBoxPrim4(box, &p4))      fout << prim4name(p4);
00145     else if (isBoxPrim5(box, &p5))      fout << prim5name(p5);
00146 
00147     else if (isBoxAbstr(box,arg,body))  fout << "\\" << boxpp(arg) << ".(" << boxpp(body) << ")";
00148     else if (isBoxAppl(box, fun, args)) fout << boxpp(fun) << boxpp(args) ;
00149 
00150     else if (isBoxWithLocalDef(box, body, ldef))    fout << boxpp(body) << " with { " << envpp(ldef) << " }";
00151 
00152     // foreign elements
00153     else if (isBoxFFun(box, ff))        fout << "ffunction(" << ffname(ff) << ')';
00154     else if (isBoxFConst(box, type, name, file))
00155                                         fout << "fconstant(" /*<< tree2str(type) */<< tree2str(name) << ')';
00156     else if (isBoxFVar(box, type, name, file))
00157                                         fout << "fvariable(" << tree2str(name) << ')';
00158 
00159     // block diagram binary operator
00160     else if (isBoxSeq(box, t1, t2))     streambinop(fout, t1, ":", t2, 1, priority);
00161     else if (isBoxSplit(box, t1, t2))   streambinop(fout, t1, "<:", t2, 1, priority);
00162     else if (isBoxMerge(box, t1, t2))   streambinop(fout, t1, ":>", t2, 1, priority);
00163     else if (isBoxPar(box, t1, t2))     streambinop(fout, t1,",",t2, 2, priority);
00164     else if (isBoxRec(box, t1, t2))     streambinop(fout, t1,"~",t2, 4, priority);
00165 
00166     // iterative block diagram construction
00167     else if (isBoxIPar(box, t1, t2, t3))    fout << "par(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
00168     else if (isBoxISeq(box, t1, t2, t3))    fout << "seq(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
00169     else if (isBoxISum(box, t1, t2, t3))    fout << "sum(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
00170     else if (isBoxIProd(box, t1, t2, t3))   fout << "prod(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
00171 
00172     // user interface
00173     else if (isBoxButton(box, label))   fout << "button(" << tree2str(label) << ')';
00174     else if (isBoxCheckbox(box, label)) fout << "checkbox(" << tree2str(label) << ')';
00175     else if (isBoxVSlider(box, label, cur, min, max, step))     {
00176         fout << "vslider("
00177              << tree2str(label) << ", "
00178              << boxpp(cur) << ", "
00179              << boxpp(min) << ", "
00180              << boxpp(max) << ", "
00181              << boxpp(step)<< ')';
00182     }
00183     else if (isBoxHSlider(box, label, cur, min, max, step))     {
00184         fout << "hslider("
00185              << tree2str(label) << ", "
00186              << boxpp(cur) << ", "
00187              << boxpp(min) << ", "
00188              << boxpp(max) << ", "
00189              << boxpp(step)<< ')';
00190     }
00191     else if (isBoxVGroup(box, label, t1)) {
00192         fout << "vgroup(" << tree2str(label) << ", " << boxpp(t1, 0) << ')';
00193     }
00194     else if (isBoxHGroup(box, label, t1)) {
00195         fout << "hgroup(" << tree2str(label) << ", " << boxpp(t1, 0) << ')';
00196     }
00197     else if (isBoxTGroup(box, label, t1)) {
00198         fout << "tgroup(" << tree2str(label) << ", " << boxpp(t1, 0) << ')';
00199     }
00200     else if (isBoxHBargraph(box, label, min, max))  {
00201         fout << "hbargraph("
00202              << tree2str(label) << ", "
00203              << boxpp(min) << ", "
00204              << boxpp(max) << ')';
00205     }
00206     else if (isBoxVBargraph(box, label, min, max))  {
00207         fout << "vbargraph("
00208              << tree2str(label) << ", "
00209              << boxpp(min) << ", "
00210              << boxpp(max) << ')';
00211     }
00212     else if (isBoxNumEntry(box, label, cur, min, max, step))    {
00213         fout << "nentry("
00214              << tree2str(label) << ", "
00215              << boxpp(cur) << ", "
00216              << boxpp(min) << ", "
00217              << boxpp(max) << ", "
00218              << boxpp(step)<< ')';
00219     }
00220     else if (isNil(box)) {
00221         fout << "()" ;
00222     }
00223     else if (isList(box)) {
00224 
00225         Tree l = box;
00226         char sep = '(';
00227 
00228         do {
00229             fout << sep << boxpp(hd(l));
00230             sep = ',';
00231             l = tl(l);
00232         } while (isList(l));
00233 
00234         fout << ')';
00235 
00236     }
00237     else if (isBoxEnvironment(box)) {
00238         fout << "environment";
00239     }
00240     else if (isClosure(box, abstr, genv, vis, lenv)) {
00241         fout << "closure[" << boxpp(abstr)
00242             << ", genv = " << envpp(genv)
00243             << ", lenv = " << envpp(lenv)
00244             << "]";
00245     }
00246     else if (isBoxComponent(box, label)) {
00247         fout << "component("
00248             << tree2str(label) << ')';
00249     }
00250     else if (isBoxAccess(box, t1, t2)) {
00251         fout << boxpp(t1) << '.' << boxpp(t2);
00252     }
00253     else if (isImportFile(box, label)) {
00254         fout << "import("
00255             << tree2str(label) << ')';
00256     }
00257     else if (isBoxSlot(box, &id)) {
00258         fout << "#" << id;
00259     }
00260     else if (isBoxSymbolic(box, slot, body)) {
00261         fout << "[" << boxpp(slot) << ">" << boxpp(body) << "]";
00262     }
00263     
00264     // Pattern Matching Extensions
00265     else if (isBoxCase(box, rules)) {
00266         fout << "case {";
00267         while (!isNil(rules)) { printRule(fout, hd(rules)); rules = tl(rules); }
00268         fout << "}";     
00269     }
00270 #if 1
00271     // more useful for debugging output
00272     else if (isBoxPatternVar(box, ident)) {
00273         fout << "<" << boxpp(ident) << ">"; 
00274     }
00275 #else
00276     // beautify messages involving lhs patterns
00277     else if (isBoxPatternVar(box, ident)) {
00278         fout << boxpp(ident);   
00279     }
00280 #endif
00281 
00282     else if (isBoxPatternMatcher(box)) {
00283         fout << "PM[" << box << "]";    
00284     }
00285 
00286     else if (isBoxError(box)) {
00287         fout << "ERROR";    
00288     }
00289 
00290     
00291     // None of the previous tests succeded, then it is not a valid box
00292     else {
00293         cerr << "Error in box::print() : " << *box << " is not a valid box" << endl;
00294         exit(1);
00295     }
00296 
00297     return fout;
00298 }
00299 
00300 
00301 /*****************************************************************************
00302      affichage d'un environnement
00303 *****************************************************************************/
00304 
00305 ostream& envpp::print (ostream& fout) const
00306 {
00307         const char*     sep = "";
00308         Tree    l = fEnv;
00309 
00310         fout << '{';
00311         while (isList(l)) {
00312             fout << sep << boxpp(hd(hd(l))) << "=" << boxpp(tl(hd(l)));
00313             sep = ", ";
00314             l = tl(l);
00315         }
00316         fout << '}';
00317     return fout;
00318 }
00319