FAUST compiler  0.9.9.6b8
sigToGraph.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 <stdio.h>
00025 
00026 #include <set>
00027 #include <vector>
00028 #include <iostream>
00029 #include <sstream>
00030 #include <string>
00031 
00032 #include "signals.hh"
00033 #include "sigtype.hh"
00034 #include "sigtyperules.hh"
00035 #include "xtended.hh"
00036 
00037 #include "sigToGraph.hh"
00038 
00039 using namespace std;
00040 
00041 static void     recdraw(Tree sig, set<Tree>& drawn, ofstream& fout );
00042 static string   nodeattr(Type t);
00043 static string   edgeattr(Type t);
00044 static string   sigLabel(Tree sig);
00045 
00046 
00050 void sigToGraph (Tree L, ofstream& fout)
00051 {
00052     set<Tree>   alreadyDrawn;
00053 
00054     fout << "strict digraph loopgraph {\n"
00055          << "    rankdir=LR; node [fontsize=10];"
00056          << endl;
00057     int out = 0;
00058     while (isList(L)) {
00059         recdraw(hd(L), alreadyDrawn, fout);
00060 
00061         fout << "OUTPUT_" << out << "[color=\"red2\" style=\"filled\" fillcolor=\"pink\"];" << endl;
00062         fout << 'S' << hd(L) << " -> " << "OUTPUT_" << out++ << "[" << edgeattr(getCertifiedSigType(hd(L))) << "];" << endl;
00063         L = tl(L);
00064     }
00065 
00066     fout << "}" << endl;
00067 }
00068 
00069 
00070 /******************************* IMPLEMENTATION ***********************************/
00071 
00072 
00076 static void recdraw(Tree sig, set<Tree>& drawn, ofstream& fout )
00077 {
00078     //cerr << ++TABBER << "ENTER REC DRAW OF " << sig << "$" << *sig << endl;
00079     vector<Tree>    subsig;
00080     int             n;
00081 
00082     if (drawn.count(sig) == 0) {
00083         drawn.insert(sig);
00084         if (isList(sig)) {
00085             do {
00086                 recdraw(hd(sig), drawn, fout);
00087                 sig = tl(sig);
00088             } while (isList(sig));
00089         } else {
00090             // draw the node
00091             fout    << 'S' << sig << "[label=\"" << sigLabel(sig) << "\""
00092                     << nodeattr(getCertifiedSigType(sig)) << "];"
00093                     << endl;
00094 
00095             // draw the subsignals
00096             n = getSubSignals(sig, subsig);
00097             if (n > 0) {
00098                 if (n==1 && isList(subsig[0])) {
00099                     Tree id, body;
00100                     assert(isRec(sig,id,body));
00101                     // special recursion case, recreate a vector of subsignals instead of the
00102                     // list provided by getSubSignal
00103                     Tree L = subsig[0];
00104                     subsig.clear();
00105                     n = 0;
00106                     do {
00107                         subsig.push_back(hd(L));
00108                         L = tl(L);
00109                         n += 1;
00110                     } while (isList(L));
00111                 }
00112 
00113                 for (int i=0; i<n; i++) {
00114                     recdraw(subsig[i], drawn, fout);
00115                     fout    << 'S' << subsig[i] << " -> " << 'S' << sig
00116                             << "[" << edgeattr(getCertifiedSigType(subsig[i])) << "];"
00117                             << endl;
00118                 }
00119             }
00120         }
00121     }
00122     //cerr << --TABBER << "EXIT REC DRAW OF " << sig << endl;
00123 }
00124 
00125 
00129 static string edgeattr(Type t)
00130 {
00131     string s;
00132 
00133     // nature
00134     if (t->nature()==kInt) {
00135         s += " color=\"blue\"";
00136     } else {
00137         s += " color=\"red\"";
00138     }
00139 
00140     // vectorability
00141     if (t->vectorability()==kVect && t->variability()==kSamp) {
00142         s += " style=\"bold\"";
00143     }
00144     return s;
00145 }
00146 
00147 
00151 static string nodeattr(Type t)
00152 {
00153     string s = edgeattr(t);
00154 
00155     // variability
00156     if (t->variability()==kKonst) {
00157         s += " shape=\"box\"";
00158     } else if (t->variability()==kBlock) {
00159         s += " shape=\"hexagon\"";
00160     } else if (t->variability()==kSamp) {
00161         s += " shape=\"ellipse\"";
00162     }
00163 
00164     return s;
00165 }
00166 
00167 
00171 static const char* binopname[]= {
00172         "+", "-", "*", "/", "%",
00173         "<<", ">>",
00174         ">", "<", ">=", "<=", "==", "!=",
00175         "&", "|", "^"
00176 };
00177 
00178 
00182 static string sigLabel(Tree sig)
00183 {
00184     int         i;
00185     double      r;
00186     Tree        x, y, z, c, type, name, file, ff, largs, id, le, sel, var, label;
00187 
00188     xtended*    p = (xtended*) getUserData(sig);
00189 
00190     stringstream fout;
00191 
00192          if (p)                                     { fout << p->name(); }
00193     else if ( isSigInt(sig, &i) )                   { fout << i;    }
00194     else if ( isSigReal(sig, &r) )                  { fout << r;    }
00195     else if ( isSigInput(sig, &i) )                 { fout << "INPUT_" << i; }
00196     else if ( isSigOutput(sig, &i, x) )             { fout << "OUTPUT_" << i; }
00197 
00198     else if ( isSigDelay1(sig, x) )                 { fout << "mem";        }
00199     else if ( isSigFixDelay(sig, x, y) )            { fout << "@";          }
00200     else if ( isSigPrefix(sig, x, y) )              { fout << "prefix";     }
00201     else if ( isSigIota(sig, x) )                   { fout << "iota";       }
00202     else if ( isSigBinOp(sig, &i, x, y) )           { fout << binopname[i]; }
00203     else if ( isSigFFun(sig, ff, largs) )           { fout << "ffunction:" << *ff; }
00204     else if ( isSigFConst(sig, type, name, file) )  { fout << *name; }
00205     else if ( isSigFVar(sig, type, name, file) )    { fout << *name; }
00206 
00207     else if ( isSigTable(sig, id, x, y) )           { fout << "table:" << id;   }
00208     else if ( isSigWRTbl(sig, id, x, y, z) )        { fout << "write:" << id;   }
00209     else if ( isSigRDTbl(sig, x, y) )               { fout << "read";   }
00210 
00211 
00212 
00213     else if ( isSigSelect2(sig, sel, x, y) )        { fout << "select2"; }
00214     else if ( isSigSelect3(sig, sel, x, y, z) )     { fout << "select3"; }
00215 
00216     else if ( isSigGen(sig, x) )                    { fout << "generator"; }
00217 
00218     else if ( isProj(sig, &i, x) )                  { fout << "Proj" << i;  }
00219     else if ( isRec(sig, var, le) )                 { fout << "REC " << *var; }
00220 
00221     else if ( isSigIntCast(sig, x) )                { fout << "int"; }
00222     else if ( isSigFloatCast(sig, x) )              { fout << "float"; }
00223 #if 0
00224     else if ( isSigButton(sig, label) )             { fout << "button \"" << *label << '"'; }
00225     else if ( isSigCheckbox(sig, label) )           { fout << "checkbox \"" << *label << '"'; }
00226     else if ( isSigVSlider(sig, label,c,x,y,z) )    { fout << "vslider \"" << *label << '"';  }
00227     else if ( isSigHSlider(sig, label,c,x,y,z) )    { fout << "hslider \"" << *label << '"';  }
00228     else if ( isSigNumEntry(sig, label,c,x,y,z) )   { fout << "nentry \"" << *label << '"';  }
00229 
00230     else if ( isSigVBargraph(sig, label,x,y,z) )    { fout << "vbargraph \"" << *label << '"';  }
00231     else if ( isSigHBargraph(sig, label,x,y,z) )    { fout << "hbargraph \"" << *label << '"';  }
00232 #else
00233     else if ( isSigButton(sig, label) )             { fout << "button"; }
00234     else if ( isSigCheckbox(sig, label) )           { fout << "checkbox"; }
00235     else if ( isSigVSlider(sig, label,c,x,y,z) )    { fout << "vslider";  }
00236     else if ( isSigHSlider(sig, label,c,x,y,z) )    { fout << "hslider";  }
00237     else if ( isSigNumEntry(sig, label,c,x,y,z) )   { fout << "nentry";  }
00238 
00239     else if ( isSigVBargraph(sig, label,x,y,z) )    { fout << "vbargraph";  }
00240     else if ( isSigHBargraph(sig, label,x,y,z) )    { fout << "hbargraph";  }
00241 #endif
00242     else if ( isSigAttach(sig, x, y) )              { fout << "attach";     }
00243 
00244     else {
00245         cerr << "ERROR, unrecognized signal : " << *sig << endl;
00246         exit(1);
00247     }
00248 
00249     return fout.str();
00250 }