FAUST compiler  0.9.9.6b8
boxtype.cpp
Go to the documentation of this file.
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 /*****************************************************************************
25 ******************************************************************************
26 
27  Box Type System
28 
29 ******************************************************************************
30 *****************************************************************************/
31 
32 
42 #include <stdio.h>
43 #include <string.h>
44 #include "boxes.hh"
45 #include "ppbox.hh"
46 #include "prim2.hh"
47 #include "xtended.hh"
48 
49 
50 Tree BOXTYPEPROP = tree(symbol("boxTypeProp"));
51 static bool infereBoxType (Tree box, int* inum, int* onum);
52 
53 
54 
63 bool getBoxType (Tree box, int* inum, int* onum)
64 {
65  Tree t;
66  if (getProperty(box, BOXTYPEPROP, t)) {
67 
68  if (isNil(t)) {
69  return false;
70  } else {
71  *inum = hd(t)->node().getInt();
72  *onum = tl(t)->node().getInt();
73  return true;
74  }
75 
76  } else {
77 
78  if (infereBoxType(box, inum, onum)) {
79  setProperty(box, BOXTYPEPROP, cons(tree(*inum), tree(*onum)));
80  return true;
81  } else {
82  setProperty(box, BOXTYPEPROP, nil);
83  return false;
84  }
85  }
86 }
87 
88 
89 
101 static bool infereBoxType (Tree t, int* inum, int* onum)
102 {
103  Tree a, b, ff, l, s;
104  //Tree abstr, genv, vis, lenv;
105 
106  xtended* p = (xtended*) getUserData(t);
107 
108  if (p) { *inum = p->arity(); *onum = 1; }
109  else if (isBoxInt(t)) { *inum = 0; *onum = 1; }
110  else if (isBoxReal(t)) { *inum = 0; *onum = 1; }
111 
112  else if (isBoxWaveform(t)) { *inum = 0; *onum = 2; }
113 
114  else if (isBoxWire(t)) { *inum = 1; *onum = 1; }
115  else if (isBoxCut(t)) { *inum = 1; *onum = 0; }
116 
117  else if (isBoxSlot(t)) { *inum = 0; *onum = 1; }
118  else if (isBoxSymbolic(t,s,b)) { if (!getBoxType(b, inum, onum)) return false; *inum += 1; }
119 
120  else if (isBoxPatternVar(t,a)) { return false; }
121 
122  else if (isBoxPrim0(t)) { *inum = 0; *onum = 1; }
123  else if (isBoxPrim1(t)) { *inum = 1; *onum = 1; }
124  else if (isBoxPrim2(t)) { *inum = 2; *onum = 1; }
125  else if (isBoxPrim3(t)) { *inum = 3; *onum = 1; }
126  else if (isBoxPrim4(t)) { *inum = 4; *onum = 1; }
127  else if (isBoxPrim5(t)) { *inum = 5; *onum = 1; }
128 
129  else if (isBoxFFun(t,ff)) { *inum = ffarity(ff); *onum = 1; }
130  else if (isBoxFConst(t)) { *inum = 0; *onum = 1; }
131  else if (isBoxFVar(t)) { *inum = 0; *onum = 1; }
132 
133  else if (isBoxButton(t)) { *inum = 0; *onum = 1; }
134  else if (isBoxCheckbox(t)) { *inum = 0; *onum = 1; }
135  else if (isBoxVSlider(t)) { *inum = 0; *onum = 1; }
136  else if (isBoxHSlider(t)) { *inum = 0; *onum = 1; }
137  else if (isBoxNumEntry(t)) { *inum = 0; *onum = 1; }
138  else if (isBoxVGroup(t,l,a)){ return getBoxType(a, inum, onum); }
139  else if (isBoxHGroup(t,l,a)){ return getBoxType(a, inum, onum); }
140  else if (isBoxTGroup(t,l,a)){ return getBoxType(a, inum, onum); }
141 
142  else if (isBoxVBargraph(t)) { *inum = 1; *onum = 1; }
143  else if (isBoxHBargraph(t)) { *inum = 1; *onum = 1; }
144 
145  else if (isBoxSeq(t, a, b)) {
146 
147  int u,v,x,y;
148  if (!getBoxType(a, &u, &v)) return false;
149  if (!getBoxType(b, &x, &y)) return false;
150 
151  if (v != x) {
152  cerr << "Error in sequential composition (A:B)" << endl
153  << "The number of outputs (" << v << ") of A = " << boxpp(a) << endl
154  << "must be equal to the number of inputs (" << x << ") of B : " << boxpp(b) << endl;
155  exit(1);
156  } else {
157  *inum = u; *onum = y;
158  }
159 
160  } else if (isBoxPar(t, a, b)) {
161 
162  int u,v,x,y;
163  if (!getBoxType(a, &u, &v)) return false;
164  if (!getBoxType(b, &x, &y)) return false;
165 
166  *inum = u+x; *onum = v+y;
167 
168  } else if (isBoxSplit(t, a, b)) {
169 
170  int u,v,x,y;
171  if (!getBoxType(a, &u, &v)) return false;
172  if (!getBoxType(b, &x, &y)) return false;
173 
174  if (v == 0) {
175  cerr << "Connection error in : " << boxpp(t) << endl
176  << "The first expression : " << boxpp(a) << " has no outputs" << endl;
177  exit(1);
178  }
179 
180  if (x == 0) {
181  cerr << "Connection error in : " << boxpp(t) << endl
182  << "The second expression : " << boxpp(b) << " has no inputs" << endl;
183  exit(1);
184  }
185 
186  if (x % v != 0) {
187  cerr << "Connection error in : " << boxpp(t) << endl
188  << "The number of outputs " << v
189  << " of the first expression should be a divisor of the number of inputs " << x
190  << " of the second expression" << endl;
191  exit(1);
192  }
193 
194  *inum = u; *onum = y;
195 
196  } else if (isBoxMerge(t, a, b)) {
197 
198  int u,v,x,y;
199  if (!getBoxType(a, &u, &v)) return false;
200  if (!getBoxType(b, &x, &y)) return false;
201 
202  if (v == 0) {
203  cerr << "Connection error in : " << boxpp(t) << endl
204  << "The first expression : " << boxpp(a) << " has no outputs" << endl;
205  exit(1);
206  }
207 
208  if (x == 0) {
209  cerr << "Connection error in : " << boxpp(t) << endl
210  << "The second expression : " << boxpp(b) << " has no inputs" << endl;
211  exit(1);
212  }
213 
214  if (v % x != 0) {
215  cerr << "Connection error in : " << boxpp(t) << endl
216  << "The number of outputs " << v
217  << " of the first expression should be a multiple of the number of inputs " << x
218  << " of the second expression" << endl;
219  exit(1);
220  }
221 
222  *inum = u; *onum = y;
223 
224  } else if (isBoxRec(t, a, b)) {
225 
226  int u,v,x,y;
227  if (!getBoxType(a, &u, &v)) return false;
228  if (!getBoxType(b, &x, &y)) return false;
229  if ( (x > v) | (y > u) ) {
230  cerr << "Connection error in : " << boxpp(t) << endl;
231  if (x > v) cerr << "The number of outputs " << v
232  << " of the first expression should be greater or equal \n to the number of inputs " << x
233  << " of the second expression" << endl;
234  if (y > u) cerr << "The number of inputs " << u
235  << " of the first expression should be greater or equal \n to the number of outputs " << y
236  << " of the second expression" << endl;
237  exit(1);
238  }
239  *inum = max(0,u-y); *onum = v;
240 
241  } else if (isBoxEnvironment(t)) {
242  cerr << "Connection error : an environment is not a block-diagram : " << boxpp(t) << endl;
243  exit(1);
244  } else {
245  cerr << "boxType() internal error : unrecognized box expression " << boxpp(t) << endl;
246  exit(1);
247  }
248  return true;
249 }
250 
251 
252 
bool isBoxPrim1(Tree s)
Definition: boxes.cpp:315
bool isBoxPrim5(Tree s)
Definition: boxes.cpp:335
bool isBoxWire(Tree t)
Definition: boxes.cpp:109
static bool infereBoxType(Tree box, int *inum, int *onum)
Infere the type (number of inputs and outputs) of a box.
Definition: boxtype.cpp:101
bool isBoxSeq(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:136
bool isBoxInt(Tree t)
Definition: boxes.cpp:78
Tree cons(Tree a, Tree b)
Definition: list.hh:124
bool isBoxSplit(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:148
bool isBoxFFun(Tree s)
Definition: boxes.cpp:344
A CTree = (Node x [CTree]) is a Node associated with a list of subtrees called branches.
Definition: tree.hh:109
Tree BOXTYPEPROP
Definition: boxtype.cpp:50
bool isBoxCut(Tree t)
Definition: boxes.cpp:105
int ffarity(Tree t)
Definition: prim2.cpp:67
Tree hd(Tree l)
Definition: list.hh:133
bool isBoxPrim0(Tree s)
Definition: boxes.cpp:310
bool isBoxPrim4(Tree s)
Definition: boxes.cpp:330
const Node & node() const
return the content of the tree
Definition: tree.hh:143
bool isBoxHGroup(Tree s)
Definition: boxes.cpp:437
bool isBoxHBargraph(Tree s)
Definition: boxes.cpp:455
bool isBoxRec(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:144
double max(double x, double y)
Definition: interval.hh:60
bool isNil(Tree l)
Definition: list.hh:137
bool isBoxSymbolic(Tree t)
Definition: boxes.cpp:126
bool isBoxTGroup(Tree s)
Definition: boxes.cpp:449
bool isBoxEnvironment(Tree s)
Definition: boxes.cpp:285
bool isBoxButton(Tree s)
Definition: boxes.cpp:366
bool isBoxReal(Tree t)
Definition: boxes.cpp:79
bool isBoxPar(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:140
bool isBoxHSlider(Tree s)
Definition: boxes.cpp:379
bool isBoxVBargraph(Tree s)
Definition: boxes.cpp:461
bool isBoxWaveform(Tree s)
Definition: boxes.cpp:97
bool isBoxCheckbox(Tree s)
Definition: boxes.cpp:372
bool isBoxVGroup(Tree s)
Definition: boxes.cpp:443
virtual unsigned int arity()=0
bool isBoxFVar(Tree s)
Definition: boxes.cpp:356
Tree tree(const Node &n)
Definition: tree.hh:186
bool isBoxVSlider(Tree s)
Definition: boxes.cpp:399
int getInt() const
Definition: node.hh:104
Definition: ppbox.hh:58
bool isBoxNumEntry(Tree s)
Definition: boxes.cpp:418
void setProperty(Tree t, Tree key, Tree val)
Definition: list.cpp:418
bool isBoxSlot(Tree t)
Definition: boxes.cpp:119
void * getUserData(Symbol *sym)
Returns user data.
Definition: symbol.hh:100
bool isBoxPrim3(Tree s)
Definition: boxes.cpp:325
Tree nil
Definition: list.cpp:116
bool isBoxPatternVar(Tree s, Tree &id)
Definition: boxes.cpp:622
Symbol * symbol(const char *str)
Returns (and creates if new) the symbol of name str.
Definition: symbol.hh:95
bool isBoxMerge(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:152
bool isBoxFConst(Tree s)
Definition: boxes.cpp:350
bool isBoxPrim2(Tree s)
Definition: boxes.cpp:320
Tree tl(Tree l)
Definition: list.hh:134
bool getBoxType(Tree box, int *inum, int *onum)
Return the type (number of inputs and outputs) of a box or false if undefined.
Definition: boxtype.cpp:63
bool getProperty(Tree t, Tree key, Tree &val)
Definition: list.cpp:423