|
FAUST compiler
0.9.9.6b8
|
00001 /************************************************************************ 00002 ************************************************************************ 00003 FAUST compiler 00004 Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale 00005 --------------------------------------------------------------------- 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 ************************************************************************ 00020 ************************************************************************/ 00021 00022 00023 00024 /***************************************************************************** 00025 ****************************************************************************** 00026 00027 Box Type System 00028 00029 ****************************************************************************** 00030 *****************************************************************************/ 00031 00032 00042 #include <stdio.h> 00043 #include <string.h> 00044 #include "boxes.hh" 00045 #include "ppbox.hh" 00046 #include "prim2.hh" 00047 #include "xtended.hh" 00048 00049 00050 Tree BOXTYPEPROP = tree(symbol("boxTypeProp")); 00051 static bool infereBoxType (Tree box, int* inum, int* onum); 00052 00053 00054 00063 bool getBoxType (Tree box, int* inum, int* onum) 00064 { 00065 Tree t; 00066 if (getProperty(box, BOXTYPEPROP, t)) { 00067 00068 if (isNil(t)) { 00069 return false; 00070 } else { 00071 *inum = hd(t)->node().getInt(); 00072 *onum = tl(t)->node().getInt(); 00073 return true; 00074 } 00075 00076 } else { 00077 00078 if (infereBoxType(box, inum, onum)) { 00079 setProperty(box, BOXTYPEPROP, cons(tree(*inum), tree(*onum))); 00080 return true; 00081 } else { 00082 setProperty(box, BOXTYPEPROP, nil); 00083 return false; 00084 } 00085 } 00086 } 00087 00088 00089 00101 static bool infereBoxType (Tree t, int* inum, int* onum) 00102 { 00103 Tree a, b, ff, l, s; 00104 //Tree abstr, genv, vis, lenv; 00105 00106 xtended* p = (xtended*) getUserData(t); 00107 00108 if (p) { *inum = p->arity(); *onum = 1; } 00109 else if (isBoxInt(t)) { *inum = 0; *onum = 1; } 00110 else if (isBoxReal(t)) { *inum = 0; *onum = 1; } 00111 else if (isBoxWire(t)) { *inum = 1; *onum = 1; } 00112 else if (isBoxCut(t)) { *inum = 1; *onum = 0; } 00113 00114 else if (isBoxSlot(t)) { *inum = 0; *onum = 1; } 00115 else if (isBoxSymbolic(t,s,b)) { if (!getBoxType(b, inum, onum)) return false; *inum += 1; } 00116 00117 else if (isBoxPatternVar(t,a)) { return false; } 00118 00119 else if (isBoxPrim0(t)) { *inum = 0; *onum = 1; } 00120 else if (isBoxPrim1(t)) { *inum = 1; *onum = 1; } 00121 else if (isBoxPrim2(t)) { *inum = 2; *onum = 1; } 00122 else if (isBoxPrim3(t)) { *inum = 3; *onum = 1; } 00123 else if (isBoxPrim4(t)) { *inum = 4; *onum = 1; } 00124 else if (isBoxPrim5(t)) { *inum = 5; *onum = 1; } 00125 00126 else if (isBoxFFun(t,ff)) { *inum = ffarity(ff); *onum = 1; } 00127 else if (isBoxFConst(t)) { *inum = 0; *onum = 1; } 00128 else if (isBoxFVar(t)) { *inum = 0; *onum = 1; } 00129 00130 else if (isBoxButton(t)) { *inum = 0; *onum = 1; } 00131 else if (isBoxCheckbox(t)) { *inum = 0; *onum = 1; } 00132 else if (isBoxVSlider(t)) { *inum = 0; *onum = 1; } 00133 else if (isBoxHSlider(t)) { *inum = 0; *onum = 1; } 00134 else if (isBoxNumEntry(t)) { *inum = 0; *onum = 1; } 00135 else if (isBoxVGroup(t,l,a)){ return getBoxType(a, inum, onum); } 00136 else if (isBoxHGroup(t,l,a)){ return getBoxType(a, inum, onum); } 00137 else if (isBoxTGroup(t,l,a)){ return getBoxType(a, inum, onum); } 00138 00139 else if (isBoxVBargraph(t)) { *inum = 1; *onum = 1; } 00140 else if (isBoxHBargraph(t)) { *inum = 1; *onum = 1; } 00141 00142 else if (isBoxSeq(t, a, b)) { 00143 00144 int u,v,x,y; 00145 if (!getBoxType(a, &u, &v)) return false; 00146 if (!getBoxType(b, &x, &y)) return false; 00147 00148 if (v != x) { 00149 cerr << "Error in sequential composition (A:B)" << endl 00150 << "The number of outputs (" << v << ") of A = " << boxpp(a) << endl 00151 << "must be equal to the number of inputs (" << x << ") of B : " << boxpp(b) << endl; 00152 exit(1); 00153 } else { 00154 *inum = u; *onum = y; 00155 } 00156 00157 } else if (isBoxPar(t, a, b)) { 00158 00159 int u,v,x,y; 00160 if (!getBoxType(a, &u, &v)) return false; 00161 if (!getBoxType(b, &x, &y)) return false; 00162 00163 *inum = u+x; *onum = v+y; 00164 00165 } else if (isBoxSplit(t, a, b)) { 00166 00167 int u,v,x,y; 00168 if (!getBoxType(a, &u, &v)) return false; 00169 if (!getBoxType(b, &x, &y)) return false; 00170 00171 if (v == 0) { 00172 cerr << "Connection error in : " << boxpp(t) << endl 00173 << "The first expression : " << boxpp(a) << " has no outputs" << endl; 00174 exit(1); 00175 } 00176 00177 if (x == 0) { 00178 cerr << "Connection error in : " << boxpp(t) << endl 00179 << "The second expression : " << boxpp(b) << " has no inputs" << endl; 00180 exit(1); 00181 } 00182 00183 if (x % v != 0) { 00184 cerr << "Connection error in : " << boxpp(t) << endl 00185 << "The number of outputs " << v 00186 << " of the first expression should be a divisor of the number of inputs " << x 00187 << " of the second expression" << endl; 00188 exit(1); 00189 } 00190 00191 *inum = u; *onum = y; 00192 00193 } else if (isBoxMerge(t, a, b)) { 00194 00195 int u,v,x,y; 00196 if (!getBoxType(a, &u, &v)) return false; 00197 if (!getBoxType(b, &x, &y)) return false; 00198 00199 if (v == 0) { 00200 cerr << "Connection error in : " << boxpp(t) << endl 00201 << "The first expression : " << boxpp(a) << " has no outputs" << endl; 00202 exit(1); 00203 } 00204 00205 if (x == 0) { 00206 cerr << "Connection error in : " << boxpp(t) << endl 00207 << "The second expression : " << boxpp(b) << " has no inputs" << endl; 00208 exit(1); 00209 } 00210 00211 if (v % x != 0) { 00212 cerr << "Connection error in : " << boxpp(t) << endl 00213 << "The number of outputs " << v 00214 << " of the first expression should be a multiple of the number of inputs " << x 00215 << " of the second expression" << endl; 00216 exit(1); 00217 } 00218 00219 *inum = u; *onum = y; 00220 00221 } else if (isBoxRec(t, a, b)) { 00222 00223 int u,v,x,y; 00224 if (!getBoxType(a, &u, &v)) return false; 00225 if (!getBoxType(b, &x, &y)) return false; 00226 if ( (x > v) | (y > u) ) { 00227 cerr << "Connection error in : " << boxpp(t) << endl; 00228 if (x > v) cerr << "The number of outputs " << v 00229 << " of the first expression should be greater or equal \n to the number of inputs " << x 00230 << " of the second expression" << endl; 00231 if (y > u) cerr << "The number of inputs " << u 00232 << " of the first expression should be greater or equal \n to the number of outputs " << y 00233 << " of the second expression" << endl; 00234 exit(1); 00235 } 00236 *inum = max(0,u-y); *onum = v; 00237 00238 } else if (isBoxEnvironment(t)) { 00239 cerr << "Connection error : an environment is not a block-diagram : " << boxpp(t) << endl; 00240 exit(1); 00241 } else { 00242 cerr << "boxType() internal error : unrecognized box expression " << boxpp(t) << endl; 00243 exit(1); 00244 } 00245 return true; 00246 } 00247 00248 00249
1.8.0