|
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 "tree.hh" 00025 #include "sigtype.hh" 00026 #include "property.hh" 00027 00028 int AudioType::gAllocationCount = 0; 00029 00030 bool SimpleType::isMaximal() const 00031 { 00032 return (fNature==kReal) 00033 && (fVariability==kSamp) 00034 && (fComputability==kExec); 00035 00036 } 00037 00038 00039 //------------------------------------------------------------------------------------ 00040 // 00041 // Surcharges de l'operateur d'impression << 00042 // 00043 //------------------------------------------------------------------------------------ 00044 00045 00046 ostream& operator<<(ostream& dst, const Type& t) { return t->print(dst);} 00047 00048 ostream& operator<<(ostream& dst, const SimpleType& t) { return t.print(dst); } 00049 00050 ostream& operator<<(ostream& dst, const TableType& t) { return t.print(dst); } 00051 00052 ostream& operator<<(ostream& dst, const TupletType& t) { return t.print(dst); } 00053 00054 00055 //------------------------------------------------------------------------------------ 00056 // 00057 // Definition des methodes d'impression 00058 // 00059 //------------------------------------------------------------------------------------ 00060 00061 00065 ostream& SimpleType::print(ostream& dst) const 00066 { 00067 return dst << "NR"[nature()] 00068 << "KB?S"[variability()] 00069 << "CI?E"[computability()] 00070 << "VS?TS"[vectorability()] 00071 << "N?B"[boolean()] 00072 << " " << fInterval; 00073 } 00074 00075 00079 ostream& TableType::print(ostream& dst) const 00080 { 00081 dst << "KB?S"[variability()] 00082 << "CI?E"[computability()] 00083 << " " << fInterval 00084 << ":Table("; 00085 fContent->print(dst); 00086 return dst << ')'; 00087 } 00088 00089 00093 bool TableType::isMaximal() const 00094 { 00095 return (fNature==kReal) 00096 && (fVariability==kSamp) 00097 && (fComputability==kExec); 00098 } 00099 00100 00101 00105 ostream& TupletType::print(ostream& dst) const 00106 { 00107 dst << "KB?S"[variability()] 00108 << "CI?E"[computability()] 00109 << " " << fInterval 00110 << " : {"; 00111 string sep = ""; 00112 for (unsigned int i = 0; i < fComponents.size(); i++, sep="*") { 00113 dst << sep; 00114 fComponents[i]->print(dst); 00115 } 00116 dst << '}'; 00117 return dst; 00118 } 00119 00120 00124 bool TupletType::isMaximal() const 00125 { 00126 for (unsigned int i = 0; i < fComponents.size(); i++) { 00127 if (! fComponents[i]->isMaximal()) return false; 00128 } 00129 return true; 00130 } 00131 00132 00133 //------------------------------------------------------------------------------------ 00134 // 00135 // Construction des types 00136 // t := p, table(t), t|t, t*t 00137 // 00138 //------------------------------------------------------------------------------------ 00139 00140 // Essential predefined types 00141 00142 Type TINT = makeSimpleType(kInt, kKonst, kComp, kVect, kNum, interval()); 00143 Type TREAL = makeSimpleType(kReal, kKonst, kComp, kVect, kNum, interval()); 00144 00145 Type TKONST = makeSimpleType(kInt, kKonst, kComp, kVect, kNum, interval()); 00146 Type TBLOCK = makeSimpleType(kInt, kBlock, kComp, kVect, kNum, interval()); 00147 Type TSAMP = makeSimpleType(kInt, kSamp, kComp, kVect, kNum, interval()); 00148 00149 Type TCOMP = makeSimpleType(kInt, kKonst, kComp, kVect, kNum, interval()); 00150 Type TINIT = makeSimpleType(kInt, kKonst, kInit, kVect, kNum, interval()); 00151 Type TEXEC = makeSimpleType(kInt, kKonst, kExec, kVect, kNum, interval()); 00152 00153 // more predefined types 00154 00155 Type TINPUT = makeSimpleType(kReal, kSamp, kExec, kVect, kNum, interval()); 00156 Type TGUI = makeSimpleType(kReal, kBlock,kExec, kVect, kNum, interval()); 00157 Type TGUI01 = makeSimpleType(kReal, kBlock,kExec, kVect, kNum, interval(0,1)); 00158 Type INT_TGUI = makeSimpleType(kInt, kBlock,kExec, kVect, kNum, interval()); 00159 //Type TREC = makeSimpleType(kInt, kSamp, kInit, kVect, kNum, interval()); // kVect ou kScal ? 00160 00161 // trying to accelerate type convergence 00162 //Type TREC = TINT; 00163 Type TREC = makeSimpleType(kInt, kSamp, kInit, kScal, kNum, interval()); // kVect ou kScal ? 00164 00165 00166 Type operator| ( const Type& t1, const Type& t2) 00167 { 00168 SimpleType *st1, *st2; 00169 TableType *tt1, *tt2; 00170 TupletType *nt1, *nt2; 00171 00172 if ( (st1 = isSimpleType(t1)) && (st2 = isSimpleType(t2)) ) { 00173 00174 return makeSimpleType( st1->nature()|st2->nature(), 00175 st1->variability()|st2->variability(), 00176 st1->computability()|st2->computability(), 00177 st1->vectorability()|st2->vectorability(), 00178 st1->boolean()|st2->boolean(), 00179 reunion(st1->getInterval(), st2->getInterval()) 00180 ); 00181 00182 } else if ( (tt1 = isTableType(t1)) && (tt2 = isTableType(t2)) ) { 00183 00184 return makeTableType( tt1->content() | tt2->content() ); 00185 00186 } else if ( (nt1 = isTupletType(t1)) && (nt2 = isTupletType(t2)) ) { 00187 00188 vector<Type> v; 00189 int n = min(nt1->arity(), nt2->arity()); 00190 for (int i=0; i<n; i++) { v.push_back( (*nt1)[i] | (*nt2)[i]); } 00191 return new TupletType( v ); 00192 00193 } else { 00194 00195 cerr << "Error : trying to combine incompatible types, " << t1 << " and " << t2 << endl; 00196 exit(1); 00197 return 0; 00198 } 00199 } 00200 00201 bool operator== ( const Type& t1, const Type& t2) 00202 { 00203 SimpleType *st1, *st2; 00204 TableType *tt1, *tt2; 00205 TupletType *nt1, *nt2; 00206 00207 if (t1->variability() != t2->variability()) return false; 00208 if (t1->computability() != t2->computability()) return false; 00209 00210 if ( (st1 = isSimpleType(t1)) && (st2 = isSimpleType(t2)) ) 00211 return (st1->nature() == st2->nature()) 00212 && (st1->variability() == st2->variability()) 00213 && (st1->computability() == st2->computability()) 00214 && (st1->vectorability() == st2->vectorability()) 00215 && (st1->boolean() == st2->boolean()) 00216 && (st1->getInterval().lo == st2->getInterval().lo) 00217 && (st1->getInterval().hi == st2->getInterval().hi) 00218 && (st1->getInterval().valid == st2->getInterval().valid); 00219 if ( (tt1 = isTableType(t1)) && (tt2 = isTableType(t2)) ) 00220 return tt1->content()== tt2->content(); 00221 if ( (nt1 = isTupletType(t1)) && (nt2 = isTupletType(t2)) ) { 00222 int a1 = nt1->arity(); 00223 int a2 = nt2->arity(); 00224 if (a1 == a2) { 00225 for (int i=0; i<a1; i++) { if ((*nt1)[i] != (*nt2)[i]) return false; } 00226 return true; 00227 } else { 00228 return false; 00229 } 00230 } 00231 return false; 00232 } 00233 00234 bool operator<= ( const Type& t1, const Type& t2) 00235 { 00236 return (t1|t2) == t2; 00237 } 00238 00239 00240 00241 Type operator* (const Type& t1, const Type& t2) 00242 { 00243 vector<Type> v; 00244 00245 TupletType* nt1 = dynamic_cast<TupletType*>((AudioType*)t1); 00246 TupletType* nt2 = dynamic_cast<TupletType*>((AudioType*)t2); 00247 00248 if (nt1) { 00249 for (int i=0; i<nt1->arity(); i++) { 00250 v.push_back((*nt1)[i]); 00251 } 00252 } else { 00253 v.push_back(t1); 00254 } 00255 00256 if (nt2) { 00257 for (int i=0; i<nt2->arity(); i++) { 00258 v.push_back((*nt2)[i]); 00259 } 00260 } else { 00261 v.push_back(t2); 00262 } 00263 return new TupletType(v); 00264 } 00265 00266 00267 SimpleType* isSimpleType(AudioType* t) { return dynamic_cast<SimpleType*>(t); } 00268 TableType* isTableType(AudioType* t) { return dynamic_cast<TableType*>(t); } 00269 TupletType* isTupletType(AudioType* t) { return dynamic_cast<TupletType*>(t); } 00270 00271 00272 00273 //-------------------------------------------------- 00274 // verification de type 00275 00276 Type checkInt(Type t) 00277 { 00278 // verifie que t est entier 00279 SimpleType* st = isSimpleType(t); 00280 if (st == 0 || st->nature() > kInt) { 00281 cerr << "Error : checkInt failed for type " << t << endl; 00282 exit(1); 00283 } 00284 return t; 00285 } 00286 00287 Type checkKonst(Type t) 00288 { 00289 // verifie que t est constant 00290 if (t->variability() > kKonst) { 00291 cerr << "Error : checkKonst failed for type " << t << endl; 00292 exit(1); 00293 } 00294 return t; 00295 } 00296 00297 Type checkInit(Type t) 00298 { 00299 // verifie que t est connu a l'initialisation 00300 if (t->computability() > kInit) { 00301 cerr << "Error : checkInit failed for type " << t << endl; 00302 exit(1); 00303 } 00304 return t; 00305 } 00306 00307 Type checkIntParam(Type t) 00308 { 00309 return checkInit(checkKonst(checkInt(t))); 00310 } 00311 00312 Type checkWRTbl(Type tbl, Type wr) 00313 { 00314 // verifie que wr est compatible avec le contenu de tbl 00315 if (wr->nature() > tbl->nature()) { 00316 cerr << "Error : checkWRTbl failed, the content of " << tbl << " is incompatible with " << wr << endl; 00317 exit(1); 00318 } 00319 return tbl; 00320 } 00321 00327 int checkDelayInterval(Type t) 00328 { 00329 interval i = t->getInterval(); 00330 if (i.valid && i.lo >= 0) { 00331 return int(i.hi+0.5); 00332 } else { 00333 //cerr << "checkDelayInterval failed for : " << i << endl; 00334 return -1; 00335 } 00336 } 00337 00338 00339 // Donne le nom du type C correspondant �la nature d'un signal 00340 string cType (Type t) 00341 { 00342 return (t->nature() == kInt) ? "int" : "float"; 00343 } 00344 00345 00346 00347 /***************************************************************************** 00348 * 00349 * codeAudioType(Type) -> Tree 00350 * Code an audio type as a tree in order to benefit of memoization 00351 * 00352 *****************************************************************************/ 00353 00354 // memoized type contruction 00355 00356 property<AudioType*> MemoizedTypes; 00357 00358 00359 Sym SIMPLETYPE = symbol ("SimpleType"); 00360 Sym TABLETYPE = symbol ("TableType"); 00361 Sym TUPLETTYPE = symbol ("TupletType"); 00362 00363 static Tree codeSimpleType(SimpleType* st); 00364 static Tree codeTableType(TableType* st); 00365 static Tree codeTupletType(TupletType* st); 00366 00367 00374 Tree codeAudioType(AudioType* t) 00375 { 00376 SimpleType *st; 00377 TableType *tt; 00378 TupletType *nt; 00379 00380 Tree r; 00381 00382 if ((r=t->getCode())) return r; 00383 00384 if ((st = isSimpleType(t))) { 00385 r = codeSimpleType(st); 00386 } else if ((tt = isTableType(t))) { 00387 r = codeTableType(tt); 00388 } else if ((nt = isTupletType(t))) { 00389 r = codeTupletType(nt); 00390 } else { 00391 cerr << "ERROR in codeAudioType() : invalide pointer " << t << endl; 00392 exit(1); 00393 } 00394 00395 r->setType(t); 00396 return r; 00397 00398 } 00399 00400 00404 static Tree codeSimpleType(SimpleType* st) 00405 { 00406 vector<Tree> elems; 00407 elems.push_back(tree(st->nature())); 00408 elems.push_back(tree(st->variability())); 00409 elems.push_back(tree(st->computability())); 00410 elems.push_back(tree(st->vectorability())); 00411 elems.push_back(tree(st->boolean())); 00412 00413 elems.push_back(tree(st->getInterval().valid)); 00414 elems.push_back(tree(st->getInterval().lo)); 00415 elems.push_back(tree(st->getInterval().hi)); 00416 00417 return CTree::make(SIMPLETYPE, elems); 00418 00419 } 00420 00421 AudioType* makeSimpleType(int n, int v, int c, int vec, int b, const interval& i) 00422 { 00423 SimpleType prototype(n,v,c,vec,b,i); 00424 Tree code = codeAudioType(&prototype); 00425 00426 AudioType* t; 00427 if (MemoizedTypes.get(code, t)) { 00428 return t; 00429 } else { 00430 AudioType::gAllocationCount++; 00431 t = new SimpleType(n,v,c,vec,b,i); 00432 MemoizedTypes.set(code, t); 00433 t->setCode(code); 00434 return t; 00435 } 00436 } 00437 00438 00443 static Tree codeTableType(TableType* tt) 00444 { 00445 return tree(TABLETYPE, codeAudioType(tt->content())); 00446 } 00447 00448 AudioType* makeTableType(const Type& ct) 00449 { 00450 TableType prototype(ct); 00451 Tree code = codeAudioType(&prototype); 00452 00453 AudioType* tt; 00454 if (MemoizedTypes.get(code, tt)) { 00455 return tt; 00456 } else { 00457 AudioType::gAllocationCount++; 00458 tt = new TableType(ct); 00459 MemoizedTypes.set(code, tt); 00460 tt->setCode(code); 00461 return tt; 00462 } 00463 } 00464 00465 AudioType* makeTableType(const Type& ct, int n, int v, int c, int vec, int b, const interval& i) 00466 { 00467 TableType prototype(ct,n,v,c,vec,b,i); 00468 Tree code = codeAudioType(&prototype); 00469 00470 AudioType* tt; 00471 if (MemoizedTypes.get(code, tt)) { 00472 return tt; 00473 } else { 00474 AudioType::gAllocationCount++; 00475 tt = new TableType(ct); 00476 MemoizedTypes.set(code, tt); 00477 tt->setCode(code); 00478 return tt; 00479 } 00480 } 00481 00482 AudioType* makeTableType(const Type& ct, int n, int v, int c, int vec) 00483 { 00484 TableType prototype(ct,n,v,c,vec); 00485 Tree code = codeAudioType(&prototype); 00486 00487 AudioType* tt; 00488 if (MemoizedTypes.get(code, tt)) { 00489 return tt; 00490 } else { 00491 AudioType::gAllocationCount++; 00492 tt = new TableType(ct); 00493 MemoizedTypes.set(code, tt); 00494 tt->setCode(code); 00495 return tt; 00496 } 00497 } 00498 00499 00504 static Tree codeTupletType(TupletType* nt) 00505 { 00506 vector<Tree> elems; 00507 for (int i=0; i<nt->arity(); i++) { 00508 elems.push_back(codeAudioType((*nt)[i])); 00509 } 00510 return CTree::make(TUPLETTYPE, elems); 00511 } 00512 00513 AudioType* makeTupletType(const vector<Type>& vt) 00514 { 00515 TupletType prototype(vt); 00516 Tree code = codeAudioType(&prototype); 00517 00518 AudioType* t; 00519 if (MemoizedTypes.get(code, t)) { 00520 return t; 00521 } else { 00522 AudioType::gAllocationCount++; 00523 t = new TupletType(vt); 00524 MemoizedTypes.set(code, t); 00525 t->setCode(code); 00526 return t; 00527 } 00528 00529 } 00530 00531 AudioType* makeTupletType(const vector<Type>& vt, int n, int v, int c, int vec, int b, const interval& i) 00532 { 00533 TupletType prototype(vt,n,v,c,vec,b,i); 00534 Tree code = codeAudioType(&prototype); 00535 00536 AudioType* t; 00537 if (MemoizedTypes.get(code, t)) { 00538 return t; 00539 } else { 00540 AudioType::gAllocationCount++; 00541 t = new TupletType(vt,n,v,c,vec,b,i); 00542 MemoizedTypes.set(code, t); 00543 t->setCode(code); 00544 return t; 00545 } 00546 00547 }
1.8.0