FAUST compiler  0.9.9.6b8
sigtype.cpp
Go to the documentation of this file.
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 }