|
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 #include "propagate.hh" 00025 #include "prim2.hh" 00026 #include <assert.h> 00027 #include "ppbox.hh" 00028 #include "xtended.hh" 00029 #include "labels.hh" 00030 #include "Text.hh" 00031 #include "ppsig.hh" 00032 #include "names.hh" 00033 00034 //extern bool gPrintDocSwitch; 00035 //static siglist realPropagate (Tree slotenv, Tree path, Tree box, const siglist& lsig); 00036 00037 00039 00045 00046 00047 00049 siglist mix(const siglist& lsig, int nbus) 00050 { 00051 int nlines = lsig.size(); 00052 00053 siglist dst(nbus); 00054 00055 for (int b=0; b<nbus; b++) { 00056 Tree t = (b<nlines) ? lsig[b] : sigInt(0); 00057 for (int i=b+nbus; i<nlines; i+=nbus) { 00058 t = sigAdd(t, lsig[i]); 00059 } 00060 dst[b] = t; 00061 } 00062 return dst; 00063 } 00064 00066 siglist split(const siglist& inputs, int nbus) 00067 { 00068 int nlines = inputs.size(); 00069 00070 siglist outputs(nbus); 00071 00072 for (int b=0; b<nbus; b++) { 00073 outputs[b] = inputs[b % nlines]; 00074 } 00075 return outputs; 00076 } 00077 00079 siglist makeSigProjList (Tree t, int n) 00080 { 00081 siglist l(n); 00082 for (int i = 0; i < n; i++) l[i] = sigDelay0(sigProj(i, t)); 00083 return l; 00084 } 00085 00087 siglist makeMemSigProjList (Tree t, int n) 00088 { 00089 siglist l(n); 00090 for (int i = 0; i < n; i++) l[i] = sigDelay1(sigProj(i, t)); 00091 return l; 00092 } 00093 00094 00096 siglist makeSigInputList (int n) 00097 { 00098 siglist l(n); 00099 for (int i = 0; i < n; i++) l[i] = sigInput(i); 00100 return l; 00101 } 00102 00103 inline siglist makeList(Tree t) 00104 { 00105 siglist l(1); 00106 l[0] = t; 00107 return l; 00108 } 00109 00110 siglist listRange(const siglist& l, int i, int j) 00111 { 00112 siglist r(j-i); 00113 for (int x = i; x < j; x++) r[x-i] = l[x]; 00114 return r; 00115 } 00116 00117 siglist listConcat(const siglist& a, const siglist& b) 00118 { 00119 int n1 = a.size(); 00120 int n2 = b.size(); 00121 siglist r(n1+n2); 00122 00123 for (int x=0; x<n1; x++) r[x] = a[x]; 00124 for (int x=0; x<n2; x++) r[x+n1] = b[x]; 00125 return r; 00126 } 00127 00131 Tree listConvert(const siglist& a) 00132 { 00133 int n = a.size(); 00134 Tree t=nil; 00135 while (n--) t = cons(a[n],t); 00136 return t; 00137 } 00138 00139 // siglist listConvertBack(Tree l) 00140 // { 00141 // siglist r; 00142 // while (!isNil(l)) { r.push_back(hd(l)); l = tl(l); } 00143 // return r; 00144 // } 00145 00146 siglist listLift(const siglist& l) 00147 { 00148 int n = l.size(); 00149 siglist r(n); 00150 00151 for(int i = 0; i<n; i++) r[i] = lift(l[i]); 00152 return r; 00153 } 00154 00155 static int gDummyInput = 10000; 00156 00166 /* 00167 // for debugging purposes 00168 00169 siglist realpropagate (Tree slotenv, Tree path, Tree box, const siglist& lsig); 00170 00171 siglist propagate (Tree slotenv, Tree path, Tree box, const siglist& lsig) 00172 { 00173 cerr << "propagate in " << boxpp(box) << endl; 00174 for (int i=0; i<lsig.size(); i++) { cerr << " -> signal " << i << " : " << *(lsig[i]) << endl; } 00175 cerr << endl; 00176 return realpropagate (slotenv, path, box, lsig); 00177 } 00178 */ 00179 00183 //siglist propagate (Tree slotenv, Tree path, Tree box, const siglist& lsig) 00184 //{ 00185 // siglist S = realPropagate(slotenv, path, box, lsig); 00186 // 00187 // if (gPrintDocSwitch) { 00188 // Tree id; 00189 // if (lsig.size()==0 && getDefNameProperty(box, id)) { 00190 // string nickname = defName2NickName(tree2str(id)); 00191 // //setSigListNickName(S, nickname); 00192 // } 00193 // } 00194 // 00195 // return S; 00196 //} 00197 00198 //siglist realPropagate (Tree slotenv, Tree path, Tree box, const siglist& lsig) 00199 siglist propagate (Tree slotenv, Tree path, Tree box, const siglist& lsig) 00200 { 00201 int i; 00202 double r; 00203 prim0 p0; 00204 prim1 p1; 00205 prim2 p2; 00206 prim3 p3; 00207 prim4 p4; 00208 prim5 p5; 00209 00210 Tree t1, t2, ff, label, cur, min, max, step, type, name, file, slot, body; 00211 00212 00213 xtended* xt = (xtended*)getUserData(box); 00214 00215 // Extended Primitives 00216 00217 if (xt) { 00218 assert(lsig.size() == xt->arity()); 00219 return makeList(xt->computeSigOutput(lsig)); 00220 } 00221 00222 // Numbers and Constants 00223 00224 else if (isBoxInt(box, &i)) { 00225 assert(lsig.size()==0); 00226 return makeList(sigInt(i)); 00227 } 00228 else if (isBoxReal(box, &r)) { 00229 assert(lsig.size()==0); 00230 return makeList(sigReal(r)); 00231 } 00232 00233 else if (isBoxFConst(box, type, name, file)) { 00234 assert(lsig.size()==0); 00235 return makeList(sigFConst(type, name, file)); 00236 } 00237 00238 else if (isBoxFVar(box, type, name, file)) { 00239 assert(lsig.size()==0); 00240 return makeList(sigFVar(type, name, file)); 00241 } 00242 00243 // Wire and Cut 00244 00245 else if (isBoxCut(box)) { 00246 assert(lsig.size()==1); 00247 return siglist(); 00248 } 00249 00250 else if (isBoxWire(box)) { 00251 assert(lsig.size()==1); 00252 return lsig; 00253 } 00254 00255 // Slots and Symbolic Boxes 00256 00257 else if (isBoxSlot(box)) { 00258 Tree sig; 00259 assert(lsig.size()==0); 00260 if (!searchEnv(box,sig,slotenv)) { 00261 // test YO simplification des diagrames 00262 //fprintf(stderr, "propagate : internal error (slot undefined)\n"); 00263 //exit(1); 00264 sig = sigInput(++gDummyInput); 00265 } 00266 return makeList(sig); 00267 } 00268 00269 else if (isBoxSymbolic(box, slot, body)) { 00270 assert(lsig.size()>0); 00271 return propagate(pushEnv(slot,lsig[0],slotenv), path, body, listRange(lsig, 1, lsig.size())); 00272 } 00273 00274 // Primitives 00275 00276 else if (isBoxPrim0(box, &p0)) { 00277 assert(lsig.size()==0); 00278 return makeList( p0() ); 00279 } 00280 00281 else if (isBoxPrim1(box, &p1)) { 00282 assert(lsig.size()==1); 00283 return makeList( p1(lsig[0]) ); 00284 } 00285 00286 else if (isBoxPrim2(box, &p2)) { 00287 // printf("prim2 recoit : "); print(lsig); printf("\n"); 00288 assert(lsig.size()==2); 00289 return makeList( p2(lsig[0],lsig[1]) ); 00290 } 00291 00292 else if (isBoxPrim3(box, &p3)) { 00293 assert(lsig.size()==3); 00294 return makeList( p3(lsig[0],lsig[1],lsig[2]) ); 00295 } 00296 00297 else if (isBoxPrim4(box, &p4)) { 00298 assert(lsig.size()==4); 00299 return makeList( p4(lsig[0],lsig[1],lsig[2],lsig[3]) ); 00300 } 00301 00302 else if (isBoxPrim5(box, &p5)) { 00303 assert(lsig.size()==5); 00304 return makeList( p5(lsig[0],lsig[1],lsig[2],lsig[3],lsig[4]) ); 00305 } 00306 00307 else if (isBoxFFun(box, ff)) { 00308 //cerr << "propagate en boxFFun of arity " << ffarity(ff) << endl; 00309 assert(int(lsig.size())==ffarity(ff)); 00310 return makeList(sigFFun(ff, listConvert(lsig))); 00311 } 00312 00313 // User Interface Widgets 00314 00315 else if (isBoxButton(box, label)) { 00316 assert(lsig.size()==0); 00317 return makeList(sigButton(normalizePath(cons(label, path)))); 00318 } 00319 00320 else if (isBoxCheckbox(box, label)) { 00321 assert(lsig.size()==0); 00322 return makeList(sigCheckbox(normalizePath(cons(label, path)))); 00323 } 00324 00325 else if (isBoxVSlider(box, label, cur, min, max, step)) { 00326 assert(lsig.size()==0); 00327 return makeList(sigVSlider(normalizePath(cons(label, path)), cur, min, max, step)); 00328 } 00329 00330 else if (isBoxHSlider(box, label, cur, min, max, step)) { 00331 assert(lsig.size()==0); 00332 return makeList(sigHSlider(normalizePath(cons(label, path)), cur, min, max, step)); 00333 } 00334 00335 else if (isBoxNumEntry(box, label, cur, min, max, step)) { 00336 assert(lsig.size()==0); 00337 return makeList(sigNumEntry(normalizePath(cons(label, path)), cur, min, max, step)); 00338 } 00339 00340 else if (isBoxVBargraph(box, label, min, max)) { 00341 assert(lsig.size()==1); 00342 return makeList(sigVBargraph(normalizePath(cons(label, path)), min, max, lsig[0])); 00343 } 00344 00345 else if (isBoxHBargraph(box, label, min, max)) { 00346 assert(lsig.size()==1); 00347 return makeList(sigHBargraph(normalizePath(cons(label, path)), min, max, lsig[0])); 00348 } 00349 00350 // User Interface Groups 00351 00352 else if (isBoxVGroup(box, label, t1)) { 00353 return propagate(slotenv,cons(cons(tree(0),label), path), t1, lsig); 00354 } 00355 00356 else if (isBoxHGroup(box, label, t1)) { 00357 return propagate(slotenv, cons(cons(tree(1),label), path), t1, lsig); 00358 } 00359 00360 else if (isBoxTGroup(box, label, t1)) { 00361 return propagate(slotenv, cons(cons(tree(2),label), path), t1, lsig); 00362 } 00363 00364 // Block Diagram Composition Algebra 00365 00366 else if (isBoxSeq(box, t1, t2)) { 00367 int in1, out1, in2, out2; 00368 getBoxType(t1, &in1, &out1); 00369 getBoxType(t2, &in2, &out2); 00370 00371 assert(out1==in2); 00372 00373 if (out1 == in2) { 00374 return propagate(slotenv, path, t2, propagate(slotenv, path,t1,lsig)); 00375 } else if (out1 > in2) { 00376 siglist lr = propagate(slotenv, path, t1,lsig); 00377 return listConcat(propagate(slotenv, path, t2, listRange(lr, 0, in2)), listRange(lr, in2, out1)); 00378 } else { 00379 return propagate(slotenv, path, t2, listConcat( propagate(slotenv, path, t1, listRange(lsig,0,in1)), listRange(lsig,in1,in1+in2-out1) ) ); 00380 } 00381 } 00382 00383 else if (isBoxPar(box, t1, t2)) { 00384 int in1, out1, in2, out2; 00385 getBoxType(t1, &in1, &out1); 00386 getBoxType(t2, &in2, &out2); 00387 00388 return listConcat( propagate(slotenv, path, t1, listRange(lsig, 0, in1)), 00389 propagate(slotenv, path, t2, listRange(lsig, in1, in1+in2)) ); 00390 } 00391 00392 else if (isBoxSplit(box, t1, t2)) { 00393 int in1, out1, in2, out2; 00394 getBoxType(t1, &in1, &out1); 00395 getBoxType(t2, &in2, &out2); 00396 00397 siglist l1 = propagate(slotenv, path, t1, lsig); 00398 siglist l2 = split(l1, in2); 00399 return propagate(slotenv, path, t2, l2); 00400 } 00401 00402 else if (isBoxMerge(box, t1, t2)) { 00403 int in1, out1, in2, out2; 00404 getBoxType(t1, &in1, &out1); 00405 getBoxType(t2, &in2, &out2); 00406 00407 siglist l1 = propagate(slotenv, path, t1, lsig); 00408 siglist l2 = mix(l1, in2); 00409 return propagate(slotenv, path, t2, l2); 00410 } 00411 /* 00412 else if (isBoxRec(box, t1, t2)) { 00413 int in1, out1, in2, out2; 00414 getBoxType(t1, &in1, &out1); 00415 getBoxType(t2, &in2, &out2); 00416 00417 siglist l0 = makeSigProjList(ref(1), in2); 00418 siglist l1 = propagate(slotenv, path, t2, l0); 00419 siglist l2 = propagate(slotenv, path, t1, listConcat(l1,listLift(lsig))); 00420 Tree g = rec(listConvert(l2)); 00421 return makeSigProjList(g, out1); 00422 } 00423 */ 00424 else if (isBoxRec(box, t1, t2)) { 00425 // Bug Corrected 00426 int in1, out1, in2, out2; 00427 getBoxType(t1, &in1, &out1); 00428 getBoxType(t2, &in2, &out2); 00429 00430 Tree slotenv2 = lift(slotenv); // the environment must also be lifted 00431 00432 siglist l0 = makeMemSigProjList(ref(1), in2); 00433 siglist l1 = propagate(slotenv2, path, t2, l0); 00434 siglist l2 = propagate(slotenv2, path, t1, listConcat(l1,listLift(lsig))); 00435 Tree g = rec(listConvert(l2)); 00436 return makeSigProjList(g, out1); 00437 } 00438 00439 cout << "ERROR in file " << __FILE__ << ':' << __LINE__ << ", unrecognised box expression : " << boxpp(box) << endl; 00440 exit(1); 00441 return siglist(); 00442 } 00443 00444 00445 Tree boxPropagateSig (Tree path, Tree box, const siglist& lsig) 00446 { 00447 return listConvert(propagate(nil, path, box, lsig)); 00448 } 00449
1.8.0