X-Git-Url: https://scm.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/c7f552fd8888da2f0d8cfb228fe0f28d3df3a12c..b4b6f2ea75b9f0f3ca918f5b84016610bf7a4d4f:/interpretor/preprocessor/faust-0.9.47mr3/compiler/draw/sigToGraph.cpp diff --git a/interpretor/preprocessor/faust-0.9.47mr3/compiler/draw/sigToGraph.cpp b/interpretor/preprocessor/faust-0.9.47mr3/compiler/draw/sigToGraph.cpp new file mode 100644 index 0000000..fdbeee9 --- /dev/null +++ b/interpretor/preprocessor/faust-0.9.47mr3/compiler/draw/sigToGraph.cpp @@ -0,0 +1,295 @@ +/************************************************************************ + ************************************************************************ + 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. + ************************************************************************ + ************************************************************************/ + + + +#include + +#include +#include +#include +#include +#include + +#include "signals.hh" +#include "sigtype.hh" +#include "sigtyperules.hh" +#include "xtended.hh" + +#include "sigToGraph.hh" +#include "sigraterules.hh" +#include "Text.hh" + +using namespace std; + +static void recdraw(Tree sig, set& drawn, ofstream& fout, RateInferrer* R ); +static string commonattr(Type t); +static string nodeattr(Type t); +static string edgeattr(Type t, int rate); +static string sigLabel(Tree sig); + + +/** + * Draw a list of signals as a directed graph using graphviz's dot language + */ +void sigToGraph (Tree L, ofstream& fout, RateInferrer* R) +{ + set alreadyDrawn; + + fout << "strict digraph loopgraph {\n" + << " rankdir=LR; node [fontsize=10];" + << endl; + int out = 0; + while (isList(L)) { + recdraw(hd(L), alreadyDrawn, fout, R); + + fout << "OUTPUT_" << out << "[color=\"red2\" style=\"filled\" fillcolor=\"pink\"];" << endl; + fout << 'S' << hd(L) << " -> " << "OUTPUT_" << out++ << "[" << edgeattr(getCertifiedSigType(hd(L)), R->rate(hd(L))) << "];" << endl; + L = tl(L); + } + + fout << "}" << endl; +} + + +/******************************* IMPLEMENTATION ***********************************/ + + +/** + * Draw recursively a signal + */ +static void recdraw(Tree sig, set& drawn, ofstream& fout, RateInferrer* R ) +{ + //cerr << ++TABBER << "ENTER REC DRAW OF " << sig << "$" << *sig << endl; + vector subsig; + int n; + + if (drawn.count(sig) == 0) { + // the signal has never been drawn + drawn.insert(sig); // remember it + if (isList(sig)) { + // it's a list of signals : we draw each signal of the list + do { + recdraw(hd(sig), drawn, fout, R); + sig = tl(sig); + } while (isList(sig)); + } else { + // it is a regular signal + // first draw the node + fout << 'S' << sig << "[label=\"" << sigLabel(sig) << "\"" + << nodeattr(getCertifiedSigType(sig)) << "];" + << endl; + + // then draw the subsignals if any + n = getSubSignals(sig, subsig); + if (n > 0) { + Tree id, body; + // check special recursion case, recreate a vector of subsignals instead of the + // list provided by getSubSignal + if (n==1 && isList(subsig[0])) { + assert(isRec(sig,id,body)); + + Tree L = subsig[0]; + subsig.clear(); + n = 0; + do { + subsig.push_back(hd(L)); + L = tl(L); + n += 1; + } while (isList(L)); + } + + // draw each subsignal + for (int i=0; i " << 'S' << sig + << "[style=dashed];" + << endl; + } else { + // special case when source is a recursive group, we don't want a rate + fout << 'S' << subsig[i] << " -> " << 'S' << sig + << "[" << edgeattr(getCertifiedSigType(subsig[i]), R->rate(subsig[i])) << "];" + << endl; + } + } + } + } + } + //cerr << --TABBER << "EXIT REC DRAW OF " << sig << endl; +} + + +/** + * Convert a signal type into attributes common to edges and nodes + */ +static string commonattr(Type t) +{ + string s; + + // nature + if (t->nature()==kInt) { + s += " color=\"blue\""; + } else { + s += " color=\"red\""; + } + + // vectorability + if (t->vectorability()==kVect && t->variability()==kSamp) { + s += " style=\"bold\""; + } + + return s; +} +/** + * Convert a signal type into edge attributes + */ + static string edgeattr(Type t, int rate) +{ + string s; + vector d; + Type b = t->dimensions(d); + + s = commonattr(t); + + // add rate information as label at the head of the arrow + s += " label=\""; + for (int i=0; ivariability()==kKonst) { + s += " shape=\"box\""; + } else if (t->variability()==kBlock) { + s += " shape=\"hexagon\""; + } else if (t->variability()==kSamp) { + s += " shape=\"ellipse\""; + } + + return s; +} + + +/** + * translate signal binary operations into strings + */ +static const char* binopname[]= { + "+", "-", "*", "/", "%", + "<<", ">>", + ">", "<", ">=", "<=", "==", "!=", + "&", "|", "^" +}; + + +/** + * return the label of a signal as a string + */ +static string sigLabel(Tree sig) +{ + int i; + double r; + Tree x, y, z, c, type, name, file, ff, largs, id, le, sel, var, label; + + xtended* p = (xtended*) getUserData(sig); + + stringstream fout; + + if (p) { fout << p->name(); } + else if ( isSigInt(sig, &i) ) { fout << i; } + else if ( isSigReal(sig, &r) ) { fout << r; } + else if ( isSigInput(sig, &i) ) { fout << "INPUT_" << i; } + else if ( isSigOutput(sig, &i, x) ) { fout << "OUTPUT_" << i; } + + else if ( isSigDelay1(sig, x) ) { fout << "mem"; } + else if ( isSigFixDelay(sig, x, y) ) { fout << "@"; } + else if ( isSigPrefix(sig, x, y) ) { fout << "prefix"; } + else if ( isSigIota(sig, x) ) { fout << "iota"; } + else if ( isSigBinOp(sig, &i, x, y) ) { fout << binopname[i]; } + else if ( isSigFFun(sig, ff, largs) ) { fout << "ffunction:" << *ff; } + else if ( isSigFConst(sig, type, name, file) ) { fout << *name; } + else if ( isSigFVar(sig, type, name, file) ) { fout << *name; } + + else if ( isSigTable(sig, id, x, y) ) { fout << "table:" << id; } + else if ( isSigWRTbl(sig, id, x, y, z) ) { fout << "write:" << id; } + else if ( isSigRDTbl(sig, x, y) ) { fout << "read"; } + + + + else if ( isSigSelect2(sig, sel, x, y) ) { fout << "select2"; } + else if ( isSigSelect3(sig, sel, x, y, z) ) { fout << "select3"; } + + else if ( isSigGen(sig, x) ) { fout << "generator"; } + + else if ( isProj(sig, &i, x) ) { fout << "Proj" << i; } + else if ( isRec(sig, var, le) ) { fout << "REC " << *var; } + + else if ( isSigIntCast(sig, x) ) { fout << "int"; } + else if ( isSigFloatCast(sig, x) ) { fout << "float"; } +#if 0 + else if ( isSigButton(sig, label) ) { fout << "button \"" << *label << '"'; } + else if ( isSigCheckbox(sig, label) ) { fout << "checkbox \"" << *label << '"'; } + else if ( isSigVSlider(sig, label,c,x,y,z) ) { fout << "vslider \"" << *label << '"'; } + else if ( isSigHSlider(sig, label,c,x,y,z) ) { fout << "hslider \"" << *label << '"'; } + else if ( isSigNumEntry(sig, label,c,x,y,z) ) { fout << "nentry \"" << *label << '"'; } + + else if ( isSigVBargraph(sig, label,x,y,z) ) { fout << "vbargraph \"" << *label << '"'; } + else if ( isSigHBargraph(sig, label,x,y,z) ) { fout << "hbargraph \"" << *label << '"'; } +#else + else if ( isSigButton(sig, label) ) { fout << "button"; } + else if ( isSigCheckbox(sig, label) ) { fout << "checkbox"; } + else if ( isSigVSlider(sig, label,c,x,y,z) ) { fout << "vslider"; } + else if ( isSigHSlider(sig, label,c,x,y,z) ) { fout << "hslider"; } + else if ( isSigNumEntry(sig, label,c,x,y,z) ) { fout << "nentry"; } + + else if ( isSigVBargraph(sig, label,x,y,z) ) { fout << "vbargraph"; } + else if ( isSigHBargraph(sig, label,x,y,z) ) { fout << "hbargraph"; } +#endif + else if ( isSigAttach(sig, x, y) ) { fout << "attach"; } + + else if ( isSigVectorize(sig, x, y) ) { fout << "vectorize"; } + else if ( isSigSerialize(sig, x) ) { fout << "serialize"; } + else if ( isSigConcat(sig, x, y) ) { fout << "#"; } + else if ( isSigVectorAt(sig, x, y) ) { fout << "[]"; } + + else if ( isSigUpSample(sig, x, y) ) { fout << "up"; } + else if ( isSigDownSample(sig, x, y) ) { fout << "down"; } + + else { + cerr << "ERROR in sigLabel(), unrecognized signal : " << *sig << endl; + exit(1); + } + + return fout.str(); +}