d0e64d993acd93aa6d3f7fdb238666c1ee606e17
[Faustine.git] / interpretor / faust-0.9.47mr3 / compiler / generator / occurences.cpp
1 #include <assert.h>
2 #include <stdlib.h>
3 #include "recursivness.hh"
4 #include "occurences.hh"
5 #include "sigtype.hh"
6 #include "sigtyperules.hh"
7 #include <iostream>
8
9 using namespace std;
10
11 /**
12 * Extended Variability with recursiveness indication
13 */
14 static int xVariability (int v, int r)
15 {
16 //cerr << "xVariability (" << v << ", " << r << ")" << endl;
17 //assert (v < 3); // kKonst=0, kBlock=1, kSamp=2
18 //assert(r==0 | v==2);
19 if (r>1) r=1;
20 return min(3, v + r);
21 }
22
23 //-------------------------------------------------
24 // Occurences methods
25 //-------------------------------------------------
26
27 Occurences::Occurences(int v, int r) : fXVariability(xVariability(v,r)) {
28 for (int i=0; i<4; i++) fOccurences[i]=0;
29 fMultiOcc = false;
30 fMaxDelay = 0;
31 fOutDelayOcc = false;
32 }
33
34 Occurences* Occurences::incOccurences(int v, int r, int d) {
35 int ctxt = xVariability(v,r);
36 //assert (ctxt >= fXVariability);
37 fOccurences[ctxt] += 1;
38 fMultiOcc = fMultiOcc | (ctxt > fXVariability) | (fOccurences[ctxt] > 1);
39 if (d == 0) {
40 //cerr << "Occurence outside a delay " << endl;
41 fOutDelayOcc = true;
42 }
43 if (d > fMaxDelay) {
44 //cerr << "Max delay : " << fMaxDelay << " <- " << d << endl;
45 fMaxDelay = d;
46 }
47 return this;
48 }
49
50 bool Occurences::hasMultiOccurences() const { return fMultiOcc; }
51
52 bool Occurences::hasOutDelayOccurences() const { return fOutDelayOcc; }
53
54 int Occurences::getMaxDelay() const
55 {
56 return fMaxDelay;
57 }
58
59 //--------------------------------------------------
60 // Mark and retrieve occurences of subtrees of root
61 //--------------------------------------------------
62
63 void OccMarkup::mark(Tree root)
64 {
65 fRootTree = root;
66 fPropKey = tree(unique("OCCURENCES"));
67
68 if (isList(root)) {
69 while (isList(root)) {
70 //incOcc(kSamp, 1, hd(root));
71 incOcc(nil, kSamp, 0, 0, hd(root));
72 root = tl(root);
73 }
74 //cerr << "END OF LIST IS " << *root << endl;
75 } else {
76 //incOcc(kSamp, 1, root);
77 incOcc(nil, kSamp, 0, 0, root);
78 }
79 }
80
81 Occurences* OccMarkup::retrieve(Tree t)
82 {
83 Occurences* p = getOcc(t);
84 if (p == 0) {
85 //cerr << "No Occurences info attached to : " << *t << endl;
86 //exit(1);
87 }
88 return p;
89 }
90
91 //------------------------------------------------------------------------------
92 // Increment the occurences of t within context v,r,d and proceed recursively
93 //------------------------------------------------------------------------------
94
95 void OccMarkup::incOcc(Tree env, int v, int r, int d, Tree t)
96 {
97 // Check if we have already visited this tree
98 Occurences* occ = getOcc(t);
99
100 if (occ==0) {
101 // 1) We build initial occurence information
102 Type ty = getCertifiedSigType(t);
103 int v0 = ty->variability();
104 int r0 = getRecursivness(t);
105
106 occ = new Occurences(v0,r0);
107 setOcc(t, occ);
108
109 // We mark the subtrees of t
110 Tree c, x, y, z;
111 if (isSigFixDelay(t,x,y)) {
112 Type g2 = getCertifiedSigType(y);
113 int d2 = checkDelayInterval(g2);
114 assert(d2>=0);
115 incOcc(env, v0, r0, d2, x);
116 incOcc(env, v0, r0, 0, y);
117 } else if (isSigPrefix(t,y,x)) {
118 incOcc(env, v0, r0, 1, x);
119 incOcc(env, v0, r0, 0, y);
120 } else if (isSigSelect3(t,c,y,x,z)) {
121 // make a special case for select3 implemented with real if
122 // because the c expression will be used twice in the C++
123 // translation
124 incOcc(env, v0, r0, 0, c);
125 incOcc(env, v0, r0, 0, c);
126 incOcc(env, v0, r0, 0, x);
127 incOcc(env, v0, r0, 0, y);
128 incOcc(env, v0, r0, 0, z);
129 } else {
130 vector<Tree> br;
131 int n = getSubSignals(t, br);
132 if (n>0 && ! isSigGen(t)) {
133 for (int i=0; i<n; i++) incOcc(env, v0, r0, 0, br[i]);
134 }
135 }
136 }
137
138 occ->incOccurences(v,r,d);
139
140 }
141
142
143
144 Occurences* OccMarkup::getOcc(Tree t)
145 {
146 Tree p = t->getProperty(fPropKey);
147 if (p) {
148 return (Occurences*) tree2ptr(p);
149 } else {
150 return 0;
151 }
152 }
153
154
155 void OccMarkup::setOcc(Tree t, Occurences* occ)
156 {
157 t->setProperty(fPropKey, tree(occ));
158 }
159
160
161
162 /**
163 * return the position of a signal in the current recursive environment
164 * @param env the current recursive environment of the signal
165 * @param t signal we want to know the position
166 * @return the position in the recursive environment
167 */
168 static int position (Tree env, Tree t, int p)
169 {
170 if (isNil(env)) return 0; // was not in the environment
171 if (hd(env) == t) return p;
172 else return position (tl(env), t, p+1);
173 }