+++ /dev/null
-/************************************************************************
- ************************************************************************
- 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 <stdio.h>
-
-#include <set>
-#include <vector>
-#include <iostream>
-#include <sstream>
-#include <string>
-
-#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<Tree>& 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<Tree> 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<Tree>& drawn, ofstream& fout, RateInferrer* R )
-{
- //cerr << ++TABBER << "ENTER REC DRAW OF " << sig << "$" << *sig << endl;
- vector<Tree> 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<n; i++) {
- recdraw(subsig[i], drawn, fout, R);
- if (isRec(subsig[i],id,body)) {
- // special case when source is a recursive group, we don't want a rate
- fout << 'S' << subsig[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<int> 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; i<d.size(); i++) {
- s += subst("[$0]", T(d[i]));
- }
- s += subst("x$0\" fontsize=8", T(rate));
-
- return s;
-}
-
-
-/**
- * Convert a signal type into node attributes
- */
-static string nodeattr(Type t)
-{
- string s = commonattr(t);
-
- // variability
- if (t->variability()==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();
-}