00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00035 #include "forexpression.h"
00036
00037 ForExpression::ForExpression(VarExpression * _var, VarExpression * _varexp, Expression * _exp):
00038 Expression(et_for), var(_var), varexp(_varexp), varstep(NULL), exp(_exp),
00039 bit(NULL) {
00040 }
00041
00042 ForExpression::ForExpression(VarExpression * _var, VarStepExpression * _varstep, Expression * _exp):
00043 Expression(et_for), var(_var), varexp(NULL), varstep(_varstep), exp(_exp),
00044 bit(NULL) {
00045 }
00046
00047 ForExpression::~ForExpression() {
00048 delete var;
00049 delete varexp;
00050 delete varstep;
00051 delete exp;
00052 delete bit;
00053 }
00054
00055 void ForExpression::scopeCheck(vector < unsigned >&def_vars,
00056 vector < unsigned >&introduced_vars,
00057 vector < unsigned >&violating_vars) {
00058 vector < unsigned >new_def_vars = def_vars;
00059
00060
00061 bool varname_in_use = false;
00062
00063 for (unsigned i = 0; i < introduced_vars.size() && !varname_in_use; i++) {
00064 varname_in_use |=
00065 strcmp(VarName::getInstance()->getVarname(introduced_vars[i]),
00066 VarName::getInstance()->getVarname(var->getId())) ==
00067 TAGID_ROOT;
00068 }
00069
00070
00071 if (varname_in_use) {
00072 unsigned old_id = var->getId();
00073 const char *var_name = VarName::getInstance()->getVarname(old_id);
00074
00075
00076 unsigned new_id = VarName::getInstance()->insertVarname(var_name, true);
00077
00078 var->setId(new_id);
00079 exp->replaceVarId(old_id, new_id);
00080 new_def_vars.push_back(new_id);
00081 } else {
00082
00083
00084
00085 introduced_vars.push_back(var->getId());
00086 new_def_vars.push_back(var->getId());
00087 }
00088
00089 if (varexp) {
00090 varexp->scopeCheck(def_vars, introduced_vars, violating_vars);
00091 exp->scopeCheck(new_def_vars, introduced_vars, violating_vars);
00092 } else {
00093 varstep->scopeCheck(def_vars, introduced_vars, violating_vars);
00094 exp->scopeCheck(new_def_vars, introduced_vars, violating_vars);
00095 }
00096 }
00097
00098 void ForExpression::replaceVarId(unsigned old_id, unsigned new_id) {
00099 if (varexp) {
00100 varexp->replaceVarId(old_id, new_id);
00101 } else {
00102 varstep->replaceVarId(old_id, new_id);
00103 }
00104
00105
00106 if (strcmp(VarName::getInstance()->getVarname(old_id),
00107 VarName::getInstance()->getVarname(var->getId())) !=
00108 TAGID_ROOT) {
00109 exp->replaceVarId(old_id, new_id);
00110 }
00111 }
00112
00113 void ForExpression::mergeSequences() {
00114 exp->mergeSequences();
00115 }
00116
00117 void ForExpression::extractFSAMap(FSAMap * fsamap, unsigned parent_var) {
00118 unsigned var_id = var->getId();
00119 unsigned parent_var_id = varstep ? varstep->getId() : varexp->getId();
00120
00121 if (parent_var_id == parent_var) {
00122 if (fsamap->getFSA(parent_var) == parent_var) {
00123 fsamap->insertFSA(var_id, var_id);
00124 } else {
00125 fsamap->insertFSA(var_id, fsamap->getFSA(parent_var));
00126 }
00127 } else {
00128 fsamap->insertFSA(var_id, fsamap->getFSA(parent_var_id));
00129 }
00130
00131 exp->extractFSAMap(fsamap, var_id);
00132 }
00133
00134 void ForExpression::extractParVarMap(ParVarMap * parvarmap) {
00135 if (varexp) {
00136 parvarmap->insertParVar(var->getId(), varexp->getId(), NULL,
00137 containsDirectOutput());
00138 } else {
00139 parvarmap->insertParVar(var->getId(), varstep->getId(),
00140 varstep->getPath(), containsDirectOutput());
00141 }
00142
00143 exp->extractParVarMap(parvarmap);
00144 }
00145
00146 void ForExpression::extractDependencies(vector < DependencySet * >*depset) {
00147 exp->extractDependencies(depset);
00148 }
00149
00150 Expression *ForExpression::placeSignOffs(vector <
00151 SignOffExpression * >&signoffs) {
00152 exp = exp->placeSignOffs(signoffs);
00153 for (unsigned i = 0; i < signoffs.size(); i++) {
00154 if (signoffs[i]->getVar() == var->getId()) {
00155 SequenceExpression *sexp = new SequenceExpression(exp, signoffs[i]);
00156
00157 exp = sexp;
00158 }
00159 }
00160
00161 return this;
00162 }
00163
00164 void ForExpression::rewriteWhereExps() {
00165 exp->rewriteWhereExps();
00166 }
00167
00168 void ForExpression::rewriteEmptyFuncts() {
00169 exp->rewriteEmptyFuncts();
00170 }
00171
00172 void ForExpression::rewriteVarstepCondExps() {
00173 exp->rewriteVarstepCondExps();
00174 }
00175
00176 void ForExpression::rewriteAggregateFuncts() {
00177 exp->rewriteAggregateFuncts();
00178 }
00179
00180 void ForExpression::rewriteVarsteps() {
00181 if (exp->getType() == et_varstep) {
00182 VarStepExpression *sub = ((VarStepExpression *) exp)->clone();
00183 delete exp;
00184 VarExpression *tmpvar =
00185 new VarExpression(VarName::getInstance()->getFreshVarname(),
00186 true);
00187 ForExpression *forexp = new ForExpression(tmpvar, sub, tmpvar->clone());
00188
00189 exp = forexp;
00190 } else {
00191 exp->rewriteVarsteps();
00192 }
00193 }
00194
00195 void ForExpression::print(OutputStream & dos) const {
00196 if (varexp) {
00197 dos << "for " << (*var) << " in " << (*varexp);
00198 } else {
00199 dos << "for " << (*var) << " in " << (*varstep);
00200 }
00201
00202 if (exp->getType() != et_where) {
00203 dos << " return ";
00204 }
00205
00206 EXP_TYPE subtype = exp->getType();
00207
00208 if (subtype == et_for || subtype == et_where || subtype == et_if ||
00209 subtype == et_nodeconstr || subtype == et_sequence ||
00210 subtype == et_signoff) {
00211 dos << NEWLINE << incrementIndents() << writeIndents() << (*exp)
00212 << decrementIndents();
00213 } else {
00214 dos << (*exp);
00215 }
00216 }
00217
00218 void ForExpression::init(BufferNode * root) {
00219 delete bit;
00220
00221 bit =
00222 varexp ? new BufferIterator(root, NULL) : new BufferIterator(root,
00223 varstep->
00224 getPath());
00225 exp->init(root);
00226 }
00227
00228 void ForExpression::eval(OutputStream & eos, Environment * env, unsigned modus) {
00229
00230 switch (modus) {
00231
00232 case EVAL_QUERY:
00233 {
00234
00235
00236
00237 varexp ? bit->init(env->getNodeBinding(varexp->getId())) :
00238 bit->init(env->getNodeBinding(varstep->getId()));
00239
00240 while (BufferNode * cur =
00241 bit->getNext(READ_UP_TO_CLOSE_NONE,
00242 LOCK_CONTEXT_ALWAYS_CLEAR)) {
00243 Environment *newenv = env->clone();
00244
00245 newenv->insertNodeBinding(var->getId(), cur);
00246 exp->eval(eos, newenv, EVAL_QUERY);
00247
00248 delete newenv;
00249 }
00250 bit->clear();
00251
00252 break;
00253 }
00254
00255 case EVAL_SIGNOFF:
00256 {
00257 varexp ? bit->init(env->getNodeBinding(varexp->getId())) :
00258 bit->init(env->getNodeBinding(varstep->getId()));
00259
00260 while (BufferNode * cur =
00261 bit->getNext(READ_UP_TO_CLOSE_NONE,
00262 LOCK_CONTEXT_ALWAYS_CLEAR)) {
00263
00264 Environment *newenv = env->clone();
00265
00266 newenv->insertNodeBinding(var->getId(), cur);
00267 exp->eval(eos, newenv, EVAL_SIGNOFF);
00268
00269 delete newenv;
00270 }
00271 bit->clear();
00272 break;
00273 }
00274
00275 default:
00276 throw RuntimeException("ForExpression: Illegal Evaluation Mode",
00277 eid_runtime_illegalmode);
00278 break;
00279 }
00280 }
00281
00282 void ForExpression::evalSignOffForBinding(OutputStream & eos,
00283 Environment * env, BufferNode * cur) {
00284
00285 Environment *newenv = env->clone();
00286
00287 newenv->insertNodeBinding(var->getId(), cur);
00288 exp->eval(eos, newenv, EVAL_SIGNOFF);
00289 delete newenv;
00290 }
00291
00292 bool ForExpression::containsDirectOutput() {
00293 switch (exp->getType()) {
00294 case et_nodeconstr:
00295 case et_stringconst:
00296 return true;
00297 case et_numericconst:
00298 return true;
00299 case et_sequence:
00300 case et_if:
00301 return exp->containsDirectOutput();
00302 default:
00303 return false;
00304 }
00305 }