d2a6d35cea3efc066c47be58d6b3a81c653a95d0
[Faustine.git] / interpretor / faust-0.9.47mr3 / compiler / signals / sigtyperules.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 <stdio.h>
25 #include <assert.h>
26 #include <iostream>
27 #include <fstream>
28 #include <time.h>
29
30
31 #include "sigtype.hh"
32 #include "sigprint.hh"
33 #include "ppsig.hh"
34 //#include "prim.hh"
35 #include "prim2.hh"
36 #include "tlib.hh"
37 #include "sigtyperules.hh"
38 #include "xtended.hh"
39 #include "recursivness.hh"
40 #include "sigraterules.hh"
41
42
43 //--------------------------------------------------------------------------
44 // Uncomment to activate type inference tracing
45
46 //#define TRACE(x) x
47 #define TRACE(x) 0;
48
49
50
51 //--------------------------------------------------------------------------
52 // prototypes
53 static ostream& printRateEnvironment(ostream& fout, Tree E);
54 static Tree inferreMultiRates(Tree lsig, bool& success);
55 static ostream& printRateEnvironmentList(ostream& fout, Tree LE);
56
57 static void setSigType(Tree sig, Type t);
58 static Type getSigType(Tree sig);
59 static Type initialRecType(Tree t);
60
61 static Type T(Tree term, Tree env);
62
63 static Type infereSigType(Tree term, Tree env);
64 static Type infereFFType (Tree ff, Tree ls, Tree env);
65 static Type infereFConstType (Tree type);
66 static Type infereFVarType (Tree type);
67 static Type infereRecType (Tree var, Tree body, Tree env);
68 static Type infereReadTableType(Type tbl, Type ri);
69 static Type infereWriteTableType(Type tbl, Type wi, Type wd);
70 static Type infereProjType(Type t, int i, int vec);
71 static Type infereXType(Tree sig, Tree env);
72 static Type infereDocConstantTblType(Type size, Type init);
73 static Type infereDocWriteTblType(Type size, Type init, Type widx, Type wsig);
74 static Type infereDocAccessTblType(Type tbl, Type ridx);
75 static interval arithmetic (int opcode, const interval& x, const interval& y);
76
77
78 static Type infereVectorizeType(Tree sig, Type T, Type Tsize);
79 static Type infereSerializeType(Tree sig, Type Tvec);
80 static Type infereConcatType(Type Tvec1, Type Tvec2);
81 static Type infereVectorAtType(Type Tvec, Type Tidx);
82
83
84
85
86 /**
87 * The empty type environment (also property key for closed term type)
88 */
89 static Tree NULLTYPEENV = tree(symbol("NullTypeEnv"));
90
91 static int countInferences;
92 static int countMaximal;
93
94
95
96 /**
97 * Fully annotate every subtree of term with type information.
98 * @param sig the signal term tree to annotate
99 */
100
101 void typeAnnotation(Tree sig)
102 {
103 Tree sl = symlist(sig);
104 int n = len(sl);
105
106 vector<Tree> vrec, vdef;
107 vector<Type> vtype;
108
109 //cerr << "Symlist " << *sl << endl;
110 for (Tree l=sl; isList(l); l=tl(l)) {
111 Tree id, body;
112 assert(isRec(hd(l), id, body));
113
114 vrec.push_back(hd(l));
115 vdef.push_back(body);
116 }
117
118 // init recursive types
119 for (int i=0; i<n; i++) {
120 vtype.push_back(initialRecType(vdef[i]));
121 }
122
123 assert (int(vrec.size())==n);
124 assert (int(vdef.size())==n);
125 assert (int(vtype.size())==n);
126
127 // find least fixpoint
128 for (bool finished = false; !finished; ) {
129
130 // init recursive types
131 CTree::startNewVisit();
132 for (int i=0; i<n; i++) {
133 setSigType(vrec[i], vtype[i]);
134 vrec[i]->setVisited();
135 }
136
137 // compute recursive types
138 for (int i=0; i<n; i++) {
139 vtype[i] = T(vdef[i], NULLTYPEENV);
140 }
141
142 // check finished
143 finished = true;
144 for (int i=0; i<n; i++) {
145 //cerr << i << "-" << *vrec[i] << ":" << *getSigType(vrec[i]) << " => " << *vtype[i] << endl;
146 finished = finished & (getSigType(vrec[i]) == vtype[i]);
147 }
148 }
149
150 // type full term
151 T(sig, NULLTYPEENV);
152
153 #if 0
154 //cerr << TABBER << "COUNT INFERENCE " << countInferences << " AT TIME " << clock()/CLOCKS_PER_SEC << 's' << endl;
155 fixInferredType(sig, NULLTYPEENV);
156 //cerr << --TABBER << "EXIT TYPE ANNOTATION OF " << *sig << " AT TIME " << clock()/CLOCKS_PER_SEC << 's' << endl;
157
158 #if 0
159 bool success;
160 Tree RE = inferreMultiRates(sig, success);
161 if (success) {
162 printRateEnvironment(cerr, RE); cerr << endl;
163 } else {
164 cerr << "ERROR can't inferre rate environment of " << ppsig(sig) << endl;
165 }
166 #else
167 //RateInferrer R(sig);
168
169 #endif
170 #endif
171
172 }
173
174
175 void annotationStatistics()
176 {
177 cerr << TABBER << "COUNT INFERENCE " << countInferences << " AT TIME " << clock()/CLOCKS_PER_SEC << 's' << endl;
178 cerr << TABBER << "COUNT ALLOCATION " << AudioType::gAllocationCount << endl;
179 cerr << TABBER << "COUNT MAXIMAL " << countMaximal << endl;
180 }
181
182 /**
183 * Retrieve the type of sig and check it exists. Produces an
184 * error if the signal has no type associated
185 * @param sig the signal we want to know the type
186 * @return the type of the signal
187 */
188 Type getCertifiedSigType(Tree sig)
189 {
190 Type ty = getSigType(sig);
191 assert(ty);
192 return ty;
193 }
194
195
196
197 /***********************************************
198 * Set and get the type property of a signal
199 * (we suppose the signal have been previously
200 * annotated with type information)
201 ***********************************************/
202
203 /**
204 * Set the type annotation of sig
205 * @param sig the signal we want to type
206 * @param t the type of the signal
207 */
208 static void setSigType(Tree sig, Type t)
209 {
210 TRACE(cerr << TABBER << "SET FIX TYPE OF " << *sig << " TO TYPE " << *t << endl;)
211 sig->setType(t);
212 }
213
214
215 /**
216 * Retrieve the type annotation of sig
217 * @param sig the signal we want to know the type
218 */
219 static Type getSigType(Tree sig)
220 {
221 AudioType* ty = (AudioType*) sig->getType();
222 if (ty == 0)
223 TRACE(cerr << TABBER << "GET FIX TYPE OF " << *sig << " HAS NO TYPE YET" << endl;)
224 else
225 TRACE(cerr << TABBER << "GET FIX TYPE OF " << *sig << " IS TYPE " << *ty << endl;)
226 return ty;
227 }
228
229
230
231
232
233 /**************************************************************************
234
235 Type Inference System
236
237 ***************************************************************************/
238
239
240 /**************************************************************************
241
242 Infered Type property
243
244 ***************************************************************************/
245
246 /**
247 * Shortcut to getOrInferType, retrieve or infere the type of a term according to its surrounding type environment
248 * @param sig the signal to analyze
249 * @param env the type environment
250 * @return the type of sig according to environment env
251 * @see getCertifiedSigType
252 */
253 static Type T(Tree term, Tree ignoreenv)
254 {
255 TRACE(cerr << ++TABBER << "ENTER T() " << *term << endl;)
256
257 if (term->isAlreadyVisited()) {
258 Type ty = getSigType(term);
259 TRACE(cerr << --TABBER << "EXIT 1 T() " << *term << " AS TYPE " << *ty << endl);
260 return ty;
261
262 } else {
263 Type ty = infereSigType(term, ignoreenv);
264 setSigType(term,ty);
265 term->setVisited();
266 TRACE(cerr << --TABBER << "EXIT 2 T() " << *term << " AS TYPE " << *ty << endl);
267 return ty;
268 }
269 }
270
271
272 /**
273 * Infere the type of a term according to its surrounding type environment
274 * @param sig the signal to aanlyze
275 * @param env the type environment
276 * @return the type of sig according to environment env
277 */
278
279 static Type infereSigType(Tree sig, Tree env)
280 {
281 int i;
282 double r;
283 Tree sel, s1, s2, s3, ff, id, ls, l, x, y, z, u, var, body, type, name, file;
284 Tree label, cur, min, max, step;
285
286 countInferences++;
287
288 if ( getUserData(sig) ) return infereXType(sig, env);
289
290 else if (isSigInt(sig, &i)) { Type t = makeSimpleType(kInt, kKonst, kComp, kVect, kNum, interval(i));
291 /*sig->setType(t);*/ return t; }
292
293 else if (isSigReal(sig, &r)) { Type t = makeSimpleType(kReal, kKonst, kComp, kVect, kNum, interval(r));
294 /*sig->setType(t);*/ return t; }
295
296 else if (isSigInput(sig, &i)) { /*sig->setType(TINPUT);*/ return TINPUT; }
297
298 else if (isSigOutput(sig, &i, s1)) return sampCast(T(s1,env));
299
300 else if (isSigDelay1(sig, s1)) {
301 Type t = T(s1,env);
302 return castInterval(sampCast(t), reunion(t->getInterval(), interval(0,0)));
303 }
304
305 else if (isSigPrefix(sig, s1, s2)) {
306 Type t1 = T(s1,env);
307 Type t2 = T(s2,env);
308 checkInit(t1);
309 return castInterval(sampCast(t1|t2), reunion(t1->getInterval(), t2->getInterval()));
310 }
311
312 else if (isSigFixDelay(sig, s1, s2)) {
313 Type vt1 = T(s1,env);
314 vector<int> dim;
315 Type t1 = vt1->dimensions(dim);
316 Type t2 = T(s2,env);
317 interval i = t2->getInterval();
318
319 // cerr << "for sig fix delay : s1 = "
320 // << t1 << ':' << ppsig(s1) << ", s2 = "
321 // << t2 << ':' << ppsig(s2) << endl;
322 if (!i.valid) {
323 cerr << "ERROR : can't compute the min and max values of : " << ppsig(s2) << endl;
324 cerr << " used in delay expression : " << ppsig(sig) << endl;
325 cerr << " (probably a recursive signal)" << endl;
326 exit(1);
327 } else if (i.lo < 0) {
328 cerr << "ERROR : possible negative values of : " << ppsig(s2) << endl;
329 cerr << " used in delay expression : " << ppsig(sig) << endl;
330 cerr << " " << i << endl;
331 exit(1);
332 }
333
334 Type nt1 = castInterval(sampCast(t1), reunion(t1->getInterval(), interval(0,0)));
335 return makeVectorType(nt1,dim);
336 }
337
338 else if (isSigBinOp(sig, &i, s1, s2)) {
339
340 Type t1 = T(s1,env);
341 Type t2 = T(s2,env);
342
343 vector<int> D1, D2, D3;
344 Type b1 = t1->dimensions(D1);
345 Type b2 = t2->dimensions(D2);
346
347 if (maxdimensions(D1, D2, D3)) {
348 Type b3 = castInterval(b1 | b2, arithmetic(i, b1->getInterval(), b2->getInterval()));
349 if ((i>=kGT) && (i<=kNE)) b3 = intCast(b3);
350 Type t3 = makeVectorType(b3, D3);
351 return t3;
352 } else {
353 cerr << "ERROR operation on incompatible types : " << *t1 << " and " << *t2
354 << " in expression : " << ppsig(sig) << endl;
355 exit(1);
356 }
357 //cerr <<"type rule for : " << ppsig(sig) << " -> " << *t3 << endl;
358 //return (!gVectorSwitch && (i>=kGT) && (i<=kNE)) ? intCast(t3) : t3; // for comparaison operation the result is int
359 //return ((i>=kGT) && (i<=kNE)) ? intCast(t3) : t3; // for comparaison operation the result is int
360 }
361
362 else if (isSigIntCast(sig, s1)) return intCast(T(s1,env));
363
364 else if (isSigFloatCast(sig, s1)) return floatCast(T(s1,env));
365
366 else if (isSigFFun(sig, ff, ls)) return infereFFType(ff,ls,env);
367
368 else if (isSigFConst(sig,type,name,file)) return infereFConstType(type);
369
370 else if (isSigFVar(sig,type,name,file)) return infereFVarType(type);
371
372 else if (isSigButton(sig)) { /*sig->setType(TGUI01);*/ return TGUI01; }
373
374 else if (isSigCheckbox(sig)) { /*sig->setType(TGUI01);*/ return TGUI01; }
375
376 else if (isSigVSlider(sig,label,cur,min,max,step))
377 return castInterval(TGUI,interval(tree2float(min),tree2float(max)));
378
379 else if (isSigHSlider(sig,label,cur,min,max,step))
380 return castInterval(TGUI,interval(tree2float(min),tree2float(max)));
381
382 else if (isSigNumEntry(sig,label,cur,min,max,step))
383 return castInterval(TGUI,interval(tree2float(min),tree2float(max)));
384
385 else if (isSigHBargraph(sig, l, x, y, s1)) return T(s1,env);
386
387 else if (isSigVBargraph(sig, l, x, y, s1)) return T(s1,env);
388
389 else if (isSigAttach(sig, s1, s2)) { T(s2,env); return T(s1,env); }
390
391 else if (isRec(sig, var, body)) return infereRecType(sig, body, env);
392
393 else if (isProj(sig, &i, s1)) return infereProjType(T(s1,env),i,kScal);
394
395 else if (isSigTable(sig, id, s1, s2)) { checkInt(checkInit(T(s1,env))); return makeTableType(checkInit(T(s2,env))); }
396
397 else if (isSigWRTbl(sig, id, s1, s2, s3)) return infereWriteTableType(T(s1,env), T(s2,env), T(s3,env));
398
399 else if (isSigRDTbl(sig, s1, s2)) return infereReadTableType(T(s1,env), T(s2,env));
400
401 else if (isSigGen(sig, s1)) return T(s1,NULLTYPEENV);
402
403 else if ( isSigDocConstantTbl(sig, x, y) ) return infereDocConstantTblType(T(x,env), T(y,env));
404 else if ( isSigDocWriteTbl(sig,x,y,z,u) ) return infereDocWriteTblType(T(x,env), T(y,env), T(z,env), T(u,env));
405 else if ( isSigDocAccessTbl(sig, x, y) ) return infereDocAccessTblType(T(x,env), T(y,env));
406
407 else if (isSigSelect2(sig,sel,s1,s2)) {
408 SimpleType *st1, *st2, *stsel;
409
410 st1 = isSimpleType(T(s1,env));
411 st2 = isSimpleType(T(s2,env));
412 stsel = isSimpleType(T(sel,env));
413
414 return makeSimpleType( st1->nature()|st2->nature(),
415 st1->variability()|st2->variability()|stsel->variability(),
416 st1->computability()|st2->computability()|stsel->computability(),
417 st1->vectorability()|st2->vectorability()|stsel->vectorability(),
418 st1->boolean()|st2->boolean(),
419 reunion(st1->getInterval(), st2->getInterval())
420 );
421 }
422
423 else if (isSigSelect3(sig,sel,s1,s2,s3)) { return T(sel,env)|T(s1,env)|T(s2,env)|T(s3,env); }
424
425 else if (isNil(sig)) { Type t = new TupletType(); /*sig->setType(t);*/ return t; }
426
427 else if (isList(sig)) { return T( hd(sig),env ) * T( tl(sig),env ); }
428
429 else if ( isSigVectorize(sig, x, y) ) return infereVectorizeType(sig, T(x,env), T(y,env));
430 else if ( isSigSerialize(sig, x) ) return infereSerializeType(sig, T(x,env));
431 else if ( isSigConcat(sig, x, y) ) return infereConcatType(T(x,env), T(y,env));
432 else if ( isSigVectorAt(sig, x, y) ) return infereVectorAtType(T(x,env), T(y,env));
433
434 else if ( isSigUpSample(sig, x, y) ) { T(x,env); return T(y,env); }
435 else if ( isSigDownSample(sig, x, y) ) { T(x,env); return T(y,env); }
436
437 // unrecognized signal here
438 fprintf(stderr, "ERROR in ***infereSigType()***, unrecognized signal : "); print(sig, stderr); fprintf(stderr, "\n");
439 exit(1);
440 return 0;
441 }
442
443
444 /**
445 * Infere the type of a projection (selection) of a tuplet element
446 */
447 static Type infereProjType(Type t, int i, int vec)
448 {
449 TupletType* tt = isTupletType(t);
450 if (tt == 0) {
451 cerr << "ERROR infering projection type, not a tuplet type : " << t << endl;
452 exit(1);
453 }
454 //return (*tt)[i] ->promoteVariability(t->variability())
455 // ->promoteComputability(t->computability());
456 Type temp = (*tt)[i] ->promoteVariability(t->variability())
457 ->promoteComputability(t->computability())
458 ->promoteVectorability(vec/*t->vectorability()*/);
459 //->promoteBooleanity(t->boolean());
460
461 if(vec==kVect) temp = vecCast(temp);
462 //cerr << "infereProjType(" << t << ',' << i << ',' << vec << ")" << " -> " << temp << endl;
463
464 return temp;
465 }
466
467
468
469 /**
470 * Infere the type of the result of writing into a table
471 */
472 static Type infereWriteTableType(Type tbl, Type wi, Type wd)
473 {
474 TableType* tt = isTableType(tbl);
475 if (tt == 0) {
476 cerr << "ERROR infering write table type, wrong table type : " << tbl << endl;
477 exit(1);
478 }
479 SimpleType* st = isSimpleType(wi);
480 if (st == 0 || st->nature() > kInt) {
481 cerr << "ERROR infering write table type, wrong write index type : " << wi << endl;
482 exit(1);
483 }
484
485 int n = tt->nature();
486 int v = wi->variability() | wd->variability();
487 int c = wi->computability() | wd->computability();
488 int vec = wi->vectorability() | wd->vectorability();
489
490 return makeTableType(tt->content(), n, v, c, vec);
491
492 }
493
494
495
496 /**
497 * Infere the type of the result of reading a table
498 */
499 static Type infereReadTableType(Type tbl, Type ri)
500 {
501 TableType* tt = isTableType(tbl);
502 if (tt == 0) {
503 cerr << "ERROR infering read table type, wrong table type : " << tbl << endl;
504 exit(1);
505 }
506 SimpleType* st = isSimpleType(ri);
507 if (st == 0 || st->nature() > kInt) {
508 cerr << "ERROR infering read table type, wrong write index type : " << ri << endl;
509 exit(1);
510 }
511
512 Type temp = tt->content()->promoteVariability(ri->variability()|tt->variability())
513 ->promoteComputability(ri->computability()|tt->computability())
514 ->promoteVectorability(ri->vectorability()|tt->vectorability())
515 ->promoteBoolean(ri->boolean()|tt->boolean())
516 ;
517
518 return temp;
519
520 }
521
522
523 static Type infereDocConstantTblType(Type size, Type init)
524 {
525 checkKonst(checkInt(checkInit(size)));
526
527 return init;
528 }
529
530 static Type infereDocWriteTblType(Type size, Type init, Type widx, Type wsig)
531 {
532 checkKonst(checkInt(checkInit(size)));
533
534 Type temp = init
535 ->promoteVariability(kSamp) // difficult to tell, therefore kSamp to be safe
536 ->promoteComputability(widx->computability()|wsig->computability())
537 ->promoteVectorability(kScal) // difficult to tell, therefore kScal to be safe
538 ->promoteNature(wsig->nature()) // nature of the initial and written signal
539 ->promoteBoolean(wsig->boolean()) // booleanity of the initial and written signal
540 ;
541 return temp;
542 }
543
544 static Type infereDocAccessTblType(Type tbl, Type ridx)
545 {
546 Type temp = tbl
547 ->promoteVariability(ridx->variability())
548 ->promoteComputability(ridx->computability())
549 ->promoteVectorability(ridx->vectorability())
550 ;
551 return temp;
552 }
553
554
555 /**
556 * Compute an initial type solution for a recursive block
557 * E1,E2,...En -> TREC,TREC,...TREC
558 */
559 static Type initialRecType(Tree t)
560 {
561 assert (isList(t));
562
563 vector<Type> v;
564 while (isList(t)) { v.push_back(TREC); t = tl(t); };
565 return new TupletType(v);
566 }
567
568
569 /**
570 * Infere the type of e recursive block by trying solutions of
571 * increasing generality
572 */
573 static Type infereRecType (Tree sig, Tree body, Tree env)
574 {
575 assert(false); // we should not come here
576 return 0;
577 }
578
579
580 /**
581 * Infere the type of a foreign function call
582 */
583 static Type infereFFType (Tree ff, Tree ls, Tree env)
584 {
585 // une primitive externe ne peut pas se calculer au plus tot qu'a
586 // l'initialisation. Sa variabilite depend de celle de ses arguments
587 // sauf si elle n'en pas, auquel cas on considere que c'est comme
588 // rand() c'est a dire que le resultat varie a chaque appel.
589 if (ffarity(ff)==0) {
590 // case of functions like rand()
591 return makeSimpleType(ffrestype(ff),kSamp,kInit,kVect,kNum, interval());
592 } else {
593 // otherwise variability and computability depends
594 // arguments (OR of all arg types)
595 Type t = makeSimpleType(kInt,kKonst,kInit,kVect,kNum, interval());
596 while (isList(ls)) { t = t|T(hd(ls),env); ls=tl(ls); }
597 // but the result type is defined by the function
598
599 //return t;
600 return makeSimpleType( ffrestype(ff),
601 t->variability(),
602 t->computability(),
603 t->vectorability(),
604 t->boolean(),
605 interval() );
606 }
607 }
608
609
610 /**
611 * Infere the type of a foreign constant
612 */
613 static Type infereFConstType (Tree type)
614 {
615 // une constante externe ne peut pas se calculer au plus tot qu'a
616 // l'initialisation. Elle est constante, auquel cas on considere que c'est comme
617 // rand() c'est a dire que le resultat varie a chaque appel.
618 return makeSimpleType(tree2int(type),kKonst,kInit,kVect,kNum, interval());
619 }
620
621
622 /**
623 * Infere the type of a foreign variable
624 */
625 static Type infereFVarType (Tree type)
626 {
627 // une variable externe ne peut pas se calculer au plus tot qu'a
628 // l'execution. Elle est varie par blocs comme les éléments d'interface utilisateur.
629 return makeSimpleType(tree2int(type),kBlock,kExec,kVect,kNum, interval());
630 }
631
632
633 /**
634 * Infere the type of an extended (primitive) block
635 */
636 static Type infereXType(Tree sig, Tree env)
637 {
638 //cerr << "infereXType :" << endl;
639 //cerr << "infereXType of " << *sig << endl;
640 xtended* p = (xtended*) getUserData(sig);
641 vector<Type> vt;
642
643 for (int i = 0; i < sig->arity(); i++) vt.push_back(T(sig->branch(i), env));
644 return p->infereSigType(vt);
645 }
646
647
648
649
650
651 /**
652 * Compute the resulting interval of an arithmetic operation
653 * @param op code of the operation
654 * @param s1 interval of the left operand
655 * @param s2 interval of the right operand
656 * @return the resulting interval
657 */
658
659 static interval arithmetic (int opcode, const interval& x, const interval& y)
660 {
661 switch (opcode) {
662 case kAdd: return x+y;
663 case kSub: return x-y;
664 case kMul: return x*y;
665 case kDiv: return x/y;
666 case kRem: return x%y;
667 case kLsh: return x<<y;
668 case kRsh: return x>>y;
669 case kGT: return x>y;
670 case kLT: return x<y;
671 case kGE: return x>=y;
672 case kLE: return x<=y;
673 case kEQ: return x==y;
674 case kNE: return x!=y;
675 case kAND: return x&y;
676 case kOR: return x|y;
677 case kXOR: return x^y;
678 default:
679 cerr << "Unrecognized opcode : " << opcode << endl;
680 exit(1);
681 }
682
683 return interval();
684 }
685
686
687
688 static Type infereVectorizeType(Tree sig, Type Tsize, Type T)
689 {
690 SimpleType* st = isSimpleType(Tsize);
691 if (st && st->nature()==kInt) {
692 interval i = Tsize->getInterval();
693 if (i.valid && i.lo >= 0 && i.lo == i.hi) {
694 return new VectorType(int(i.lo+0.5), T);
695 }
696 }
697 cerr << "ERROR in expression : " << ppsig(sig) << endl;
698 cerr << "the size of the vector is not of a valide type : " << *Tsize << endl;
699 exit(1);
700 }
701
702 static Type infereSerializeType(Tree sig, Type Tvec)
703 {
704 VectorType* vt = isVectorType(Tvec);
705 if (vt) {
706 return vt->content();
707 } else {
708 cerr << "ERROR in expression : " << ppsig(sig) << endl;
709 cerr << "the 'serialize' operation can only be used on vectorized signals" << endl;
710 exit(1);
711 }
712 }
713
714 static Type infereConcatType(Type Tvec1, Type Tvec2)
715 {
716 VectorType* vt1 = isVectorType(Tvec1);
717 VectorType* vt2 = isVectorType(Tvec2);
718
719 if (vt1 && vt2) {
720 Type ct1 = vt1->content();
721 Type ct2 = vt2->content();
722 if (ct1 == ct2) {
723 return new VectorType(vt1->size()+vt2->size(), ct1);
724 }
725 }
726 cerr << "ERROR in vector concatenation, the types : " << Tvec1 << " and " << Tvec2 << " are incompatible" << endl;
727 exit(1);
728 }
729
730 static Type infereVectorAtType(Type Tvec, Type Tidx)
731 {
732 VectorType* vt = isVectorType(Tvec);
733 SimpleType* it = isSimpleType(Tidx);
734
735 if (vt && it) {
736 Type ct = vt->content();
737 int n = vt->size();
738 interval i = it->getInterval();
739 if (i.valid && i.lo >= 0 && i.hi <= n) {
740 return ct;
741 }
742 }
743 cerr << "ERROR in vector access, with types : " << Tvec << " and " << Tidx << endl;
744 exit(1);
745 }