1 /************************************************************************
2 ************************************************************************
3 FAUST compiler
4 Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
21
22 /************************************************************************
23 ************************************************************************
24 Signals Order Rules
25 Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
26 ---------------------------------------------------------------------
27 A small typing system that computes the "order" of a signal :
28 0 = numerical constant
29 1 = non-numerical constants (FConst)
30 2 = User Interface
31 3 = Audio
32 This order will be used to put expressions in normal form.
33
34 Contrary to the full type system, it doesn't require environments
35 or special treatments for recursions
36 ************************************************************************
37 ************************************************************************/
38
39 #include "sigorderrules.hh"
40 #include <stdio.h>
41 #include "exception.hh"
42 #include "global.hh"
43 #include "prim2.hh"
44 #include "sigprint.hh"
45 #include "sigtype.hh"
46 #include "tlib.hh"
47 #include "xtended.hh"
48
49 static int infereSigOrder(Tree sig);
50
51 /**
52 * Retrieve the order annotation (between 0 and 3) of a signal.
53 * (compute the order the first time). Orders have the following meanings
54 * 0 : numbers
55 * 1 : constants
56 * 2 : user interface values
57 * 3 : audio values
58 * @param sig the signal we want to know the order
59 * @return the order number
60 */
getSigOrder(Tree sig)61 int getSigOrder(Tree sig)
62 {
63 Tree tt;
64 if (getProperty(sig, gGlobal->ORDERPROP, tt)) {
65 return tree2int(tt);
66 } else {
67 int order = infereSigOrder(sig);
68 setProperty(sig, gGlobal->ORDERPROP, tree(order));
69 return order;
70 }
71 }
72
73 // shortcut for order inference algorithm
74 #define O getSigOrder
75
76 /**
77 * Infere the order of a term according to its components
78 * @param sig the signal to analyze
79 * @return the order of sig
80 */
infereSigOrder(Tree sig)81 static int infereSigOrder(Tree sig)
82 {
83 int i;
84 double r;
85 Tree sel, s1, s2, s3, s4, ff, id, ls, l, x, y, z, var, body, type, name, file, sf;
86
87 xtended* xt = (xtended*)getUserData(sig);
88 // primitive elements
89 if (xt) {
90 vector<int> args;
91 for (int i1 = 0; i1 < sig->arity(); i1++) {
92 args.push_back(O(sig->branch(i1)));
93 }
94 return xt->infereSigOrder(args);
95 }
96
97 else if (isSigInt(sig, &i))
98 return 0;
99
100 else if (isSigReal(sig, &r))
101 return 0;
102
103 else if (isSigWaveform(sig))
104 return 3;
105
106 else if (isSigInput(sig, &i))
107 return 3;
108
109 else if (isSigOutput(sig, &i, s1))
110 return 3;
111
112 else if (isSigDelay1(sig, s1))
113 return 3;
114
115 else if (isSigPrefix(sig, s1, s2))
116 return 3;
117
118 else if (isSigDelay(sig, s1, s2))
119 return 3;
120
121 else if (isSigBinOp(sig, &i, s1, s2))
122 return max(O(s1), O(s2));
123
124 else if (isSigIntCast(sig, s1))
125 return O(s1);
126
127 else if (isSigFloatCast(sig, s1))
128 return O(s1);
129
130 else if (isSigFFun(sig, ff, ls) && isNil(ls))
131 return 1;
132
133 else if (isSigFFun(sig, ff, ls))
134 return max(1, O(ls));
135
136 else if (isSigFConst(sig, type, name, file))
137 return 1;
138
139 else if (isSigFVar(sig, type, name, file))
140 return 2;
141
142 else if (isSigButton(sig))
143 return 2;
144
145 else if (isSigCheckbox(sig))
146 return 2;
147
148 else if (isSigVSlider(sig))
149 return 2;
150
151 else if (isSigHSlider(sig))
152 return 2;
153
154 else if (isSigNumEntry(sig))
155 return 2;
156
157 else if (isSigHBargraph(sig, l, x, y, s1))
158 return max(2, O(s1)); // at least a user interface
159
160 else if (isSigVBargraph(sig, l, x, y, s1))
161 return max(2, O(s1)); // at least a user interface
162
163 else if (isSigEnable(sig, s1, s2))
164 return max(O(s1), O(s2)); // O(s1);
165
166 else if (isSigControl(sig, s1, s2))
167 return max(O(s1), O(s2)); // O(s1);
168
169 else if (isSigSoundfile(sig, l))
170 throw faustexception("ERROR inferring signal order : isSigSoundfile\n"); // not supposed to happen.;
171
172 else if (isSigSoundfileLength(sig, sf, x))
173 return 2;
174
175 else if (isSigSoundfileRate(sig, sf, x))
176 return 2;
177
178 else if (isSigSoundfileBuffer(sig, sf, x, y, z))
179 return 3;
180
181 else if (isSigAttach(sig, s1, s2))
182 return max(1, O(s1)); // at least a constant
183
184 else if (isRec(sig, var, body))
185 throw faustexception("ERROR inferring signal order : isRec\n"); // return 3; // not supposed to happen.
186
187 else if (isRef(sig, var))
188 throw faustexception("ERROR inferring signal order : isRef\n"); // return 3; // not supposed to happen.
189
190 else if (isProj(sig, &i, s1))
191 return 3;
192
193 else if (isSigTable(sig, id, s1, s2))
194 return 3;
195
196 else if (isSigWRTbl(sig, id, s1, s2, s3))
197 return 3;
198
199 else if (isSigRDTbl(sig, s1, s2))
200 return 3;
201
202 else if (isSigDocConstantTbl(sig, s1, s2))
203 return 3;
204
205 else if (isSigDocWriteTbl(sig, s1, s2, s3, s4))
206 return 3;
207
208 else if (isSigDocAccessTbl(sig, s1, s2))
209 return 3;
210
211 else if (isSigGen(sig, s1))
212 return 3;
213
214 else if (isSigSelect2(sig, sel, s1, s2))
215 return 3;
216
217 else if (isList(sig)) {
218 int r1 = 0;
219 while (isList(sig)) {
220 int x1 = O(hd(sig));
221 if (x1 > r1) r1 = x1;
222 sig = tl(sig);
223 }
224 return r1;
225 }
226
227 // unrecognized signal here
228 throw faustexception("ERROR inferring signal order : unrecognized signal\n");
229 }
230