00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define TRACE
00022
00032 #include "eval.hh"
00033 #include <stdio.h>
00034 #include "errormsg.hh"
00035 #include "ppbox.hh"
00036 #include "simplify.hh"
00037 #include "propagate.hh"
00038 #include "patternmatcher.hh"
00039 #include "signals.hh"
00040 #include "xtended.hh"
00041 #include "loopDetector.hh"
00042
00043 #include <assert.h>
00044 extern SourceReader gReader;
00045 extern int gMaxNameSize;
00046 extern bool gPatternEvalMode;
00047 extern bool gSimpleNames;
00048
00049
00050
00051
00052
00053
00054 static Tree a2sb(Tree exp);
00055 static Tree eval (Tree exp, Tree visited, Tree localValEnv);
00056 static Tree realeval (Tree exp, Tree visited, Tree localValEnv);
00057 static Tree revEvalList (Tree lexp, Tree visited, Tree localValEnv);
00058 static Tree applyList (Tree fun, Tree larg);
00059 static Tree iteratePar (Tree var, int num, Tree body, Tree visited, Tree localValEnv);
00060 static Tree iterateSeq (Tree id, int num, Tree body, Tree visited, Tree localValEnv);
00061 static Tree iterateSum (Tree id, int num, Tree body, Tree visited, Tree localValEnv);
00062 static Tree iterateProd (Tree id, int num, Tree body, Tree visited, Tree localValEnv);
00063 static Tree larg2par (Tree larg);
00064 static int eval2int (Tree exp, Tree visited, Tree localValEnv);
00065 static float eval2float (Tree exp, Tree visited, Tree localValEnv);
00066 static const char * evalLabel (const char* l, Tree visited, Tree localValEnv);
00067
00068 static Tree pushMultiClosureDefs(Tree ldefs, Tree visited, Tree lenv);
00069 static Tree evalIdDef(Tree id, Tree visited, Tree env);
00070
00071
00072
00073 static Tree evalCase(Tree rules, Tree env);
00074 static Tree evalRuleList(Tree rules, Tree env);
00075 static Tree evalRule(Tree rule, Tree env);
00076 static Tree evalPatternList(Tree patterns, Tree env);
00077 static Tree evalPattern(Tree pattern, Tree env);
00078
00079 static Tree patternSimplification (Tree pattern);
00080 static bool isBoxNumeric (Tree in, Tree& out);
00081 static Tree replaceBoxNumeric (Tree exp);
00082
00083
00084 static Tree vec2list(const vector<Tree>& v);
00085 static void list2vec(Tree l, vector<Tree>& v);
00086 static Tree listn (int n, Tree e);
00087
00088
00089
00090
00091
00099 Tree evalprocess (Tree eqlist)
00100 {
00101 return a2sb(eval(boxIdent("process"), nil, pushMultiClosureDefs(eqlist, nil, nil)));
00102 }
00103
00104
00105
00106
00107
00115 static Tree real_a2sb(Tree exp);
00116
00117 static Tree a2sb(Tree exp)
00118 {
00119 Tree id;
00120 Tree result = real_a2sb(exp);
00121 if (result != exp && getDefNameProperty(exp, id)) {
00122 setDefNameProperty(result, id);
00123 }
00124 return result;
00125 }
00126
00127 static int gBoxSlotNumber = 0;
00128
00129 static Tree real_a2sb(Tree exp)
00130 {
00131 Tree abstr, visited, unusedEnv, localValEnv, var, name, body;
00132
00133 if (isClosure(exp, abstr, unusedEnv, visited, localValEnv)) {
00134
00135 if (isBoxIdent(abstr)) {
00136
00137 Tree result = a2sb(eval(abstr, visited, localValEnv));
00138
00139
00140 if (getDefNameProperty(exp, name)) setDefNameProperty(result, name);
00141 return result;
00142
00143 } else if (isBoxAbstr(abstr, var, body)) {
00144
00145
00146
00147 Tree slot = boxSlot(++gBoxSlotNumber);
00148 stringstream s; s << boxpp(var);
00149 setDefNameProperty(slot, s.str() );
00150
00151
00152 Tree result = boxSymbolic(slot, a2sb(eval(body, visited, pushValueDef(var, slot, localValEnv))));
00153
00154
00155 if (getDefNameProperty(exp, name)) setDefNameProperty(result, name);
00156 return result;
00157
00158 } else {
00159 evalerror(yyfilename, -1, " a2sb : internal error : not an abstraction inside closure ", exp);
00160 exit(1);
00161 }
00162
00163 } else if (isBoxPatternMatcher(exp)) {
00164
00165
00166
00167 Tree slot = boxSlot(++gBoxSlotNumber);
00168 stringstream s; s << "PM" << gBoxSlotNumber;
00169 setDefNameProperty(slot, s.str() );
00170
00171
00172 Tree result = boxSymbolic(slot, a2sb(applyList(exp, cons(slot,nil))));
00173
00174
00175 if (getDefNameProperty(exp, name)) setDefNameProperty(result, name);
00176 return result;
00177
00178 } else {
00179
00180 Tree B[4];
00181 for (int i = 0; i < exp->arity(); i++) {
00182 B[i] = a2sb(exp->branch(i));
00183 }
00184 return replaceBoxNumeric(CTree::make(exp->node(), exp->arity(), B));
00185 }
00186 }
00187
00194 Tree DEFNAMEPROPERTY = tree(symbol("DEFNAMEPROPERTY"));
00195
00196 void setDefNameProperty(Tree t, Tree id)
00197 {
00198
00199 setProperty(t, DEFNAMEPROPERTY, id);
00200 }
00201
00202 void setDefNameProperty(Tree t, const string& name)
00203 {
00204
00205 int n = name.size();
00206 int m = (gMaxNameSize>1023) ? 1023 : gMaxNameSize;
00207 if (n > m) {
00208
00209 char buf[1024];
00210 int i = 0;
00211
00212 for (; i < m/3; i++) { buf[i] = name[i]; }
00213
00214 buf[i++] = '.';
00215 buf[i++] = '.';
00216 buf[i++] = '.';
00217
00218 for (int c = n-m/3; c<n; c++, i++) { buf[i] = name[c]; }
00219 buf[i] = 0;
00220 setProperty(t, DEFNAMEPROPERTY, tree(buf));
00221 } else {
00222 setProperty(t, DEFNAMEPROPERTY, tree(name.c_str()));
00223 }
00224
00225 }
00226
00227 bool getDefNameProperty(Tree t, Tree& id)
00228 {
00229
00230 return getProperty(t, DEFNAMEPROPERTY, id);
00231 }
00232
00233 static bool autoName(Tree exp , Tree& id)
00234 {
00235 stringstream s; s << boxpp(exp);
00236 id = tree(s.str().c_str());
00237 return true;
00238 }
00239
00240 bool getArgName(Tree t, Tree& id)
00241 {
00242
00243 return autoName(t, id) ;
00244 }
00245
00246
00247
00257 static loopDetector LD(1024, 1);
00258
00259
00260 static Node EVALPROPERTY(symbol("EvalProperty"));
00261
00267 void setEvalProperty(Tree box, Tree env, Tree value)
00268 {
00269
00270 setProperty(box, tree(EVALPROPERTY,env), value);
00271 }
00272
00273
00281 bool getEvalProperty(Tree box, Tree env, Tree& value)
00282 {
00283 return getProperty(box, tree(EVALPROPERTY,env), value);
00284 }
00285
00286
00287 static Tree eval (Tree exp, Tree visited, Tree localValEnv)
00288 {
00289 Tree id;
00290 Tree result;
00291
00292 LD.detect(cons(exp,localValEnv));
00293
00294 if (!getEvalProperty(exp, localValEnv, result)) {
00295 result = realeval(exp, visited, localValEnv);
00296 setEvalProperty(exp, localValEnv, result);
00297
00298
00299
00300 if (getDefNameProperty(exp, id)) {
00301 setDefNameProperty(result, id);
00302 }
00303 }
00304 return result;
00305 }
00306
00317 static Tree realeval (Tree exp, Tree visited, Tree localValEnv)
00318 {
00319
00320 Tree fun;
00321 Tree arg;
00322 Tree var, num, body, ldef;
00323 Tree label;
00324 Tree cur, lo, hi, step;
00325 Tree e1, e2, exp2, notused, visited2, lenv2;
00326 Tree rules;
00327 Tree id;
00328
00329
00330
00331
00332 xtended* xt = (xtended*) getUserData(exp);
00333
00334
00335
00336
00337
00338 if ( xt ||
00339 isBoxInt(exp) || isBoxReal(exp) ||
00340 isBoxWire(exp) || isBoxCut(exp) ||
00341 isBoxPrim0(exp) || isBoxPrim1(exp) ||
00342 isBoxPrim2(exp) || isBoxPrim3(exp) ||
00343 isBoxPrim4(exp) || isBoxPrim5(exp) ||
00344 isBoxFFun(exp) || isBoxFConst(exp) || isBoxFVar(exp) ) {
00345 return exp;
00346
00347
00348
00349
00350 } else if ( isBoxSeq(exp, e1, e2) ) {
00351 return boxSeq(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
00352
00353 } else if ( isBoxPar(exp, e1, e2) ) {
00354 return boxPar(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
00355
00356 } else if ( isBoxRec(exp, e1, e2) ) {
00357 return boxRec(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
00358
00359 } else if ( isBoxSplit(exp, e1, e2) ) {
00360 return boxSplit(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
00361
00362 } else if ( isBoxMerge(exp, e1, e2) ) {
00363 return boxMerge(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
00364
00365
00366
00367
00368 } else if (isBoxAccess(exp, body, var)) {
00369 Tree val = eval(body, visited, localValEnv);
00370 if (isClosure(val, exp2, notused, visited2, lenv2)) {
00371
00372 return eval(closure(var,notused,visited2,lenv2), visited, localValEnv);
00373 } else {
00374 evalerror(getDefFileProp(exp), getDefLineProp(exp), "No environment to access ", exp);
00375 exit(1);
00376 }
00377
00378 } else if (isBoxComponent(exp, label)) {
00379 string fname = tree2str(label);
00380 Tree eqlst = gReader.expandlist(gReader.getlist(fname));
00381 Tree res = closure(boxIdent("process"), nil, nil, pushMultiClosureDefs(eqlst, nil, nil));
00382 setDefNameProperty(res, label);
00383
00384 return res;
00385
00386
00387
00388
00389
00390 } else if (isBoxButton(exp, label)) {
00391 const char* l1 = tree2str(label);
00392 const char* l2= evalLabel(l1, visited, localValEnv);
00393
00394 return ((l1 == l2) ? exp : boxButton(tree(l2)));
00395
00396 } else if (isBoxCheckbox(exp, label)) {
00397 const char* l1 = tree2str(label);
00398 const char* l2= evalLabel(l1, visited, localValEnv);
00399
00400 return ((l1 == l2) ? exp : boxCheckbox(tree(l2)));
00401
00402 } else if (isBoxVSlider(exp, label, cur, lo, hi, step)) {
00403 const char* l1 = tree2str(label);
00404 const char* l2= evalLabel(l1, visited, localValEnv);
00405 return ( boxVSlider(tree(l2),
00406 tree(eval2float(cur, visited, localValEnv)),
00407 tree(eval2float(lo, visited, localValEnv)),
00408 tree(eval2float(hi, visited, localValEnv)),
00409 tree(eval2float(step, visited, localValEnv))));
00410
00411 } else if (isBoxHSlider(exp, label, cur, lo, hi, step)) {
00412 const char* l1 = tree2str(label);
00413 const char* l2= evalLabel(l1, visited, localValEnv);
00414 return ( boxHSlider(tree(l2),
00415 tree(eval2float(cur, visited, localValEnv)),
00416 tree(eval2float(lo, visited, localValEnv)),
00417 tree(eval2float(hi, visited, localValEnv)),
00418 tree(eval2float(step, visited, localValEnv))));
00419
00420 } else if (isBoxNumEntry(exp, label, cur, lo, hi, step)) {
00421 const char* l1 = tree2str(label);
00422 const char* l2= evalLabel(l1, visited, localValEnv);
00423 return (boxNumEntry(tree(l2),
00424 tree(eval2float(cur, visited, localValEnv)),
00425 tree(eval2float(lo, visited, localValEnv)),
00426 tree(eval2float(hi, visited, localValEnv)),
00427 tree(eval2float(step, visited, localValEnv))));
00428
00429 } else if (isBoxVGroup(exp, label, arg)) {
00430 const char* l1 = tree2str(label);
00431 const char* l2= evalLabel(l1, visited, localValEnv);
00432 return boxVGroup(tree(l2), eval(arg, visited, localValEnv) );
00433
00434 } else if (isBoxHGroup(exp, label, arg)) {
00435 const char* l1 = tree2str(label);
00436 const char* l2= evalLabel(l1, visited, localValEnv);
00437 return boxHGroup(tree(l2), eval(arg, visited, localValEnv) );
00438
00439 } else if (isBoxTGroup(exp, label, arg)) {
00440 const char* l1 = tree2str(label);
00441 const char* l2= evalLabel(l1, visited, localValEnv);
00442 return boxTGroup(tree(l2), eval(arg, visited, localValEnv) );
00443
00444 } else if (isBoxHBargraph(exp, label, lo, hi)) {
00445 const char* l1 = tree2str(label);
00446 const char* l2= evalLabel(l1, visited, localValEnv);
00447 return boxHBargraph(tree(l2),
00448 tree(eval2float(lo, visited, localValEnv)),
00449 tree(eval2float(hi, visited, localValEnv)));
00450
00451 } else if (isBoxVBargraph(exp, label, lo, hi)) {
00452 const char* l1 = tree2str(label);
00453 const char* l2= evalLabel(l1, visited, localValEnv);
00454 return boxVBargraph(tree(l2),
00455 tree(eval2float(lo, visited, localValEnv)),
00456 tree(eval2float(hi, visited, localValEnv)));
00457
00458
00459
00460
00461 } else if (isBoxIdent(exp)) {
00462 return evalIdDef(exp, visited, localValEnv);
00463
00464 } else if (isBoxWithLocalDef(exp, body, ldef)) {
00465 return eval(body, visited, pushMultiClosureDefs(ldef, visited, localValEnv));
00466
00467 } else if (isBoxAppl(exp, fun, arg)) {
00468 return applyList( eval(fun, visited, localValEnv),
00469 revEvalList(arg, visited, localValEnv) );
00470
00471 } else if (isBoxAbstr(exp)) {
00472
00473 return closure(exp, nil, visited, localValEnv);
00474
00475 } else if (isClosure(exp, exp2, notused, visited2, lenv2)) {
00476
00477 if (isBoxAbstr(exp2)) {
00478
00479 return closure(exp2, nil, setUnion(visited,visited2), lenv2);
00480 } else {
00481
00482 return eval(exp2, setUnion(visited,visited2), lenv2);
00483 }
00484
00485
00486
00487
00488 } else if (isBoxIPar(exp, var, num, body)) {
00489 int n = eval2int(num, visited, localValEnv);
00490 return iteratePar(var, n, body, visited, localValEnv);
00491
00492 } else if (isBoxISeq(exp, var, num, body)) {
00493 int n = eval2int(num, visited, localValEnv);
00494 return iterateSeq(var, n, body, visited, localValEnv);
00495
00496 } else if (isBoxISum(exp, var, num, body)) {
00497 int n = eval2int(num, visited, localValEnv);
00498 return iterateSum(var, n, body, visited, localValEnv);
00499
00500 } else if (isBoxIProd(exp, var, num, body)) {
00501 int n = eval2int(num, visited, localValEnv);
00502 return iterateProd(var, n, body, visited, localValEnv);
00503
00504 } else if (isBoxSlot(exp)) {
00505 return exp;
00506
00507 } else if (isBoxSymbolic(exp)) {
00508
00509 return exp;
00510
00511
00512
00513
00514
00515 } else if (isBoxCase(exp, rules)) {
00516 return evalCase(rules, localValEnv);
00517
00518 } else if (isBoxPatternVar(exp, id)) {
00519 return exp;
00520
00521
00522 } else if (isBoxPatternMatcher(exp)) {
00523 return exp;
00524
00525 } else {
00526 cout << "ERROR : EVAL don't intercept : " << *exp << endl;
00527 exit(1);
00528 }
00529 }
00530
00531
00532
00533 static inline bool isBoxPatternOp(Tree box, Node& n, Tree& t1, Tree& t2)
00534 {
00535 if ( isBoxPar(box, t1, t2) ||
00536 isBoxSeq(box, t1, t2) ||
00537 isBoxSplit(box, t1, t2) ||
00538 isBoxMerge(box, t1, t2) ||
00539 isBoxRec(box, t1, t2) )
00540 {
00541 n = box->node();
00542 return true;
00543 } else {
00544 return false;
00545 }
00546 }
00547
00548
00549 Tree NUMERICPROPERTY = tree(symbol("NUMERICPROPERTY"));
00550
00551 void setNumericProperty(Tree t, Tree num)
00552 {
00553 setProperty(t, NUMERICPROPERTY, num);
00554 }
00555
00556 bool getNumericProperty(Tree t, Tree& num)
00557 {
00558 return getProperty(t, NUMERICPROPERTY, num);
00559 }
00560
00561
00562 static Tree replaceBoxNumeric (Tree exp)
00563 {
00564 int numInputs, numOutputs;
00565 float x;
00566 int i;
00567 Tree out;
00568
00569 if (isBoxInt(exp, &i) || isBoxReal(exp, &x)) {
00570 return exp;
00571 } else if (getNumericProperty(exp, out)) {
00572 return out;
00573 } else {
00574 if ( getBoxType(exp, &numInputs, &numOutputs) && (numInputs == 0) && (numOutputs == 1) ) {
00575
00576 Tree lsignals = boxPropagateSig(nil, exp , makeSigInputList(numInputs) );
00577 assert(isList(lsignals));
00578 Tree res = simplify(hd(lsignals));
00579 if (isSigReal(res, &x)) out = boxReal(x);
00580 else if (isSigInt(res, &i)) out = boxInt(i);
00581 else out = exp;
00582 } else {
00583 out = exp;
00584 }
00585 setNumericProperty(exp,out);
00586 return out;
00587 }
00588 }
00589
00596
00597
00598 Tree simplifyPattern (Tree value)
00599 {
00600 Tree num;
00601 if (!getNumericProperty(value,num)) {
00602 if (!isBoxNumeric(value,num)) {
00603 num = value;
00604 }
00605 setNumericProperty(value,num);
00606 }
00607 return num;
00608 }
00609
00610
00611 static bool isBoxNumeric (Tree in, Tree& out)
00612 {
00613 int numInputs, numOutputs;
00614 float x;
00615 int i;
00616 Tree v;
00617
00618 if (isBoxInt(in, &i) || isBoxReal(in, &x)) {
00619 out = in;
00620 return true;
00621 } else {
00622 v = a2sb(in);
00623 if ( getBoxType(v, &numInputs, &numOutputs) && (numInputs == 0) && (numOutputs == 1) ) {
00624
00625 Tree lsignals = boxPropagateSig(nil, v , makeSigInputList(numInputs) );
00626 Tree res = simplify(hd(lsignals));
00627 if (isSigReal(res, &x)) {
00628 out = boxReal(x);
00629 return true;
00630 }
00631 if (isSigInt(res, &i)) {
00632 out = boxInt(i);
00633 return true;
00634 }
00635 }
00636 return false;
00637 }
00638 }
00639
00640 static Tree patternSimplification (Tree pattern)
00641 {
00642
00643 Node n(0);
00644 Tree v, t1, t2;
00645
00646 if (isBoxNumeric(pattern, v)) {
00647 return v;
00648 } else if (isBoxPatternOp(pattern, n, t1, t2)) {
00649 return tree(n, patternSimplification(t1), patternSimplification(t2));
00650 } else {
00651 return pattern;
00652 }
00653 }
00654
00655
00656
00670 static float eval2float (Tree exp, Tree visited, Tree localValEnv)
00671 {
00672 Tree diagram = eval(exp, visited, localValEnv);
00673 int numInputs, numOutputs;
00674 getBoxType(diagram, &numInputs, &numOutputs);
00675 if ( (numInputs > 0) || (numOutputs != 1) ) {
00676 evalerror (yyfilename, yylineno, "not a constant expression of type : (0->1)", exp);
00677 return 1;
00678 } else {
00679 Tree lsignals = boxPropagateSig(nil, diagram , makeSigInputList(numInputs) );
00680 Tree val = simplify(hd(lsignals));
00681 return tree2float(val);
00682 }
00683 }
00684
00685
00699 static int eval2int (Tree exp, Tree visited, Tree localValEnv)
00700 {
00701 Tree diagram = eval(exp, visited, localValEnv);
00702 int numInputs, numOutputs;
00703 getBoxType(diagram, &numInputs, &numOutputs);
00704 if ( (numInputs > 0) || (numOutputs != 1) ) {
00705 evalerror (yyfilename, yylineno, "not a constant expression of type : (0->1)", exp);
00706 return 1;
00707 } else {
00708 Tree lsignals = boxPropagateSig(nil, diagram , makeSigInputList(numInputs) );
00709 Tree val = simplify(hd(lsignals));
00710 return tree2int(val);
00711 }
00712 }
00713
00714 static bool isDigitChar(char c)
00715 {
00716 return (c >= '0') & (c <= '9');
00717 }
00718
00719 static bool isIdentChar(char c)
00720 {
00721 return ((c >= 'a') & (c <= 'z')) || ((c >= 'A') & (c <= 'Z')) || ((c >= '0') & (c <= '9')) || (c == '_');
00722 }
00723
00724 const char* Formats [] = {"%d", "%1d", "%2d", "%3d", "%4d"};
00725
00726 static char* writeIdentValue(char* dst, int format, const char* ident, Tree visited, Tree localValEnv)
00727 {
00728 int n = eval2int(boxIdent(ident), visited, localValEnv);
00729 int i = min(4,max(format,0));
00730
00731 return dst + sprintf(dst, Formats[i], n);
00732 }
00733
00734 static const char * evalLabel (const char* label, Tree visited, Tree localValEnv)
00735 {
00736 char res[2000];
00737 char ident[64];
00738
00739 const char* src = &label[0];
00740 char* dst = &res[0];
00741 char* id = &ident[0];
00742
00743 bool parametric = false;
00744 int state = 0; int format = 0;
00745 char c;
00746
00747 while ((c=*src++)) {
00748 if (state == 0) {
00749
00750 if (c == '%') {
00751
00752 if (*src == '%') {
00753 *dst++ = *src++;
00754 } else {
00755 state = 1;
00756 format = 0;
00757 parametric = true;
00758 id = &ident[0];
00759 }
00760 } else {
00761 *dst++ = c;
00762 }
00763 } else if (state == 1) {
00764
00765 if (isDigitChar(c)) {
00766 format = format*10 + (c-'0');
00767 } else {
00768 state = 2;
00769 --src;
00770 }
00771
00772 } else {
00773
00774
00775 if (isIdentChar(c)) {
00776 *id++ = c;
00777 } else {
00778 *id = 0;
00779 dst = writeIdentValue(dst, format, ident, visited, localValEnv);
00780 state = 0;
00781 src -= 1;
00782 }
00783 }
00784 }
00785
00786 if (state == 2) {
00787 *id = 0;
00788 dst = writeIdentValue(dst, format, ident, visited, localValEnv);
00789 }
00790 *dst = 0;
00791 return (parametric) ? strdup(res) : label;
00792 }
00793
00794
00795
00809 static Tree iteratePar (Tree id, int num, Tree body, Tree visited, Tree localValEnv)
00810 {
00811 assert (num>0);
00812
00813 Tree res = eval(body, visited, pushValueDef(id, tree(0), localValEnv));
00814 for (int i = 1; i < num; i++) {
00815 res = boxPar(res, eval(body, visited, pushValueDef(id, tree(i), localValEnv)));
00816 }
00817
00818 return res;
00819 }
00820
00821
00822
00835 static Tree iterateSeq (Tree id, int num, Tree body, Tree visited, Tree localValEnv)
00836 {
00837 assert (num>0);
00838
00839 Tree res = eval(body, visited, pushValueDef(id, tree(0), localValEnv));
00840
00841 for (int i = 1; i < num; i++) {
00842 res = boxSeq(res, eval(body, visited, pushValueDef(id, tree(i), localValEnv)));
00843 }
00844
00845 return res;
00846 }
00847
00848
00849
00863 static Tree iterateSum (Tree id, int num, Tree body, Tree visited, Tree localValEnv)
00864 {
00865 assert (num>0);
00866
00867 Tree res = eval(body, visited, pushValueDef(id, tree(0), localValEnv));
00868
00869 for (int i = 1; i < num; i++) {
00870 res = boxSeq(boxPar(res, eval(body, visited, pushValueDef(id, tree(i), localValEnv))),boxPrim2(sigAdd)) ;
00871 }
00872
00873 return res;
00874 }
00875
00876
00877
00891 static Tree iterateProd (Tree id, int num, Tree body, Tree visited, Tree localValEnv)
00892 {
00893 assert (num>0);
00894
00895 Tree res = eval(body, visited, pushValueDef(id, tree(0), localValEnv));
00896
00897 for (int i = 1; i < num; i++) {
00898 res = boxSeq(boxPar(res, eval(body, visited, pushValueDef(id, tree(i), localValEnv))),boxPrim2(sigMul)) ;
00899 }
00900
00901 return res;
00902 }
00903
00915 static Tree applyList (Tree fun, Tree larg)
00916 {
00917 Tree abstr;
00918 Tree globalDefEnv;
00919 Tree visited;
00920 Tree localValEnv;
00921 Tree envList;
00922 Tree originalRules;
00923 Tree revParamList;
00924
00925 Tree id;
00926 Tree body;
00927
00928 Automaton* automat;
00929 int state;
00930
00931 prim2 p2;
00932
00933 if (isNil(larg)) return fun;
00934
00935 if (isBoxError(fun) || isBoxError(larg)) {
00936 return boxError();
00937 }
00938
00939 if (isBoxPatternMatcher(fun, automat, state, envList, originalRules, revParamList)) {
00940 Tree result;
00941 int state2;
00942 vector<Tree> envVect;
00943
00944 list2vec(envList, envVect);
00945 state2 = apply_pattern_matcher(automat, state, hd(larg), result, envVect);
00946 if (state2 >= 0 && isNil(result)) {
00947
00948 return applyList(
00949 boxPatternMatcher(automat, state2, vec2list(envVect), originalRules, cons(hd(larg),revParamList)),
00950 tl(larg) );
00951 } else if (state2 < 0) {
00952 cerr << "ERROR : pattern matching failed, no rule of " << boxpp(boxCase(originalRules))
00953 << " matches argument list " << boxpp(reverse(cons(hd(larg), revParamList))) << endl;
00954 exit(1);
00955 } else {
00956
00957
00958 if (isClosure(result, body, globalDefEnv, visited, localValEnv)) {
00959
00960
00961 return applyList(eval(body, nil, localValEnv), tl(larg));
00962 } else {
00963 cout << "wrong result from pattern matching (not a closure) : " << boxpp(result) << endl;
00964 return boxError();
00965 }
00966 }
00967 }
00968 if (!isClosure(fun, abstr, globalDefEnv, visited, localValEnv)) {
00969 if (isNil(tl(larg)) && isBoxPrim2(fun, &p2) && (p2 != sigPrefix)) {
00970 return boxSeq(boxPar(boxWire(), hd(larg)), fun);
00971 }
00972 return boxSeq(larg2par(larg), fun);
00973 }
00974
00975 if (!isBoxAbstr(abstr, id, body)) {
00976 evalerror(yyfilename, -1, "(internal) not an abstraction inside closure", fun);
00977 exit(1);
00978 }
00979
00980
00981 {
00982 Tree arg = eval(hd(larg), visited, localValEnv);
00983 Tree narg; if ( isBoxNumeric(arg,narg) ) { arg = narg; }
00984 Tree f = eval(body, visited, pushValueDef(id, arg, localValEnv));
00985
00986 Tree fname;
00987 if (getDefNameProperty(fun, fname)) {
00988 stringstream s; s << tree2str(fname); if (!gSimpleNames) s << "(" << boxpp(arg) << ")";
00989 setDefNameProperty(f, s.str());
00990 }
00991 return applyList(f, tl(larg));
00992 }
00993 }
00994
00995
00996
01008 static Tree revEvalList (Tree lexp, Tree visited, Tree localValEnv)
01009 {
01010 Tree result = nil;
01011 while (!isNil(lexp)) {
01012 result = cons(eval(hd(lexp), visited, localValEnv), result);
01013 lexp = tl(lexp);
01014 }
01015 return result;
01016 }
01017
01018
01019
01026 static Tree larg2par (Tree larg)
01027 {
01028 if (isNil(larg)) {
01029 evalerror(yyfilename, -1, "empty list of arguments", larg);
01030 exit(1);
01031 }
01032 if (isNil(tl(larg))) {
01033 return hd(larg);
01034 }
01035 return boxPar(hd(larg), larg2par(tl(larg)));
01036 }
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01058 static Tree pushNewLayer(Tree lenv)
01059 {
01060 return tree(unique("ENV_LAYER"), lenv);
01061 }
01062
01063
01071 static void addLayerDef(Tree id, Tree def, Tree lenv)
01072 {
01073
01074 Tree olddef;
01075 if (getProperty(lenv, id, olddef)) {
01076 if (def == olddef) {
01077 evalwarning(getDefFileProp(id), getDefLineProp(id), "equivalent re-definitions of", id);
01078 } else {
01079 fprintf(stderr, "%s:%d: ERROR: redefinition of symbols are not allowed : ", getDefFileProp(id), getDefLineProp(id));
01080 print(id,stderr);
01081 fprintf(stderr, " is already defined in file \"%s\" line %d \n", getDefFileProp(id), getDefLineProp(id));
01082 gErrorCount++;
01083 }
01084 }
01085 setProperty(lenv, id, def);
01086 }
01087
01088
01096 Tree pushValueDef(Tree id, Tree def, Tree lenv)
01097 {
01098 Tree lenv2 = pushNewLayer(lenv);
01099 addLayerDef(id, def, lenv2);
01100 return lenv2;
01101 }
01102
01103
01111 static Tree pushMultiClosureDefs(Tree ldefs, Tree visited, Tree lenv)
01112 {
01113 Tree lenv2 = pushNewLayer(lenv);
01114 while (!isNil(ldefs)) {
01115 Tree def = hd(ldefs);
01116 Tree id = hd(def);
01117 Tree rhs= tl(def);
01118 Tree cl = closure(tl(def),nil,visited,lenv2);
01119 stringstream s; s << boxpp(id);
01120 if (!isBoxCase(rhs)) setDefNameProperty(cl,s.str());
01121 addLayerDef( id, cl, lenv2 );
01122 ldefs = tl(ldefs);
01123 }
01124 return lenv2;
01125 }
01126
01127
01136 bool searchIdDef(Tree id, Tree& def, Tree lenv)
01137 {
01138
01139
01140 while (!isNil(lenv) && !getProperty(lenv, id, def)) {
01141 lenv = lenv->branch(0);
01142 }
01143 return !isNil(lenv);
01144 }
01145
01146
01147
01158 static Tree evalIdDef(Tree id, Tree visited, Tree lenv)
01159 {
01160 Tree def, name;
01161
01162
01163 while (!isNil(lenv) && !getProperty(lenv, id, def)) {
01164 lenv = lenv->branch(0);
01165 }
01166
01167
01168 if (isNil(lenv)) {
01169 if (gPatternEvalMode) return boxPatternVar(id);
01170 cerr << "undefined symbol " << *id << endl;
01171 evalerror(getDefFileProp(id), getDefLineProp(id), "undefined symbol ", id);
01172 exit(1);
01173
01174 }
01175
01176
01177 Tree p = cons(id,lenv);
01178
01179 if (!getDefNameProperty(def, name)) {
01180
01181 stringstream s; s << boxpp(id);
01182
01183 }
01184
01185
01186 return eval(def, addElement(p,visited), nil);
01187 }
01188
01189
01197 static Tree listn (int n, Tree e)
01198 {
01199 return (n<= 0) ? nil : cons(e, listn(n-1,e));
01200 }
01201
01207 static Node PMPROPERTYNODE(symbol("PMPROPERTY"));
01208
01209 static void setPMProperty(Tree t, Tree env, Tree pm)
01210 {
01211 setProperty(t, tree(PMPROPERTYNODE, env), pm);
01212 }
01213
01214 static bool getPMProperty(Tree t, Tree env, Tree& pm)
01215 {
01216 return getProperty(t, tree(PMPROPERTYNODE, env), pm);
01217 }
01218
01228 static Tree evalCase(Tree rules, Tree env)
01229 {
01230 Tree pm;
01231 if (!getPMProperty(rules, env, pm)) {
01232 Automaton* a = make_pattern_matcher(evalRuleList(rules, env));
01233 pm = boxPatternMatcher(a, 0, listn(len(rules), env), rules, nil);
01234 setPMProperty(rules, env, pm);
01235 }
01236 return pm;
01237 }
01238
01239
01243 static Tree evalRuleList(Tree rules, Tree env)
01244 {
01245 if (isNil(rules)) return nil;
01246 else return cons(evalRule(hd(rules), env), evalRuleList(tl(rules), env));
01247 }
01248
01249
01253 static Tree evalRule(Tree rule, Tree env)
01254 {
01255 return cons(evalPatternList(left(rule), env), right(rule));
01256 }
01257
01258
01262 static Tree evalPatternList(Tree patterns, Tree env)
01263 {
01264 if (isNil(patterns)) {
01265 return nil;
01266 } else {
01267 return cons( evalPattern(hd(patterns), env),
01268 evalPatternList(tl(patterns), env) );
01269 }
01270 }
01271
01272
01277 static Tree evalPattern(Tree pattern, Tree env)
01278 {
01279 bool saveMode = gPatternEvalMode;
01280 gPatternEvalMode = true;
01281 Tree p = eval(pattern, nil, env);
01282 gPatternEvalMode = saveMode;
01283 return patternSimplification(p);
01284 }
01285
01286
01287 static void list2vec(Tree l, vector<Tree>& v)
01288 {
01289 while (!isNil(l)) {
01290 v.push_back(hd(l));
01291 l = tl(l);
01292 }
01293 }
01294
01295
01296 static Tree vec2list(const vector<Tree>& v)
01297 {
01298 Tree l = nil;
01299 int n = v.size();
01300 while (n--) { l = cons(v[n],l); }
01301 return l;
01302 }