Merge branch 'master' of https://scm.cri.ensmp.fr/git/Faustine
[Faustine.git] / interpretor / preprocessor / faust-0.9.47mr3 / compiler / signals / sigtype.cpp
1 /************************************************************************
2 ************************************************************************
3 FAUST compiler
4 Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
21
22
23
24 #include "tree.hh"
25 #include "sigtype.hh"
26 #include "property.hh"
27
28 int AudioType::gAllocationCount = 0;
29
30 bool SimpleType::isMaximal() const ///< true when type is maximal (and therefore can't change depending of hypothesis)
31 {
32 return (fNature==kReal)
33 && (fVariability==kSamp)
34 && (fComputability==kExec);
35
36 }
37
38
39 //------------------------------------------------------------------------------------
40 //
41 // Surcharges de l'operateur d'impression <<
42 //
43 //------------------------------------------------------------------------------------
44
45
46 ostream& operator<<(ostream& dst, const Type& t) { return t->print(dst);}
47
48 ostream& operator<<(ostream& dst, const SimpleType& t) { return t.print(dst); }
49
50 ostream& operator<<(ostream& dst, const TableType& t) { return t.print(dst); }
51
52 ostream& operator<<(ostream& dst, const TupletType& t) { return t.print(dst); }
53
54 ostream& operator<<(ostream& dst, const VectorType& t) { return t.print(dst); }
55
56
57 //------------------------------------------------------------------------------------
58 //
59 // Definition des methodes d'impression
60 //
61 //------------------------------------------------------------------------------------
62
63
64 /**
65 * Print the content of a simple type on a stream
66 */
67 ostream& SimpleType::print(ostream& dst) const
68 {
69 return dst << "NR"[nature()]
70 << "KB?S"[variability()]
71 << "CI?E"[computability()]
72 << "VS?TS"[vectorability()]
73 << "N?B"[boolean()]
74 << " " << fInterval;
75 }
76
77
78 /**
79 * Print the content of a table type on a stream
80 */
81 ostream& TableType::print(ostream& dst) const
82 {
83 dst << "KB?S"[variability()]
84 << "CI?E"[computability()]
85 << " " << fInterval
86 << ":Table(";
87 fContent->print(dst);
88 return dst << ')';
89 }
90
91
92 /**
93 * true when type is maximal (and therefore can't change depending of hypothesis)
94 */
95 bool TableType::isMaximal() const
96 {
97 return (fNature==kReal)
98 && (fVariability==kSamp)
99 && (fComputability==kExec);
100 }
101
102
103
104 /**
105 * Print the content of a tuplet of types on a stream
106 */
107 ostream& TupletType::print(ostream& dst) const
108 {
109 dst << "KB?S"[variability()]
110 << "CI?E"[computability()]
111 << " " << fInterval
112 << " : {";
113 string sep = "";
114 for (unsigned int i = 0; i < fComponents.size(); i++, sep="*") {
115 dst << sep;
116 fComponents[i]->print(dst);
117 }
118 dst << '}';
119 return dst;
120 }
121
122
123
124 /**
125 * Print the content of a vector type on a stream
126 */
127 ostream& VectorType::print(ostream& dst) const
128 {
129 dst << "vector[" << fSize << "," << fContent << "]";
130 return dst;
131 }
132
133
134 /**
135 * true when type is maximal (and therefore can't change depending of hypothesis)
136 */
137 bool TupletType::isMaximal() const
138 {
139 for (unsigned int i = 0; i < fComponents.size(); i++) {
140 if (! fComponents[i]->isMaximal()) return false;
141 }
142 return true;
143 }
144
145
146 //------------------------------------------------------------------------------------
147 //
148 // Construction des types
149 // t := p, table(t), t|t, t*t
150 //
151 //------------------------------------------------------------------------------------
152
153 // Essential predefined types
154
155 Type TINT = makeSimpleType(kInt, kKonst, kComp, kVect, kNum, interval());
156 Type TREAL = makeSimpleType(kReal, kKonst, kComp, kVect, kNum, interval());
157
158 Type TKONST = makeSimpleType(kInt, kKonst, kComp, kVect, kNum, interval());
159 Type TBLOCK = makeSimpleType(kInt, kBlock, kComp, kVect, kNum, interval());
160 Type TSAMP = makeSimpleType(kInt, kSamp, kComp, kVect, kNum, interval());
161
162 Type TCOMP = makeSimpleType(kInt, kKonst, kComp, kVect, kNum, interval());
163 Type TINIT = makeSimpleType(kInt, kKonst, kInit, kVect, kNum, interval());
164 Type TEXEC = makeSimpleType(kInt, kKonst, kExec, kVect, kNum, interval());
165
166 // more predefined types
167
168 Type TINPUT = makeSimpleType(kReal, kSamp, kExec, kVect, kNum, interval());
169 Type TGUI = makeSimpleType(kReal, kBlock,kExec, kVect, kNum, interval());
170 Type TGUI01 = makeSimpleType(kReal, kBlock,kExec, kVect, kNum, interval(0,1));
171 Type INT_TGUI = makeSimpleType(kInt, kBlock,kExec, kVect, kNum, interval());
172 //Type TREC = makeSimpleType(kInt, kSamp, kInit, kVect, kNum, interval()); // kVect ou kScal ?
173
174 // trying to accelerate type convergence
175 //Type TREC = TINT;
176 Type TREC = makeSimpleType(kInt, kSamp, kInit, kScal, kNum, interval()); // kVect ou kScal ?
177
178
179 Type operator| ( const Type& t1, const Type& t2)
180 {
181 SimpleType *st1, *st2;
182 TableType *tt1, *tt2;
183 TupletType *nt1, *nt2;
184
185 if ( (st1 = isSimpleType(t1)) && (st2 = isSimpleType(t2)) ) {
186
187 return makeSimpleType( st1->nature()|st2->nature(),
188 st1->variability()|st2->variability(),
189 st1->computability()|st2->computability(),
190 st1->vectorability()|st2->vectorability(),
191 st1->boolean()|st2->boolean(),
192 reunion(st1->getInterval(), st2->getInterval())
193 );
194
195 } else if ( (tt1 = isTableType(t1)) && (tt2 = isTableType(t2)) ) {
196
197 return makeTableType( tt1->content() | tt2->content() );
198
199 } else if ( (nt1 = isTupletType(t1)) && (nt2 = isTupletType(t2)) ) {
200
201 vector<Type> v;
202 int n = min(nt1->arity(), nt2->arity());
203 for (int i=0; i<n; i++) { v.push_back( (*nt1)[i] | (*nt2)[i]); }
204 return new TupletType( v );
205
206 } else {
207
208 vector<int> D1, D2, D3;
209 Type b1 = t1->dimensions(D1);
210 Type b2 = t2->dimensions(D2);
211 if (maxdimensions(D1, D2, D3)) {
212 Type b3 = b1|b2;
213 return makeVectorType(b3, D3);
214 }
215
216 cerr << "Error : trying to combine incompatible types, " << t1 << " and " << t2 << endl;
217 exit(1);
218 return 0;
219 }
220 }
221
222 bool operator== ( const Type& t1, const Type& t2)
223 {
224 SimpleType *st1, *st2;
225 TableType *tt1, *tt2;
226 TupletType *nt1, *nt2;
227 VectorType *vt1, *vt2;
228
229 if (t1->variability() != t2->variability()) return false;
230 if (t1->computability() != t2->computability()) return false;
231
232 if ( (st1 = isSimpleType(t1)) && (st2 = isSimpleType(t2)) )
233 return (st1->nature() == st2->nature())
234 && (st1->variability() == st2->variability())
235 && (st1->computability() == st2->computability())
236 && (st1->vectorability() == st2->vectorability())
237 && (st1->boolean() == st2->boolean())
238 && (st1->getInterval().lo == st2->getInterval().lo)
239 && (st1->getInterval().hi == st2->getInterval().hi)
240 && (st1->getInterval().valid == st2->getInterval().valid);
241 if ( (tt1 = isTableType(t1)) && (tt2 = isTableType(t2)) )
242 return tt1->content()== tt2->content();
243 if ( (nt1 = isTupletType(t1)) && (nt2 = isTupletType(t2)) ) {
244 int a1 = nt1->arity();
245 int a2 = nt2->arity();
246 if (a1 == a2) {
247 for (int i=0; i<a1; i++) { if ((*nt1)[i] != (*nt2)[i]) return false; }
248 return true;
249 } else {
250 return false;
251 }
252 }
253
254 // compare vector types
255 if ( (vt1 = isVectorType(t1)) && (vt2 = isVectorType(t2)) ) {
256 if (vt1->size() == vt2->size()) {
257 return vt1->content() == vt2->content();
258 } else {
259 return false;
260 }
261 }
262
263 // types are different
264 return false;
265 }
266
267 bool operator<= ( const Type& t1, const Type& t2)
268 {
269 return (t1|t2) == t2;
270 }
271
272
273
274 Type operator* (const Type& t1, const Type& t2)
275 {
276 vector<Type> v;
277
278 TupletType* nt1 = dynamic_cast<TupletType*>((AudioType*)t1);
279 TupletType* nt2 = dynamic_cast<TupletType*>((AudioType*)t2);
280
281 if (nt1) {
282 for (int i=0; i<nt1->arity(); i++) {
283 v.push_back((*nt1)[i]);
284 }
285 } else {
286 v.push_back(t1);
287 }
288
289 if (nt2) {
290 for (int i=0; i<nt2->arity(); i++) {
291 v.push_back((*nt2)[i]);
292 }
293 } else {
294 v.push_back(t2);
295 }
296 return new TupletType(v);
297 }
298
299
300 SimpleType* isSimpleType(AudioType* t) { return dynamic_cast<SimpleType*>(t); }
301 TableType* isTableType(AudioType* t) { return dynamic_cast<TableType*>(t); }
302 TupletType* isTupletType(AudioType* t) { return dynamic_cast<TupletType*>(t); }
303 VectorType* isVectorType(AudioType* t) { return dynamic_cast<VectorType*>(t); }
304
305
306
307 //--------------------------------------------------
308 // verification de type
309
310 Type checkInt(Type t)
311 {
312 // verifie que t est entier
313 SimpleType* st = isSimpleType(t);
314 if (st == 0 || st->nature() > kInt) {
315 cerr << "Error : checkInt failed for type " << t << endl;
316 exit(1);
317 }
318 return t;
319 }
320
321 Type checkKonst(Type t)
322 {
323 // verifie que t est constant
324 if (t->variability() > kKonst) {
325 cerr << "Error : checkKonst failed for type " << t << endl;
326 exit(1);
327 }
328 return t;
329 }
330
331 Type checkInit(Type t)
332 {
333 // verifie que t est connu a l'initialisation
334 if (t->computability() > kInit) {
335 cerr << "Error : checkInit failed for type " << t << endl;
336 exit(1);
337 }
338 return t;
339 }
340
341 Type checkIntParam(Type t)
342 {
343 return checkInit(checkKonst(checkInt(t)));
344 }
345
346 Type checkWRTbl(Type tbl, Type wr)
347 {
348 // verifie que wr est compatible avec le contenu de tbl
349 if (wr->nature() > tbl->nature()) {
350 cerr << "Error : checkWRTbl failed, the content of " << tbl << " is incompatible with " << wr << endl;
351 exit(1);
352 }
353 return tbl;
354 }
355
356 /**
357 \brief Check is a type is appropriate for a delay.
358 @return -1 if not appropriate, mxd (max delay) if appropriate
359
360 */
361 int checkDelayInterval(Type t)
362 {
363 interval i = t->getInterval();
364 if (i.valid && i.lo >= 0) {
365 return int(i.hi+0.5);
366 } else {
367 //cerr << "checkDelayInterval failed for : " << i << endl;
368 return -1;
369 }
370 }
371
372
373 // Donne le nom du type C correspondant �la nature d'un signal
374 string cType (Type t)
375 {
376 return (t->nature() == kInt) ? "int" : "float";
377 }
378
379
380
381 /*****************************************************************************
382 *
383 * codeAudioType(Type) -> Tree
384 * Code an audio type as a tree in order to benefit of memoization
385 *
386 *****************************************************************************/
387
388 // memoized type contruction
389
390 property<AudioType*> MemoizedTypes;
391
392
393 Sym SIMPLETYPE = symbol ("SimpleType");
394 Sym TABLETYPE = symbol ("TableType");
395 Sym TUPLETTYPE = symbol ("TupletType");
396 Sym VECTORTYPE = symbol ("VectorType");
397
398 static Tree codeSimpleType(SimpleType* st);
399 static Tree codeTableType(TableType* st);
400 static Tree codeTupletType(TupletType* st);
401 static Tree codeVectorType(VectorType* st);
402
403
404 /**
405 * codeAudioType(Type) -> Tree
406 * Code an audio type as a tree in order to benefit of memoization
407 * The type field (of the coded type) is used to store the audio
408 * type
409 */
410 Tree codeAudioType(AudioType* t)
411 {
412 SimpleType* st;
413 TableType* tt;
414 TupletType* nt;
415 VectorType* vt;
416
417 Tree r;
418
419 if ((r=t->getCode())) return r;
420
421 if ((st = isSimpleType(t))) {
422 r = codeSimpleType(st);
423 } else if ((tt = isTableType(t))) {
424 r = codeTableType(tt);
425 } else if ((nt = isTupletType(t))) {
426 r = codeTupletType(nt);
427 } else if ((vt = isVectorType(t))) {
428 r = codeVectorType(vt);
429 } else {
430 cerr << "ERROR in codeAudioType() : invalide pointer " << t << endl;
431 exit(1);
432 }
433
434 r->setType(t);
435 return r;
436
437 }
438
439
440 /**
441 * Code a simple audio type as a tree in order to benefit of memoization
442 */
443 static Tree codeSimpleType(SimpleType* st)
444 {
445 vector<Tree> elems;
446 elems.push_back(tree(st->nature()));
447 elems.push_back(tree(st->variability()));
448 elems.push_back(tree(st->computability()));
449 elems.push_back(tree(st->vectorability()));
450 elems.push_back(tree(st->boolean()));
451
452 elems.push_back(tree(st->getInterval().valid));
453 elems.push_back(tree(st->getInterval().lo));
454 elems.push_back(tree(st->getInterval().hi));
455
456 return CTree::make(SIMPLETYPE, elems);
457
458 }
459
460 AudioType* makeSimpleType(int n, int v, int c, int vec, int b, const interval& i)
461 {
462 SimpleType prototype(n,v,c,vec,b,i);
463 Tree code = codeAudioType(&prototype);
464
465 AudioType* t;
466 if (MemoizedTypes.get(code, t)) {
467 return t;
468 } else {
469 AudioType::gAllocationCount++;
470 t = new SimpleType(n,v,c,vec,b,i);
471 MemoizedTypes.set(code, t);
472 t->setCode(code);
473 return t;
474 }
475 }
476
477
478 /**
479 * Code a table type as a tree in order to benefit of memoization
480 */
481
482 static Tree codeTableType(TableType* tt)
483 {
484 return tree(TABLETYPE, codeAudioType(tt->content()));
485 }
486
487 AudioType* makeTableType(const Type& ct)
488 {
489 TableType prototype(ct);
490 Tree code = codeAudioType(&prototype);
491
492 AudioType* tt;
493 if (MemoizedTypes.get(code, tt)) {
494 return tt;
495 } else {
496 AudioType::gAllocationCount++;
497 tt = new TableType(ct);
498 MemoizedTypes.set(code, tt);
499 tt->setCode(code);
500 return tt;
501 }
502 }
503
504 AudioType* makeTableType(const Type& ct, int n, int v, int c, int vec, int b, const interval& i)
505 {
506 TableType prototype(ct,n,v,c,vec,b,i);
507 Tree code = codeAudioType(&prototype);
508
509 AudioType* tt;
510 if (MemoizedTypes.get(code, tt)) {
511 return tt;
512 } else {
513 AudioType::gAllocationCount++;
514 tt = new TableType(ct);
515 MemoizedTypes.set(code, tt);
516 tt->setCode(code);
517 return tt;
518 }
519 }
520
521 AudioType* makeTableType(const Type& ct, int n, int v, int c, int vec)
522 {
523 TableType prototype(ct,n,v,c,vec);
524 Tree code = codeAudioType(&prototype);
525
526 AudioType* tt;
527 if (MemoizedTypes.get(code, tt)) {
528 return tt;
529 } else {
530 AudioType::gAllocationCount++;
531 tt = new TableType(ct);
532 MemoizedTypes.set(code, tt);
533 tt->setCode(code);
534 return tt;
535 }
536 }
537
538
539 /**
540 * Code a tuplet type as a tree in order to benefit of memoization
541 */
542
543 static Tree codeTupletType(TupletType* nt)
544 {
545 vector<Tree> elems;
546 for (int i=0; i<nt->arity(); i++) {
547 elems.push_back(codeAudioType((*nt)[i]));
548 }
549 return CTree::make(TUPLETTYPE, elems);
550 }
551
552 AudioType* makeTupletType(const vector<Type>& vt)
553 {
554 TupletType prototype(vt);
555 Tree code = codeAudioType(&prototype);
556
557 AudioType* t;
558 if (MemoizedTypes.get(code, t)) {
559 return t;
560 } else {
561 AudioType::gAllocationCount++;
562 t = new TupletType(vt);
563 MemoizedTypes.set(code, t);
564 t->setCode(code);
565 return t;
566 }
567
568 }
569
570 AudioType* makeTupletType(const vector<Type>& vt, int n, int v, int c, int vec, int b, const interval& i)
571 {
572 TupletType prototype(vt,n,v,c,vec,b,i);
573 Tree code = codeAudioType(&prototype);
574
575 AudioType* t;
576 if (MemoizedTypes.get(code, t)) {
577 return t;
578 } else {
579 AudioType::gAllocationCount++;
580 t = new TupletType(vt,n,v,c,vec,b,i);
581 MemoizedTypes.set(code, t);
582 t->setCode(code);
583 return t;
584 }
585
586 }
587
588 /**
589 * Code a vector type as a tree in order to benefit of memoization
590 */
591
592 static Tree codeVectorType(VectorType* vt)
593 {
594 assert(vt);
595 //cerr << "codeVectorType(" << *vt << ")" << endl;
596 int i = vt->size();
597 return tree(VECTORTYPE, tree(i), codeAudioType(vt->content()));
598 }
599
600 Type makeVectorType(const Type& b, const vector<int>& dim)
601 {
602 Type r = b;
603 for (unsigned int i=0; i<dim.size(); i++) r = new VectorType(dim[i],r);
604 return r;
605 }
606
607
608 /**
609 * Returns true if D1 and D2 are compatible (one is the prefix of the other)).
610 * In this case D3 contains the longuest vector D1 or D2
611 */
612 bool maxdimensions(const vector<int>& D1, const vector<int>& D2, vector<int>& D3)
613 {
614 unsigned int n1 = D1.size();
615 unsigned int n2 = D2.size();
616 unsigned int i = 0;
617 while ( (i<n1) && (i<n2) && (D1[i]==D2[i]) ) i++;
618 if (i==n1) {
619 D3=D2;
620 return true;
621 } else if (i==n2) {
622 D3=D1;
623 return true;
624 } else {
625 return false;
626 }
627 }