|
FAUST compiler
0.9.9.6b8
|
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 do { 00106 subsig.push_back(hd(L)); 00107 L = tl(L); 00108 } while (isList(L)); 00109 } 00110 00111 for (int i=0; i<n; i++) { 00112 recdraw(subsig[i], drawn, fout); 00113 fout << 'S' << subsig[i] << " -> " << 'S' << sig 00114 << "[" << edgeattr(getCertifiedSigType(subsig[i])) << "];" 00115 << endl; 00116 } 00117 } 00118 } 00119 } 00120 //cerr << --TABBER << "EXIT REC DRAW OF " << sig << endl; 00121 } 00122 00123 00127 static string edgeattr(Type t) 00128 { 00129 string s; 00130 00131 // nature 00132 if (t->nature()==kInt) { 00133 s += " color=\"blue\""; 00134 } else { 00135 s += " color=\"red\""; 00136 } 00137 00138 // vectorability 00139 if (t->vectorability()==kVect && t->variability()==kSamp) { 00140 s += " style=\"bold\""; 00141 } 00142 return s; 00143 } 00144 00145 00149 static string nodeattr(Type t) 00150 { 00151 string s = edgeattr(t); 00152 00153 // variability 00154 if (t->variability()==kKonst) { 00155 s += " shape=\"box\""; 00156 } else if (t->variability()==kBlock) { 00157 s += " shape=\"hexagon\""; 00158 } else if (t->variability()==kSamp) { 00159 s += " shape=\"ellipse\""; 00160 } 00161 00162 return s; 00163 } 00164 00165 00169 static const char* binopname[]= { 00170 "+", "-", "*", "/", "%", 00171 "<<", ">>", 00172 ">", "<", ">=", "<=", "==", "!=", 00173 "&", "|", "^" 00174 }; 00175 00176 00180 static string sigLabel(Tree sig) 00181 { 00182 int i; 00183 double r; 00184 Tree x, y, z, c, type, name, file, ff, largs, id, le, sel, var, label; 00185 00186 xtended* p = (xtended*) getUserData(sig); 00187 00188 stringstream fout; 00189 00190 if (p) { fout << p->name(); } 00191 else if ( isSigInt(sig, &i) ) { fout << i; } 00192 else if ( isSigReal(sig, &r) ) { fout << r; } 00193 else if ( isSigInput(sig, &i) ) { fout << "INPUT_" << i; } 00194 else if ( isSigOutput(sig, &i, x) ) { fout << "OUTPUT_" << i; } 00195 00196 else if ( isSigDelay1(sig, x) ) { fout << "mem"; } 00197 else if ( isSigFixDelay(sig, x, y) ) { fout << "@"; } 00198 else if ( isSigPrefix(sig, x, y) ) { fout << "prefix"; } 00199 else if ( isSigIota(sig, x) ) { fout << "iota"; } 00200 else if ( isSigBinOp(sig, &i, x, y) ) { fout << binopname[i]; } 00201 else if ( isSigFFun(sig, ff, largs) ) { fout << "ffunction:" << *ff; } 00202 else if ( isSigFConst(sig, type, name, file) ) { fout << *name; } 00203 else if ( isSigFVar(sig, type, name, file) ) { fout << *name; } 00204 00205 else if ( isSigTable(sig, id, x, y) ) { fout << "table:" << id; } 00206 else if ( isSigWRTbl(sig, id, x, y, z) ) { fout << "write:" << id; } 00207 else if ( isSigRDTbl(sig, x, y) ) { fout << "read"; } 00208 00209 00210 00211 else if ( isSigSelect2(sig, sel, x, y) ) { fout << "select2"; } 00212 else if ( isSigSelect3(sig, sel, x, y, z) ) { fout << "select3"; } 00213 00214 else if ( isSigGen(sig, x) ) { fout << "generator"; } 00215 00216 else if ( isProj(sig, &i, x) ) { fout << "Proj" << i; } 00217 else if ( isRec(sig, var, le) ) { fout << "REC " << *var; } 00218 00219 else if ( isSigIntCast(sig, x) ) { fout << "int"; } 00220 else if ( isSigFloatCast(sig, x) ) { fout << "float"; } 00221 #if 0 00222 else if ( isSigButton(sig, label) ) { fout << "button \"" << *label << '"'; } 00223 else if ( isSigCheckbox(sig, label) ) { fout << "checkbox \"" << *label << '"'; } 00224 else if ( isSigVSlider(sig, label,c,x,y,z) ) { fout << "vslider \"" << *label << '"'; } 00225 else if ( isSigHSlider(sig, label,c,x,y,z) ) { fout << "hslider \"" << *label << '"'; } 00226 else if ( isSigNumEntry(sig, label,c,x,y,z) ) { fout << "nentry \"" << *label << '"'; } 00227 00228 else if ( isSigVBargraph(sig, label,x,y,z) ) { fout << "vbargraph \"" << *label << '"'; } 00229 else if ( isSigHBargraph(sig, label,x,y,z) ) { fout << "hbargraph \"" << *label << '"'; } 00230 #else 00231 else if ( isSigButton(sig, label) ) { fout << "button"; } 00232 else if ( isSigCheckbox(sig, label) ) { fout << "checkbox"; } 00233 else if ( isSigVSlider(sig, label,c,x,y,z) ) { fout << "vslider"; } 00234 else if ( isSigHSlider(sig, label,c,x,y,z) ) { fout << "hslider"; } 00235 else if ( isSigNumEntry(sig, label,c,x,y,z) ) { fout << "nentry"; } 00236 00237 else if ( isSigVBargraph(sig, label,x,y,z) ) { fout << "vbargraph"; } 00238 else if ( isSigHBargraph(sig, label,x,y,z) ) { fout << "hbargraph"; } 00239 #endif 00240 else if ( isSigAttach(sig, x, y) ) { fout << "attach"; } 00241 00242 else { 00243 cerr << "ERROR, unrecognized signal : " << *sig << endl; 00244 exit(1); 00245 } 00246 00247 return fout.str(); 00248 }
1.7.5.1