1 /************************************************************************
2  ************************************************************************
3     FAUST compiler
4     Copyright (C) 2003-2018 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 #ifndef _SigType_
23 #define _SigType_
24 
25 #include <iostream>
26 #include <string>
27 #include <vector>
28 #include "garbageable.hh"
29 #include "interval.hh"
30 #include "smartpointer.hh"
31 #include "tree.hh"
32 
33 /*********************************************************************
34  *
35  *						Type System for FAUST
36  *
37  *	<type> 			::= <simpletype> ||  table(<type>)
38  *			 		 	||  <type>|<type>  || <type>*<type>
39  *	<simpletype>	::= <nature><variability><computability><vectorability>||<boolean>
40  *	<nature>		::= TINT || TREAL
41  *	<variability>	::= TKONST || TBLOCK || TSAMP
42  *	<computability>	::= TCOMP  || TINIT  || TEXEC
43  *	<vectorability> ::= KVECT  || KSCAL  || KTRUESCAL
44  *	<boolean>       ::= KNUM   || KBOOL
45  *
46  **********************************************************************/
47 
48 //--------------------------------------------------
49 // simple types quality
50 
51 enum { kInt = 0, kReal = 1 };  ///< nature : integer or floating point values
52 enum {
53     kNum  = 0,
54     kBool = 1
55 };  ///< boolean : when a signal stands for a boolean value ( while being of c-type int or float )
56 enum { kKonst = 0, kBlock = 1, kSamp = 3 };  ///< variability : how fast values change
57 enum { kComp = 0, kInit = 1, kExec = 3 };    ///< computability : when values are available
58 enum {
59     kVect     = 0,
60     kScal     = 1,
61     kTrueScal = 3 /*, kIndex = 4*/
62 };  ///< vectorability: when a signal can be vectorized (actually, only kVect and kScal matter; kTrueScal and kIndex
63     ///< don't denote types but are here to simplify code generation)
64 
65 /*---------------------------------------------------------------------
66 
67     AbstractType :
68     The root class for SimpleType, TableType and TupletType
69 
70     Type :
71     A smartPointer to type
72 
73 ----------------------------------------------------------------------*/
74 
75 using namespace std;
76 
77 class AudioType;
78 
79 typedef P<AudioType> Type;
80 
81 /**
82  * The Root class for all audio data types.
83  * All audio types have a "variability" (how fast the values change) and
84  * a "computability" (when the values are available). Simple types have
85  * also a "nature" (integer or floating point).
86  */
87 
88 class AudioType : public virtual Garbageable {
89    protected:
90     int fNature;         ///< the kind of data represented
91     int fVariability;    ///< how fast values change
92     int fComputability;  ///< when are values available
93     int fVectorability;  ///< when a signal can be vectorized
94     int fBoolean;        ///< when a signal stands for a boolean value
95 
96     interval fInterval;  ///< Minimal and maximal values the signal can take
97     res      fRes;       ///< Resolution (fixed-point)
98     Tree     fCode;      ///< Tree representation (for memoization purposes)
99 
100    public:
AudioType(int n,int v,int c,int vec=kVect,int b=kNum,interval i=interval (),res r=res ())101     AudioType(int n, int v, int c, int vec = kVect, int b = kNum, interval i = interval(), res r = res())
102         : fNature(n), fVariability(v), fComputability(c), fVectorability(vec), fBoolean(b), fInterval(i), fRes(r), fCode(0)
103     {
104     }                        ///< constructs an abstract audio type
~AudioType()105     virtual ~AudioType() {}  ///< not really useful here, but make compiler happier
106 
nature() const107     int nature() const { return fNature; }  ///< returns the kind of values (integre or floating point)
variability() const108     int variability() const
109     {
110         return fVariability;
111     }  ///< returns how fast values change (constant, by blocks, by samples)
computability() const112     int computability() const
113     {
114         return fComputability;
115     }  ///< returns when values are available (compilation, initialisation, execution)
vectorability() const116     int vectorability() const { return fVectorability; }  ///< returns when a signal can be vectorized
boolean() const117     int boolean() const { return fBoolean; }              ///< returns when a signal stands for a boolean value
118 
getInterval() const119     interval getInterval() const { return fInterval; }  ///< returns the interval (min dn max values) of a signal
getRes() const120     res getRes() const { return fRes; } ///< return the resolution of the signal (fixed)
121 
setCode(Tree code)122     void setCode(Tree code) { fCode = code; }  ///< returns the interval (min dn max values) of a signal
getCode()123     Tree getCode() { return fCode; }           ///< returns the interval (min dn max values) of a signal
124 
125     virtual AudioType* promoteNature(int n)        = 0;  ///< promote the nature of a type
126     virtual AudioType* promoteVariability(int n)   = 0;  ///< promote the variability of a type
127     virtual AudioType* promoteComputability(int n) = 0;  ///< promote the computability of a type
128     virtual AudioType* promoteVectorability(int n) = 0;  ///< promote the vectorability of a type
129     virtual AudioType* promoteBoolean(int n)       = 0;  ///< promote the booleanity of a type
130     virtual AudioType* promoteInterval(const interval& i) = 0; ///< promote the interval of a type
131 
132     virtual ostream& print(ostream& dst) const = 0;  ///< print nicely a type
133     ///< true when type is maximal (and therefore can't change depending of hypothesis)
134     virtual bool isMaximal() const = 0;
135 
136    protected:
setInterval(const interval & r)137     void setInterval(const interval& r) { fInterval = r; }
138 };
139 
140 // printing
operator <<(ostream & s,const AudioType & n)141 inline ostream& operator<<(ostream& s, const AudioType& n)
142 {
143     return n.print(s);
144 }
145 
146 /**
147  * Return the nature of a vector of types.
148  */
mergenature(const vector<Type> & v)149 inline int mergenature(const vector<Type>& v)
150 {
151     int r = 0;
152     for (unsigned int i = 0; i < v.size(); i++) r |= v[i]->nature();
153     return r;
154 }
155 
156 /**
157  * Return the variability of a vector of types.
158  */
mergevariability(const vector<Type> & v)159 inline int mergevariability(const vector<Type>& v)
160 {
161     int r = 0;
162     for (unsigned int i = 0; i < v.size(); i++) r |= v[i]->variability();
163     return r;
164 }
165 
166 /**
167  * Return the computability of a vector of types.
168  */
mergecomputability(const vector<Type> & v)169 inline int mergecomputability(const vector<Type>& v)
170 {
171     int r = 0;
172     for (unsigned int i = 0; i < v.size(); i++) r |= v[i]->computability();
173     return r;
174 }
175 
176 /**
177  * Return the vectorability of a vector of types.
178  */
mergevectorability(const vector<Type> & v)179 inline int mergevectorability(const vector<Type>& v)
180 {
181     int r = 0;
182     for (unsigned int i = 0; i < v.size(); i++) r |= v[i]->vectorability();
183     return r;
184 }
185 
186 /**
187  * Return the booleanity of a vector of types.
188  */
mergeboolean(const vector<Type> & v)189 inline int mergeboolean(const vector<Type>& v)
190 {
191     int r = 0;
192     for (unsigned int i = 0; i < v.size(); i++) r |= v[i]->boolean();
193     return r;
194 }
195 
196 /**
197  * Return the interval of a vector of types.
198  */
mergeinterval(const vector<Type> & v)199 inline interval mergeinterval(const vector<Type>& v)
200 {
201     if (v.size() == 0) {
202         return interval();
203     } else {
204         double lo = 0, hi = 0;
205         for (unsigned int i = 0; i < v.size(); i++) {
206             interval r = v[i]->getInterval();
207             if (!r.valid) return r;
208             if (i == 0) {
209                 lo = r.lo;
210                 hi = r.hi;
211             } else {
212                 lo = min(lo, r.lo);
213                 hi = max(hi, r.hi);
214             }
215         }
216         return interval(lo, hi);
217     }
218 }
219 
220 AudioType* makeSimpleType(int n, int v, int c, int vec, int b, const interval& i);
221 AudioType* makeSimpleType(int n, int v, int c, int vec, int b, const interval& i, const res& lsb);
222 //didn't use a default arg, would have created a cyclic dependancy with global.hh
223 
224 AudioType* makeTableType(const Type& ct);
225 AudioType* makeTableType(const Type& ct, int n, int v, int c, int vec);
226 AudioType* makeTableType(const Type& ct, int n, int v, int c, int vec, int b, const interval& i);
227 
228 AudioType* makeTupletType(const vector<Type>& vt);
229 AudioType* makeTupletType(const vector<Type>& vt, int n, int v, int c, int vec, int b, const interval& i);
230 
231 /**
232  * The type of a simple numeric audio signal.
233  * Beside a computability and a variability, SimpleTypes have
234  * a "nature" indicating if they represent an integer or floating
235  * point audio signals.
236  */
237 class SimpleType : public AudioType {
238    public:
SimpleType(int n,int v,int c,int vec,int b,const interval & i,const res & lsb)239     SimpleType(int n, int v, int c, int vec, int b, const interval& i, const res& lsb) : AudioType(n, v, c, vec, b, i, lsb)
240     {
241         // cerr << "new simple type " << i << " -> " << *this << endl;
242     }  ///< constructs a SimpleType from a nature a variability and a computability
243 
244     virtual ostream& print(ostream& dst) const;  ///< print a SimpleType
245 
promoteNature(int n)246     virtual AudioType* promoteNature(int n)
247     {
248         return makeSimpleType(n | fNature, fVariability, fComputability, fVectorability, fBoolean, fInterval);
249     }  ///< promote the nature of a type
promoteVariability(int v)250     virtual AudioType* promoteVariability(int v)
251     {
252         return makeSimpleType(fNature, v | fVariability, fComputability, fVectorability, fBoolean, fInterval);
253     }  ///< promote the variability of a type
promoteComputability(int c)254     virtual AudioType* promoteComputability(int c)
255     {
256         return makeSimpleType(fNature, fVariability, c | fComputability, fVectorability, fBoolean, fInterval);
257     }  ///< promote the computability of a type
promoteVectorability(int vec)258     virtual AudioType* promoteVectorability(int vec)
259     {
260         return makeSimpleType(fNature, fVariability, fComputability, vec | fVectorability, fBoolean, fInterval);
261     }  ///< promote the vectorability of a type
promoteBoolean(int b)262     virtual AudioType* promoteBoolean(int b)
263     {
264         return makeSimpleType(fNature, fVariability, fComputability, fVectorability, b | fBoolean, fInterval);
265     }  ///< promote the booleanity of a type
promoteInterval(const interval & i)266     virtual AudioType* promoteInterval(const interval& i)
267     {
268         // cerr << "promote to Interval " << i << endl;
269         // cerr << "for type : " << *this << endl;
270         Type t = makeSimpleType(fNature, fVariability, fComputability, fVectorability, fBoolean, i);  ///< promote the interval of a type
271                                                                                                       // cerr << "gives type " << *t << endl;
272         return t;
273     }
274     virtual bool isMaximal()
275             const;  ///< true when type is maximal (and therefore can't change depending of hypothesis)
276     };
277 
intCast(Type t)278 inline Type intCast(Type t)
279 {
280     return makeSimpleType(kInt, t->variability(), t->computability(), t->vectorability(), t->boolean(),
281                           t->getInterval());
282 }
floatCast(Type t)283 inline Type floatCast(Type t)
284 {
285     return makeSimpleType(kReal, t->variability(), t->computability(), t->vectorability(), t->boolean(),
286                           t->getInterval());
287 }
sampCast(Type t)288 inline Type sampCast(Type t)
289 {
290     return makeSimpleType(t->nature(), kSamp, t->computability(), t->vectorability(), t->boolean(), t->getInterval());
291 }
boolCast(Type t)292 inline Type boolCast(Type t)
293 {
294     return makeSimpleType(kInt, t->variability(), t->computability(), t->vectorability(), kBool, t->getInterval());
295 }
numCast(Type t)296 inline Type numCast(Type t)
297 {
298     return makeSimpleType(t->nature(), t->variability(), t->computability(), t->vectorability(), kNum,
299                           t->getInterval());
300 }
vecCast(Type t)301 inline Type vecCast(Type t)
302 {
303     return makeSimpleType(t->nature(), t->variability(), t->computability(), kVect, t->boolean(), t->getInterval());
304 }
scalCast(Type t)305 inline Type scalCast(Type t)
306 {
307     return makeSimpleType(t->nature(), t->variability(), t->computability(), kScal, t->boolean(), t->getInterval());
308 }
truescalCast(Type t)309 inline Type truescalCast(Type t)
310 {
311     return makeSimpleType(t->nature(), t->variability(), t->computability(), kTrueScal, t->boolean(), t->getInterval());
312 }
313 
castInterval(Type t,const interval & i)314 inline Type castInterval(Type t, const interval& i)
315 {
316     return makeSimpleType(t->nature(), t->variability(), t->computability(), t->vectorability(), t->boolean(), i);
317 }
318 
319 /**
320  * The type of a table of audio data.
321  * Beside a computability and a variability, TableTypes have
322  * a "content" indicating the type of the data stored in the table.
323  */
324 class TableType : public AudioType {
325    protected:
326     const Type fContent;  ///< type of that data stored in the table
327 
328    public:
TableType(const Type & t)329     TableType(const Type& t) : AudioType(t->nature(), kKonst, kInit, kVect, t->boolean(), t->getInterval()), fContent(t)
330     {
331     }  ///< construct a TableType with a content of a type t
332 #if 0
333 	TableType(const Type& t, int v, int c) :
334 		  AudioType(t->nature(), t->variability()|v, t->computability()|c, t->vectorability(), t->boolean()),
335 		  fContent(t) {}		///< construct a TableType with a content of a type t, promoting variability and computability
336 
337 	TableType(const Type& t, int n, int v, int c) :
338 		  AudioType(t->nature()|n, t->variability()|v, t->computability()|c, t->vectorability(), t->boolean()),
339 		  fContent(t) {}		///< construct a TableType with a content of a type t, promoting nature, variability and computability
340 
341 	TableType(const Type& t, int n, int v, int c, int vec, int b) :
342 		  AudioType(t->nature()|n, t->variability()|v, t->computability()|c, t->vectorability()|vec, t->boolean()|b),
343 		  fContent(t) {}		///< construct a TableType with a content of a type t, promoting nature, variability, computability, vectorability and booleanity
344 #endif
345 
TableType(const Type & t,int n,int v,int c,int vec,int b,const interval & i)346     TableType(const Type& t, int n, int v, int c, int vec, int b, const interval& i)
347         : AudioType(t->nature() | n, kKonst | v, kInit | c, kVect | vec, t->boolean() | b, i), fContent(t)
348     {
349     }  ///< construct a TableType with a content of a type t, promoting nature, variability, computability,
350        ///< vectorability and booleanity
351 
TableType(const Type & t,int n,int v,int c,int vec)352     TableType(const Type& t, int n, int v, int c, int vec)
353         : AudioType(t->nature() | n, kKonst | v, kInit | c, kVect | vec, t->boolean()), fContent(t)
354     {
355     }  ///< construct a TableType with a content of a type t, promoting nature, variability, computability and
356        ///< vectorability
357 
content() const358     Type             content() const { return fContent; }  ///< return the type of data store in the table
359     virtual ostream& print(ostream& dst) const;            ///< print a TableType
360 
promoteNature(int n)361     virtual AudioType* promoteNature(int n)
362     {
363         return makeTableType(fContent, n | fNature, fVariability, fComputability, fVectorability, fBoolean, fInterval);
364     }  ///< promote the nature of a type
promoteVariability(int v)365     virtual AudioType* promoteVariability(int v)
366     {
367         return makeTableType(fContent, fNature, v | fVariability, fComputability, fVectorability, fBoolean, fInterval);
368     }  ///< promote the variability of a type
promoteComputability(int c)369     virtual AudioType* promoteComputability(int c)
370     {
371         return makeTableType(fContent, fNature, fVariability, c | fComputability, fVectorability, fBoolean, fInterval);
372     }  ///< promote the computability of a type
promoteVectorability(int vec)373     virtual AudioType* promoteVectorability(int vec)
374     {
375         return makeTableType(fContent, fNature, fVariability, fComputability, vec | fVectorability, fBoolean,
376                              fInterval);
377     }  ///< promote the vectorability of a type
promoteBoolean(int b)378     virtual AudioType* promoteBoolean(int b)
379     {
380         return makeTableType(fContent, fNature, fVariability, fComputability, fVectorability, b | fBoolean, fInterval);
381     }  ///< promote the booleanity of a type
promoteInterval(const interval & i)382     virtual AudioType* promoteInterval(const interval& i)
383     {
384         return makeTableType(fContent, fNature, fVariability, fComputability, fVectorability, fBoolean, i);
385     }  ///< promote the interval of a type
386 
387     virtual bool isMaximal() const;  ///< true when type is maximal (and therefore can't change depending of hypothesis)
388 };
389 
390 /**
391  * The type of a tuplet of data.
392  * Beside a computability and a variability, TupletTypes have
393  * a set of components.
394  */
395 class TupletType : public AudioType {
396    protected:
397     vector<Type> fComponents;
398 
399    public:
TupletType()400     TupletType() : AudioType(0, 0, 0) {}
401 
TupletType(const vector<Type> & vt)402     TupletType(const vector<Type>& vt)
403         : AudioType(mergenature(vt), mergevariability(vt), mergecomputability(vt), mergevectorability(vt),
404                     mergeboolean(vt), mergeinterval(vt)),
405           fComponents(vt)
406     {
407     }
408 
TupletType(const vector<Type> & vt,int n,int v,int c,int vec,int b,const interval & i)409     TupletType(const vector<Type>& vt, int n, int v, int c, int vec, int b, const interval& i)
410         : AudioType(n | mergenature(vt), v | mergevariability(vt), c | mergecomputability(vt),
411                     vec | mergevectorability(vt), b | mergeboolean(vt), i),
412           fComponents(vt)
413     {
414     }
415 
arity() const416     int              arity() const { return (int)fComponents.size(); }
operator [](unsigned int i) const417     Type             operator[](unsigned int i) const { return fComponents[i]; }
418     virtual ostream& print(ostream& dst) const;
419 
promoteNature(int n)420     virtual AudioType* promoteNature(int n)
421     {
422         return new TupletType(fComponents, n | fNature, fVariability, fComputability, fVectorability, fBoolean,
423                               fInterval);
424     }  ///< promote the nature of a type
promoteVariability(int v)425     virtual AudioType* promoteVariability(int v)
426     {
427         return new TupletType(fComponents, fNature, v | fVariability, fComputability, fVectorability, fBoolean,
428                               fInterval);
429     }  ///< promote the variability of a type
promoteComputability(int c)430     virtual AudioType* promoteComputability(int c)
431     {
432         return new TupletType(fComponents, fNature, fVariability, c | fComputability, fVectorability, fBoolean,
433                               fInterval);
434     }  ///< promote the computability of a type
promoteVectorability(int vec)435     virtual AudioType* promoteVectorability(int vec)
436     {
437         return new TupletType(fComponents, fNature, fVariability, fComputability, vec | fVectorability, fBoolean,
438                               fInterval);
439     }  ///< promote the vectorability of a type
promoteBoolean(int b)440     virtual AudioType* promoteBoolean(int b)
441     {
442         return new TupletType(fComponents, fNature, fVariability, fComputability, fVectorability, b | fBoolean,
443                               fInterval);
444     }  ///< promote the booleanity of a type
promoteInterval(const interval & i)445     virtual AudioType* promoteInterval(const interval& i)
446     {
447         return new TupletType(fComponents, fNature, fVariability, fComputability, fVectorability, fBoolean, i);
448     }  ///< promote the interval of a type
449 
450     virtual bool isMaximal() const;  ///< true when type is maximal (and therefore can't change depending of hypothesis)
451 };
452 
453 //-------------------------------------------------
454 //-------------------------------------------------
455 // 				operations on types
456 //-------------------------------------------------
457 //-------------------------------------------------
458 
459 //--------------------------------------------------
460 // list of predefined types
461 
462 extern Type TINT;
463 extern Type TREAL;
464 
465 extern Type TKONST;
466 extern Type TBLOCK;
467 extern Type TSAMP;
468 
469 extern Type TCOMP;
470 extern Type TINIT;
471 extern Type TEXEC;
472 
473 extern Type TINPUT;
474 extern Type TGUI;
475 extern Type TGUI01;
476 extern Type INT_TGUI;
477 extern Type TREC;
478 
479 //--------------------------------------------------
480 // types creation
481 
482 Type table(const Type& t);
483 Type operator|(const Type& t1, const Type& t2);
484 Type operator*(const Type& t1, const Type& t2);
485 
486 //--------------------------------------------------
487 // types comparaison
488 
489 bool operator==(const Type& t1, const Type& t2);
490 bool operator<=(const Type& t1, const Type& t2);
491 
operator !=(const Type & t1,const Type & t2)492 inline bool operator!=(const Type& t1, const Type& t2)
493 {
494     return !(t1 == t2);
495 }
operator <(const Type & t1,const Type & t2)496 inline bool operator<(const Type& t1, const Type& t2)
497 {
498     return t1 <= t2 && t1 != t2;
499 }
operator >(const Type & t1,const Type & t2)500 inline bool operator>(const Type& t1, const Type& t2)
501 {
502     return t2 < t1;
503 }
operator >=(const Type & t1,const Type & t2)504 inline bool operator>=(const Type& t1, const Type& t2)
505 {
506     return t2 <= t1;
507 }
508 
509 //--------------------------------------------------
510 // types predicats-conversion
511 
512 SimpleType* isSimpleType(AudioType* t);
513 TableType*  isTableType(AudioType* t);
514 TupletType* isTupletType(AudioType* t);
515 
516 //--------------------------------------------------
517 // types impressions
518 
519 ostream& operator<<(ostream& dst, const SimpleType& t);
520 ostream& operator<<(ostream& dst, const Type& t);
521 ostream& operator<<(ostream& dst, const TableType& t);
522 ostream& operator<<(ostream& dst, const TupletType& t);
523 
524 //--------------------------------------------------
525 // type verification
526 
527 Type checkInt(Type t);    ///< check that t is an integer
528 Type checkKonst(Type t);  ///< check that t is a constant
529 Type checkInit(Type t);   ///< check that t is a known at init time
530 
531 Type checkIntParam(Type t);  ///< check that t is a known at init time, constant and an integer
532 
533 Type checkWRTbl(Type tbl, Type wr);  ///< check that wr is compatible with tbl content
534 
535 int checkDelayInterval(Type t);      ///< check if the interval of t is appropriate for a delay
536 
537 //--------------------------------------------------
538 // Type conversion
539 
540 Tree codeAudioType(AudioType* t);  ///< Code an audio type as a tree (memoization)
541 
542 #endif
543