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
00027
00028
00029
00030
00031 #include "relPrintExpr.h"
00032
00034 class relStatement : public relObject
00035 {
00036 public:
00037 virtual void
00038 interpret(bddSymTab* pSymTab) = 0;
00039 };
00040
00042 class relStmtSeq : public relStatement
00043 {
00044 private:
00045 relStatement* mStmt1;
00046 relStatement* mStmt2;
00047
00048 public:
00049 relStmtSeq(relStatement* pStmt1, relStatement* pStmt2)
00050 : mStmt1(pStmt1),
00051 mStmt2(pStmt2)
00052 {}
00053
00054 ~relStmtSeq()
00055 {
00056 delete mStmt1;
00057 delete mStmt2;
00058 }
00059
00060 virtual void
00061 interpret(bddSymTab* pSymTab)
00062 {
00063 mStmt1->interpret(pSymTab);
00064 mStmt2->interpret(pSymTab);
00065 }
00066 };
00067
00069 class relStmtAssign : public relStatement
00070 {
00071 private:
00073 string* mRelVar;
00074
00075 vector<relTerm*>* mTermList;
00076
00077 relExpression* mExpr;
00078
00079 public:
00080 relStmtAssign(string* pRelVar,
00081 vector<relTerm*>* pTermList,
00082 relExpression* pExpr)
00083 : mRelVar(pRelVar),
00084 mTermList(pTermList),
00085 mExpr(pExpr)
00086 {}
00087
00088 ~relStmtAssign()
00089 {
00090 delete mRelVar;
00091 for( vector<relTerm*>::iterator
00092 lIt = mTermList->begin();
00093 lIt != mTermList->end();
00094 ++lIt)
00095 {
00096 delete *lIt;
00097 }
00098 delete mTermList;
00099 delete mExpr;
00100 }
00101
00102 virtual void
00103 interpret(bddSymTab* pSymTab)
00104 {
00105 {
00106
00107 set<string> lFreeAttrs = mExpr->collectFreeAttrs();
00108
00109
00110 for( vector<relTerm*>::const_iterator lIt = mTermList->begin();
00111 lIt != mTermList->end();
00112 ++lIt)
00113 {
00114 if (dynamic_cast<relTermAttribute*>(*lIt) != NULL) {
00115
00116 string lAttr = (*lIt)->interpret(pSymTab);
00117 set<string>::iterator found = lFreeAttrs.find(lAttr);
00118 if ( found == lFreeAttrs.end()) {
00119 cerr << "Error: Attribute '" << lAttr
00120 << "' occurs on the left hand side of an assignment," << endl
00121 << "but does not occur free in the expression on the right hand side." << endl;
00122 exit(EXIT_FAILURE);
00123 }
00124 lFreeAttrs.erase(found);
00125 }
00126 }
00127 if (lFreeAttrs.size() > 0) {
00128 cerr << "Error: The following attributes occur free in the expression" << endl
00129 << "on the right hand side of an assignment, but do not occur on the left side: ";
00130 copy(lFreeAttrs.begin(),
00131 lFreeAttrs.end(),
00132 ostream_iterator<string>(cerr, " "));
00133 cerr << endl;
00134 exit(EXIT_FAILURE);
00135 }
00136 }
00137
00138 bddRelation lExprResult = mExpr->interpret(pSymTab);
00139
00140
00141
00142 bddRelation lEliminateCofactor(pSymTab, true);
00143
00144
00145
00146 for(unsigned i = 0; i < mTermList->size(); ++i)
00147 {
00148 const string lTerm = (*mTermList)[i]->interpret(pSymTab);
00149 if ( dynamic_cast<relTermAttribute*>( (*mTermList)[i] ) != NULL )
00150 {
00151
00152
00153 pSymTab->addAttribute(gAttributePrefix + unsigned2string(i));
00154
00155
00156 lExprResult.rename(lTerm,
00157 gAttributePrefix + unsigned2string(i));
00158 }
00159 else if (dynamic_cast<relTermStrExpr*>((*mTermList)[i]) != NULL)
00160 {
00161
00162
00163
00164
00165 lEliminateCofactor.intersect(bddRelation::mkAttributeValue(
00166 pSymTab,
00167 gAttributePrefix + unsigned2string(i),
00168 lTerm)
00169 );
00170
00171
00172 lExprResult.intersect(bddRelation::mkAttributeValue(
00173 pSymTab,
00174 gAttributePrefix + unsigned2string(i),
00175 lTerm)
00176 );
00177 }
00178 else
00179 {
00180
00181 assert(false);
00182 }
00183 }
00184 lEliminateCofactor.complement();
00185
00186
00187 map<string, relDataType*>::const_iterator lVarIt = gVariables.find(*mRelVar);
00188 assert(lVarIt != gVariables.end());
00189 assert(lVarIt->second != NULL);
00190 if (dynamic_cast<bddRelationConst*>(lVarIt->second) != NULL) {
00191
00192 cerr << "Error: Constant relation '" << *mRelVar << "'" << endl
00193 << "must not appear on the left hand side of an assignment." << endl;
00194 exit(EXIT_FAILURE);
00195 }
00196 bddRelation* lResult = dynamic_cast<bddRelation*>(lVarIt->second);
00197 assert(lResult != NULL);
00198
00199 lResult->intersect(lEliminateCofactor);
00200 lResult->unite(lExprResult);
00201
00202
00203 lResult->mArity = mTermList->size();
00204
00205 pSymTab->removeUserAttributes(gAttributePrefix);
00206 }
00207 };
00208
00210 class relStmtAssignNum : public relStatement
00211 {
00212 private:
00213 string* mVar;
00214 relNumExpr* mExpr;
00215
00216 public:
00217 relStmtAssignNum(string* pVar,
00218 relNumExpr* pExpr)
00219 : mVar(pVar),
00220 mExpr(pExpr)
00221 {}
00222
00223 ~relStmtAssignNum()
00224 {
00225 delete mVar;
00226 delete mExpr;
00227 }
00228
00229 virtual void
00230 interpret(bddSymTab* pSymTab)
00231 {
00232 relNumber lExprResult = mExpr->interpret(pSymTab);
00233
00234
00235 map<string, relDataType*>::const_iterator lVarIt = gVariables.find(*mVar);
00236 assert(lVarIt != gVariables.end());
00237 assert(lVarIt->second != NULL);
00238 relNumber* lResult = dynamic_cast<relNumber*>(lVarIt->second);
00239 assert(lResult != NULL);
00240
00241 *lResult = lExprResult;
00242
00243 pSymTab->removeUserAttributes(gAttributePrefix);
00244 }
00245 };
00246
00248 class relStmtAssignStr : public relStatement
00249 {
00250 private:
00251 string* mVar;
00252 relStrExpr* mExpr;
00253
00254 public:
00255 relStmtAssignStr(string* pVar,
00256 relStrExpr* pExpr)
00257 : mVar(pVar),
00258 mExpr(pExpr)
00259 {}
00260
00261 ~relStmtAssignStr()
00262 {
00263 delete mVar;
00264 delete mExpr;
00265 }
00266
00267 virtual void
00268 interpret(bddSymTab* pSymTab)
00269 {
00270 relString lExprResult = mExpr->interpret(pSymTab);
00271
00272
00273 map<string, relDataType*>::const_iterator lVarIt = gVariables.find(*mVar);
00274 assert(lVarIt != gVariables.end());
00275 assert(lVarIt->second != NULL);
00276 relString* lResult = dynamic_cast<relString*>(lVarIt->second);
00277 assert(lResult != NULL);
00278
00279 *lResult = lExprResult;
00280
00281 pSymTab->removeUserAttributes(gAttributePrefix);
00282 }
00283 };
00284
00286 class relStmtPrint : public relStatement
00287 {
00288 private:
00289 relPrintExpr* mPrintExpr;
00290 ostream* mOut;
00291 relStrExpr* mFilename;
00292
00293 public:
00294 relStmtPrint(relPrintExpr* pPrintExpr, ostream* pOut, relStrExpr* pFilename)
00295 : mPrintExpr(pPrintExpr),
00296 mOut(pOut),
00297 mFilename(pFilename)
00298 {}
00299
00300 ~relStmtPrint()
00301 {
00302 delete mPrintExpr;
00303 delete mFilename;
00304 }
00305
00306 virtual void
00307 interpret(bddSymTab* pSymTab)
00308 {
00309
00310 if (mOut == NULL) {
00311 const string lFileName = mFilename->interpret(pSymTab).getValue();
00312 if(lFileName == "") {
00313 cerr << "Error: Empty filename given." << endl;
00314 exit(EXIT_FAILURE);
00315 }
00316
00317 ofstream lStream;
00318 lStream.open(lFileName.c_str(), ofstream::out | ofstream::app);
00319 mPrintExpr->interpret(pSymTab, &lStream);
00320 lStream.close();
00321 } else {
00322 mPrintExpr->interpret(pSymTab, mOut);
00323 }
00324 pSymTab->removeUserAttributes(gAttributePrefix);
00325 }
00326 };
00327
00329 class relStmtExec : public relStatement
00330 {
00331 private:
00332 relStrExpr* mExpr;
00333
00334 public:
00335 relStmtExec(relStrExpr* pExpr)
00336 : mExpr(pExpr)
00337 {}
00338
00339 ~relStmtExec()
00340 {
00341 delete mExpr;
00342 }
00343
00344 virtual void
00345 interpret(bddSymTab* pSymTab)
00346 {
00347 int lExitCode = system(mExpr->interpret(pSymTab).getValue().c_str());
00348 if (lExitCode == -1) {
00349 perror("\nExternal program execution error");
00350 exit(128);
00351 }
00352
00353 map<string, relDataType*>::const_iterator lVarIt = gVariables.find("exitStatus");
00354 assert(lVarIt != gVariables.end());
00355 assert(lVarIt->second != NULL);
00356 relNumber* lResult = dynamic_cast<relNumber*>(lVarIt->second);
00357 assert(lResult != NULL);
00358
00359 lResult->setValue(lExitCode);
00360 }
00361 };
00362
00364 class relStmtIf : public relStatement
00365 {
00366 private:
00367 relExpression* mExpr;
00368 relStatement* mStmtThen;
00369 relStatement* mStmtElse;
00370 public:
00371 relStmtIf(relExpression* pExpr,
00372 relStatement* pStmtThen,
00373 relStatement* pStmtElse)
00374 : mExpr(pExpr),
00375 mStmtThen(pStmtThen),
00376 mStmtElse(pStmtElse)
00377 {}
00378
00379 ~relStmtIf()
00380 {
00381 delete mExpr;
00382 delete mStmtThen;
00383 delete mStmtElse;
00384 }
00385
00386 virtual void
00387 interpret(bddSymTab* pSymTab)
00388 {
00389 bddRelation lCondition = mExpr->interpret(pSymTab);
00390 pSymTab->removeUserAttributes(gAttributePrefix);
00391 if ( ! lCondition.setEqual(bddRelation(pSymTab, true)) &&
00392 ! lCondition.setEqual(bddRelation(pSymTab, false)) ) {
00393 if (gPrintWarnings) {
00394 cerr << "Warning: Boolean expression expected after IF. "
00395 << "Quantify free attributes." << endl;
00396 }
00397 }
00398 if ( lCondition.setEqual(bddRelation(pSymTab, true)) ) {
00399 mStmtThen->interpret(pSymTab);
00400 } else {
00401 mStmtElse->interpret(pSymTab);
00402 }
00403 }
00404 };
00405
00407 class relStmtWhile : public relStatement
00408 {
00409 private:
00410 relExpression* mExpr;
00411 relStatement* mStmt;
00412 public:
00413 relStmtWhile(relExpression* pExpr,
00414 relStatement* pStmt)
00415 : mExpr(pExpr),
00416 mStmt(pStmt)
00417 {}
00418
00419 ~relStmtWhile()
00420 {
00421 delete mExpr;
00422 delete mStmt;
00423 }
00424
00425 virtual void
00426 interpret(bddSymTab* pSymTab)
00427 {
00428 bddRelation lCondition = mExpr->interpret(pSymTab);
00429 pSymTab->removeUserAttributes(gAttributePrefix);
00430 if ( ! lCondition.setEqual(bddRelation(pSymTab, true)) &&
00431 ! lCondition.setEqual(bddRelation(pSymTab, false)) ) {
00432 if (gPrintWarnings) {
00433 cerr << "Warning: Boolean expression expected after WHILE. "
00434 << "Quantify free attributes." << endl;
00435 }
00436 }
00437 while( lCondition.setEqual(bddRelation(pSymTab, true)) )
00438 {
00439 mStmt->interpret(pSymTab);
00440
00441 lCondition = mExpr->interpret(pSymTab);
00442 pSymTab->removeUserAttributes(gAttributePrefix);
00443 }
00444 }
00445 };
00446
00448 class relStmtFor : public relStatement
00449 {
00450 private:
00451 string* mStrVar;
00452 relExpression* mExpr;
00453 relStatement* mStmt;
00454
00455 public:
00456 relStmtFor(string* pStrVar,
00457 relExpression* pExpr,
00458 relStatement* pStmt)
00459 : mStrVar(pStrVar),
00460 mExpr(pExpr),
00461 mStmt(pStmt)
00462 {}
00463
00464 ~relStmtFor()
00465 {
00466 delete mStrVar;
00467 delete mExpr;
00468 delete mStmt;
00469 }
00470
00471 virtual void
00472 interpret(bddSymTab* pSymTab)
00473 {
00474
00475 bddRelation lRel = mExpr->interpret(pSymTab);
00476 const set<string> lFree = mExpr->collectFreeAttrs();
00477
00478 if(lFree.size() != 1) {
00479 cerr << "Error: FOR statement requires one free attribute (i.e. a set)."
00480 << endl;
00481 exit(EXIT_FAILURE);
00482 }
00483 const unsigned lVarId = pSymTab->getAttributePos(*lFree.begin());
00484
00485
00486 pSymTab->removeUserAttributes(gAttributePrefix);
00487
00488
00489 map<string, relDataType*>::const_iterator lVarIt = gVariables.find(*mStrVar);
00490 assert(lVarIt != gVariables.end());
00491 assert(lVarIt->second != NULL);
00492 relString* lResult = dynamic_cast<relString*>(lVarIt->second);
00493 assert(lResult != NULL);
00494
00495
00496 while (!lRel.isEmpty()) {
00497
00498 string lValue = lRel.getElement(lVarId);
00499
00500
00501 lResult->setValue(lValue);
00502
00503
00504 bddRelation lCurrentValue( bddRelation::mkEqual(pSymTab,
00505 lVarId,
00506 pSymTab->getValueNum(lValue)) );
00507 lCurrentValue.complement();
00508 lRel.intersect(lCurrentValue);
00509
00510
00511 mStmt->interpret(pSymTab);
00512 }
00513 }
00514 };
00515
00517 class relStmtExit : public relStatement
00518 {
00519 private:
00520 relNumExpr* mExitCode;
00521
00522 public:
00523 relStmtExit(relNumExpr* pExitCode)
00524 : mExitCode(pExitCode)
00525 {}
00526
00527 ~relStmtExit()
00528 {
00529 delete mExitCode;
00530 }
00531
00532 virtual void
00533 interpret(bddSymTab* pSymTab)
00534 {
00535 exit((int) mExitCode->interpret(pSymTab).getValue());
00536 }
00537 };
00538
00541 class relStmtEmpty : public relStatement
00542 {
00543 public:
00544 relStmtEmpty()
00545 {}
00546
00547 ~relStmtEmpty()
00548 {}
00549
00550 virtual void
00551 interpret(bddSymTab* pSymTab)
00552 {}
00553 };
00554