Merge branch 'newtree'
[Faustine.git] / interpretor / preprocessor / faust-0.9.47mr3 / compiler / signals / sigorderrules.cpp
1 /************************************************************************
2 ************************************************************************
3 FAUST compiler
4 Copyright (C) 2003-2004 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-2004 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
40 #include <stdio.h>
41 #include "sigtype.hh"
42 #include "sigprint.hh"
43 #include "prim2.hh"
44 #include "tlib.hh"
45 #include "sigorderrules.hh"
46 #include "xtended.hh"
47
48 Tree ORDERPROP = tree(symbol("OrderProp"));
49
50 static int infereSigOrder(Tree sig);
51
52 /**
53 * retrieve the order annotation (between 0 and 3) of a signal.
54 * (compute the order the first time). Orders have the following meanings
55 * 0 : numbers
56 * 1 : constants
57 * 2 : user interface values
58 * 3 : audio values
59 * @param sig the signal we want to know the order
60 * @return the order number
61 */
62 int getSigOrder(Tree sig)
63 {
64 Tree tt;
65 if (getProperty(sig, ORDERPROP, tt)) {
66 return tree2int(tt);
67 } else {
68 int order = infereSigOrder(sig);
69 setProperty(sig, ORDERPROP, tree(order));
70 return order;
71 }
72 }
73
74 // shortcut for order inference algorithm
75 #define O getSigOrder
76
77
78
79 /**
80 * Infere the order of a term according to its components
81 * @param sig the signal to analyze
82 * @return the order of sig
83 */
84 static int infereSigOrder(Tree sig)
85 {
86 int i;
87 double r;
88 Tree sel, s1, s2, s3, s4, ff, id, ls, l, x, y, var, body, type, name, file;
89
90 xtended* xt = (xtended*) getUserData(sig);
91 // primitive elements
92 if (xt)
93 {
94 //return 3;
95 vector<int> args;
96 for (int i=0; i<sig->arity(); i++) { args.push_back( O(sig->branch(i)) ); }
97 return xt->infereSigOrder(args);
98 }
99
100
101 else if (isSigInt(sig, &i)) return 0;
102
103 else if (isSigReal(sig, &r)) return 0;
104
105 else if (isSigInput(sig, &i)) return 3;
106
107 else if (isSigOutput(sig, &i, s1)) return 3;
108
109 else if (isSigDelay1(sig, s1)) return 3;
110
111 else if (isSigPrefix(sig, s1, s2)) return 3;
112
113 else if (isSigFixDelay(sig, s1, s2)) return 3;
114
115 else if (isSigBinOp(sig, &i, s1, s2)) return max(O(s1),O(s2));
116
117 else if (isSigIntCast(sig, s1)) return O(s1);
118
119 else if (isSigFloatCast(sig, s1)) return O(s1);
120
121 else if (isSigFFun(sig,ff,ls) && isNil(ls)) return 1;
122
123 else if (isSigFFun(sig, ff, ls)) return max(1,O(ls));
124
125 else if (isSigFConst(sig,type,name,file)) return 1;
126
127 else if (isSigFVar(sig,type,name,file)) return 2;
128
129 else if (isSigButton(sig)) return 2;
130
131 else if (isSigCheckbox(sig)) return 2;
132
133 else if (isSigVSlider(sig)) return 2;
134
135 else if (isSigHSlider(sig)) return 2;
136
137 else if (isSigNumEntry(sig)) return 2;
138
139 else if (isSigHBargraph(sig, l, x, y, s1)) return O(s1);
140
141 else if (isSigVBargraph(sig, l, x, y, s1)) return O(s1);
142
143 else if (isSigAttach(sig, s1, s2)) return O(s1);
144
145 else if (isRec(sig, var, body)) exit(1); //return 3; // not supposed to happen.
146
147 else if (isRef(sig, var)) exit(1); //return 3; // not supposed to happen.
148
149 else if (isProj(sig, &i, s1)) return 3;
150
151 else if (isSigTable(sig, id, s1, s2)) return 3;
152
153 else if (isSigWRTbl(sig, id, s1, s2, s3)) return 3;
154
155 else if (isSigRDTbl(sig, s1, s2)) return 3;
156
157 else if (isSigDocConstantTbl(sig, s1, s2)) return 3;
158
159 else if (isSigDocWriteTbl(sig,s1,s2,s3,s4)) return 3;
160
161 else if (isSigDocAccessTbl(sig,s1,s2)) return 3;
162
163 else if (isSigGen(sig, s1)) return 3;
164
165 else if (isSigSelect2(sig,sel,s1,s2)) return 3;
166
167 else if (isSigSelect3(sig,sel,s1,s2,s3)) return 3;
168
169 else if (isSigVectorize(sig,s1,s2)) return 3;
170 else if (isSigSerialize(sig,s1)) return 3;
171 else if (isSigVectorAt(sig,s1,s2)) return 3;
172 else if (isSigConcat(sig,s1,s2)) return 3;
173
174 else if (isSigUpSample(sig,s1,s2)) return 3;
175 else if (isSigDownSample(sig,s1,s2)) return 3;
176
177 else if (isList(sig))
178 {
179 int r = 0;
180 while (isList(sig)) { int x = O(hd(sig)); if (x > r) r = x; sig = tl(sig); }
181 return r;
182 }
183
184 // unrecognized signal here
185 fprintf(stderr, "ERROR infering signal order : unrecognized signal : "); print(sig, stderr); fprintf(stderr, "\n");
186 exit(1);
187 return 0;
188 }
189