string DocCompiler::generateInput (Tree sig, const string& idx) { if (fLateq->inputs() == 1) { setVectorNameProperty(sig, "x"); fLateq->addInputSigFormula("x(t)"); gGlobal->gDocNoticeFlagMap["inputsig"] = true; return generateCacheCode(sig, "x(t)"); } else { setVectorNameProperty(sig, subst("x_{$0}", idx)); fLateq->addInputSigFormula(subst("x_{$0}(t)", idx)); gGlobal->gDocNoticeFlagMap["inputsigs"] = true; return generateCacheCode(sig, subst("x_{$0}(t)", idx)); } }
string DocCompiler::generateNumEntry(Tree sig, Tree path, Tree cur, Tree min, Tree max, Tree step) { string varname = getFreshID("{u_n}") + "(t)"; fLateq->addUISigFormula(getUIDir(path), prepareIntervallicUI(varname, path, cur, min, max)); gDocNoticeFlagMap["nentrysigs"] = true; return generateCacheCode(sig, varname); }
/** * Generate LaTeX code for "prefix", a 1sample-delay explicitely initialized. * * @param sig The signal expression to treat. * @param x The initial value for the delay line. * @param e The value for the delay line, after initialization. * @param priority The priority of the environment of the expression. * * @return <string> The LaTeX code translation of the signal, cached. */ string DocCompiler::generatePrefix(Tree sig, Tree x, Tree e, int priority) { string var = getFreshID("m"); string exp0 = CS(x, priority); string exp1 = CS(e, priority); // ensure exp1 is compiled to have a vector name string vecname; if(!getVectorNameProperty(e, vecname)) { cerr << "No vector name for : " << ppsig(e) << endl; assert(0); } string ltqPrefixDef; ltqPrefixDef += subst("$0(t) = \n", var); ltqPrefixDef += "\\left\\{\\begin{array}{ll}\n"; ltqPrefixDef += subst("$0 & \\mbox{, when \\,} t = 0\\\\\n", exp0); ltqPrefixDef += subst("$0 & \\mbox{, when \\,} t > 0\n", subst("$0(t\\!-\\!1)", vecname)); ltqPrefixDef += "\\end{array}\\right."; fLateq->addPrefixSigFormula(ltqPrefixDef); gDocNoticeFlagMap["prefixsigs"] = true; return generateCacheCode(sig, subst("$0(t)", var)); }
string DocCompiler::generateCheckbox(Tree sig, Tree path) { string vname = getFreshID("{u_c}"); string varname = vname + "(t)"; fLateq->addUISigFormula(getUIDir(path), prepareBinaryUI(varname, path)); gDocNoticeFlagMap["checkboxsigs"] = true; return generateCacheCode(sig, varname); }
/** * Generate the equation of a write table, which content is time dependent. * It is basically a signal of vectors. */ string DocCompiler::generateDocAccessTbl(Tree sig, Tree tbl, Tree ridx) { // the compilation of a table always returns its name string vname = CS(tbl, 0); string result = subst("$0[$1]", vname, CS(ridx, 0)); return generateCacheCode(sig, result); }
string VectorCompiler::generateWaveform(Tree sig) { string vname; int size; declareWaveform(sig, vname, size); fClass->addPostCode(subst("idx$0 = (idx$0 + count) % $1;", vname, T(size)) ); return generateCacheCode(sig, subst("$0[(idx$0+i)%$1]", vname, T(size))); }
string DocCompiler::generateAttach (Tree sig, Tree x, Tree y, int priority) { string vname; string exp; CS(y, priority); exp = CS(x, priority); if(getVectorNameProperty(x, vname)) { setVectorNameProperty(sig, vname); } return generateCacheCode(sig, exp); }
string DocCompiler::generateFVar (Tree sig, const string& file, const string& exp) { string ctype, vname; Occurences* o = fOccMarkup.retrieve(sig); if (o->getMaxDelay()>0) { getTypedNames(getCertifiedSigType(sig), "r", ctype, vname); gGlobal->gDocNoticeFlagMap["recursigs"] = true; //cerr << "- r : generateFVar : \"" << vname << "\"" << endl; setVectorNameProperty(sig, vname); generateDelayVec(sig, exp, ctype, vname, o->getMaxDelay()); } return generateCacheCode(sig, exp); }
string DocCompiler::generateHBargraph(Tree sig, Tree path, Tree min, Tree max, const string& exp) { string varname = getFreshID("{u_g}"); Type t = getCertifiedSigType(sig); switch (t->variability()) { case kKonst : break; case kBlock : break; case kSamp : break; } return generateCacheCode(sig, varname); }
/** * retrieve the type annotation of sig * @param sig the signal we want to know the type */ string DocCompiler::generateXtended (Tree sig, int priority) { xtended* p = (xtended*) getUserData(sig); vector<string> args; vector<Type> types; for (int i=0; i<sig->arity(); i++) { args.push_back(CS(sig->branch(i), 0)); types.push_back(getCertifiedSigType(sig->branch(i))); } if (p->needCache()) { //cerr << "!! generateXtended : <needCache> : calls generateCacheCode(sig, p->generateLateq(fLateq, args, types))" << endl; return generateCacheCode(sig, p->generateLateq(fLateq, args, types)); } else { //cerr << "!! generateXtended : <do not needCache> : calls p->generateLateq(fLateq, args, types)" << endl; return p->generateLateq(fLateq, args, types); } }
/** * @brief Don't generate float cast ! * * It is just a kind of redirection. * Calling generateCacheCode ensures to create a new * variable name if the input signal expression is shared. */ string DocCompiler::generateFloatCast(Tree sig, Tree x, int priority) { return generateCacheCode(sig, subst("$0", CS(x, priority))); }
string DocCompiler::generateIntCast(Tree sig, Tree x, int priority) { gDocNoticeFlagMap["intcast"] = true; return generateCacheCode(sig, subst("\\mathrm{int}\\left($0\\right)", CS(x, 0))); }
string DocCompiler::generateBinOp(Tree sig, int opcode, Tree arg1, Tree arg2, int priority) { string s; int thisPriority = gBinOpLateqTable[opcode]->fPriority; /* Priority parenthesis handling. */ string lpar = ""; string rpar = ""; if((thisPriority < priority) || ((thisPriority == priority) && !associative(opcode))) { // (a+b)*c or (a/b)/c need parenthesis lpar = " \\left("; rpar = "\\right) "; } Type t1 = getCertifiedSigType(arg1); Type t2 = getCertifiedSigType(arg2); bool intOpDetected = false; if((t1->nature() == kInt) && (t2->nature() == kInt)) { intOpDetected = true; } string op; if(!intOpDetected) { op = gBinOpLateqTable[opcode]->fName; } else { switch(opcode) { case kAdd: op = "\\oplus"; gDocNoticeFlagMap["intplus"] = true; break; case kSub: op = "\\ominus"; gDocNoticeFlagMap["intminus"] = true; break; case kMul: op = "\\odot"; gDocNoticeFlagMap["intmult"] = true; break; case kDiv: op = "\\oslash"; gDocNoticeFlagMap["intdiv"] = true; gDocNoticeFlagMap["intcast"] = true; // "$normalize(int(i/j))$" in the notice. break; default: op = gBinOpLateqTable[opcode]->fName; break; } } /* LaTeX frac{}{} handling VS general case. */ if((opcode == kDiv) && (!intOpDetected)) { s = subst("$0\\frac{$1}{$2}$3", lpar, CS(arg1, 0), CS(arg2, 0), rpar); } else { s = subst("$0$1 $2 $3$4", lpar, CS(arg1, thisPriority), op, CS(arg2, thisPriority), rpar); } // if (opcode == kMul) { // gDocNoticeFlagMap["cdot"] = true; // } return generateCacheCode(sig, s); }