static inline bool isBoxPatternOp(Tree box, Node& n, Tree& t1, Tree& t2) { if (isBoxPar(box, t1, t2) || isBoxSeq(box, t1, t2) || isBoxSplit(box, t1, t2) || isBoxMerge(box, t1, t2) || isBoxRec(box, t1, t2)) { n = box->node(); return true; } else { return false; } }
ostream& boxpp::print (ostream& fout) const { int i, id; double r; prim0 p0; prim1 p1; prim2 p2; prim3 p3; prim4 p4; prim5 p5; Tree t1, t2, t3, ff, label, cur, min, max, step, type, name, file, arg, body, fun, args, abstr, genv, vis, lenv, ldef, slot, ident, rules; const char* str; xtended* xt = (xtended*) getUserData(box); // primitive elements if (xt) fout << xt->name(); else if (isBoxInt(box, &i)) fout << i; else if (isBoxReal(box, &r)) fout << T(r); else if (isBoxCut(box)) fout << '!'; else if (isBoxWire(box)) fout << '_'; else if (isBoxIdent(box, &str)) fout << str; else if (isBoxPrim0(box, &p0)) fout << prim0name(p0); else if (isBoxPrim1(box, &p1)) fout << prim1name(p1); else if (isBoxPrim2(box, &p2)) fout << prim2name(p2); else if (isBoxPrim3(box, &p3)) fout << prim3name(p3); else if (isBoxPrim4(box, &p4)) fout << prim4name(p4); else if (isBoxPrim5(box, &p5)) fout << prim5name(p5); else if (isBoxAbstr(box,arg,body)) fout << "\\" << boxpp(arg) << ".(" << boxpp(body) << ")"; else if (isBoxAppl(box, fun, args)) fout << boxpp(fun) << boxpp(args) ; else if (isBoxWithLocalDef(box, body, ldef)) fout << boxpp(body) << " with { " << envpp(ldef) << " }"; // foreign elements else if (isBoxFFun(box, ff)) { fout << "ffunction(" << type2str(ffrestype(ff)); Tree namelist = nth(ffsignature(ff),1); char sep = ' '; for (int i = 0; i < gFloatSize; i++) { fout << sep << tree2str(nth(namelist,i)); sep = '|'; } sep = '('; for (int i = 0; i < ffarity(ff); i++) { fout << sep << type2str(ffargtype(ff, i)); sep = ','; } fout << ')'; fout << ',' << ffincfile(ff) << ',' << fflibfile(ff) << ')'; } else if (isBoxFConst(box, type, name, file)) fout << "fconstant(" << type2str(tree2int(type)) << ' ' << tree2str(name) << ", " << tree2str(file) << ')'; else if (isBoxFVar(box, type, name, file)) fout << "fvariable(" << type2str(tree2int(type)) << ' ' << tree2str(name) << ", " << tree2str(file) << ')'; // block diagram binary operator else if (isBoxSeq(box, t1, t2)) streambinop(fout, t1, " : ", t2, 1, priority); else if (isBoxSplit(box, t1, t2)) streambinop(fout, t1, "<:", t2, 1, priority); else if (isBoxMerge(box, t1, t2)) streambinop(fout, t1, ":>", t2, 1, priority); else if (isBoxPar(box, t1, t2)) streambinop(fout, t1,",",t2, 2, priority); else if (isBoxRec(box, t1, t2)) streambinop(fout, t1,"~",t2, 4, priority); // iterative block diagram construction else if (isBoxIPar(box, t1, t2, t3)) fout << "par(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}"; else if (isBoxISeq(box, t1, t2, t3)) fout << "seq(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}"; else if (isBoxISum(box, t1, t2, t3)) fout << "sum(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}"; else if (isBoxIProd(box, t1, t2, t3)) fout << "prod(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}"; else if (isBoxInputs(box, t1)) fout << "inputs(" << boxpp(t1) << ")"; else if (isBoxOutputs(box, t1)) fout << "outputs(" << boxpp(t1) << ")"; // user interface else if (isBoxButton(box, label)) fout << "button(" << tree2quotedstr(label) << ')'; else if (isBoxCheckbox(box, label)) fout << "checkbox(" << tree2quotedstr(label) << ')'; else if (isBoxVSlider(box, label, cur, min, max, step)) { fout << "vslider(" << tree2quotedstr(label) << ", " << boxpp(cur) << ", " << boxpp(min) << ", " << boxpp(max) << ", " << boxpp(step)<< ')'; } else if (isBoxHSlider(box, label, cur, min, max, step)) { fout << "hslider(" << tree2quotedstr(label) << ", " << boxpp(cur) << ", " << boxpp(min) << ", " << boxpp(max) << ", " << boxpp(step)<< ')'; } else if (isBoxVGroup(box, label, t1)) { fout << "vgroup(" << tree2quotedstr(label) << ", " << boxpp(t1, 0) << ')'; } else if (isBoxHGroup(box, label, t1)) { fout << "hgroup(" << tree2quotedstr(label) << ", " << boxpp(t1, 0) << ')'; } else if (isBoxTGroup(box, label, t1)) { fout << "tgroup(" << tree2quotedstr(label) << ", " << boxpp(t1, 0) << ')'; } else if (isBoxHBargraph(box, label, min, max)) { fout << "hbargraph(" << tree2quotedstr(label) << ", " << boxpp(min) << ", " << boxpp(max) << ')'; } else if (isBoxVBargraph(box, label, min, max)) { fout << "vbargraph(" << tree2quotedstr(label) << ", " << boxpp(min) << ", " << boxpp(max) << ')'; } else if (isBoxNumEntry(box, label, cur, min, max, step)) { fout << "nentry(" << tree2quotedstr(label) << ", " << boxpp(cur) << ", " << boxpp(min) << ", " << boxpp(max) << ", " << boxpp(step)<< ')'; } else if (isNil(box)) { fout << "()" ; } else if (isList(box)) { Tree l = box; char sep = '('; do { fout << sep << boxpp(hd(l)); sep = ','; l = tl(l); } while (isList(l)); fout << ')'; } else if (isBoxWaveform(box)) { fout << "waveform"; char sep = '{'; for (int i=0; i<box->arity(); i++) { fout << sep << boxpp(box->branch(i)); sep = ','; } fout << '}'; /* size_t n = box->arity(); if (n < 6) { // small waveform, print all data fout << "waveform"; char sep = '{'; for (size_t i=0; i<n; i++) { fout << sep << boxpp(box->branch(i)); sep = ','; } fout << '}'; } else { // large waveform print only first and last values fout << "waveform{" << box->branch(0) << ", ..<" << n-2 << ">..," << box->branch(n-1) << "}"; } */ } else if (isBoxEnvironment(box)) { fout << "environment"; } else if (isClosure(box, abstr, genv, vis, lenv)) { fout << "closure[" << boxpp(abstr) << ", genv = " << envpp(genv) << ", lenv = " << envpp(lenv) << "]"; } else if (isBoxComponent(box, label)) { fout << "component(" << tree2quotedstr(label) << ')'; } else if (isBoxAccess(box, t1, t2)) { fout << boxpp(t1) << '.' << boxpp(t2); } else if (isImportFile(box, label)) { fout << "import(" << tree2quotedstr(label) << ')'; } else if (isBoxSlot(box, &id)) { //fout << "#" << id; fout << "x" << id; } else if (isBoxSymbolic(box, slot, body)) { fout << "\\(" << boxpp(slot) << ").(" << boxpp(body) << ")"; } // Pattern Matching Extensions else if (isBoxCase(box, rules)) { fout << "case {"; while (!isNil(rules)) { printRule(fout, hd(rules)); rules = tl(rules); } fout << "}"; } #if 1 // more useful for debugging output else if (isBoxPatternVar(box, ident)) { fout << "<" << boxpp(ident) << ">"; } #else // beautify messages involving lhs patterns else if (isBoxPatternVar(box, ident)) { fout << boxpp(ident); } #endif else if (isBoxPatternMatcher(box)) { fout << "PM[" << box << "]"; } else if (isBoxError(box)) { fout << "ERROR"; } //else if (isImportFile(box, filename)) { // printf("filename %s\n", tree2str(filename)); // fout << tree2quotedstr(filename); //} // None of the previous tests succeded, then it is not a valid box else { cerr << "Error in box::print() : " << *box << " is not a valid box" << endl; exit(1); } return fout; }
/** * Prepare a "pattern" by replacing variables x by special * pattern variables ?x. * * P[x] -> ?x * P[x(e)] -> x(P[e]) * P[e(f)] -> P[e](P[f]) * P[e:f] -> P[e]:P[f] * etc. */ static Tree preparePattern(Tree box) { // cerr << "preparePattern(" << boxpp(box) << ")" << endl; int id; double r; prim0 p0; prim1 p1; prim2 p2; prim3 p3; prim4 p4; prim5 p5; Tree t1, t2, t3, ff, label, cur, min, max, step, type, name, file, arg, body, fun, args, ldef, slot, ident, rules; xtended* xt = (xtended*)getUserData(box); // primitive elements if(xt) return box; else if(isBoxIdent(box)) return boxPatternVar(box); else if(isBoxAppl(box, fun, args)) { if(isBoxIdent(fun)) return boxAppl(fun, lmap(preparePattern, args)); else return boxAppl(preparePattern(fun), lmap(preparePattern, args)); } else if(isBoxAbstr(box, arg, body)) return box; else if(isBoxInt(box)) return box; else if(isBoxReal(box, &r)) return box; else if(isBoxWaveform(box)) return box; else if(isBoxCut(box)) return box; else if(isBoxWire(box)) return box; else if(isBoxPrim0(box, &p0)) return box; else if(isBoxPrim1(box, &p1)) return box; else if(isBoxPrim2(box, &p2)) return box; else if(isBoxPrim3(box, &p3)) return box; else if(isBoxPrim4(box, &p4)) return box; else if(isBoxPrim5(box, &p5)) return box; else if(isBoxWithLocalDef(box, body, ldef)) return boxWithLocalDef(preparePattern(body), ldef); // foreign elements else if(isBoxFFun(box, ff)) return box; else if(isBoxFConst(box, type, name, file)) return box; else if(isBoxFVar(box, type, name, file)) return box; // block diagram binary operator else if(isBoxSeq(box, t1, t2)) return boxSeq(preparePattern(t1), preparePattern(t2)); else if(isBoxSplit(box, t1, t2)) return boxSplit(preparePattern(t1), preparePattern(t2)); else if(isBoxMerge(box, t1, t2)) return boxMerge(preparePattern(t1), preparePattern(t2)); else if(isBoxPar(box, t1, t2)) return boxPar(preparePattern(t1), preparePattern(t2)); else if(isBoxRec(box, t1, t2)) return boxRec(preparePattern(t1), preparePattern(t2)); // iterative block diagram construction else if(isBoxIPar(box, t1, t2, t3)) return boxIPar(t1, t2, preparePattern(t3)); else if(isBoxISeq(box, t1, t2, t3)) return boxISeq(t1, t2, preparePattern(t3)); else if(isBoxISum(box, t1, t2, t3)) return boxISum(t1, t2, preparePattern(t3)); else if(isBoxIProd(box, t1, t2, t3)) return boxIProd(t1, t2, preparePattern(t3)); // static information else if(isBoxInputs(box, t1)) return boxInputs(preparePattern(t1)); else if(isBoxOutputs(box, t1)) return boxOutputs(preparePattern(t1)); // user interface else if(isBoxButton(box, label)) return box; else if(isBoxCheckbox(box, label)) return box; else if(isBoxVSlider(box, label, cur, min, max, step)) return box; else if(isBoxHSlider(box, label, cur, min, max, step)) return box; else if(isBoxVGroup(box, label, t1)) return boxVGroup(label, preparePattern(t1)); else if(isBoxHGroup(box, label, t1)) return boxHGroup(label, preparePattern(t1)); else if(isBoxTGroup(box, label, t1)) return boxTGroup(label, preparePattern(t1)); else if(isBoxHBargraph(box, label, min, max)) return box; else if(isBoxVBargraph(box, label, min, max)) return box; else if(isBoxNumEntry(box, label, cur, min, max, step)) return box; else if(isNil(box)) return box; else if(isList(box)) return lmap(preparePattern, box); else if(isBoxEnvironment(box)) return box; /* not expected else if (isClosure(box, abstr, genv, vis, lenv)) { fout << "closure[" << boxpp(abstr) << ", genv = " << envpp(genv) << ", lenv = " << envpp(lenv) << "]"; } */ else if(isBoxComponent(box, label)) return box; else if(isBoxAccess(box, t1, t2)) return box; /* not expected else if (isImportFile(box, label)) { fout << "import(" << tree2str(label) << ')'; } */ else if(isBoxSlot(box, &id)) return box; else if(isBoxSymbolic(box, slot, body)) return box; // Pattern Matching Extensions else if(isBoxCase(box, rules)) return box; else if(isBoxPatternVar(box, ident)) return box; // None of the previous tests succeded, then it is not a valid box else { cerr << "Error in preparePattern() : " << *box << " is not a valid box" << endl; exit(1); } return box; }
static Tree realeval (Tree exp, Tree visited, Tree localValEnv) { //Tree def; Tree fun; Tree arg; Tree var, num, body, ldef; Tree label; Tree cur, lo, hi, step; Tree e1, e2, exp2, notused, visited2, lenv2; Tree rules; Tree id; //cerr << "EVAL " << *exp << " (visited : " << *visited << ")" << endl; //cerr << "REALEVAL of " << *exp << endl; xtended* xt = (xtended*) getUserData(exp); // constants //----------- if ( xt || isBoxInt(exp) || isBoxReal(exp) || isBoxWire(exp) || isBoxCut(exp) || isBoxPrim0(exp) || isBoxPrim1(exp) || isBoxPrim2(exp) || isBoxPrim3(exp) || isBoxPrim4(exp) || isBoxPrim5(exp) || isBoxFFun(exp) || isBoxFConst(exp) || isBoxFVar(exp) || isBoxWaveform(exp)) { return exp; // block-diagram constructors //--------------------------- } else if (isBoxSeq(exp, e1, e2)) { return boxSeq(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv)); } else if (isBoxPar(exp, e1, e2)) { return boxPar(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv)); } else if (isBoxRec(exp, e1, e2)) { return boxRec(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv)); } else if (isBoxSplit(exp, e1, e2)) { return boxSplit(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv)); } else if (isBoxMerge(exp, e1, e2)) { return boxMerge(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv)); // Modules //-------- } else if (isBoxAccess(exp, body, var)) { Tree val = eval(body, visited, localValEnv); if (isClosure(val, exp2, notused, visited2, lenv2)) { // it is a closure, we have an environment to access return eval(closure(var,notused,visited2,lenv2), visited, localValEnv); } else { evalerror(getDefFileProp(exp), getDefLineProp(exp), "no environment to access", exp); } //////////////////////en chantier//////////////////////////// } else if (isBoxModifLocalDef(exp, body, ldef)) { Tree val = eval(body, visited, localValEnv); if (isClosure(val, exp2, notused, visited2, lenv2)) { // we rebuild the closure using a copy of the original environment // modified with some new definitions Tree lenv3 = copyEnvReplaceDefs(lenv2, ldef, visited2, localValEnv); return eval(closure(exp2,notused,visited2,lenv3), visited, localValEnv); } else { evalerror(getDefFileProp(exp), getDefLineProp(exp), "not a closure", val); evalerror(getDefFileProp(exp), getDefLineProp(exp), "no environment to access", exp); } /////////////////////////////////////////////////////////////////// } else if (isBoxComponent(exp, label)) { string fname = tree2str(label); Tree eqlst = gGlobal->gReader.expandlist(gGlobal->gReader.getlist(fname)); Tree res = closure(boxIdent("process"), gGlobal->nil, gGlobal->nil, pushMultiClosureDefs(eqlst, gGlobal->nil, gGlobal->nil)); setDefNameProperty(res, label); //cerr << "component is " << boxpp(res) << endl; return res; } else if (isBoxLibrary(exp, label)) { string fname = tree2str(label); Tree eqlst = gGlobal->gReader.expandlist(gGlobal->gReader.getlist(fname)); Tree res = closure(boxEnvironment(), gGlobal->nil, gGlobal->nil, pushMultiClosureDefs(eqlst, gGlobal->nil, gGlobal->nil)); setDefNameProperty(res, label); //cerr << "component is " << boxpp(res) << endl; return res; // user interface elements //------------------------ } else if (isBoxButton(exp, label)) { const char* l1 = tree2str(label); const char* l2 = evalLabel(l1, visited, localValEnv); //cout << "button label : " << l1 << " become " << l2 << endl; return ((l1 == l2) ? exp : boxButton(tree(l2))); } else if (isBoxCheckbox(exp, label)) { const char* l1 = tree2str(label); const char* l2 = evalLabel(l1, visited, localValEnv); //cout << "check box label : " << l1 << " become " << l2 << endl; return ((l1 == l2) ? exp : boxCheckbox(tree(l2))); } else if (isBoxVSlider(exp, label, cur, lo, hi, step)) { const char* l1 = tree2str(label); const char* l2 = evalLabel(l1, visited, localValEnv); return ( boxVSlider(tree(l2), tree(eval2double(cur, visited, localValEnv)), tree(eval2double(lo, visited, localValEnv)), tree(eval2double(hi, visited, localValEnv)), tree(eval2double(step, visited, localValEnv)))); } else if (isBoxHSlider(exp, label, cur, lo, hi, step)) { const char* l1 = tree2str(label); const char* l2 = evalLabel(l1, visited, localValEnv); return ( boxHSlider(tree(l2), tree(eval2double(cur, visited, localValEnv)), tree(eval2double(lo, visited, localValEnv)), tree(eval2double(hi, visited, localValEnv)), tree(eval2double(step, visited, localValEnv)))); } else if (isBoxNumEntry(exp, label, cur, lo, hi, step)) { const char* l1 = tree2str(label); const char* l2 = evalLabel(l1, visited, localValEnv); return (boxNumEntry(tree(l2), tree(eval2double(cur, visited, localValEnv)), tree(eval2double(lo, visited, localValEnv)), tree(eval2double(hi, visited, localValEnv)), tree(eval2double(step, visited, localValEnv)))); } else if (isBoxVGroup(exp, label, arg)) { const char* l1 = tree2str(label); const char* l2 = evalLabel(l1, visited, localValEnv); return boxVGroup(tree(l2), eval(arg, visited, localValEnv) ); } else if (isBoxHGroup(exp, label, arg)) { const char* l1 = tree2str(label); const char* l2 = evalLabel(l1, visited, localValEnv); return boxHGroup(tree(l2), eval(arg, visited, localValEnv) ); } else if (isBoxTGroup(exp, label, arg)) { const char* l1 = tree2str(label); const char* l2 = evalLabel(l1, visited, localValEnv); return boxTGroup(tree(l2), eval(arg, visited, localValEnv) ); } else if (isBoxHBargraph(exp, label, lo, hi)) { const char* l1 = tree2str(label); const char* l2 = evalLabel(l1, visited, localValEnv); return boxHBargraph(tree(l2), tree(eval2double(lo, visited, localValEnv)), tree(eval2double(hi, visited, localValEnv))); } else if (isBoxVBargraph(exp, label, lo, hi)) { const char* l1 = tree2str(label); const char* l2 = evalLabel(l1, visited, localValEnv); return boxVBargraph(tree(l2), tree(eval2double(lo, visited, localValEnv)), tree(eval2double(hi, visited, localValEnv))); // lambda calculus //---------------- } else if (isBoxIdent(exp)) { return evalIdDef(exp, visited, localValEnv); } else if (isBoxWithLocalDef(exp, body, ldef)) { return eval(body, visited, pushMultiClosureDefs(ldef, visited, localValEnv)); } else if (isBoxAppl(exp, fun, arg)) { return applyList( eval(fun, visited, localValEnv), revEvalList(arg, visited, localValEnv) ); } else if (isBoxAbstr(exp)) { // it is an abstraction : return a closure return closure(exp, gGlobal->nil, visited, localValEnv); } else if (isBoxEnvironment(exp)) { // environment : return also a closure return closure(exp, gGlobal->nil, visited, localValEnv); } else if (isClosure(exp, exp2, notused, visited2, lenv2)) { if (isBoxAbstr(exp2)) { // a 'real' closure return closure(exp2, gGlobal->nil, setUnion(visited,visited2), lenv2); } else if (isBoxEnvironment(exp2)) { // a 'real' closure return closure(exp2, gGlobal->nil, setUnion(visited,visited2), lenv2); } else { // it was a suspended evaluation return eval(exp2, setUnion(visited,visited2), lenv2); } // Algorithmic constructions //-------------------------- } else if (isBoxIPar(exp, var, num, body)) { int n = eval2int(num, visited, localValEnv); return iteratePar(var, n, body, visited, localValEnv); } else if (isBoxISeq(exp, var, num, body)) { int n = eval2int(num, visited, localValEnv); return iterateSeq(var, n, body, visited, localValEnv); } else if (isBoxISum(exp, var, num, body)) { int n = eval2int(num, visited, localValEnv); return iterateSum(var, n, body, visited, localValEnv); } else if (isBoxIProd(exp, var, num, body)) { int n = eval2int(num, visited, localValEnv); return iterateProd(var, n, body, visited, localValEnv); // static } else if (isBoxInputs(exp, body)) { int ins, outs; Tree b = a2sb(eval(body, visited, localValEnv)); if (getBoxType (b, &ins, &outs)) { return boxInt(ins); } else { stringstream error; error << "ERROR : can't evaluate ' : " << *exp << endl; throw faustexception(error.str()); } } else if (isBoxOutputs(exp, body)) { int ins, outs; Tree b = a2sb(eval(body, visited, localValEnv)); if (getBoxType (b, &ins, &outs)) { return boxInt(outs); } else { stringstream error; error << "ERROR : can't evaluate ' : " << *exp << endl; throw faustexception(error.str()); } } else if (isBoxSlot(exp)) { return exp; } else if (isBoxSymbolic(exp)) { return exp; // Pattern matching extension //--------------------------- } else if (isBoxCase(exp, rules)) { return evalCase(rules, localValEnv); } else if (isBoxPatternVar(exp, id)) { return exp; //return evalIdDef(id, visited, localValEnv); } else if (isBoxPatternMatcher(exp)) { return exp; } else { stringstream error; error << "ERROR : EVAL doesn't intercept : " << *exp << endl; throw faustexception(error.str()); } return NULL; }
/** * Simplify inside a block-diagram : S[A*B] => S[A]*S[B] */ Tree insideBoxSimplification (Tree box) { int i; double r; prim0 p0; prim1 p1; prim2 p2; prim3 p3; prim4 p4; prim5 p5; Tree t1, t2, ff, label, cur, min, max, step, type, name, file, slot, body; xtended* xt = (xtended*)getUserData(box); // Extended Primitives if (xt) { return box; } // Numbers and Constants else if (isBoxInt(box, &i)) { return box; } else if (isBoxReal(box, &r)) { return box; } else if (isBoxFConst(box, type, name, file)) { return box; } else if (isBoxFVar(box, type, name, file)) { return box; } // Wire and Cut else if (isBoxCut(box)) { return box; } else if (isBoxWire(box)) { return box; } // Primitives else if (isBoxPrim0(box, &p0)) { return box; } else if (isBoxPrim1(box, &p1)) { return box; } else if (isBoxPrim2(box, &p2)) { return box; } else if (isBoxPrim3(box, &p3)) { return box; } else if (isBoxPrim4(box, &p4)) { return box; } else if (isBoxPrim5(box, &p5)) { return box; } else if (isBoxFFun(box, ff)) { return box; } // User Interface Widgets else if (isBoxButton(box, label)) { return box; } else if (isBoxCheckbox(box, label)) { return box; } else if (isBoxVSlider(box, label, cur, min, max, step)) { return box; } else if (isBoxHSlider(box, label, cur, min, max, step)) { return box; } else if (isBoxNumEntry(box, label, cur, min, max, step)) { return box; } else if (isBoxVBargraph(box, label, min, max)) { return box; } else if (isBoxHBargraph(box, label, min, max)) { return box; } // User Interface Groups else if (isBoxVGroup(box, label, t1)) { return boxVGroup(label, boxSimplification(t1)); } else if (isBoxHGroup(box, label, t1)) { return boxHGroup(label, boxSimplification(t1)); } else if (isBoxTGroup(box, label, t1)) { return boxTGroup(label, boxSimplification(t1)); } // Slots and Symbolic Boxes else if (isBoxSlot(box)) { return box;; } else if (isBoxSymbolic(box, slot, body)){ Tree b = boxSimplification(body); return boxSymbolic(slot,b); } // Block Diagram Composition Algebra else if (isBoxSeq(box, t1, t2)) { Tree s1 = boxSimplification(t1); Tree s2 = boxSimplification(t2); return boxSeq(s1,s2); } else if (isBoxPar(box, t1, t2)) { Tree s1 = boxSimplification(t1); Tree s2 = boxSimplification(t2); return boxPar(s1,s2); } else if (isBoxSplit(box, t1, t2)) { Tree s1 = boxSimplification(t1); Tree s2 = boxSimplification(t2); return boxSplit(s1,s2); } else if (isBoxMerge(box, t1, t2)) { Tree s1 = boxSimplification(t1); Tree s2 = boxSimplification(t2); return boxMerge(s1,s2); } else if (isBoxRec(box, t1, t2)) { Tree s1 = boxSimplification(t1); Tree s2 = boxSimplification(t2); return boxRec(s1,s2); } stringstream error; error << "ERROR in file " << __FILE__ << ':' << __LINE__ << ", unrecognised box expression : " << *box << endl; throw faustexception(error.str()); return 0; }
siglist realPropagate (Tree slotenv, Tree path, Tree box, const siglist& lsig) { int i; double r; prim0 p0; prim1 p1; prim2 p2; prim3 p3; prim4 p4; prim5 p5; Tree t1, t2, ff, label, cur, min, max, step, type, name, file, slot, body, chan; tvec wf; xtended* xt = (xtended*)getUserData(box); // Extended Primitives if (xt) { faustassert(lsig.size() == xt->arity()); return makeList(xt->computeSigOutput(lsig)); } // Numbers and Constants else if (isBoxInt(box, &i)) { faustassert(lsig.size()==0); return makeList(sigInt(i)); } else if (isBoxReal(box, &r)) { faustassert(lsig.size()==0); return makeList(sigReal(r)); } // A Waveform has two outputs it size and a period signal representing its content else if (isBoxWaveform(box)) { faustassert(lsig.size()==0); const tvec br = box->branches(); return listConcat(makeList(sigInt(int(br.size()))), makeList(sigWaveform(br))); } else if (isBoxFConst(box, type, name, file)) { faustassert(lsig.size()==0); return makeList(sigFConst(type, name, file)); } else if (isBoxFVar(box, type, name, file)) { faustassert(lsig.size()==0); return makeList(sigFVar(type, name, file)); } // Wire and Cut else if (isBoxCut(box)) { faustassert(lsig.size()==1); return siglist(); } else if (isBoxWire(box)) { faustassert(lsig.size()==1); return lsig; } // Slots and Symbolic Boxes else if (isBoxSlot(box)) { Tree sig; faustassert(lsig.size()==0); if (!searchEnv(box,sig,slotenv)) { // test YO simplification des diagrames //fprintf(stderr, "propagate : internal error (slot undefined)\n"); sig = sigInput(++gGlobal->gDummyInput); } return makeList(sig); } else if (isBoxSymbolic(box, slot, body)) { faustassert(lsig.size()>0); return propagate(pushEnv(slot,lsig[0],slotenv), path, body, listRange(lsig, 1, (int)lsig.size())); } // Primitives else if (isBoxPrim0(box, &p0)) { faustassert(lsig.size()==0); return makeList(p0()); } else if (isBoxPrim1(box, &p1)) { faustassert(lsig.size()==1); return makeList(p1(lsig[0])); } else if (isBoxPrim2(box, &p2)) { // printf("prim2 recoit : "); print(lsig); printf("\n"); faustassert(lsig.size()==2); if (p2 == &sigEnable) { if (gGlobal->gEnableFlag) { // special case for sigEnable that requires a transformation // enable(X,Y) -> sigEnable(X*Y, Y>0) return makeList(sigEnable( sigMul(lsig[0],lsig[1]), sigGT(lsig[1],sigReal(0.0)))); } else { // We gEnableFlag is false we replace enable by a simple multiplication return makeList(sigMul(lsig[0],lsig[1])); } } else if (p2 == &sigControl) { if (gGlobal->gEnableFlag) { // special case for sigEnable that requires a transformation // enable(X,Y) -> sigEnable(X*Y, Y>0) return makeList(sigEnable( lsig[0], lsig[1])); } else { // We gEnableFlag is false we replace control by identity function return makeList(lsig[0]); } } return makeList( p2(lsig[0],lsig[1]) ); } else if (isBoxPrim3(box, &p3)) { faustassert(lsig.size()==3); return makeList(p3(lsig[0],lsig[1],lsig[2])); } else if (isBoxPrim4(box, &p4)) { faustassert(lsig.size()==4); return makeList(p4(lsig[0],lsig[1],lsig[2],lsig[3])); } else if (isBoxPrim5(box, &p5)) { faustassert(lsig.size()==5); return makeList(p5(lsig[0],lsig[1],lsig[2],lsig[3],lsig[4])); } else if (isBoxFFun(box, ff)) { //cerr << "propagate en boxFFun of arity " << ffarity(ff) << endl; faustassert(int(lsig.size())==ffarity(ff)); return makeList(sigFFun(ff, listConvert(lsig))); } // User Interface Widgets else if (isBoxButton(box, label)) { faustassert(lsig.size()==0); return makeList(sigButton(normalizePath(cons(label, path)))); } else if (isBoxCheckbox(box, label)) { faustassert(lsig.size()==0); return makeList(sigCheckbox(normalizePath(cons(label, path)))); } else if (isBoxVSlider(box, label, cur, min, max, step)) { faustassert(lsig.size()==0); return makeList(sigVSlider(normalizePath(cons(label, path)), cur, min, max, step)); } else if (isBoxHSlider(box, label, cur, min, max, step)) { faustassert(lsig.size()==0); return makeList(sigHSlider(normalizePath(cons(label, path)), cur, min, max, step)); } else if (isBoxNumEntry(box, label, cur, min, max, step)) { faustassert(lsig.size()==0); return makeList(sigNumEntry(normalizePath(cons(label, path)), cur, min, max, step)); } else if (isBoxVBargraph(box, label, min, max)) { faustassert(lsig.size()==1); return makeList(sigVBargraph(normalizePath(cons(label, path)), min, max, lsig[0])); } else if (isBoxHBargraph(box, label, min, max)) { faustassert(lsig.size()==1); return makeList(sigHBargraph(normalizePath(cons(label, path)), min, max, lsig[0])); } else if (isBoxSoundfile(box, label, chan)) { faustassert(lsig.size()==1); Tree fullpath = normalizePath(cons(label, path)); Tree soundfile = sigSoundfile(fullpath); int c = tree2int(chan); siglist lsig2(c+3); lsig2[0] = sigSoundfileLength(soundfile); lsig2[1] = sigSoundfileRate(soundfile); lsig2[2] = sigSoundfileChannels(soundfile); // compute bound limited read index : int(max(0, min(ridx,length-1))) Tree ridx = sigIntCast(tree(gGlobal->gMaxPrim->symbol(), sigInt(0), tree(gGlobal->gMinPrim->symbol(), lsig[0], sigAdd(lsig2[0],sigInt(-1))))); for (int i = 0; i<c; i++) { lsig2[i+3] = sigSoundfileBuffer(soundfile, sigInt(i), ridx); } return lsig2; } // User Interface Groups else if (isBoxVGroup(box, label, t1)) { return propagate(slotenv,cons(cons(tree(0),label), path), t1, lsig); } else if (isBoxHGroup(box, label, t1)) { return propagate(slotenv, cons(cons(tree(1),label), path), t1, lsig); } else if (isBoxTGroup(box, label, t1)) { return propagate(slotenv, cons(cons(tree(2),label), path), t1, lsig); } // Block Diagram Composition Algebra else if (isBoxSeq(box, t1, t2)) { int in1, out1, in2, out2; getBoxType(t1, &in1, &out1); getBoxType(t2, &in2, &out2); faustassert(out1==in2); if (out1 == in2) { return propagate(slotenv, path, t2, propagate(slotenv, path,t1,lsig)); } else if (out1 > in2) { siglist lr = propagate(slotenv, path, t1,lsig); return listConcat(propagate(slotenv, path, t2, listRange(lr, 0, in2)), listRange(lr, in2, out1)); } else { return propagate(slotenv, path, t2, listConcat( propagate(slotenv, path, t1, listRange(lsig,0,in1)), listRange(lsig,in1,in1+in2-out1))); } } else if (isBoxPar(box, t1, t2)) { int in1, out1, in2, out2; getBoxType(t1, &in1, &out1); getBoxType(t2, &in2, &out2); return listConcat(propagate(slotenv, path, t1, listRange(lsig, 0, in1)), propagate(slotenv, path, t2, listRange(lsig, in1, in1+in2))); } else if (isBoxSplit(box, t1, t2)) { int in1, out1, in2, out2; getBoxType(t1, &in1, &out1); getBoxType(t2, &in2, &out2); siglist l1 = propagate(slotenv, path, t1, lsig); siglist l2 = split(l1, in2); return propagate(slotenv, path, t2, l2); } else if (isBoxMerge(box, t1, t2)) { int in1, out1, in2, out2; getBoxType(t1, &in1, &out1); getBoxType(t2, &in2, &out2); siglist l1 = propagate(slotenv, path, t1, lsig); siglist l2 = mix(l1, in2); return propagate(slotenv, path, t2, l2); } else if (isBoxRec(box, t1, t2)) { // Bug Corrected int in1, out1, in2, out2; getBoxType(t1, &in1, &out1); getBoxType(t2, &in2, &out2); Tree slotenv2 = lift(slotenv); // the environment must also be lifted siglist l0 = makeMemSigProjList(ref(1), in2); siglist l1 = propagate(slotenv2, path, t2, l0); siglist l2 = propagate(slotenv2, path, t1, listConcat(l1,listLift(lsig))); siglist l3 = (gGlobal->gFTZMode > 0) ? wrapWithFTZ(l2) : l2; Tree g = rec(listConvert(l3)); return makeSigProjList(g, out1); } stringstream error; error << "ERROR in file " << __FILE__ << ':' << __LINE__ << ", unrecognised box expression : " << boxpp(box) << endl; throw faustexception(error.str()); return siglist(); }