|
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 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 }
1.8.0