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 static Type infereDocConstantTblType(Type size, Type init);
00051 static Type infereDocWriteTblType(Type size, Type init, Type widx, Type wsig);
00052 static Type infereDocAccessTblType(Type tbl, Type ridx);
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 Tree TYPEPROPERTY = tree(symbol("TypeProperty"));
00064
00070 void setSigType(Tree sig, Type t)
00071 {
00072
00073
00074 sig->setType(t);
00075 }
00076
00077
00082 Type getSigType(Tree sig)
00083 {
00084 AudioType* t = (AudioType*) sig->getType();
00085 if (t==0) {
00086 cerr << "ERROR in getSigType : no type information available for signal :" << *sig << endl;
00087 exit(1);
00088 }
00089 return t;
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00106 Tree NULLENV = tree(symbol("NullEnv"));
00107
00108
00109
00117 Tree addEnv(Tree var, Type tp, Tree env)
00118 {
00119 Tree r = cons(cons(var,tree((AudioType*)tp)),env);
00120 return r;
00121 }
00122
00123
00130 Type searchEnv(Tree env, Tree var)
00131 {
00132 while ( (env != NULLENV) && (hd(hd(env)) != var) ) { env = tl(env); }
00133 if (env == NULLENV) {
00134 cerr << "Problem in searchEnv "; print(var, stderr);
00135 cerr << " was not found" << endl;
00136 assert(env != NULLENV);
00137 }
00138
00139 return Type((AudioType*)tree2ptr(tl(hd(env))));
00140 }
00141
00142
00143
00151 static bool isInEnv(Tree env, Tree var, Type& val)
00152 {
00153 while ( (env != NULLENV) && (hd(hd(env)) != var) ) { env = tl(env); }
00154 if (env == NULLENV) return false;
00155 val = Type((AudioType*)tree2ptr(tl(hd(env))));
00156 return true;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00171 void typeAnnotation(Tree sig)
00172 {
00173 getInferredType(sig, NULLENV);
00174 }
00175
00176
00177
00184 Type getInferredType(Tree term, Tree env)
00185 {
00186 AudioType* at = (AudioType*) term->getType();
00187 if (at) {
00188 return at;
00189 } else {
00190 Tree tt;
00191 if (!getProperty(term, env, tt)) {
00192 Type tp;
00193 if (!isInEnv(env, term, tp)) {
00194 Type t = infereSigType(term, env);
00195 if (env == NULLENV) {
00196 setSigType(term, t);
00197 } else {
00198 setProperty(term, env, tree((void*)t));
00199 }
00200 return t;
00201 } else {
00202 return tp;
00203 }
00204 }
00205 Type rt((AudioType*)tree2ptr(tt));
00206 return rt;
00207 }
00208 }
00209
00210
00218 Type T(Tree term, Tree env)
00219 {
00220 Type t = getInferredType(term, env);
00221 return t;
00222 }
00223
00224
00225
00234 static interval __arithmetic (int opcode, const interval& x, const interval& y)
00235 {
00236 switch (opcode) {
00237 case kAdd: return x+y;
00238 case kSub: return x-y;
00239 case kMul: return x*y;
00240 case kDiv: return x/y;
00241 case kRem: return x%y;
00242 case kLsh: return x<<y;
00243 case kRsh: return x>>y;
00244 case kGT: return x>y;
00245 case kLT: return x<y;
00246 case kGE: return x>=y;
00247 case kLE: return x<=y;
00248 case kEQ: return x==y;
00249 case kNE: return x!=y;
00250 case kAND: return x&y;
00251 case kOR: return x|y;
00252 case kXOR: return x^y;
00253 default:
00254 cerr << "Unrecognized opcode : " << opcode << endl;
00255 exit(1);
00256 }
00257
00258 return interval();
00259 }
00260
00261 static interval arithmetic (int opcode, const interval& x, const interval& y)
00262 {
00263 interval r = __arithmetic(opcode,x,y);
00264 return r;
00265 }
00266
00267
00275 static Type infereSigType(Tree sig, Tree env)
00276 {
00277 int i;
00278 double r;
00279 Tree sel, s1, s2, s3, ff, id, ls, l, x, y, z, u, var, body, type, name, file;
00280 Tree label, cur, min, max, step;
00281
00282
00283 if ( getUserData(sig) ) return infereXType(sig, env);
00284
00285 else if (isSigInt(sig, &i)) return new SimpleType(kInt, kKonst, kComp, kVect, kNum, interval(i));
00286
00287 else if (isSigReal(sig, &r)) return new SimpleType(kReal, kKonst, kComp, kVect, kNum, interval(r));
00288
00289 else if (isSigInput(sig, &i)) return new SimpleType(kReal, kSamp, kExec, kVect, kNum, interval(-1,1));
00290
00291 else if (isSigOutput(sig, &i, s1)) return sampCast(T(s1,env));
00292
00293 else if (isSigDelay1(sig, s1)) {
00294 Type t = T(s1,env);
00295 return castInterval(sampCast(t), reunion(t->getInterval(), interval(0,0)));
00296 }
00297
00298 else if (isSigPrefix(sig, s1, s2)) {
00299 Type t1 = T(s1,env);
00300 Type t2 = T(s2,env);
00301 checkInit(t1);
00302 return castInterval(sampCast(t1|t2), reunion(t1->getInterval(), t2->getInterval()));
00303 }
00304
00305 else if (isSigFixDelay(sig, s1, s2)) {
00306 Type t1 = T(s1,env);
00307 Type t2 = T(s2,env);
00308 interval i = t2->getInterval();
00309
00310
00311
00312
00313 if (!i.valid) {
00314 cerr << "ERROR : can't compute the min and max values of : " << ppsig(s2) << endl;
00315 cerr << " used in delay expression : " << ppsig(sig) << endl;
00316 cerr << " (probably a recursive signal)" << endl;
00317 exit(1);
00318 } else if (i.lo < 0) {
00319 cerr << "ERROR : possible negative values of : " << ppsig(s2) << endl;
00320 cerr << " used in delay expression : " << ppsig(sig) << endl;
00321 cerr << " " << i << endl;
00322 exit(1);
00323 }
00324
00325 return castInterval(sampCast(t1), reunion(t1->getInterval(), interval(0,0)));
00326 }
00327
00328 else if (isSigBinOp(sig, &i, s1, s2)) {
00329
00330 Type t1 = T(s1,env);
00331 Type t2 = T(s2,env);
00332 Type t3 = castInterval(t1 | t2, arithmetic(i, t1->getInterval(), t2->getInterval()));
00333
00334
00335 return ((i>=kGT) && (i<=kNE)) ? intCast(t3) : t3;
00336 }
00337
00338 else if (isSigIntCast(sig, s1)) return intCast(T(s1,env));
00339
00340 else if (isSigFloatCast(sig, s1)) return floatCast(T(s1,env));
00341
00342 else if (isSigFFun(sig, ff, ls)) return infereFFType(ff,ls,env);
00343
00344 else if (isSigFConst(sig,type,name,file)) return infereFConstType(type);
00345
00346 else if (isSigFVar(sig,type,name,file)) return infereFVarType(type);
00347
00348 else if (isSigButton(sig)) return castInterval(TGUI,interval(0,1));
00349
00350 else if (isSigCheckbox(sig)) return castInterval(TGUI,interval(0,1));
00351
00352 else if (isSigVSlider(sig,label,cur,min,max,step))
00353 return castInterval(TGUI,interval(tree2float(min),tree2float(max)));
00354
00355 else if (isSigHSlider(sig,label,cur,min,max,step))
00356 return castInterval(TGUI,interval(tree2float(min),tree2float(max)));
00357
00358 else if (isSigNumEntry(sig,label,cur,min,max,step))
00359 return castInterval(TGUI,interval(tree2float(min),tree2float(max)));
00360
00361 else if (isSigHBargraph(sig, l, x, y, s1)) return T(s1,env);
00362
00363 else if (isSigVBargraph(sig, l, x, y, s1)) return T(s1,env);
00364
00365 else if (isSigAttach(sig, s1, s2)) { T(s2,env); return T(s1,env); }
00366
00367 else if (isRec(sig, var, body)) return infereRecType(sig, body, env);
00368
00369 else if (isProj(sig, &i, s1)) return infereProjType(T(s1,env),i,kScal);
00370
00371 else if (isSigTable(sig, id, s1, s2)) { checkInt(checkInit(T(s1,env))); return new TableType(checkInit(T(s2,env))); }
00372
00373 else if (isSigWRTbl(sig, id, s1, s2, s3)) return infereWriteTableType(T(s1,env), T(s2,env), T(s3,env));
00374
00375 else if (isSigRDTbl(sig, s1, s2)) return infereReadTableType(T(s1,env), T(s2,env));
00376
00377 else if (isSigGen(sig, s1)) return T(s1,NULLENV);
00378
00379 else if ( isSigDocConstantTbl(sig, x, y) ) return infereDocConstantTblType(T(x,env), T(y,env));
00380 else if ( isSigDocWriteTbl(sig,x,y,z,u) ) return infereDocWriteTblType(T(x,env), T(y,env), T(z,env), T(u,env));
00381 else if ( isSigDocAccessTbl(sig, x, y) ) return infereDocAccessTblType(T(x,env), T(y,env));
00382
00383 else if (isSigSelect2(sig,sel,s1,s2)) {
00384
00385 SimpleType *st1, *st2, *stsel;
00386
00387 st1 = isSimpleType(T(s1,env));
00388 st2 = isSimpleType(T(s2,env));
00389 stsel = isSimpleType(T(sel,env));
00390
00391 return new SimpleType( st1->nature()|st2->nature(),
00392 st1->variability()|st2->variability()|stsel->variability(),
00393 st1->computability()|st2->computability()|stsel->computability(),
00394 st1->vectorability()|st2->vectorability()|stsel->vectorability(),
00395 st1->boolean()|st2->boolean(),
00396 reunion(st1->getInterval(), st2->getInterval())
00397 );
00398
00399
00400
00401 }
00402
00403 else if (isSigSelect3(sig,sel,s1,s2,s3)) { return T(sel,env)|T(s1,env)|T(s2,env)|T(s3,env); }
00404
00405 else if (isList(sig))
00406 {
00407 vector<Type> v;
00408 while (isList(sig)) { v.push_back(T(hd(sig),env)); sig = tl(sig); }
00409 return new TupletType(v);
00410 }
00411
00412
00413 fprintf(stderr, "ERROR infering signal type : unrecognized signal : "); print(sig, stderr); fprintf(stderr, "\n");
00414 exit(1);
00415 return 0;
00416 }
00417
00418
00419
00423 static Type infereProjType(Type t, int i, int vec)
00424 {
00425 TupletType* tt = isTupletType(t);
00426 if (tt == 0) {
00427 cerr << "ERROR infering projection type, not a tuplet type : " << t << endl;
00428 exit(1);
00429 }
00430
00431
00432 Type temp = (*tt)[i] ->promoteVariability(t->variability())
00433 ->promoteComputability(t->computability())
00434 ->promoteVectorability(vec);
00435
00436
00437 if(vec==kVect) return vecCast(temp);
00438 else return temp;
00439 }
00440
00441
00442
00446 static Type infereWriteTableType(Type tbl, Type wi, Type wd)
00447 {
00448 TableType* tt = isTableType(tbl);
00449 if (tt == 0) {
00450 cerr << "ERROR infering write table type, wrong table type : " << tbl << endl;
00451 exit(1);
00452 }
00453 SimpleType* st = isSimpleType(wi);
00454 if (st == 0 || st->nature() > kInt) {
00455 cerr << "ERROR infering write table type, wrong write index type : " << wi << endl;
00456 exit(1);
00457 }
00458
00459 int n = tt->nature();
00460 int v = wi->variability() | wd->variability();
00461 int c = wi->computability() | wd->computability();
00462 int vec = wi->vectorability() | wd->vectorability();
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 return new TableType(tt->content(), n, v, c, vec);
00475
00476 }
00477
00478
00479
00483 static Type infereReadTableType(Type tbl, Type ri)
00484 {
00485 TableType* tt = isTableType(tbl);
00486 if (tt == 0) {
00487 cerr << "ERROR infering read table type, wrong table type : " << tbl << endl;
00488 exit(1);
00489 }
00490 SimpleType* st = isSimpleType(ri);
00491 if (st == 0 || st->nature() > kInt) {
00492 cerr << "ERROR infering read table type, wrong write index type : " << ri << endl;
00493 exit(1);
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 Type temp = tt->content()->promoteVariability(ri->variability()|tt->variability())
00507 ->promoteComputability(ri->computability()|tt->computability())
00508 ->promoteVectorability(ri->vectorability()|tt->vectorability())
00509 ->promoteBoolean(ri->boolean()|tt->boolean())
00510 ;
00511
00512
00513
00514
00515 return temp;
00516
00517
00518
00519
00520
00521
00522
00523 }
00524
00525
00526 static Type infereDocConstantTblType(Type size, Type init)
00527 {
00528 checkKonst(checkInt(checkInit(size)));
00529
00530 return init;
00531 }
00532
00533 static Type infereDocWriteTblType(Type size, Type init, Type widx, Type wsig)
00534 {
00535 checkKonst(checkInt(checkInit(size)));
00536
00537 Type temp = init
00538 ->promoteVariability(kSamp)
00539 ->promoteComputability(widx->computability()|wsig->computability())
00540 ->promoteVectorability(kScal)
00541 ->promoteNature(wsig->nature())
00542 ->promoteBoolean(wsig->boolean())
00543 ;
00544 return temp;
00545 }
00546
00547 static Type infereDocAccessTblType(Type tbl, Type ridx)
00548 {
00549 Type temp = tbl
00550 ->promoteVariability(ridx->variability())
00551 ->promoteComputability(ridx->computability())
00552 ->promoteVectorability(ridx->vectorability())
00553 ;
00554 return temp;
00555 }
00556
00560 static Type initialRecType(Tree t)
00561 {
00562 if (isList(t)) {
00563 vector<Type> v;
00564 do { v.push_back(initialRecType(hd(t))); t = tl(t); } while (isList(t));
00565 return new TupletType(v);
00566 } else {
00567 return TREC;
00568 }
00569 }
00570
00571
00572
00577 static Type infereRecType (Tree var, Tree body, Tree env)
00578 {
00579 Type t0, t1;
00580
00581 t1 = initialRecType(body);
00582 do {
00583 t0 = t1;
00584 setProperty(var, env, tree((void*)t0));
00585 t1 = T(body, addEnv(var, t0, env));
00586 } while (t1 > t0);
00587
00588 assert (t1 == t0);
00589
00590 if (getRecursivness(body) == 1 || env == NULLENV) {
00591 setSigType(var, t1);
00592 T(body, NULLENV);
00593 }
00594 return t1;
00595 }
00596
00597
00601 static Type infereFFType (Tree ff, Tree ls, Tree env)
00602 {
00603
00604
00605
00606
00607 if (ffarity(ff)==0) {
00608
00609 return new SimpleType(ffrestype(ff),kSamp,kInit,kVect,kNum, interval());
00610 } else {
00611
00612
00613 Type t = new SimpleType(kInt,kKonst,kInit,kVect,kNum, interval());
00614 while (isList(ls)) { t = t|T(hd(ls),env); ls=tl(ls); }
00615
00616
00617
00618 return new SimpleType( ffrestype(ff),
00619 t->variability(),
00620 t->computability(),
00621 t->vectorability(),
00622 t->boolean(),
00623 interval() );
00624 }
00625 }
00626
00630 static Type infereFConstType (Tree type)
00631 {
00632
00633
00634
00635 return new SimpleType(tree2int(type),kKonst,kInit,kVect,kNum, interval());
00636 }
00637
00641 static Type infereFVarType (Tree type)
00642 {
00643
00644
00645 return new SimpleType(tree2int(type),kBlock,kExec,kVect,kNum, interval());
00646 }
00647
00648
00649
00650
00654 static Type infereXType(Tree sig, Tree env)
00655 {
00656
00657
00658 xtended* p = (xtended*) getUserData(sig);
00659 vector<Type> vt;
00660
00661 for (int i = 0; i < sig->arity(); i++) vt.push_back(T(sig->branch(i), env));
00662 return p->infereSigType(vt);
00663 }