|
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 <stdio.h> 00025 #include <assert.h> 00026 #include "list.hh" 00027 #include "signals.hh" 00028 #include "sigtype.hh" 00029 #include "recursivness.hh" 00030 #include "sigtyperules.hh" 00031 #include "sigorderrules.hh" 00032 #include "sigprint.hh" 00033 #include "ppsig.hh" 00034 #include "simplify.hh" 00035 #include "num.hh" 00036 #include "xtended.hh" 00037 #include <map> 00038 #include "compatibility.hh" 00039 00040 #include "normalize.hh" 00041 00042 #undef TRACE 00043 00044 // declarations 00045 Tree SIMPLIFIED = tree(symbol("sigSimplifiedProp")); 00046 //static Tree binequiv (Tree sig, int opnum, Tree a, Tree b); 00047 static Tree simplification (Tree sig); 00048 static Tree sigMap (Tree key, tfun f, Tree t); 00049 00050 static Tree traced_simplification(Tree sig) 00051 { 00052 assert(sig); 00053 #ifdef TRACE 00054 cerr << ++TABBER << "Start simplification of : " << ppsig(sig) << endl; 00055 /* 00056 fprintf(stderr, "\nStart simplification of : "); 00057 printSignal(sig, stderr); 00058 fprintf(stderr, "\n"); 00059 */ 00060 #endif 00061 Tree r = simplification(sig); 00062 assert(r!=0); 00063 #ifdef TRACE 00064 cerr << --TABBER << "Simplification of : " << ppsig(sig) << " Returns : " << ppsig(r) << endl; 00065 /* 00066 fprintf(stderr, "Simplification of : "); 00067 printSignal(sig, stderr); 00068 fprintf(stderr, " -> "); 00069 printSignal(r, stderr); 00070 fprintf(stderr, "\n"); 00071 */ 00072 #endif 00073 return r; 00074 } 00075 00076 Tree simplify (Tree sig) 00077 { 00078 return sigMap(SIMPLIFIED, traced_simplification, sig); 00079 } 00080 00081 00082 // Implementation 00083 00084 static Tree simplification (Tree sig) 00085 { 00086 assert(sig); 00087 int opnum; 00088 Tree t1, t2, t3, t4; 00089 00090 xtended* xt = (xtended*) getUserData(sig); 00091 // primitive elements 00092 if (xt) 00093 { 00094 //return 3; 00095 vector<Tree> args; 00096 for (int i=0; i<sig->arity(); i++) { args.push_back( sig->branch(i) ); } 00097 00098 // to avoid negative power to further normalization 00099 if (xt != gPowPrim) { 00100 return xt->computeSigOutput(args); 00101 } else { 00102 return normalizeAddTerm(xt->computeSigOutput(args)); 00103 } 00104 00105 } else if (isSigBinOp(sig, &opnum, t1, t2)) { 00106 00107 BinOp* op = gBinOpTable[opnum]; 00108 00109 Node n1 = t1->node(); 00110 Node n2 = t2->node(); 00111 00112 if (isNum(n1) && isNum(n2)) return tree(op->compute(n1,n2)); 00113 00114 else if (op->isLeftNeutral(n1)) return t2; 00115 00116 else if (op->isRightNeutral(n2)) return t1; 00117 00118 else return normalizeAddTerm(sig); 00119 00120 } else if (isSigDelay1(sig, t1)) { 00121 00122 return normalizeDelay1Term (t1); 00123 00124 } else if (isSigFixDelay(sig, t1, t2)) { 00125 00126 return normalizeFixedDelayTerm (t1, t2); 00127 00128 } else if (isSigIntCast(sig, t1)) { 00129 00130 Tree tx; 00131 int i; 00132 double x; 00133 Node n1 = t1->node(); 00134 00135 if (isInt(n1, &i)) return t1; 00136 if (isDouble(n1, &x)) return tree(int(x)); 00137 if (isSigIntCast(t1, tx)) return t1; 00138 00139 return sig; 00140 00141 } else if (isSigFloatCast(sig, t1)) { 00142 00143 Tree tx; 00144 int i; 00145 double x; 00146 Node n1 = t1->node(); 00147 00148 if (isInt(n1, &i)) return tree(double(i)); 00149 if (isDouble(n1, &x)) return t1; 00150 if (isSigFloatCast(t1, tx)) return t1; 00151 00152 return sig; 00153 00154 } else if (isSigSelect2(sig, t1, t2, t3)){ 00155 00156 Node n1 = t1->node(); 00157 00158 if (isZero(n1)) return t2; 00159 if (isNum(n1)) return t3; 00160 00161 if (t2==t3) return t2; 00162 00163 return sig; 00164 00165 } else if (isSigSelect3(sig, t1, t2, t3, t4)){ 00166 00167 Node n1 = t1->node(); 00168 00169 if (isZero(n1)) return t2; 00170 if (isOne(n1)) return t3; 00171 if (isNum(n1)) return t4; 00172 00173 if (t3==t4) return simplification(sigSelect2(t1,t2,t3)); 00174 00175 return sig; 00176 00177 } else { 00178 00179 return sig; 00180 } 00181 } 00182 00187 static Tree sigMap (Tree key, tfun f, Tree t) 00188 { 00189 //printf("start sigMap\n"); 00190 Tree p,id,body; 00191 00192 if (getProperty(t, key, p)) { 00193 00194 return (isNil(p)) ? t : p; // truc pour eviter les boucles 00195 00196 } else if (isRec(t, id, body)) { 00197 00198 setProperty(t, key, nil); // avoid infinite loop 00199 return rec(id, sigMap(key, f, body)); 00200 00201 } else { 00202 00203 Tree r1=nil; 00204 switch (t->arity()) { 00205 00206 case 0 : 00207 r1 = t; 00208 break; 00209 case 1 : 00210 r1 = tree(t->node(), sigMap(key,f,t->branch(0))); 00211 break; 00212 case 2 : 00213 r1 = tree(t->node(), sigMap(key,f,t->branch(0)), sigMap(key,f,t->branch(1))); 00214 break; 00215 case 3 : 00216 r1 = tree(t->node(), sigMap(key,f,t->branch(0)), sigMap(key,f,t->branch(1)), 00217 sigMap(key,f,t->branch(2))); 00218 break; 00219 case 4 : 00220 r1 = tree(t->node(), sigMap(key,f,t->branch(0)), sigMap(key,f,t->branch(1)), 00221 sigMap(key,f,t->branch(2)), sigMap(key,f,t->branch(3))); 00222 break; 00223 } 00224 Tree r2 = f(r1); 00225 if (r2 == t) { 00226 setProperty(t, key, nil); 00227 } else { 00228 setProperty(t, key, r2); 00229 } 00230 return r2; 00231 } 00232 } 00233 00234 00235 00236 00237 00243 static Tree sigMapRename (Tree key, Tree env, tfun f, Tree t) 00244 { 00245 //printf("start sigMap\n"); 00246 Tree p,id,body; 00247 00248 if (getProperty(t, key, p)) { 00249 00250 return (isNil(p)) ? t : p; // truc pour eviter les boucles 00251 00252 } else if (isRec(t, id, body)) { 00253 00254 assert(isRef(t,id)); // controle temporaire 00255 00256 Tree id2; 00257 if (searchEnv(id, id2, env)) { 00258 // déjà en cours de visite de cette recursion 00259 return ref(id2); 00260 } else { 00261 // premiere visite de cette recursion 00262 id2 = tree(Node(unique("renamed"))); 00263 Tree body2 = sigMapRename(key, pushEnv(id, id2, env), f, body); 00264 return rec(id2,body2); 00265 } 00266 00267 } else { 00268 00269 Tree r1=nil; 00270 switch (t->arity()) { 00271 00272 case 0 : 00273 r1 = t; 00274 break; 00275 case 1 : 00276 r1 = tree(t->node(), sigMapRename(key,env,f,t->branch(0))); 00277 break; 00278 case 2 : 00279 r1 = tree(t->node(), sigMapRename(key,env,f,t->branch(0)), 00280 sigMapRename(key,env,f,t->branch(1))); 00281 break; 00282 case 3 : 00283 r1 = tree(t->node(), sigMapRename(key,env,f,t->branch(0)), 00284 sigMapRename(key,env,f,t->branch(1)), 00285 sigMapRename(key,env,f,t->branch(2))); 00286 break; 00287 case 4 : 00288 r1 = tree(t->node(), sigMapRename(key,env,f,t->branch(0)), 00289 sigMapRename(key,env,f,t->branch(1)), 00290 sigMapRename(key,env,f,t->branch(2)), 00291 sigMapRename(key,env,f,t->branch(3))); 00292 break; 00293 } 00294 Tree r2 = f(r1); 00295 if (r2 == t) { 00296 setProperty(t, key, nil); 00297 } else { 00298 setProperty(t, key, r2); 00299 } 00300 return r2; 00301 } 00302 } 00303 00304 #if 0 00305 static void eraseProperties (Tree key, Tree t) 00306 { 00307 //printf("start sigMap\n"); 00308 Tree p,id,body; 00309 00310 if (getProperty(t, key, p)) { 00311 // already erased, nothing to do 00312 00313 } else if (isRec(t, id, body)) { 00314 t->clearProperties(); 00315 Tree r=rec(id, body); 00316 assert(r==t); 00317 setProperty(t, key, nil); // avoid infinite loop 00318 eraseProperties(key, body); 00319 00320 } else { 00321 00322 for (int i=0; i<t->arity(); i++) { 00323 eraseProperties(key,t->branch(i)); 00324 } 00325 } 00326 } 00327 00328 void eraseAllProperties(Tree t) 00329 { 00330 cerr << "begin eraseAllProperties" << endl; 00331 eraseProperties(tree(Node(unique("erase_"))), t); 00332 cerr << "end eraseAllProperties" << endl; 00333 } 00334 #endif 00335 00341 Tree DOCTABLES = tree(symbol("DocTablesProp")); 00342 00343 static Tree docTableConverter (Tree sig); 00344 00345 static Tree NULLENV = tree(symbol("NullRenameEnv")); 00346 00347 Tree docTableConvertion (Tree sig) 00348 { 00349 Tree r = sigMapRename(DOCTABLES, NULLENV, docTableConverter, sig); 00350 return r; 00351 } 00352 00353 00354 // Implementation 00355 00356 static Tree docTableConverter (Tree sig) 00357 { 00358 Tree tbl, tbl2, id, id2, size, igen, isig, ridx, widx, wsig; 00359 00360 if (isSigRDTbl(sig, tbl, ridx)) { 00361 // we are in a table to convert 00362 if (isSigTable(tbl, id, size, igen)) { 00363 // it's a read only table 00364 assert(isSigGen(igen, isig)); 00365 return sigDocAccessTbl(sigDocConstantTbl(size,isig),ridx); 00366 } else { 00367 // it's a read write table 00368 assert(isSigWRTbl(tbl,id,tbl2,widx,wsig)); 00369 assert(isSigTable(tbl2, id2, size, igen)); 00370 assert(isSigGen(igen, isig)); 00371 00372 return sigDocAccessTbl(sigDocWriteTbl(size,isig,widx,wsig),ridx); 00373 } 00374 00375 } else { 00376 // nothing to convert 00377 return sig; 00378 } 00379 }
1.8.0