|
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 <iostream> 00027 #include <fstream> 00028 #include <time.h> 00029 00030 00031 #include "sigtype.hh" 00032 #include "sigprint.hh" 00033 #include "ppsig.hh" 00034 //#include "prim.hh" 00035 #include "prim2.hh" 00036 #include "tlib.hh" 00037 #include "sigtyperules.hh" 00038 #include "xtended.hh" 00039 #include "recursivness.hh" 00040 00041 00042 //-------------------------------------------------------------------------- 00043 // prototypes 00044 00045 static void setSigType(Tree sig, Type t); 00046 static Type getSigType(Tree sig); 00047 static Type initialRecType(Tree t); 00048 00049 static Type T(Tree term, Tree env); 00050 00051 static Type infereSigType(Tree term, Tree env); 00052 static Type infereFFType (Tree ff, Tree ls, Tree env); 00053 static Type infereFConstType (Tree type); 00054 static Type infereFVarType (Tree type); 00055 static Type infereRecType (Tree var, Tree body, Tree env); 00056 static Type infereReadTableType(Type tbl, Type ri); 00057 static Type infereWriteTableType(Type tbl, Type wi, Type wd); 00058 static Type infereProjType(Type t, int i, int vec); 00059 static Type infereXType(Tree sig, Tree env); 00060 static Type infereDocConstantTblType(Type size, Type init); 00061 static Type infereDocWriteTblType(Type size, Type init, Type widx, Type wsig); 00062 static Type infereDocAccessTblType(Type tbl, Type ridx); 00063 static interval arithmetic (int opcode, const interval& x, const interval& y); 00064 00065 00066 00067 // Uncomment to activate type inferrence tracing 00068 //#define TRACE(x) x 00069 #define TRACE(x) 0; 00070 00071 00075 static Tree NULLTYPEENV = tree(symbol("NullTypeEnv")); 00076 00077 static int countInferences; 00078 static int countMaximal; 00079 00080 00081 00087 void typeAnnotation(Tree sig) 00088 { 00089 Tree sl = symlist(sig); 00090 int n = len(sl); 00091 00092 vector<Tree> vrec, vdef; 00093 vector<Type> vtype; 00094 00095 //cerr << "Symlist " << *sl << endl; 00096 for (Tree l=sl; isList(l); l=tl(l)) { 00097 Tree id, body; 00098 assert(isRec(hd(l), id, body)); 00099 00100 vrec.push_back(hd(l)); 00101 vdef.push_back(body); 00102 } 00103 00104 // init recursive types 00105 for (int i=0; i<n; i++) { 00106 vtype.push_back(initialRecType(vdef[i])); 00107 } 00108 00109 assert (int(vrec.size())==n); 00110 assert (int(vdef.size())==n); 00111 assert (int(vtype.size())==n); 00112 00113 // find least fixpoint 00114 for (bool finished = false; !finished; ) { 00115 00116 // init recursive types 00117 CTree::startNewVisit(); 00118 for (int i=0; i<n; i++) { 00119 setSigType(vrec[i], vtype[i]); 00120 vrec[i]->setVisited(); 00121 } 00122 00123 // compute recursive types 00124 for (int i=0; i<n; i++) { 00125 vtype[i] = T(vdef[i], NULLTYPEENV); 00126 } 00127 00128 // check finished 00129 finished = true; 00130 for (int i=0; i<n; i++) { 00131 //cerr << i << "-" << *vrec[i] << ":" << *getSigType(vrec[i]) << " => " << *vtype[i] << endl; 00132 finished = finished & (getSigType(vrec[i]) == vtype[i]); 00133 } 00134 } 00135 00136 // type full term 00137 T(sig, NULLTYPEENV); 00138 } 00139 00140 00141 void annotationStatistics() 00142 { 00143 cerr << TABBER << "COUNT INFERENCE " << countInferences << " AT TIME " << clock()/CLOCKS_PER_SEC << 's' << endl; 00144 cerr << TABBER << "COUNT ALLOCATION " << AudioType::gAllocationCount << endl; 00145 cerr << TABBER << "COUNT MAXIMAL " << countMaximal << endl; 00146 } 00147 00154 Type getCertifiedSigType(Tree sig) 00155 { 00156 Type ty = getSigType(sig); 00157 assert(ty); 00158 return ty; 00159 } 00160 00161 00162 00163 /*********************************************** 00164 * Set and get the type property of a signal 00165 * (we suppose the signal have been previously 00166 * annotated with type information) 00167 ***********************************************/ 00168 00174 static void setSigType(Tree sig, Type t) 00175 { 00176 TRACE(cerr << TABBER << "SET FIX TYPE OF " << *sig << " TO TYPE " << *t << endl;) 00177 sig->setType(t); 00178 } 00179 00180 00185 static Type getSigType(Tree sig) 00186 { 00187 AudioType* ty = (AudioType*) sig->getType(); 00188 if (ty == 0) 00189 TRACE(cerr << TABBER << "GET FIX TYPE OF " << *sig << " HAS NO TYPE YET" << endl;) 00190 else 00191 TRACE(cerr << TABBER << "GET FIX TYPE OF " << *sig << " IS TYPE " << *ty << endl;) 00192 return ty; 00193 } 00194 00195 00196 00197 00198 00199 /************************************************************************** 00200 00201 Type Inference System 00202 00203 ***************************************************************************/ 00204 00205 /************************************************************************** 00206 00207 Infered Type property 00208 00209 ***************************************************************************/ 00210 00218 static Type T(Tree term, Tree ignoreenv) 00219 { 00220 TRACE(cerr << ++TABBER << "ENTER T() " << *term << endl;) 00221 00222 if (term->isAlreadyVisited()) { 00223 Type ty = getSigType(term); 00224 TRACE(cerr << --TABBER << "EXIT 1 T() " << *term << " AS TYPE " << *ty << endl); 00225 return ty; 00226 00227 } else { 00228 Type ty = infereSigType(term, ignoreenv); 00229 setSigType(term,ty); 00230 term->setVisited(); 00231 TRACE(cerr << --TABBER << "EXIT 2 T() " << *term << " AS TYPE " << *ty << endl); 00232 return ty; 00233 } 00234 } 00235 00236 00244 static Type infereSigType(Tree sig, Tree env) 00245 { 00246 int i; 00247 double r; 00248 Tree sel, s1, s2, s3, ff, id, ls, l, x, y, z, u, var, body, type, name, file; 00249 Tree label, cur, min, max, step; 00250 00251 countInferences++; 00252 00253 if ( getUserData(sig) ) return infereXType(sig, env); 00254 00255 else if (isSigInt(sig, &i)) { Type t = makeSimpleType(kInt, kKonst, kComp, kVect, kNum, interval(i)); 00256 /*sig->setType(t);*/ return t; } 00257 00258 else if (isSigReal(sig, &r)) { Type t = makeSimpleType(kReal, kKonst, kComp, kVect, kNum, interval(r)); 00259 /*sig->setType(t);*/ return t; } 00260 00261 else if (isSigInput(sig, &i)) { /*sig->setType(TINPUT);*/ return TINPUT; } 00262 00263 else if (isSigOutput(sig, &i, s1)) return sampCast(T(s1,env)); 00264 00265 else if (isSigDelay1(sig, s1)) { 00266 Type t = T(s1,env); 00267 return castInterval(sampCast(t), reunion(t->getInterval(), interval(0,0))); 00268 } 00269 00270 else if (isSigPrefix(sig, s1, s2)) { 00271 Type t1 = T(s1,env); 00272 Type t2 = T(s2,env); 00273 checkInit(t1); 00274 return castInterval(sampCast(t1|t2), reunion(t1->getInterval(), t2->getInterval())); 00275 } 00276 00277 else if (isSigFixDelay(sig, s1, s2)) { 00278 Type t1 = T(s1,env); 00279 Type t2 = T(s2,env); 00280 interval i = t2->getInterval(); 00281 00282 // cerr << "for sig fix delay : s1 = " 00283 // << t1 << ':' << ppsig(s1) << ", s2 = " 00284 // << t2 << ':' << ppsig(s2) << endl; 00285 if (!i.valid) { 00286 cerr << "ERROR : can't compute the min and max values of : " << ppsig(s2) << endl; 00287 cerr << " used in delay expression : " << ppsig(sig) << endl; 00288 cerr << " (probably a recursive signal)" << endl; 00289 exit(1); 00290 } else if (i.lo < 0) { 00291 cerr << "ERROR : possible negative values of : " << ppsig(s2) << endl; 00292 cerr << " used in delay expression : " << ppsig(sig) << endl; 00293 cerr << " " << i << endl; 00294 exit(1); 00295 } 00296 00297 return castInterval(sampCast(t1), reunion(t1->getInterval(), interval(0,0))); 00298 } 00299 00300 else if (isSigBinOp(sig, &i, s1, s2)) { 00301 //Type t = T(s1,env)|T(s2,env); 00302 Type t1 = T(s1,env); 00303 Type t2 = T(s2,env); 00304 Type t3 = castInterval(t1 | t2, arithmetic(i, t1->getInterval(), t2->getInterval())); 00305 //cerr <<"type rule for : " << ppsig(sig) << " -> " << *t3 << endl; 00306 //return (!gVectorSwitch && (i>=kGT) && (i<=kNE)) ? intCast(t3) : t3; // for comparaison operation the result is int 00307 return ((i>=kGT) && (i<=kNE)) ? intCast(t3) : t3; // for comparaison operation the result is int 00308 } 00309 00310 else if (isSigIntCast(sig, s1)) return intCast(T(s1,env)); 00311 00312 else if (isSigFloatCast(sig, s1)) return floatCast(T(s1,env)); 00313 00314 else if (isSigFFun(sig, ff, ls)) return infereFFType(ff,ls,env); 00315 00316 else if (isSigFConst(sig,type,name,file)) return infereFConstType(type); 00317 00318 else if (isSigFVar(sig,type,name,file)) return infereFVarType(type); 00319 00320 else if (isSigButton(sig)) { /*sig->setType(TGUI01);*/ return TGUI01; } 00321 00322 else if (isSigCheckbox(sig)) { /*sig->setType(TGUI01);*/ return TGUI01; } 00323 00324 else if (isSigVSlider(sig,label,cur,min,max,step)) 00325 return castInterval(TGUI,interval(tree2float(min),tree2float(max))); 00326 00327 else if (isSigHSlider(sig,label,cur,min,max,step)) 00328 return castInterval(TGUI,interval(tree2float(min),tree2float(max))); 00329 00330 else if (isSigNumEntry(sig,label,cur,min,max,step)) 00331 return castInterval(TGUI,interval(tree2float(min),tree2float(max))); 00332 00333 else if (isSigHBargraph(sig, l, x, y, s1)) return T(s1,env); 00334 00335 else if (isSigVBargraph(sig, l, x, y, s1)) return T(s1,env); 00336 00337 else if (isSigAttach(sig, s1, s2)) { T(s2,env); return T(s1,env); } 00338 00339 else if (isRec(sig, var, body)) return infereRecType(sig, body, env); 00340 00341 else if (isProj(sig, &i, s1)) return infereProjType(T(s1,env),i,kScal); 00342 00343 else if (isSigTable(sig, id, s1, s2)) { checkInt(checkInit(T(s1,env))); return makeTableType(checkInit(T(s2,env))); } 00344 00345 else if (isSigWRTbl(sig, id, s1, s2, s3)) return infereWriteTableType(T(s1,env), T(s2,env), T(s3,env)); 00346 00347 else if (isSigRDTbl(sig, s1, s2)) return infereReadTableType(T(s1,env), T(s2,env)); 00348 00349 else if (isSigGen(sig, s1)) return T(s1,NULLTYPEENV); 00350 00351 else if ( isSigDocConstantTbl(sig, x, y) ) return infereDocConstantTblType(T(x,env), T(y,env)); 00352 else if ( isSigDocWriteTbl(sig,x,y,z,u) ) return infereDocWriteTblType(T(x,env), T(y,env), T(z,env), T(u,env)); 00353 else if ( isSigDocAccessTbl(sig, x, y) ) return infereDocAccessTblType(T(x,env), T(y,env)); 00354 00355 else if (isSigSelect2(sig,sel,s1,s2)) { 00356 SimpleType *st1, *st2, *stsel; 00357 00358 st1 = isSimpleType(T(s1,env)); 00359 st2 = isSimpleType(T(s2,env)); 00360 stsel = isSimpleType(T(sel,env)); 00361 00362 return makeSimpleType( st1->nature()|st2->nature(), 00363 st1->variability()|st2->variability()|stsel->variability(), 00364 st1->computability()|st2->computability()|stsel->computability(), 00365 st1->vectorability()|st2->vectorability()|stsel->vectorability(), 00366 st1->boolean()|st2->boolean(), 00367 reunion(st1->getInterval(), st2->getInterval()) 00368 ); 00369 } 00370 00371 else if (isSigSelect3(sig,sel,s1,s2,s3)) { return T(sel,env)|T(s1,env)|T(s2,env)|T(s3,env); } 00372 00373 else if (isNil(sig)) { Type t = new TupletType(); /*sig->setType(t);*/ return t; } 00374 00375 else if (isList(sig)) { return T( hd(sig),env ) * T( tl(sig),env ); } 00376 00377 // unrecognized signal here 00378 fprintf(stderr, "ERROR infering signal type : unrecognized signal : "); print(sig, stderr); fprintf(stderr, "\n"); 00379 exit(1); 00380 return 0; 00381 } 00382 00383 00384 00388 static Type infereProjType(Type t, int i, int vec) 00389 { 00390 TupletType* tt = isTupletType(t); 00391 if (tt == 0) { 00392 cerr << "ERROR infering projection type, not a tuplet type : " << t << endl; 00393 exit(1); 00394 } 00395 //return (*tt)[i] ->promoteVariability(t->variability()) 00396 // ->promoteComputability(t->computability()); 00397 Type temp = (*tt)[i] ->promoteVariability(t->variability()) 00398 ->promoteComputability(t->computability()) 00399 ->promoteVectorability(vec/*t->vectorability()*/); 00400 //->promoteBooleanity(t->boolean()); 00401 00402 if(vec==kVect) temp = vecCast(temp); 00403 //cerr << "infereProjType(" << t << ',' << i << ',' << vec << ")" << " -> " << temp << endl; 00404 00405 return temp; 00406 } 00407 00408 00409 00413 static Type infereWriteTableType(Type tbl, Type wi, Type wd) 00414 { 00415 TableType* tt = isTableType(tbl); 00416 if (tt == 0) { 00417 cerr << "ERROR infering write table type, wrong table type : " << tbl << endl; 00418 exit(1); 00419 } 00420 SimpleType* st = isSimpleType(wi); 00421 if (st == 0 || st->nature() > kInt) { 00422 cerr << "ERROR infering write table type, wrong write index type : " << wi << endl; 00423 exit(1); 00424 } 00425 00426 int n = tt->nature(); 00427 int v = wi->variability() | wd->variability(); 00428 int c = wi->computability() | wd->computability(); 00429 int vec = wi->vectorability() | wd->vectorability(); 00430 00431 return makeTableType(tt->content(), n, v, c, vec); 00432 00433 } 00434 00435 00436 00440 static Type infereReadTableType(Type tbl, Type ri) 00441 { 00442 TableType* tt = isTableType(tbl); 00443 if (tt == 0) { 00444 cerr << "ERROR infering read table type, wrong table type : " << tbl << endl; 00445 exit(1); 00446 } 00447 SimpleType* st = isSimpleType(ri); 00448 if (st == 0 || st->nature() > kInt) { 00449 cerr << "ERROR infering read table type, wrong write index type : " << ri << endl; 00450 exit(1); 00451 } 00452 00453 Type temp = tt->content()->promoteVariability(ri->variability()|tt->variability()) 00454 ->promoteComputability(ri->computability()|tt->computability()) 00455 ->promoteVectorability(ri->vectorability()|tt->vectorability()) 00456 ->promoteBoolean(ri->boolean()|tt->boolean()) 00457 ; 00458 00459 return temp; 00460 00461 } 00462 00463 00464 static Type infereDocConstantTblType(Type size, Type init) 00465 { 00466 checkKonst(checkInt(checkInit(size))); 00467 00468 return init; 00469 } 00470 00471 static Type infereDocWriteTblType(Type size, Type init, Type widx, Type wsig) 00472 { 00473 checkKonst(checkInt(checkInit(size))); 00474 00475 Type temp = init 00476 ->promoteVariability(kSamp) // difficult to tell, therefore kSamp to be safe 00477 ->promoteComputability(widx->computability()|wsig->computability()) 00478 ->promoteVectorability(kScal) // difficult to tell, therefore kScal to be safe 00479 ->promoteNature(wsig->nature()) // nature of the initial and written signal 00480 ->promoteBoolean(wsig->boolean()) // booleanity of the initial and written signal 00481 ; 00482 return temp; 00483 } 00484 00485 static Type infereDocAccessTblType(Type tbl, Type ridx) 00486 { 00487 Type temp = tbl 00488 ->promoteVariability(ridx->variability()) 00489 ->promoteComputability(ridx->computability()) 00490 ->promoteVectorability(ridx->vectorability()) 00491 ; 00492 return temp; 00493 } 00494 00495 00500 static Type initialRecType(Tree t) 00501 { 00502 assert (isList(t)); 00503 00504 vector<Type> v; 00505 while (isList(t)) { v.push_back(TREC); t = tl(t); }; 00506 return new TupletType(v); 00507 } 00508 00509 00514 static Type infereRecType (Tree sig, Tree body, Tree env) 00515 { 00516 assert(false); // we should not come here 00517 return 0; 00518 } 00519 00520 00524 static Type infereFFType (Tree ff, Tree ls, Tree env) 00525 { 00526 // une primitive externe ne peut pas se calculer au plus tot qu'a 00527 // l'initialisation. Sa variabilite depend de celle de ses arguments 00528 // sauf si elle n'en pas, auquel cas on considere que c'est comme 00529 // rand() c'est a dire que le resultat varie a chaque appel. 00530 if (ffarity(ff)==0) { 00531 // case of functions like rand() 00532 return makeSimpleType(ffrestype(ff),kSamp,kInit,kVect,kNum, interval()); 00533 } else { 00534 // otherwise variability and computability depends 00535 // arguments (OR of all arg types) 00536 Type t = makeSimpleType(kInt,kKonst,kInit,kVect,kNum, interval()); 00537 while (isList(ls)) { t = t|T(hd(ls),env); ls=tl(ls); } 00538 // but the result type is defined by the function 00539 00540 //return t; 00541 return makeSimpleType( ffrestype(ff), 00542 t->variability(), 00543 t->computability(), 00544 t->vectorability(), 00545 t->boolean(), 00546 interval() ); 00547 } 00548 } 00549 00550 00554 static Type infereFConstType (Tree type) 00555 { 00556 // une constante externe ne peut pas se calculer au plus tot qu'a 00557 // l'initialisation. Elle est constante, auquel cas on considere que c'est comme 00558 // rand() c'est a dire que le resultat varie a chaque appel. 00559 return makeSimpleType(tree2int(type),kKonst,kInit,kVect,kNum, interval()); 00560 } 00561 00562 00566 static Type infereFVarType (Tree type) 00567 { 00568 // une variable externe ne peut pas se calculer au plus tot qu'a 00569 // l'execution. Elle est varie par blocs comme les éléments d'interface utilisateur. 00570 return makeSimpleType(tree2int(type),kBlock,kExec,kVect,kNum, interval()); 00571 } 00572 00573 00577 static Type infereXType(Tree sig, Tree env) 00578 { 00579 //cerr << "infereXType :" << endl; 00580 //cerr << "infereXType of " << *sig << endl; 00581 xtended* p = (xtended*) getUserData(sig); 00582 vector<Type> vt; 00583 00584 for (int i = 0; i < sig->arity(); i++) vt.push_back(T(sig->branch(i), env)); 00585 return p->infereSigType(vt); 00586 } 00587 00588 00589 00590 00591 00600 static interval arithmetic (int opcode, const interval& x, const interval& y) 00601 { 00602 switch (opcode) { 00603 case kAdd: return x+y; 00604 case kSub: return x-y; 00605 case kMul: return x*y; 00606 case kDiv: return x/y; 00607 case kRem: return x%y; 00608 case kLsh: return x<<y; 00609 case kRsh: return x>>y; 00610 case kGT: return x>y; 00611 case kLT: return x<y; 00612 case kGE: return x>=y; 00613 case kLE: return x<=y; 00614 case kEQ: return x==y; 00615 case kNE: return x!=y; 00616 case kAND: return x&y; 00617 case kOR: return x|y; 00618 case kXOR: return x^y; 00619 default: 00620 cerr << "Unrecognized opcode : " << opcode << endl; 00621 exit(1); 00622 } 00623 00624 return interval(); 00625 }
1.8.0