string tree2str(TreeNode* t) { if (t == NULL) return ""; if (t->left == NULL && t->right == NULL) return int2string(t->val); if (t->right != NULL) return int2string(t->val) + "(" + tree2str(t->left) + ")" + "(" + tree2str(t->right) + ")"; return int2string(t->val) + "(" + tree2str(t->left) + ")"; }
string tree2str(TreeNode* t) { if(t == nullptr) return ""; string str = std::to_string(t->val); if (t->left != nullptr && t->right != nullptr){ str = str + "(" + tree2str(t->left)+ ")(" + tree2str(t->right) + ")"; } else if (t->left == nullptr && t->right != nullptr){ str = str + "()(" + tree2str(t->right) + ")"; } else if (t->left != nullptr && t->right == nullptr){ str = str + "(" + tree2str(t->left)+ ")"; } return str; }
std::string tree2str(ACCExpr *expr) { if (!expr) return ""; std::string ret, sep, op = expr->value; if (isParen(op)) { ret += op; if (expr->operands.size()) ret += " "; op = ","; } else if (isIdChar(op[0])) { ret += op; } else if (!expr->operands.size() || ((op == "-" || op == "!")/*unary*/ && expr->operands.size() == 1)) ret += op; bool topOp = checkOperand(expr->value) || expr->value == "," || expr->value == "[" || expr->value == PARAMETER_MARKER; for (auto item: expr->operands) { ret += sep; bool addParen = !topOp && !checkOperand(item->value) && item->value != ","; if (addParen) ret += "( "; ret += tree2str(item); if (addParen) ret += " )"; sep = " " + op + " "; if (op == "?") op = ":"; } ret += treePost(expr); return ret; }
ACCExpr *cleanupBool(ACCExpr *expr) { if (!expr) return expr; inBool++; // can be invoked recursively! walkReplaceBuiltin(expr); inBool--; int varIndex = 0; VarMap varMap; DdManager * mgr = Cudd_Init(MAX_NAME_COUNT,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); varIndex = 0; varMap.clear(); DdNode *bdd = tree2BDD(mgr, expr, varMap); char const *inames[MAX_NAME_COUNT]; for (auto item: varMap) inames[item.second->index] = strdup(item.first.c_str()); char * fform = Cudd_FactoredFormString(mgr, bdd, inames); Cudd_RecursiveDeref(mgr, bdd); int err = Cudd_CheckZeroRef(mgr); if (trace_bool) printf("%s: expr '%s' val = %s\n", __FUNCTION__, tree2str(expr).c_str(), fform); assert(err == 0 && "Reference counting"); ACCExpr *ret = str2tree(fform); free(fform); Cudd_Quit(mgr); return ret; }
/** * Get information on a user interface element for documentation. * * @param[in] path The UI full pathname to parse. * @param[out] label The place to store the UI name. * @param[out] unit The place to store the UI unit. */ void DocCompiler::getUIDocInfos(Tree path, string& label, string& unit) { label = ""; unit = ""; map<string, set<string>> metadata; extractMetadata(tree2str(hd(path)), label, metadata); set<string> myunits = metadata["unit"]; // for (set<string>::iterator i = myunits.begin(); i != myunits.end(); i++) { // cerr << "Documentator : getUIDocInfos : metadata[\"unit\"] = " << *i << endl; // } for(map<string, set<string>>::iterator i = metadata.begin(); i != metadata.end(); i++) { const string& key = i->first; const set<string>& values = i->second; for(set<string>::const_iterator j = values.begin(); j != values.end(); j++) { if(key == "unit") unit += *j; } } }
Lateq* DocCompiler::compileLateq(Tree L, Lateq* compiledEqn) { // cerr << "Documentator : compileLateq : L = "; printSignal(L, stdout, 0); cerr << endl; fLateq = compiledEqn; ///< Dynamic field ! int priority = 0; for(int i = 0; isList(L); L = tl(L), i++) { Tree sig = hd(L); Tree id; if(getSigNickname(sig, id)) { // cerr << "Documentator : compileLateq : NICKNAMEPROPERTY = " << tree2str(id) << endl; fLateq->addOutputSigFormula(subst("$0(t) = $1", tree2str(id), CS(sig, priority), docT(i))); } else { // cerr << "Documentator : compileLateq : NO NICKNAMEPROPERTY" << endl; if(fLateq->outputs() == 1) { fLateq->addOutputSigFormula(subst("y(t) = $0", CS(sig, priority))); gDocNoticeFlagMap["outputsig"] = true; } else { fLateq->addOutputSigFormula(subst("$0(t) = $1", getFreshID("y"), CS(sig, priority))); gDocNoticeFlagMap["outputsigs"] = true; } } } return fLateq; }
void Description::addGroup(int level, Tree t) { Tree label, elements, varname, sig; const char* groupnames[] = { "vgroup", "hgroup", "tgroup" }; if(isUiFolder(t, label, elements)) { const int orient = tree2int(left(label)); addLayoutLine(level, subst("<group type=\"$0\">", groupnames[orient])); addLayoutLine(level + 1, subst("<label>$0</label>", checkNullLabel(t, xmlize(tree2str(right(label))), false))); while(!isNil(elements)) { addGroup(level + 1, right(hd(elements))); elements = tl(elements); } addLayoutLine(level, "</group>"); } else if(isUiWidget(t, label, varname, sig)) { int w = addWidget(label, varname, sig); addLayoutLine(level, subst("<widgetref id=\"$0\" />", T(w))); } else { fprintf(stderr, "error in user interface generation 2\n"); exit(1); } }
/** * Generate user interface macros corresponding * to user interface element t */ void Compiler::generateMacroInterfaceTree(const string& pathname, Tree t) { Tree label, elements, varname, sig; if(isUiFolder(t, label, elements)) { string pathname2 = pathname; // string str = unquote(tree2str(right(label))); string str = tree2str(right(label)); if(str.length() > 0) pathname2 += str + "/"; generateMacroInterfaceElements(pathname2, elements); } else if(isUiWidget(t, label, varname, sig)) { generateWidgetMacro(pathname, label, varname, sig); } else { fprintf(stderr, "error in user interface macro generation 2\n"); exit(1); } }
string extractName(Tree fulllabel) { string name; map<string, set<string>> metadata; extractMetadata(tree2str(fulllabel), name, metadata); return name; }
string tree2str(TreeNode* t) { if (!t) { return ""; } auto s = to_string(t->val); if (t->left || t->right) { s += "(" + tree2str(t->left) + ")"; } if (t->right) { s += "(" + tree2str(t->right) + ")"; } return s; }
/** * Generate buildUserInterface C++ lines of code corresponding * to user interface element t */ void Compiler::generateUserInterfaceTree(Tree t) { Tree label, elements, varname, sig; if (isUiFolder(t, label, elements)) { const int orient = tree2int(left(label)); // Empty labels will be renamed with a 0xABCD (address) kind of name that is ignored and not displayed by UI architectures const char* str = tree2str(right(label)); const char* model; // extract metadata from group label str resulting in a simplifiedLabel // and metadata declarations for fictive zone at address 0 string simplifiedLabel; map<string, set<string> > metadata; extractMetadata(str, simplifiedLabel, metadata); // add metadata if any for (map<string, set<string> >::iterator i = metadata.begin(); i != metadata.end(); i++) { const string& key = i->first; const set<string>& values = i->second; for (set<string>::const_iterator j = values.begin(); j != values.end(); j++) { fClass->addUICode(subst("interface->declare($0, \"$1\", \"$2\");", "0", wdel(key) ,wdel(*j))); fJSON.declare(NULL, wdel(key).c_str(), wdel(*j).c_str()); } } //----------------- switch (orient) { case 0 : model = "interface->openVerticalBox(\"$0\");"; fJSON.openVerticalBox(checkNullLabel(t, simplifiedLabel).c_str()); break; case 1 : model = "interface->openHorizontalBox(\"$0\");"; fJSON.openHorizontalBox(checkNullLabel(t, simplifiedLabel).c_str()); break; case 2 : model = "interface->openTabBox(\"$0\");"; fJSON.openTabBox(checkNullLabel(t, simplifiedLabel).c_str()); break; default : fprintf(stderr, "error in user interface generation 1\n"); exit(1); } fClass->addUICode(subst(model, checkNullLabel(t, simplifiedLabel))); generateUserInterfaceElements(elements); fClass->addUICode("interface->closeBox();"); fJSON.closeBox(); } else if (isUiWidget(t, label, varname, sig)) { generateWidgetCode(label, varname, sig); } else { fprintf(stderr, "error in user interface generation 2\n"); exit(1); } }
/** * @brief Get the directory of a user interface element. * * Convert the input reversed path tree into a string. * The name of the UI is stripped (the head of the path tree), * the rest of the tree is a list of pointed pairs, where the names * are contained by the tail of these pointed pairs. * Metadatas (begining by '[') are stripped. * * @param[in] pathname The path tree to convert. * @return <string> A directory-like string. */ string DocCompiler::getUIDir(Tree pathname) { //cerr << "Documentator : getUIDir : print(pathname, stdout) = "; print(pathname, stdout); cerr << endl; string s; Tree dir = reverse(tl(pathname)); while (!isNil(dir)) { string tmp = tree2str(tl(hd(dir))); if ( (tmp[0] != '[') && (!tmp.empty()) ) { s += tmp + '/'; } dir = tl(dir); } return s; }
void updateWidth(ACCExpr *expr, int len) { int ilen = exprWidth(expr); if (ilen < 0 || len < 0) { printf("[%s:%d] len %d ilen %d tree %s\n", __FUNCTION__, __LINE__, len, ilen, tree2str(expr).c_str()); exit(-1); } if (isdigit(expr->value[0]) && len > 0 && expr->value.find("'") == std::string::npos) expr->value = autostr(len) + "'d" + expr->value; else if (isIdChar(expr->value[0])) { if (trace_expr) printf("[%s:%d] ID %s ilen %d len %d\n", __FUNCTION__, __LINE__, tree2str(expr).c_str(), ilen, len); if (ilen > len && len > 0 && !expr->operands.size()) { ACCExpr *subexpr = allocExpr(":", allocExpr(autostr(len-1))); if (len > 1) subexpr->operands.push_back(allocExpr("0")); expr->operands.push_back(allocExpr("[", subexpr)); } } else if (expr->value == ":") // for __phi updateWidth(getRHS(expr), len); else if (expr->value == "?") { updateWidth(getRHS(expr), len); updateWidth(getRHS(expr, 2), len); } else if (arithOp(expr->value) || expr->value == "(") { if (expr->value == "-" && expr->operands.size() == 1 && isdigit(expr->operands.front()->value[0]) && len == 1) { /* hack to update width on "~foo", which translates to "foo ^ -1" in the IR */ expr->value = expr->operands.front()->value; expr->operands.clear(); updateWidth(expr, len); } else for (auto item: expr->operands) updateWidth(item, len); } }
int Description::addWidget(Tree label, Tree varname, Tree sig) { Tree path, c, x, y, z; // add an active widget description if(isSigButton(sig, path)) { fWidgetID++; fActiveWidgetCount++; addActiveLine(subst("<widget type=\"button\" id=\"$0\">", T(fWidgetID))); addActiveLine(subst("\t<label>$0</label>", checkNullLabel(sig, xmlize(tree2str(label)), true))); addActiveLine(subst("\t<varname>$0</varname>", tree2str(varname))); addActiveLine("</widget>"); } else if(isSigCheckbox(sig, path)) { fWidgetID++; fActiveWidgetCount++; addActiveLine(subst("<widget type=\"checkbox\" id=\"$0\">", T(fWidgetID))); addActiveLine(subst("\t<label>$0</label>", checkNullLabel(sig, xmlize(tree2str(label)), true))); addActiveLine(subst("\t<varname>$0</varname>", tree2str(varname))); addActiveLine("</widget>"); } else if(isSigVSlider(sig, path, c, x, y, z)) { fWidgetID++; fActiveWidgetCount++; addActiveLine(subst("<widget type=\"vslider\" id=\"$0\">", T(fWidgetID))); addActiveLine(subst("\t<label>$0</label>", checkNullLabel(sig, xmlize(tree2str(label)), true))); addActiveLine(subst("\t<varname>$0</varname>", tree2str(varname))); addActiveLine(subst("\t<init>$0</init>", T(tree2double(c)))); addActiveLine(subst("\t<min>$0</min>", T(tree2double(x)))); addActiveLine(subst("\t<max>$0</max>", T(tree2double(y)))); addActiveLine(subst("\t<step>$0</step>", T(tree2double(z)))); addActiveLine("</widget>"); } else if(isSigHSlider(sig, path, c, x, y, z)) { fWidgetID++; fActiveWidgetCount++; addActiveLine(subst("<widget type=\"hslider\" id=\"$0\">", T(fWidgetID))); addActiveLine(subst("\t<label>$0</label>", checkNullLabel(sig, xmlize(tree2str(label)), true))); addActiveLine(subst("\t<varname>$0</varname>", tree2str(varname))); addActiveLine(subst("\t<init>$0</init>", T(tree2double(c)))); addActiveLine(subst("\t<min>$0</min>", T(tree2double(x)))); addActiveLine(subst("\t<max>$0</max>", T(tree2double(y)))); addActiveLine(subst("\t<step>$0</step>", T(tree2double(z)))); addActiveLine("</widget>"); } else if(isSigNumEntry(sig, path, c, x, y, z)) { fWidgetID++; fActiveWidgetCount++; addActiveLine(subst("<widget type=\"nentry\" id=\"$0\">", T(fWidgetID))); addActiveLine(subst("\t<label>$0</label>", checkNullLabel(sig, xmlize(tree2str(label)), true))); addActiveLine(subst("\t<varname>$0</varname>", tree2str(varname))); addActiveLine(subst("\t<init>$0</init>", T(tree2double(c)))); addActiveLine(subst("\t<min>$0</min>", T(tree2double(x)))); addActiveLine(subst("\t<max>$0</max>", T(tree2double(y)))); addActiveLine(subst("\t<step>$0</step>", T(tree2double(z)))); addActiveLine("</widget>"); // add a passive widget description } else if(isSigVBargraph(sig, path, x, y, z)) { fWidgetID++; fPassiveWidgetCount++; addPassiveLine(subst("<widget type=\"vbargraph\" id=\"$0\">", T(fWidgetID))); addPassiveLine(subst("\t<label>$0</label>", checkNullLabel(sig, xmlize(tree2str(label)), true))); addPassiveLine(subst("\t<varname>$0</varname>", tree2str(varname))); addPassiveLine(subst("\t<min>$0</min>", T(tree2double(x)))); addPassiveLine(subst("\t<max>$0</max>", T(tree2double(y)))); addPassiveLine("</widget>"); } else if(isSigHBargraph(sig, path, x, y, z)) { fWidgetID++; fPassiveWidgetCount++; addPassiveLine(subst("<widget type=\"hbargraph\" id=\"$0\">", T(fWidgetID))); addPassiveLine(subst("\t<label>$0</label>", checkNullLabel(sig, xmlize(tree2str(label)), true))); addPassiveLine(subst("\t<varname>$0</varname>", tree2str(varname))); addPassiveLine(subst("\t<min>$0</min>", T(tree2double(x)))); addPassiveLine(subst("\t<max>$0</max>", T(tree2double(y)))); addPassiveLine("</widget>"); } else { fprintf(stderr, "Error describing widget : unrecognized expression\n"); exit(1); } return fWidgetID; }
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; }
/** * @brief Main code generator dispatch. * * According to the type of the input signal, generateCode calls * the appropriate generator with appropriate arguments. * * @param sig The signal expression to compile. * @param priority The environment priority of the expression. * @return <string> The LaTeX code translation of the signal. */ string DocCompiler::generateCode(Tree sig, int priority) { int i; double r; Tree c, sel, x, y, z, u, label, ff, largs, type, name, file; if(getUserData(sig)) { printGCCall(sig, "generateXtended"); return generateXtended(sig, priority); } else if(isSigInt(sig, &i)) { printGCCall(sig, "generateNumber"); return generateNumber(sig, docT(i)); } else if(isSigReal(sig, &r)) { printGCCall(sig, "generateNumber"); return generateNumber(sig, docT(r)); } else if(isSigInput(sig, &i)) { printGCCall(sig, "generateInput"); return generateInput(sig, docT(i + 1)); } else if(isSigOutput(sig, &i, x)) { printGCCall(sig, "generateOutput"); return generateOutput(sig, docT(i + 1), CS(x, priority)); } else if(isSigFixDelay(sig, x, y)) { printGCCall(sig, "generateFixDelay"); return generateFixDelay(sig, x, y, priority); } else if(isSigPrefix(sig, x, y)) { printGCCall(sig, "generatePrefix"); return generatePrefix(sig, x, y, priority); } else if(isSigIota(sig, x)) { printGCCall(sig, "generateIota"); return generateIota(sig, x); } else if(isSigBinOp(sig, &i, x, y)) { printGCCall(sig, "generateBinOp"); return generateBinOp(sig, i, x, y, priority); } else if(isSigFFun(sig, ff, largs)) { printGCCall(sig, "generateFFun"); return generateFFun(sig, ff, largs, priority); } else if(isSigFConst(sig, type, name, file)) { printGCCall(sig, "generateFConst"); return generateFConst(sig, tree2str(file), tree2str(name)); } else if(isSigFVar(sig, type, name, file)) { printGCCall(sig, "generateFVar"); return generateFVar(sig, tree2str(file), tree2str(name)); } // new special tables for documentation purposes else if(isSigDocConstantTbl(sig, x, y)) { printGCCall(sig, "generateDocConstantTbl"); return generateDocConstantTbl(sig, x, y); } else if(isSigDocWriteTbl(sig, x, y, z, u)) { printGCCall(sig, "generateDocWriteTbl"); return generateDocWriteTbl(sig, x, y, z, u); } else if(isSigDocAccessTbl(sig, x, y)) { printGCCall(sig, "generateDocAccessTbl"); return generateDocAccessTbl(sig, x, y); } else if(isSigSelect2(sig, sel, x, y)) { printGCCall(sig, "generateSelect2"); return generateSelect2(sig, sel, x, y, priority); } else if(isSigSelect3(sig, sel, x, y, z)) { printGCCall(sig, "generateSelect3"); return generateSelect3(sig, sel, x, y, z, priority); } else if(isProj(sig, &i, x)) { printGCCall(sig, "generateRecProj"); return generateRecProj(sig, x, i, priority); } else if(isSigIntCast(sig, x)) { printGCCall(sig, "generateIntCast"); return generateIntCast(sig, x, priority); } else if(isSigFloatCast(sig, x)) { printGCCall(sig, "generateFloatCast"); return generateFloatCast(sig, x, priority); } else if(isSigButton(sig, label)) { printGCCall(sig, "generateButton"); return generateButton(sig, label); } else if(isSigCheckbox(sig, label)) { printGCCall(sig, "generateCheckbox"); return generateCheckbox(sig, label); } else if(isSigVSlider(sig, label, c, x, y, z)) { printGCCall(sig, "generateVSlider"); return generateVSlider(sig, label, c, x, y, z); } else if(isSigHSlider(sig, label, c, x, y, z)) { printGCCall(sig, "generateHSlider"); return generateHSlider(sig, label, c, x, y, z); } else if(isSigNumEntry(sig, label, c, x, y, z)) { printGCCall(sig, "generateNumEntry"); return generateNumEntry(sig, label, c, x, y, z); } else if(isSigVBargraph(sig, label, x, y, z)) { printGCCall(sig, "generateVBargraph"); return CS(z, priority); }// generateVBargraph (sig, label, x, y, CS(z, priority)); } else if(isSigHBargraph(sig, label, x, y, z)) { printGCCall(sig, "generateHBargraph"); return CS(z, priority); }// generateHBargraph (sig, label, x, y, CS(z, priority)); } else if(isSigAttach(sig, x, y)) { printGCCall(sig, "generateAttach"); return generateAttach(sig, x, y, priority); } else { cerr << "Error in d signal, unrecognized signal : " << *sig << endl; exit(1); } assert(0); return "error in generate code"; }
static DdNode *tree2BDD(DdManager *mgr, ACCExpr *expr, VarMap &varMap) { std::string op = expr->value; DdNode *ret = nullptr; if (op == "&&") op = "&"; else if (op == "||") op = "|"; if (checkInteger(expr, "1")) ret = Cudd_ReadOne(mgr); else if (checkInteger(expr, "0")) ret = Cudd_ReadLogicZero(mgr); else if (op == "!") return Cudd_Not(tree2BDD(mgr, expr->operands.front(), varMap)); // Not passes through ref count else if (op != "&" && op != "|" && op != "^") { if ((op == "!=" || op == "==")) { ACCExpr *lhs = getRHS(expr, 0); if (boolPossible(lhs) && boolPossible(getRHS(expr,1))) goto next; // we can analyze relops on booleans if (trace_bool) printf("[%s:%d] boolnot %d %d = %s\n", __FUNCTION__, __LINE__, boolPossible(getRHS(expr,0)), boolPossible(getRHS(expr,1)), tree2str(expr).c_str()); if (isIdChar(lhs->value[0])) { if (trace_bool) printf("[%s:%d] name %s type %s\n", __FUNCTION__, __LINE__, lhs->value.c_str(), refList[lhs->value].type.c_str()); } } if (op == "!=") // normalize comparison strings expr->value = "=="; std::string name = "( " + tree2str(expr) + " )"; if (!varMap[name]) { varMap[name] = new MapItem; varMap[name]->index = varMap.size(); varMap[name]->node = Cudd_bddIthVar(mgr, varMap[name]->index); } ret = varMap[name]->node; if (op == "!=") { // normalize comparison strings expr->value = op; // restore ret = Cudd_Not(ret); } } if (ret) { Cudd_Ref(ret); return ret; } next:; for (auto item: expr->operands) { DdNode *operand = tree2BDD(mgr, item, varMap), *next; if (!ret) ret = operand; else { if (op == "&") next = Cudd_bddAnd(mgr, ret, operand); else if (op == "|") next = Cudd_bddOr(mgr, ret, operand); else if (op == "^" || op == "!=") next = Cudd_bddXor(mgr, ret, operand); else if (op == "==") next = Cudd_bddXnor(mgr, ret, operand); else { printf("[%s:%d] unknown operator\n", __FUNCTION__, __LINE__); exit(-1); } Cudd_Ref(next); Cudd_RecursiveDeref(mgr, operand); Cudd_RecursiveDeref(mgr, ret); ret = next; } } return ret; }
ostream& ppsig::print (ostream& fout) const { int i; double r; Tree c, sel, x, y, z, u, var, le, label, id, ff, largs, type, name, file; if ( isList(sig) ) { printlist(fout, sig); } else if ( isProj(sig, &i, x) ) { fout << "proj" << i << '(' << ppsig(x, fEnv) << ')'; } else if ( isRec(sig, var, le) ) { printrec(fout, var, le, fHideRecursion /*&& (getRecursivness(sig)==0)*/ ); } // debruinj notation else if ( isRec(sig, le) ) { printrec(fout, le, fHideRecursion ); } else if ( isRef(sig, i) ) { fout << "REF[" << i << "]"; } else if ( getUserData(sig) ) { printextended(fout, sig); } else if ( isSigInt(sig, &i) ) { fout << i; } else if ( isSigReal(sig, &r) ) { fout << T(r); } else if ( isSigWaveform(sig) ) { fout << "waveform{...}"; } else if ( isSigInput(sig, &i) ) { fout << "IN[" << i << "]"; } else if ( isSigOutput(sig, &i, x) ) { printout(fout, i, x) ; } else if ( isSigDelay1(sig, x) ) { fout << ppsig(x, fEnv, 9) << "'"; } //else if ( isSigFixDelay(sig, x, y) ) { printinfix(fout, "@", 8, x, y); } else if ( isSigFixDelay(sig, x, y) ) { printFixDelay(fout, x, y); } else if ( isSigPrefix(sig, x, y) ) { printfun(fout, "prefix", x, y); } else if ( isSigIota(sig, x) ) { printfun(fout, "iota", x); } else if ( isSigBinOp(sig, &i, x, y) ) { printinfix(fout, gBinOpTable[i]->fName, gBinOpTable[i]->fPriority, x, y); } else if ( isSigFFun(sig, ff, largs) ) { printff(fout, ff, largs); } else if ( isSigFConst(sig, type, name, file) ) { fout << tree2str(name); } else if ( isSigFVar(sig, type, name, file) ) { fout << tree2str(name); } else if ( isSigTable(sig, id, x, y) ) { printfun(fout, "TABLE", x, y); } else if ( isSigWRTbl(sig, id, x, y, z) ) { printfun(fout, "write", x, y, z); } else if ( isSigRDTbl(sig, x, y) ) { printfun(fout, "read", x, y); } else if ( isSigGen(sig, x) ) { fout << ppsig(x, fEnv, fPriority); } else if ( isSigDocConstantTbl(sig, x, y) ) { printfun(fout, "docConstantTbl", x, y); } else if ( isSigDocWriteTbl(sig, x, y, z, u) ) { printfun(fout, "docWriteTbl", x, y, z, u); } else if ( isSigDocAccessTbl(sig, x, y) ) { printfun(fout, "docAccessTbl", x, y); } else if ( isSigSelect2(sig, sel, x, y) ) { printfun(fout, "select2", sel, x, y); } else if ( isSigSelect3(sig, sel, x, y, z) ) { printfun(fout, "select3", sel, x, y, z); } else if ( isSigIntCast(sig, x) ) { printfun(fout, "int", x); } else if ( isSigFloatCast(sig, x) ) { printfun(fout, "float", x); } else if ( isSigButton(sig, label) ) { printui(fout, "button", label); } else if ( isSigCheckbox(sig, label) ) { printui(fout, "checkbox", label); } else if ( isSigVSlider(sig, label,c,x,y,z) ) { printui(fout, "vslider", label, c, x, y, z); } else if ( isSigHSlider(sig, label,c,x,y,z) ) { printui(fout, "hslider", label, c, x, y, z); } else if ( isSigNumEntry(sig, label,c,x,y,z) ) { printui(fout, "nentry", label, c, x, y, z); } else if ( isSigVBargraph(sig, label,x,y,z) ) { printui(fout, "vbargraph", label, x, y, z); } else if ( isSigHBargraph(sig, label,x,y,z) ) { printui(fout, "hbargraph", label, x, y, z); } else if ( isSigAttach(sig, x, y) ) { printfun(fout, "attach", x, y); } else { cerr << "NOT A SIGNAL : " << *sig << endl; //exit(1); } return fout; }
static ACCExpr *getExprList(ACCExpr *head, std::string terminator, bool repeatCurrentToken, bool preserveParen) { bool parseState = false; ACCExpr *currentOperand = nullptr; ACCExpr *tok; ACCExpr *exprStack[MAX_EXPR_DEPTH]; int exprStackIndex = 0; #define TOP exprStack[exprStackIndex] TOP = nullptr; if (trace_expr) printf("[%s:%d] head %s\n", __FUNCTION__, __LINE__, head ? head->value.c_str() : "(nil)"); if (head) { while ((tok = get1Token()) && tok->value != terminator) { if (trace_expr) printf("[%s:%d] parseState %d tok->value %s repeat %d\n", __FUNCTION__, __LINE__, parseState, tok->value.c_str(), repeatCurrentToken); if ((parseState = !parseState)) { /* Operand */ ACCExpr *unary = nullptr; ACCExpr *tnext = tok; if (repeatCurrentToken) tok = head; else tnext = get1Token(); repeatCurrentToken = false; if ((tok->value == "-" || tok->value == "!") && !tok->operands.size()) { // unary '-' unary = tok; tok = tnext; tnext = get1Token(); if (trace_expr) printf("[%s:%d] unary '-' unary %p tok %p tnext %p\n", __FUNCTION__, __LINE__, (void *)unary, (void *)tok, (void *)tnext); } if (!checkOperand(tok->value) && !checkOperator(tok->value)) { printf("[%s:%d] OPERAND CHECKFAILLLLLLLLLLLLLLL %s from %s\n", __FUNCTION__, __LINE__, tree2str(tok).c_str(), lexString.c_str()); exit(-1); } while (tnext && (isParen(tnext->value) || isIdChar(tnext->value[0]))) { assert(isIdChar(tok->value[0])); tok->operands.push_back(tnext); tnext = get1Token(); } repeatGet1Token = tnext; if (unary) { unary->operands.push_back(tok); tok = unary; } currentOperand = tok; } else { /* Operator */ std::string L = TOP ? TOP->value : "", R = tok->value; if (!checkOperator(R)) { printf("[%s:%d] OPERATOR CHECKFAILLLLLLLLLLLLLLL %s from %s\n", __FUNCTION__, __LINE__, R.c_str(), lexString.c_str()); exit(-1); } else if (!((L == R && L != "?") || (L == "?" && R == ":"))) { if (TOP) { int lprec = findPrec(L), rprec = findPrec(R); if (lprec < rprec) { exprStackIndex++; TOP = nullptr; } else { TOP->operands.push_back(currentOperand); currentOperand = TOP; while (exprStackIndex > 0 && lprec >= rprec) { exprStackIndex--; TOP->operands.push_back(currentOperand); currentOperand = TOP; L = TOP->value; lprec = findPrec(L); } } } TOP = tok; } TOP->operands.push_back(currentOperand); currentOperand = nullptr; } } while (exprStackIndex != 0) { TOP->operands.push_back(currentOperand); currentOperand = TOP; exprStackIndex--; } if (currentOperand) { if (TOP) TOP->operands.push_back(currentOperand); else TOP = currentOperand; } if (TOP) { if (terminator != "") head->operands.push_back(TOP); // the first item in a recursed list else head = TOP; } } head = cleanupExpr(head, preserveParen); return head; }
/** * Apply a function to a list of arguments. * Apply a function F to a list of arguments (a,b,c,...). * F can be either a closure over an abstraction, or a * pattern matcher. If it is not the case then we have : * F(a,b,c,...) ==> (a,b,c,...):F * * @param fun the function to apply * @param larg the list of arguments * @return the resulting expression in normal form */ static Tree applyList (Tree fun, Tree larg) { Tree abstr; Tree globalDefEnv; Tree visited; Tree localValEnv; Tree envList; Tree originalRules; Tree revParamList; Tree id; Tree body; Automaton* automat; int state; prim2 p2; //cerr << "applyList (" << *fun << ", " << *larg << ")" << endl; if (isNil(larg)) return fun; if (isBoxError(fun) || isBoxError(larg)) { return boxError(); } if (isBoxPatternMatcher(fun, automat, state, envList, originalRules, revParamList)) { Tree result; int state2; vector<Tree> envVect; list2vec(envList, envVect); //cerr << "applyList/apply_pattern_matcher(" << automat << "," << state << "," << *hd(larg) << ")" << endl; state2 = apply_pattern_matcher(automat, state, hd(larg), result, envVect); //cerr << "state2 = " << state2 << "; result = " << *result << endl; if (state2 >= 0 && isNil(result)) { // we need to continue the pattern matching return applyList( boxPatternMatcher(automat, state2, vec2list(envVect), originalRules, cons(hd(larg),revParamList)), tl(larg) ); } else if (state2 < 0) { stringstream error; error << "ERROR : pattern matching failed, no rule of " << boxpp(boxCase(originalRules)) << " matches argument list " << boxpp(reverse(cons(hd(larg), revParamList))) << endl; throw faustexception(error.str()); } else { // Pattern Matching was succesful // the result is a closure that we need to evaluate. if (isClosure(result, body, globalDefEnv, visited, localValEnv)) { // why ??? return simplifyPattern(eval(body, nil, localValEnv)); //return eval(body, nil, localValEnv); return applyList(eval(body, gGlobal->nil, localValEnv), tl(larg)); } else { cerr << "wrong result from pattern matching (not a closure) : " << boxpp(result) << endl; return boxError(); } } } if (!isClosure(fun, abstr, globalDefEnv, visited, localValEnv)) { // principle : f(a,b,c,...) ==> (a,b,c,...):f int ins, outs; // check arity of function Tree efun = a2sb(fun); //cerr << "TRACEPOINT 1 : " << boxpp(efun) << endl; if (!getBoxType(efun, &ins, &outs)) { // on laisse comme ca pour le moment // we can't determine the input arity of the expression // hope for the best return boxSeq(larg2par(larg), fun); } // check arity of arg list if (!boxlistOutputs(larg, &outs)) { // we don't know yet the output arity of larg. Therefore we can't // do any arity checking nor add _ to reach the required number of arguments // cerr << "warning : can't infere the type of : " << boxpp(larg) << endl; return boxSeq(larg2par(larg), fun); } if (outs > ins) { stringstream error; error << "too much arguments : " << outs << ", instead of : " << ins << endl; error << "when applying : " << boxpp(fun) << endl << "to : " << boxpp(larg) << endl; throw faustexception(error.str()); } if ((outs == 1) && (( isBoxPrim2(fun, &p2) && (p2 != sigPrefix)) || (getUserData(fun) && ((xtended*)getUserData(fun))->isSpecialInfix()))) { // special case : /(3) ==> _,3 : / Tree larg2 = concat(nwires(ins-outs), larg); return boxSeq(larg2par(larg2), fun); } else { Tree larg2 = concat(larg, nwires(ins-outs)); return boxSeq(larg2par(larg2), fun); } } if (isBoxEnvironment(abstr)) { evalerrorbox(yyfilename, -1, "an environment can't be used as a function", fun); } if (!isBoxAbstr(abstr, id, body)) { evalerror(yyfilename, -1, "(internal) not an abstraction inside closure", fun); } // try to synthetise a name from the function name and the argument name { Tree arg = eval(hd(larg), visited, localValEnv); Tree narg; if ( isBoxNumeric(arg,narg) ) { arg = narg; } Tree f = eval(body, visited, pushValueDef(id, arg, localValEnv)); Tree fname; if (getDefNameProperty(fun, fname)) { stringstream s; s << tree2str(fname); if (!gGlobal->gSimpleNames) s << "(" << boxpp(arg) << ")"; setDefNameProperty(f, s.str()); } return applyList(f, tl(larg)); } }
/** * @brief Declare an automatic documentation. * * This function simulates a default documentation : * if no <mdoc> tag was found in the input faust file, * and yet the '-mdoc' option was called, * then print a complete 'process' doc. */ void declareAutoDoc() { Tree autodoc = nil; Tree process = boxIdent("process"); /** Autodoc's "head", with title, author, date, and metadatas. */ /** The latex title macro is bound to the metadata "name" if it exists, (corresponding to "declare name") or else just to the file name. */ autodoc = cons(docTxt("\\title{"), autodoc); if (gMetaDataSet.count(tree("name"))) { autodoc = cons(docMtd(tree("name")), autodoc); } else { autodoc = cons(docTxt(gDocName.c_str()), autodoc); } autodoc = cons(docTxt("}\n"), autodoc); /** The latex author macro is bound to the metadata "author" if it exists, (corresponding to "declare author") or else no author item is printed. */ if (gMetaDataSet.count(tree("author"))) { autodoc = cons(docTxt("\\author{"), autodoc); autodoc = cons(docMtd(tree("author")), autodoc); autodoc = cons(docTxt("}\n"), autodoc); } /** The latex date macro is bound to the metadata "date" if it exists, (corresponding to "declare date") or else to the today latex macro. */ autodoc = cons(docTxt("\\date{"), autodoc); if (gMetaDataSet.count(tree("date"))) { autodoc = cons(docMtd(tree("date")), autodoc); } else { autodoc = cons(docTxt("\\today"), autodoc); } autodoc = cons(docTxt("}\n"), autodoc); /** The latex maketitle macro. */ autodoc = cons(docTxt("\\maketitle\n"), autodoc); /** Insert all declared metadatas in a latex tabular environment. */ if (! gMetaDataSet.empty()) { autodoc = cons(docTxt("\\begin{tabular}{ll}\n"), autodoc); autodoc = cons(docTxt("\t\\hline\n"), autodoc); for (map<Tree, set<Tree> >::iterator i = gMetaDataSet.begin(); i != gMetaDataSet.end(); i++) { string mtdkey = tree2str(i->first); string mtdTranslatedKey = gDocMetadatasStringMap[mtdkey]; if (mtdTranslatedKey.empty()) { mtdTranslatedKey = mtdkey; } autodoc = cons(docTxt("\t\\textbf{"), autodoc); autodoc = cons(docTxt(mtdTranslatedKey.c_str()), autodoc); autodoc = cons(docTxt("} & "), autodoc); autodoc = cons(docMtd(tree(mtdkey.c_str())), autodoc); autodoc = cons(docTxt(" \\\\\n"), autodoc); } autodoc = cons(docTxt("\t\\hline\n"), autodoc); autodoc = cons(docTxt("\\end{tabular}\n"), autodoc); autodoc = cons(docTxt("\\bigskip\n"), autodoc); } /** Autodoc's "body", with equation and diagram of process, and notice and listing. */ string autoPresentationTxt = "\n\\bigskip\n" + gDocAutodocStringMap["thisdoc"] + "\n\n"; autodoc = cons(docTxt(autoPresentationTxt.c_str()), autodoc); string autoEquationTxt = "\n" + gDocAutodocStringMap["autoeqntitle"] + "\n\n"; autoEquationTxt += gDocAutodocStringMap["autoeqntext"] + "\n"; autodoc = cons(docTxt(autoEquationTxt.c_str()), autodoc); autodoc = cons(docEqn(process), autodoc); string autoDiagramTxt = "\n" + gDocAutodocStringMap["autodgmtitle"] + "\n\n"; autoDiagramTxt += gDocAutodocStringMap["autodgmtext"] + "\n"; autodoc = cons(docTxt(autoDiagramTxt.c_str()), autodoc); autodoc = cons(docDgm(process), autodoc); string autoNoticeTxt = "\n" + gDocAutodocStringMap["autontctitle"] + "\n\n"; // autoNoticeTxt += gDocAutodocStringMap["autontctext"] + "\n"; autodoc = cons(docTxt(autoNoticeTxt.c_str()), autodoc); autodoc = cons(docNtc(), autodoc); string autoListingTxt; vector<string> pathnames = gReader.listSrcFiles(); if(pathnames.size() > 1) { autoListingTxt = "\n" + gDocAutodocStringMap["autolsttitle2"] + "\n\n"; autoListingTxt += gDocAutodocStringMap["autolsttext2"] + "\n"; } else { autoListingTxt = "\n" + gDocAutodocStringMap["autolsttitle1"] + "\n\n"; autoListingTxt += gDocAutodocStringMap["autolsttext1"] + "\n"; } autodoc = cons(docTxt(autoListingTxt.c_str()), autodoc); autodoc = cons(docLst(), autodoc); declareDoc(autodoc); }
/** * Generate buildUserInterface C++ lines of code corresponding * to user interface widget t */ void Compiler::generateWidgetCode(Tree fulllabel, Tree varname, Tree sig) { Tree path, c, x, y, z; string label; map<string, set<string> > metadata; extractMetadata(tree2str(fulllabel), label, metadata); // add metadata if any for (map<string, set<string> >::iterator i = metadata.begin(); i != metadata.end(); i++) { const string& key = i->first; const set<string>& values = i->second; for (set<string>::const_iterator j = values.begin(); j != values.end(); j++) { fClass->addUICode(subst("interface->declare(&$0, \"$1\", \"$2\");", tree2str(varname), wdel(key), wdel(*j))); fJSON.declare(NULL, wdel(key).c_str(), wdel(*j).c_str()); } } if ( isSigButton(sig, path) ) { fClass->incUIActiveCount(); fClass->addUICode(subst("interface->addButton(\"$0\", &$1);", checkNullLabel(varname, label), tree2str(varname))); fJSON.addButton(checkNullLabel(varname, label).c_str(), NULL); } else if ( isSigCheckbox(sig, path) ) { fClass->incUIActiveCount(); fClass->addUICode(subst("interface->addCheckButton(\"$0\", &$1);", checkNullLabel(varname, label), tree2str(varname))); fJSON.addCheckButton(checkNullLabel(varname, label).c_str(), NULL); } else if ( isSigVSlider(sig, path,c,x,y,z) ) { fClass->incUIActiveCount(); fClass->addUICode(subst("interface->addVerticalSlider(\"$0\", &$1, $2, $3, $4, $5);", checkNullLabel(varname, label), tree2str(varname), T(tree2float(c)), T(tree2float(x)), T(tree2float(y)), T(tree2float(z)))); fJSON.addVerticalSlider(checkNullLabel(varname, label).c_str(), NULL, tree2float(c), tree2float(x), tree2float(y), tree2float(z)); } else if ( isSigHSlider(sig, path,c,x,y,z) ) { fClass->incUIActiveCount(); fClass->addUICode(subst("interface->addHorizontalSlider(\"$0\", &$1, $2, $3, $4, $5);", checkNullLabel(varname, label), tree2str(varname), T(tree2float(c)), T(tree2float(x)), T(tree2float(y)), T(tree2float(z)))); fJSON.addHorizontalSlider(checkNullLabel(varname, label).c_str(), NULL, tree2float(c), tree2float(x), tree2float(y), tree2float(z)); } else if ( isSigNumEntry(sig, path,c,x,y,z) ) { fClass->incUIActiveCount(); fClass->addUICode(subst("interface->addNumEntry(\"$0\", &$1, $2, $3, $4, $5);", checkNullLabel(varname, label), tree2str(varname), T(tree2float(c)), T(tree2float(x)), T(tree2float(y)), T(tree2float(z)))); fJSON.addNumEntry(checkNullLabel(varname, label).c_str(), NULL, tree2float(c), tree2float(x), tree2float(y), tree2float(z)); } else if ( isSigVBargraph(sig, path,x,y,z) ) { fClass->incUIPassiveCount(); fClass->addUICode(subst("interface->addVerticalBargraph(\"$0\", &$1, $2, $3);", checkNullLabel(varname, label, true), tree2str(varname), T(tree2float(x)), T(tree2float(y)))); fJSON.addVerticalBargraph(checkNullLabel(varname, label).c_str(), NULL, tree2float(x), tree2float(y)); } else if ( isSigHBargraph(sig, path,x,y,z) ) { fClass->incUIPassiveCount(); fClass->addUICode(subst("interface->addHorizontalBargraph(\"$0\", &$1, $2, $3);", checkNullLabel(varname, label, true), tree2str(varname), T(tree2float(x)), T(tree2float(y)))); fJSON.addHorizontalBargraph(checkNullLabel(varname, label).c_str(), NULL, tree2float(x), tree2float(y)); } else { fprintf(stderr, "Error in generating widget code\n"); exit(1); } }
/** * Generate user interface macros corresponding * to a user interface widget */ void Compiler::generateWidgetMacro(const string& pathname, Tree fulllabel, Tree varname, Tree sig) { Tree path, c, x, y, z; string label; map<string, set<string> > metadata; extractMetadata(tree2str(fulllabel), label, metadata); //string pathlabel = pathname+unquote(label); string pathlabel = pathname+label; if ( isSigButton(sig, path) ) { fClass->addUIMacro(subst("FAUST_ADDBUTTON(\"$0\", $1);", pathlabel, tree2str(varname))); } else if ( isSigCheckbox(sig, path) ) { fClass->addUIMacro(subst("FAUST_ADDCHECKBOX(\"$0\", $1);", pathlabel, tree2str(varname))); } else if ( isSigVSlider(sig, path,c,x,y,z) ) { fClass->addUIMacro(subst("FAUST_ADDVERTICALSLIDER(\"$0\", $1, $2, $3, $4, $5);", pathlabel, tree2str(varname), T(tree2float(c)), T(tree2float(x)), T(tree2float(y)), T(tree2float(z)))); } else if ( isSigHSlider(sig, path,c,x,y,z) ) { fClass->addUIMacro(subst("FAUST_ADDHORIZONTALSLIDER(\"$0\", $1, $2, $3, $4, $5);", pathlabel, tree2str(varname), T(tree2float(c)), T(tree2float(x)), T(tree2float(y)), T(tree2float(z)))); } else if ( isSigNumEntry(sig, path,c,x,y,z) ) { fClass->addUIMacro(subst("FAUST_ADDNUMENTRY(\"$0\", $1, $2, $3, $4, $5);", pathlabel, tree2str(varname), T(tree2float(c)), T(tree2float(x)), T(tree2float(y)), T(tree2float(z)))); } else if ( isSigVBargraph(sig, path,x,y,z) ) { fClass->addUIMacro(subst("FAUST_ADDVERTICALBARGRAPH(\"$0\", $1, $2, $3);", pathlabel, tree2str(varname), T(tree2float(x)), T(tree2float(y)))); } else if ( isSigHBargraph(sig, path,x,y,z) ) { fClass->addUIMacro(subst("FAUST_ADDHORIZONTALBARGRAPH(\"$0\", $1, $2, $3);", pathlabel, tree2str(varname), T(tree2float(x)), T(tree2float(y)))); } else { fprintf(stderr, "Error in generating widget code\n"); exit(1); } }
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; }