X-Git-Url: https://scm.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/1059e1cc0c2ecfa237406949aa26155b6a5b9154..66f23d4fabf89ad09adbd4dfc15ac6b5b2b7da83:/interpreter/preprocessor/faust-0.9.47mr3/compiler/generator/occurences.cpp diff --git a/interpreter/preprocessor/faust-0.9.47mr3/compiler/generator/occurences.cpp b/interpreter/preprocessor/faust-0.9.47mr3/compiler/generator/occurences.cpp new file mode 100644 index 0000000..d0e64d9 --- /dev/null +++ b/interpreter/preprocessor/faust-0.9.47mr3/compiler/generator/occurences.cpp @@ -0,0 +1,173 @@ +#include +#include +#include "recursivness.hh" +#include "occurences.hh" +#include "sigtype.hh" +#include "sigtyperules.hh" +#include + +using namespace std; + +/** + * Extended Variability with recursiveness indication + */ +static int xVariability (int v, int r) +{ + //cerr << "xVariability (" << v << ", " << r << ")" << endl; + //assert (v < 3); // kKonst=0, kBlock=1, kSamp=2 + //assert(r==0 | v==2); + if (r>1) r=1; + return min(3, v + r); +} + +//------------------------------------------------- +// Occurences methods +//------------------------------------------------- + +Occurences::Occurences(int v, int r) : fXVariability(xVariability(v,r)) { + for (int i=0; i<4; i++) fOccurences[i]=0; + fMultiOcc = false; + fMaxDelay = 0; + fOutDelayOcc = false; +} + +Occurences* Occurences::incOccurences(int v, int r, int d) { + int ctxt = xVariability(v,r); + //assert (ctxt >= fXVariability); + fOccurences[ctxt] += 1; + fMultiOcc = fMultiOcc | (ctxt > fXVariability) | (fOccurences[ctxt] > 1); + if (d == 0) { + //cerr << "Occurence outside a delay " << endl; + fOutDelayOcc = true; + } + if (d > fMaxDelay) { + //cerr << "Max delay : " << fMaxDelay << " <- " << d << endl; + fMaxDelay = d; + } + return this; +} + +bool Occurences::hasMultiOccurences() const { return fMultiOcc; } + +bool Occurences::hasOutDelayOccurences() const { return fOutDelayOcc; } + +int Occurences::getMaxDelay() const +{ + return fMaxDelay; +} + +//-------------------------------------------------- +// Mark and retrieve occurences of subtrees of root +//-------------------------------------------------- + +void OccMarkup::mark(Tree root) +{ + fRootTree = root; + fPropKey = tree(unique("OCCURENCES")); + + if (isList(root)) { + while (isList(root)) { + //incOcc(kSamp, 1, hd(root)); + incOcc(nil, kSamp, 0, 0, hd(root)); + root = tl(root); + } + //cerr << "END OF LIST IS " << *root << endl; + } else { + //incOcc(kSamp, 1, root); + incOcc(nil, kSamp, 0, 0, root); + } +} + +Occurences* OccMarkup::retrieve(Tree t) +{ + Occurences* p = getOcc(t); + if (p == 0) { + //cerr << "No Occurences info attached to : " << *t << endl; + //exit(1); + } + return p; +} + +//------------------------------------------------------------------------------ +// Increment the occurences of t within context v,r,d and proceed recursively +//------------------------------------------------------------------------------ + +void OccMarkup::incOcc(Tree env, int v, int r, int d, Tree t) +{ + // Check if we have already visited this tree + Occurences* occ = getOcc(t); + + if (occ==0) { + // 1) We build initial occurence information + Type ty = getCertifiedSigType(t); + int v0 = ty->variability(); + int r0 = getRecursivness(t); + + occ = new Occurences(v0,r0); + setOcc(t, occ); + + // We mark the subtrees of t + Tree c, x, y, z; + if (isSigFixDelay(t,x,y)) { + Type g2 = getCertifiedSigType(y); + int d2 = checkDelayInterval(g2); + assert(d2>=0); + incOcc(env, v0, r0, d2, x); + incOcc(env, v0, r0, 0, y); + } else if (isSigPrefix(t,y,x)) { + incOcc(env, v0, r0, 1, x); + incOcc(env, v0, r0, 0, y); + } else if (isSigSelect3(t,c,y,x,z)) { + // make a special case for select3 implemented with real if + // because the c expression will be used twice in the C++ + // translation + incOcc(env, v0, r0, 0, c); + incOcc(env, v0, r0, 0, c); + incOcc(env, v0, r0, 0, x); + incOcc(env, v0, r0, 0, y); + incOcc(env, v0, r0, 0, z); + } else { + vector br; + int n = getSubSignals(t, br); + if (n>0 && ! isSigGen(t)) { + for (int i=0; iincOccurences(v,r,d); + +} + + + +Occurences* OccMarkup::getOcc(Tree t) +{ + Tree p = t->getProperty(fPropKey); + if (p) { + return (Occurences*) tree2ptr(p); + } else { + return 0; + } +} + + +void OccMarkup::setOcc(Tree t, Occurences* occ) +{ + t->setProperty(fPropKey, tree(occ)); +} + + + +/** + * return the position of a signal in the current recursive environment + * @param env the current recursive environment of the signal + * @param t signal we want to know the position + * @return the position in the recursive environment + */ +static int position (Tree env, Tree t, int p) +{ + if (isNil(env)) return 0; // was not in the environment + if (hd(env) == t) return p; + else return position (tl(env), t, p+1); +}