+++ /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 "propagate.hh"
-#include "prim2.hh"
-#include <assert.h>
-#include "ppbox.hh"
-#include "xtended.hh"
-#include "labels.hh"
-#include "Text.hh"
-#include "ppsig.hh"
-#include "names.hh"
-
-//extern bool gPrintDocSwitch;
-//static siglist realPropagate (Tree slotenv, Tree path, Tree box, const siglist& lsig);
-
-
-////////////////////////////////////////////////////////////////////////
-/**
- * propagate : box listOfSignal-> listOfSignal'
- *
- * Propage une liste de signaux de l'entrée vers la sortie d'une boite
- * La boite a été annotée aec son type
- */
-///////////////////////////////////////////////////////////////////////
-
-
-//! mix une liste de signaux sur n bus
-siglist mix(const siglist& lsig, int nbus)
-{
- int nlines = lsig.size();
-
- siglist dst(nbus);
-
- for (int b=0; b<nbus; b++) {
- Tree t = (b<nlines) ? lsig[b] : sigInt(0);
- for (int i=b+nbus; i<nlines; i+=nbus) {
- t = sigAdd(t, lsig[i]);
- }
- dst[b] = t;
- }
- return dst;
-}
-
-//! split une liste de signaux sur n bus
-siglist split(const siglist& inputs, int nbus)
-{
- int nlines = inputs.size();
-
- siglist outputs(nbus);
-
- for (int b=0; b<nbus; b++) {
- outputs[b] = inputs[b % nlines];
- }
- return outputs;
-}
-
-//! Fabrique une liste de n projections d'un groupe récursif
-siglist makeSigProjList (Tree t, int n)
-{
- siglist l(n);
- for (int i = 0; i < n; i++) l[i] = sigDelay0(sigProj(i, t));
- return l;
-}
-
-//! Fabrique une liste de n mem projections d'un groupe récursif
-siglist makeMemSigProjList (Tree t, int n)
-{
- siglist l(n);
- for (int i = 0; i < n; i++) l[i] = sigDelay1(sigProj(i, t));
- return l;
-}
-
-
-//! Fabrique une liste de n entrées
-siglist makeSigInputList (int n)
-{
- siglist l(n);
- for (int i = 0; i < n; i++) l[i] = sigInput(i);
- return l;
-}
-
-inline siglist makeList(Tree t)
-{
- siglist l(1);
- l[0] = t;
- return l;
-}
-
-siglist listRange(const siglist& l, int i, int j)
-{
- siglist r(j-i);
- for (int x = i; x < j; x++) r[x-i] = l[x];
- return r;
-}
-
-siglist listConcat(const siglist& a, const siglist& b)
-{
- int n1 = a.size();
- int n2 = b.size();
- siglist r(n1+n2);
-
- for (int x=0; x<n1; x++) r[x] = a[x];
- for (int x=0; x<n2; x++) r[x+n1] = b[x];
- return r;
-}
-
-/**
- * Convert an stl list of signals into a tree list of signals
- */
-Tree listConvert(const siglist& a)
-{
- int n = a.size();
- Tree t=nil;
- while (n--) t = cons(a[n],t);
- return t;
-}
-
-// siglist listConvertBack(Tree l)
-// {
-// siglist r;
-// while (!isNil(l)) { r.push_back(hd(l)); l = tl(l); }
-// return r;
-// }
-
-siglist listLift(const siglist& l)
-{
- int n = l.size();
- siglist r(n);
-
- for(int i = 0; i<n; i++) r[i] = lift(l[i]);
- return r;
-}
-
-static int gDummyInput = 10000;
-
-/**
- * Propagate computes the outputs signals of a block-diagram according to a list of input signals.
- *
- *\param slotenv input signals associated with symbolic slots
- *\param path stack of user interface groups : (type,label)*
- *\param box block-diagram where we propagate the signals
- *\param lsig list of signals to be propagated into box
- *\return list of resulting signals
- */
-/*
-// for debugging purposes
-
-siglist realpropagate (Tree slotenv, Tree path, Tree box, const siglist& lsig);
-
-siglist propagate (Tree slotenv, Tree path, Tree box, const siglist& lsig)
-{
- cerr << "propagate in " << boxpp(box) << endl;
- for (int i=0; i<lsig.size(); i++) { cerr << " -> signal " << i << " : " << *(lsig[i]) << endl; }
- cerr << endl;
- return realpropagate (slotenv, path, box, lsig);
-}
-*/
-
-/**
- * Old try for names propagation.
- */
-//siglist propagate (Tree slotenv, Tree path, Tree box, const siglist& lsig)
-//{
-// siglist S = realPropagate(slotenv, path, box, lsig);
-//
-// if (gPrintDocSwitch) {
-// Tree id;
-// if (lsig.size()==0 && getDefNameProperty(box, id)) {
-// string nickname = defName2NickName(tree2str(id));
-// //setSigListNickName(S, nickname);
-// }
-// }
-//
-// return S;
-//}
-
-//siglist realPropagate (Tree slotenv, Tree path, Tree box, const siglist& lsig)
-siglist propagate (Tree slotenv, Tree path, Tree box, const siglist& lsig)
-{
- int i;
- double r;
- prim0 p0;
- prim1 p1;
- prim2 p2;
- prim3 p3;
- prim4 p4;
- prim5 p5;
-
- Tree t1, t2, ff, label, cur, min, max, step, type, name, file, slot, body;
-
-
- xtended* xt = (xtended*)getUserData(box);
-
- // Extended Primitives
-
- if (xt) {
- assert(lsig.size() == xt->arity());
- return makeList(xt->computeSigOutput(lsig));
- }
-
- // Numbers and Constants
-
- else if (isBoxInt(box, &i)) {
- assert(lsig.size()==0);
- return makeList(sigInt(i));
- }
- else if (isBoxReal(box, &r)) {
- assert(lsig.size()==0);
- return makeList(sigReal(r));
- }
-
- else if (isBoxFConst(box, type, name, file)) {
- assert(lsig.size()==0);
- return makeList(sigFConst(type, name, file));
- }
-
- else if (isBoxFVar(box, type, name, file)) {
- assert(lsig.size()==0);
- return makeList(sigFVar(type, name, file));
- }
-
- // Wire and Cut
-
- else if (isBoxCut(box)) {
- assert(lsig.size()==1);
- return siglist();
- }
-
- else if (isBoxWire(box)) {
- assert(lsig.size()==1);
- return lsig;
- }
-
- // Slots and Symbolic Boxes
-
- else if (isBoxSlot(box)) {
- Tree sig;
- assert(lsig.size()==0);
- if (!searchEnv(box,sig,slotenv)) {
- // test YO simplification des diagrames
- //fprintf(stderr, "propagate : internal error (slot undefined)\n");
- //exit(1);
- sig = sigInput(++gDummyInput);
- }
- return makeList(sig);
- }
-
- else if (isBoxSymbolic(box, slot, body)) {
- assert(lsig.size()>0);
- return propagate(pushEnv(slot,lsig[0],slotenv), path, body, listRange(lsig, 1, lsig.size()));
- }
-
- // Primitives
-
- else if (isBoxPrim0(box, &p0)) {
- assert(lsig.size()==0);
- return makeList( p0() );
- }
-
- else if (isBoxPrim1(box, &p1)) {
- assert(lsig.size()==1);
- return makeList( p1(lsig[0]) );
- }
-
- else if (isBoxPrim2(box, &p2)) {
-// printf("prim2 recoit : "); print(lsig); printf("\n");
- assert(lsig.size()==2);
- return makeList( p2(lsig[0],lsig[1]) );
- }
-
- else if (isBoxPrim3(box, &p3)) {
- assert(lsig.size()==3);
- return makeList( p3(lsig[0],lsig[1],lsig[2]) );
- }
-
- else if (isBoxPrim4(box, &p4)) {
- assert(lsig.size()==4);
- return makeList( p4(lsig[0],lsig[1],lsig[2],lsig[3]) );
- }
-
- else if (isBoxPrim5(box, &p5)) {
- assert(lsig.size()==5);
- return makeList( p5(lsig[0],lsig[1],lsig[2],lsig[3],lsig[4]) );
- }
-
- else if (isBoxFFun(box, ff)) {
- //cerr << "propagate en boxFFun of arity " << ffarity(ff) << endl;
- assert(int(lsig.size())==ffarity(ff));
- return makeList(sigFFun(ff, listConvert(lsig)));
- }
-
- // User Interface Widgets
-
- else if (isBoxButton(box, label)) {
- assert(lsig.size()==0);
- return makeList(sigButton(normalizePath(cons(label, path))));
- }
-
- else if (isBoxCheckbox(box, label)) {
- assert(lsig.size()==0);
- return makeList(sigCheckbox(normalizePath(cons(label, path))));
- }
-
- else if (isBoxVSlider(box, label, cur, min, max, step)) {
- assert(lsig.size()==0);
- return makeList(sigVSlider(normalizePath(cons(label, path)), cur, min, max, step));
- }
-
- else if (isBoxHSlider(box, label, cur, min, max, step)) {
- assert(lsig.size()==0);
- return makeList(sigHSlider(normalizePath(cons(label, path)), cur, min, max, step));
- }
-
- else if (isBoxNumEntry(box, label, cur, min, max, step)) {
- assert(lsig.size()==0);
- return makeList(sigNumEntry(normalizePath(cons(label, path)), cur, min, max, step));
- }
-
- else if (isBoxVBargraph(box, label, min, max)) {
- assert(lsig.size()==1);
- return makeList(sigVBargraph(normalizePath(cons(label, path)), min, max, lsig[0]));
- }
-
- else if (isBoxHBargraph(box, label, min, max)) {
- assert(lsig.size()==1);
- return makeList(sigHBargraph(normalizePath(cons(label, path)), min, max, lsig[0]));
- }
-
- // User Interface Groups
-
- else if (isBoxVGroup(box, label, t1)) {
- return propagate(slotenv,cons(cons(tree(0),label), path), t1, lsig);
- }
-
- else if (isBoxHGroup(box, label, t1)) {
- return propagate(slotenv, cons(cons(tree(1),label), path), t1, lsig);
- }
-
- else if (isBoxTGroup(box, label, t1)) {
- return propagate(slotenv, cons(cons(tree(2),label), path), t1, lsig);
- }
-
- // Block Diagram Composition Algebra
-
- else if (isBoxSeq(box, t1, t2)) {
- int in1, out1, in2, out2;
- getBoxType(t1, &in1, &out1);
- getBoxType(t2, &in2, &out2);
-
- assert(out1==in2);
-
- if (out1 == in2) {
- return propagate(slotenv, path, t2, propagate(slotenv, path,t1,lsig));
- } else if (out1 > in2) {
- siglist lr = propagate(slotenv, path, t1,lsig);
- return listConcat(propagate(slotenv, path, t2, listRange(lr, 0, in2)), listRange(lr, in2, out1));
- } else {
- return propagate(slotenv, path, t2, listConcat( propagate(slotenv, path, t1, listRange(lsig,0,in1)), listRange(lsig,in1,in1+in2-out1) ) );
- }
- }
-
- else if (isBoxPar(box, t1, t2)) {
- int in1, out1, in2, out2;
- getBoxType(t1, &in1, &out1);
- getBoxType(t2, &in2, &out2);
-
- return listConcat( propagate(slotenv, path, t1, listRange(lsig, 0, in1)),
- propagate(slotenv, path, t2, listRange(lsig, in1, in1+in2)) );
- }
-
- else if (isBoxSplit(box, t1, t2)) {
- int in1, out1, in2, out2;
- getBoxType(t1, &in1, &out1);
- getBoxType(t2, &in2, &out2);
-
- siglist l1 = propagate(slotenv, path, t1, lsig);
- siglist l2 = split(l1, in2);
- return propagate(slotenv, path, t2, l2);
- }
-
- else if (isBoxMerge(box, t1, t2)) {
- int in1, out1, in2, out2;
- getBoxType(t1, &in1, &out1);
- getBoxType(t2, &in2, &out2);
-
- siglist l1 = propagate(slotenv, path, t1, lsig);
- siglist l2 = mix(l1, in2);
- return propagate(slotenv, path, t2, l2);
- }
-/*
- else if (isBoxRec(box, t1, t2)) {
- int in1, out1, in2, out2;
- getBoxType(t1, &in1, &out1);
- getBoxType(t2, &in2, &out2);
-
- siglist l0 = makeSigProjList(ref(1), in2);
- siglist l1 = propagate(slotenv, path, t2, l0);
- siglist l2 = propagate(slotenv, path, t1, listConcat(l1,listLift(lsig)));
- Tree g = rec(listConvert(l2));
- return makeSigProjList(g, out1);
- }
-*/
- else if (isBoxRec(box, t1, t2)) {
- // Bug Corrected
- int in1, out1, in2, out2;
- getBoxType(t1, &in1, &out1);
- getBoxType(t2, &in2, &out2);
-
- Tree slotenv2 = lift(slotenv); // the environment must also be lifted
-
- siglist l0 = makeMemSigProjList(ref(1), in2);
- siglist l1 = propagate(slotenv2, path, t2, l0);
- siglist l2 = propagate(slotenv2, path, t1, listConcat(l1,listLift(lsig)));
- Tree g = rec(listConvert(l2));
- return makeSigProjList(g, out1);
- }
-
- cout << "ERROR in file " << __FILE__ << ':' << __LINE__ << ", unrecognised box expression : " << boxpp(box) << endl;
- exit(1);
- return siglist();
-}
-
-
-Tree boxPropagateSig (Tree path, Tree box, const siglist& lsig)
-{
- return listConvert(propagate(nil, path, box, lsig));
-}
-