00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025 #include <assert.h>
00026 #include "sigtype.hh"
00027 #include "sigprint.hh"
00028 #include "ppsig.hh"
00029
00030 #include "prim2.hh"
00031 #include "tlib.hh"
00032 #include "sigtyperules.hh"
00033 #include "xtended.hh"
00034 #include "recursivness.hh"
00035
00036
00037
00038
00039
00040 static Type getInferredType(Tree term, Tree env);
00041 static Type infereSigType(Tree term, Tree env);
00042 static Type infereFFType (Tree ff, Tree ls, Tree env);
00043 static Type infereFConstType (Tree type);
00044 static Type infereFVarType (Tree type);
00045 static Type infereRecType (Tree var, Tree body, Tree env);
00046 static Type infereReadTableType(Type tbl, Type ri);
00047 static Type infereWriteTableType(Type tbl, Type wi, Type wd);
00048 static Type infereProjType(Type t, int i, int vec);
00049 static Type infereXType(Tree sig, Tree env);
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 Tree TYPEPROPERTY = tree(symbol("TypeProperty"));
00061
00067 void setSigType(Tree sig, Type t)
00068 {
00069
00070
00071 sig->setType(t);
00072 }
00073
00074
00079 Type getSigType(Tree sig)
00080 {
00081 AudioType* t = (AudioType*) sig->getType();
00082 if (t==0) {
00083 cerr << "ERROR in getSigType : no type information available for signal :" << *sig << endl;
00084 exit(1);
00085 }
00086 return t;
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00103 Tree NULLENV = tree(symbol("NullEnv"));
00104
00105
00106
00114 Tree addEnv(Tree var, Type tp, Tree env)
00115 {
00116 Tree r = cons(cons(var,tree((AudioType*)tp)),env);
00117 return r;
00118 }
00119
00120
00127 Type searchEnv(Tree env, Tree var)
00128 {
00129 while ( (env != NULLENV) && (hd(hd(env)) != var) ) { env = tl(env); }
00130 if (env == NULLENV) {
00131 cerr << "Problem in searchEnv "; print(var, stderr);
00132 cerr << " was not found" << endl;
00133 assert(env != NULLENV);
00134 }
00135
00136 return Type((AudioType*)tree2ptr(tl(hd(env))));
00137 }
00138
00139
00140
00148 static bool isInEnv(Tree env, Tree var, Type& val)
00149 {
00150 while ( (env != NULLENV) && (hd(hd(env)) != var) ) { env = tl(env); }
00151 if (env == NULLENV) return false;
00152 val = Type((AudioType*)tree2ptr(tl(hd(env))));
00153 return true;
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00168 void typeAnnotation(Tree sig)
00169 {
00170 getInferredType(sig, NULLENV);
00171 }
00172
00173
00174
00181 Type getInferredType(Tree term, Tree env)
00182 {
00183 AudioType* at = (AudioType*) term->getType();
00184 if (at) {
00185 return at;
00186 } else {
00187 Tree tt;
00188 if (!getProperty(term, env, tt)) {
00189 Type tp;
00190 if (!isInEnv(env, term, tp)) {
00191 Type t = infereSigType(term, env);
00192 if (env == NULLENV) {
00193 setSigType(term, t);
00194 } else {
00195 setProperty(term, env, tree((void*)t));
00196 }
00197 return t;
00198 } else {
00199 return tp;
00200 }
00201 }
00202 Type rt((AudioType*)tree2ptr(tt));
00203 return rt;
00204 }
00205 }
00206
00207
00215 Type T(Tree term, Tree env)
00216 {
00217 Type t = getInferredType(term, env);
00218 return t;
00219 }
00220
00221
00222
00231 static interval __arithmetic (int opcode, const interval& x, const interval& y)
00232 {
00233 switch (opcode) {
00234 case kAdd: return x+y;
00235 case kSub: return x-y;
00236 case kMul: return x*y;
00237 case kDiv: return x/y;
00238 case kRem: return x%y;
00239 case kLsh: return x<<y;
00240 case kRsh: return x>>y;
00241 case kGT: return x>y;
00242 case kLT: return x<y;
00243 case kGE: return x>=y;
00244 case kLE: return x<=y;
00245 case kEQ: return x==y;
00246 case kNE: return x!=y;
00247 case kAND: return x&y;
00248 case kOR: return x|y;
00249 case kXOR: return x^y;
00250 default:
00251 cerr << "Unrecognized opcode : " << opcode << endl;
00252 exit(1);
00253 }
00254
00255 return interval();
00256 }
00257
00258 static interval arithmetic (int opcode, const interval& x, const interval& y)
00259 {
00260 interval r = __arithmetic(opcode,x,y);
00261 return r;
00262 }
00263
00264
00272 static Type infereSigType(Tree sig, Tree env)
00273 {
00274 int i;
00275 float r;
00276 Tree sel, s1, s2, s3, ff, id, ls, l, x, y, var, body, type, name, file;
00277 Tree label, cur, min, max, step;
00278
00279
00280 if ( getUserData(sig) ) return infereXType(sig, env);
00281
00282 else if (isSigInt(sig, &i)) return new SimpleType(kInt, kKonst, kComp, kVect, kNum, interval(i));
00283
00284 else if (isSigReal(sig, &r)) return new SimpleType(kReal, kKonst, kComp, kVect, kNum, interval(r));
00285
00286 else if (isSigInput(sig, &i)) return new SimpleType(kReal, kSamp, kExec, kVect, kNum, interval(-1,1));
00287
00288 else if (isSigOutput(sig, &i, s1)) return sampCast(T(s1,env));
00289
00290 else if (isSigDelay1(sig, s1)) {
00291 Type t = T(s1,env);
00292 return castInterval(sampCast(t), reunion(t->getInterval(), interval(0,0)));
00293 }
00294
00295 else if (isSigPrefix(sig, s1, s2)) {
00296 Type t1 = T(s1,env);
00297 Type t2 = T(s2,env);
00298 checkInit(t1);
00299 return castInterval(sampCast(t1|t2), reunion(t1->getInterval(), t2->getInterval()));
00300 }
00301
00302 else if (isSigFixDelay(sig, s1, s2)) {
00303 Type t1 = T(s1,env);
00304 Type t2 = T(s2,env);
00305 interval i = t2->getInterval();
00306
00307
00308
00309
00310 if (!i.valid) {
00311 cerr << "ERROR : can't compute the min and max values of : " << ppsig(s2) << endl;
00312 cerr << " used in delay expression : " << ppsig(sig) << endl;
00313 cerr << " (probably a recursive signal)" << endl;
00314 exit(1);
00315 } else if (i.lo < 0) {
00316 cerr << "ERROR : possible negative values of : " << ppsig(s2) << endl;
00317 cerr << " used in delay expression : " << ppsig(sig) << endl;
00318 cerr << " " << i << endl;
00319 exit(1);
00320 }
00321
00322 return castInterval(sampCast(t1), reunion(t1->getInterval(), interval(0,0)));
00323 }
00324
00325 else if (isSigBinOp(sig, &i, s1, s2)) {
00326
00327 Type t1 = T(s1,env);
00328 Type t2 = T(s2,env);
00329 Type t3 = castInterval(t1 | t2, arithmetic(i, t1->getInterval(), t2->getInterval()));
00330
00331
00332 return ((i>=kGT) && (i<=kNE)) ? intCast(t3) : t3;
00333 }
00334
00335 else if (isSigIntCast(sig, s1)) return intCast(T(s1,env));
00336
00337 else if (isSigFloatCast(sig, s1)) return floatCast(T(s1,env));
00338
00339 else if (isSigFFun(sig, ff, ls)) return infereFFType(ff,ls,env);
00340
00341 else if (isSigFConst(sig,type,name,file)) return infereFConstType(type);
00342
00343 else if (isSigFVar(sig,type,name,file)) return infereFVarType(type);
00344
00345 else if (isSigButton(sig)) return castInterval(TGUI,interval(0,1));
00346
00347 else if (isSigCheckbox(sig)) return castInterval(TGUI,interval(0,1));
00348
00349 else if (isSigVSlider(sig,label,cur,min,max,step))
00350 return castInterval(TGUI,interval(tree2float(min),tree2float(max)));
00351
00352 else if (isSigHSlider(sig,label,cur,min,max,step))
00353 return castInterval(TGUI,interval(tree2float(min),tree2float(max)));
00354
00355 else if (isSigNumEntry(sig,label,cur,min,max,step))
00356 return castInterval(TGUI,interval(tree2float(min),tree2float(max)));
00357
00358 else if (isSigHBargraph(sig, l, x, y, s1)) return T(s1,env);
00359
00360 else if (isSigVBargraph(sig, l, x, y, s1)) return T(s1,env);
00361
00362 else if (isSigAttach(sig, s1, s2)) { T(s2,env); return T(s1,env); }
00363
00364 else if (isRec(sig, var, body)) return infereRecType(sig, body, env);
00365
00366 else if (isProj(sig, &i, s1)) return infereProjType(T(s1,env),i,kScal);
00367
00368 else if (isSigTable(sig, id, s1, s2)) { checkInt(checkInit(T(s1,env))); return new TableType(checkInit(T(s2,env))); }
00369
00370 else if (isSigWRTbl(sig, id, s1, s2, s3)) return infereWriteTableType(T(s1,env), T(s2,env), T(s3,env));
00371
00372 else if (isSigRDTbl(sig, s1, s2)) return infereReadTableType(T(s1,env), T(s2,env));
00373
00374 else if (isSigGen(sig, s1)) return T(s1,NULLENV);
00375
00376 else if (isSigSelect2(sig,sel,s1,s2)) {
00377
00378 SimpleType *st1, *st2, *stsel;
00379
00380 st1 = isSimpleType(T(s1,env));
00381 st2 = isSimpleType(T(s2,env));
00382 stsel = isSimpleType(T(sel,env));
00383
00384 return new SimpleType( st1->nature()|st2->nature(),
00385 st1->variability()|st2->variability()|stsel->variability(),
00386 st1->computability()|st2->computability()|stsel->computability(),
00387 st1->vectorability()|st2->vectorability()|stsel->vectorability(),
00388 st1->boolean()|st2->boolean(),
00389 reunion(st1->getInterval(), st2->getInterval())
00390 );
00391
00392
00393
00394 }
00395
00396 else if (isSigSelect3(sig,sel,s1,s2,s3)) { return T(sel,env)|T(s1,env)|T(s2,env)|T(s3,env); }
00397
00398 else if (isList(sig))
00399 {
00400 vector<Type> v;
00401 while (isList(sig)) { v.push_back(T(hd(sig),env)); sig = tl(sig); }
00402 return new TupletType(v);
00403 }
00404
00405
00406 fprintf(stderr, "ERROR infering signal type : unrecognized signal : "); print(sig, stderr); fprintf(stderr, "\n");
00407 exit(1);
00408 return 0;
00409 }
00410
00411
00412
00416 static Type infereProjType(Type t, int i, int vec)
00417 {
00418 TupletType* tt = isTupletType(t);
00419 if (tt == 0) {
00420 cerr << "ERROR infering projection type, not a tuplet type : " << t << endl;
00421 exit(1);
00422 }
00423
00424
00425 Type temp = (*tt)[i] ->promoteVariability(t->variability())
00426 ->promoteComputability(t->computability())
00427 ->promoteVectorability(vec);
00428
00429
00430 if(vec==kVect) return vecCast(temp);
00431 else return temp;
00432 }
00433
00434
00435
00439 static Type infereWriteTableType(Type tbl, Type wi, Type wd)
00440 {
00441 TableType* tt = isTableType(tbl);
00442 if (tt == 0) {
00443 cerr << "ERROR infering write table type, wrong table type : " << tbl << endl;
00444 exit(1);
00445 }
00446 SimpleType* st = isSimpleType(wi);
00447 if (st == 0 || st->nature() > kInt) {
00448 cerr << "ERROR infering write table type, wrong write index type : " << wi << endl;
00449 exit(1);
00450 }
00451
00452 int n = tt->nature();
00453 int v = wi->variability() | wd->variability();
00454 int c = wi->computability() | wd->computability();
00455 int vec = wi->vectorability() | wd->vectorability();
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467 return new TableType(tt->content(), n, v, c, vec);
00468
00469 }
00470
00471
00472
00476 static Type infereReadTableType(Type tbl, Type ri)
00477 {
00478 TableType* tt = isTableType(tbl);
00479 if (tt == 0) {
00480 cerr << "ERROR infering read table type, wrong table type : " << tbl << endl;
00481 exit(1);
00482 }
00483 SimpleType* st = isSimpleType(ri);
00484 if (st == 0 || st->nature() > kInt) {
00485 cerr << "ERROR infering read table type, wrong write index type : " << ri << endl;
00486 exit(1);
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 Type temp = tt->content()->promoteVariability(ri->variability()|tt->variability())
00500 ->promoteComputability(ri->computability()|tt->computability())
00501 ->promoteVectorability(ri->vectorability()|tt->vectorability())
00502 ->promoteBoolean(ri->boolean()|tt->boolean())
00503 ;
00504
00505
00506
00507
00508 return temp;
00509
00510
00511
00512
00513
00514
00515
00516 }
00517
00518
00519
00523 static Type initialRecType(Tree t)
00524 {
00525 if (isList(t)) {
00526 vector<Type> v;
00527 do { v.push_back(initialRecType(hd(t))); t = tl(t); } while (isList(t));
00528 return new TupletType(v);
00529 } else {
00530 return TREC;
00531 }
00532 }
00533
00534
00535
00540 static Type infereRecType (Tree var, Tree body, Tree env)
00541 {
00542 Type t0, t1;
00543
00544 t1 = initialRecType(body);
00545 do {
00546 t0 = t1;
00547 setProperty(var, env, tree((void*)t0));
00548 t1 = T(body, addEnv(var, t0, env));
00549 } while (t1 > t0);
00550
00551 assert (t1 == t0);
00552
00553 if (getRecursivness(body) == 1 || env == NULLENV) {
00554 setSigType(var, t1);
00555 T(body, NULLENV);
00556 }
00557 return t1;
00558 }
00559
00560
00564 static Type infereFFType (Tree ff, Tree ls, Tree env)
00565 {
00566
00567
00568
00569
00570 if (ffarity(ff)==0) {
00571
00572 return new SimpleType(ffrestype(ff),kSamp,kInit,kVect,kNum, interval());
00573 } else {
00574
00575
00576 Type t = new SimpleType(kInt,kKonst,kInit,kVect,kNum, interval());
00577 while (isList(ls)) { t = t|T(hd(ls),env); ls=tl(ls); }
00578
00579
00580
00581 return new SimpleType( ffrestype(ff),
00582 t->variability(),
00583 t->computability(),
00584 t->vectorability(),
00585 t->boolean(),
00586 interval() );
00587 }
00588 }
00589
00593 static Type infereFConstType (Tree type)
00594 {
00595
00596
00597
00598 return new SimpleType(tree2int(type),kKonst,kInit,kVect,kNum, interval());
00599 }
00600
00604 static Type infereFVarType (Tree type)
00605 {
00606
00607
00608 return new SimpleType(tree2int(type),kBlock,kExec,kVect,kNum, interval());
00609 }
00610
00611
00612
00613
00617 static Type infereXType(Tree sig, Tree env)
00618 {
00619
00620
00621 xtended* p = (xtended*) getUserData(sig);
00622 vector<Type> vt;
00623
00624 for (int i = 0; i < sig->arity(); i++) vt.push_back(T(sig->branch(i), env));
00625 return p->infereSigType(vt);
00626 }