Files Classes Functions Hierarchy
00001 00002 00003 #include <cassert> 00004 #include <algorithm> 00005 #include <iostream> 00006 #include <iomanip> 00007 #include <deque> 00008 #include <string> 00009 #include <bitset> 00010 #include <limits> 00011 00012 using namespace std; 00013 00014 #include <rpn.h> 00015 00016 #ifndef NDEBUG 00017 // Toggle Debug code. 00018 #define DEBUG_RFC 00019 #endif 00020 00021 // Magic Number 00022 #define PRECISION 30 00023 00024 00025 00026 00027 // Implementation 00028 // ------------------------------------------------------------ 00029 // 00030 00031 /* g++ wants these. */ 00032 rpnbase::~rpnbase() {} 00033 rpnbase* rpnbase::copy() const { return 0; } 00034 00035 ostream& operator << (ostream& os, rpnbase* const p) 00036 { return p->print(os); } 00037 00038 00039 rpnreal::rpnreal(deque<rpnbase*>& ds, long double const n) 00040 : num(n) 00041 { 00042 eval(ds); 00043 } 00044 00045 /* 00046 This is a MAGIC NUMBER. 00047 00048 <TODO> Make configurable for user. 00049 00050 Why 30? I do not know, but it is beyond the accuracy 00051 of my type and hence displaysed the computers approximation. 00052 00053 eg. On my machine 00054 73.4 resulted in 00055 0: 73.40000000000000568434 00056 00057 An accuracy of 15 digits. Ofcourse the computer has 00058 a binary representation/approximation. 00059 00060 The good thing about displaying the garbage is you 00061 get to see how inaccurate the computer actually is, 00062 and its scary. 00063 00064 */ 00065 ostream& rpnreal::print(ostream& os) const 00066 { 00067 return os << fixed << showpoint 00068 << setprecision( PRECISION ) << num; 00069 } 00070 00071 rpnbase* rpnreal::copy() const 00072 { 00073 rpnreal* n = new rpnreal(); 00074 n->num = num; 00075 return n; 00076 } 00077 00078 00079 rpncomplex::rpncomplex 00080 ( 00081 deque<rpnbase*>& ds, 00082 long double const x, 00083 long double const y 00084 ) 00085 : num(x,y) 00086 { 00087 eval(ds); 00088 } 00089 00090 00091 rpncomplex::rpncomplex 00092 ( 00093 deque<rpnbase*>& ds, 00094 complex<long double> const & x 00095 ) 00096 : num(x) 00097 { 00098 eval(ds); 00099 } 00100 00101 00102 ostream& rpncomplex::print(ostream& os) const 00103 { 00104 return os << fixed << showpoint 00105 << setprecision( PRECISION ) << num; 00106 } 00107 00108 rpnbase* rpncomplex::copy() const 00109 { 00110 rpncomplex* n = new rpncomplex(); 00111 n->num = num; 00112 00113 return n; 00114 } 00115 00116 00117 00118 00119 00120 00121 00122 unsigned int rpninteger::displaybase(10); 00123 00124 00125 rpninteger::rpninteger(deque<rpnbase*>& ds, long int const n) 00126 : num(n) 00127 { 00128 eval(ds); 00129 } 00130 00131 ostream& rpninteger::print(ostream& os) const 00132 { 00133 00134 switch( displaybase ) 00135 { 00136 case 10: 00137 os.unsetf(ios::hex); 00138 os.unsetf(ios::oct); 00139 os.setf(ios::dec); 00140 break; 00141 00142 case 8: 00143 os.unsetf(ios::dec); 00144 os.unsetf(ios::hex); 00145 os.setf(ios::oct); 00146 break; 00147 00148 case 16: 00149 os.unsetf(ios::dec); 00150 os.unsetf(ios::oct); 00151 os.setf(ios::hex); 00152 break; 00153 00154 case 2: 00155 00156 os << bitset<numeric_limits<long int>::digits>( num ); 00157 return os; 00158 }; 00159 00160 return os << num; 00161 } 00162 00163 rpnbase* rpninteger::copy() const 00164 { 00165 rpninteger* n = new rpninteger(); 00166 n->num = num; 00167 return n; 00168 } 00169 00170 00171 rpnstring::rpnstring(deque<rpnbase*>& ds,string const & s) 00172 :str(s) 00173 { 00174 eval(ds); 00175 } 00176 00177 ostream& rpnstring::print(ostream& os) const 00178 { 00179 if (str=="/") 00180 return os << "\"/\""; 00181 00182 if (str.find(' ')!=string::npos) 00183 return os << '"' << str << '"'; 00184 00185 return os << str; 00186 00187 /* 00188 if (str != "/") 00189 return os << str; 00190 00191 // To distinguish between division and root node. 00192 return os << string("\"/"); 00193 */ 00194 } 00195 00196 rpnbase* rpnstring::copy() const 00197 { 00198 rpnstring* s = new rpnstring(); 00199 s->str = str; 00200 return s; 00201 } 00202 00203 void rpnstring::eval( deque<rpnbase*>& ds ) 00204 { 00205 ds.push_front(this); 00206 } 00207 00208 00209 void rpnprogram::vinc() 00210 { 00211 if (!v.empty()) 00212 { 00213 for (unsigned int i=0, imax=v.size(); i<imax; ++i) 00214 v[i]->inc(); 00215 } 00216 } 00217 00218 void rpnprogram::inc() 00219 { 00220 ++ counter; 00221 00222 vinc(); 00223 00224 if (!variables.empty()) 00225 { 00226 for (unsigned int i=0, imax=variables.size(); i<imax; ++i) 00227 variables[i]->inc(); 00228 } 00229 } 00230 00231 00232 rpnprogram::rpnprogram 00233 ( 00234 deque<rpnbase*>& ds, 00235 deque<rpnbase*>& ds2, 00236 bool const evaluate 00237 ) 00238 : state(3) 00239 { 00240 v = ds2; 00241 reverse(v.begin(),v.end()); /* <TODO> make efficent with reverse copy? */ 00242 00243 if (evaluate) 00244 { 00245 eval(ds); 00246 return; 00247 } 00248 00249 ds.push_front(this); 00250 } 00251 00252 rpnprogram::rpnprogram(deque<rpnbase*>& ds) 00253 { 00254 ds.push_front(this); 00255 } 00256 00257 rpnprogram::rpnprogram() 00258 : state(3) 00259 { 00260 } 00261 00262 ostream& rpnprogram::print(ostream& os) const 00263 { 00264 os << "{"; 00265 if( v.empty()) 00266 return os << " }"; 00267 00268 for (unsigned int i=0,imax=v.size(); i<imax; ++i) 00269 { 00270 os << " "; 00271 v[i]->print(os); 00272 } 00273 00274 return os << " }"; 00275 } 00276 00277 rpnbase* rpnprogram::copy() const 00278 { 00279 /* A deep copy is required. */ 00280 00281 rpnprogram* p = new rpnprogram(); 00282 00283 if (v.empty()) 00284 { 00285 if (variables.empty()) 00286 return p; 00287 00288 for (unsigned int i=0, imax=variables.size(); i<imax; ++i) 00289 { 00290 rpnbase* tmp = variables[i]->copy(); 00291 p->variables.push_back( (rpnvar*)tmp ); 00292 } 00293 00294 return p; 00295 } 00296 00297 deque<rpnbase*> &v2 = p->v; 00298 00299 for (unsigned int i=0, imax=v.size(); i<imax; ++i) 00300 v2.push_back( v[i]->copy() ); 00301 00302 if (variables.empty()) 00303 return p; 00304 00305 for (unsigned int i=0, imax=variables.size(); i<imax; ++i) 00306 { 00307 rpnbase* tmp = variables[i]->copy(); 00308 p->variables.push_back( (rpnvar*)tmp ); 00309 } 00310 00311 return p; 00312 }; 00313 00314 rpnprogram::~rpnprogram() 00315 { 00316 if (!v.empty()) 00317 { 00318 for (unsigned int i=0, imax=v.size(); i<imax; ++i) 00319 v[i]->dec(); 00320 v.clear(); 00321 } 00322 00323 if (!variables.empty()) 00324 { 00325 for (unsigned int i=0, imax=variables.size(); i<imax; ++i) 00326 variables[i]->dec(); 00327 variables.clear(); 00328 } 00329 } 00330 00331 void rpnprogram::eval_01( deque<rpnbase*>& ds ) 00332 { 00333 if(!v.empty()) 00334 { 00335 for (unsigned int i=0,imax=v.size(); i<imax; ++i ) 00336 { 00337 v[i]->inc(); 00338 if (v[i]->isprogram()) 00339 ds.push_front(v[i]); 00340 else 00341 v[i]->eval(ds); 00342 } 00343 } 00344 } 00345 00346 void rpnprogram::eval_00() 00347 { 00348 if(!v.empty()) 00349 { 00350 for (unsigned int i=0,imax=v.size(); i<imax; ++i ) 00351 { 00352 v[i]->inc(); 00353 if (v[i]->isprogram()) 00354 rpnprogramstackstate().ds().push_front(v[i]); 00355 else 00356 v[i]->eval(rpnprogramstackstate().ds()); 00357 } 00358 } 00359 } 00360 00361 void rpnprogram::eval_11( deque<rpnbase*>& ds ) 00362 { 00363 deque<rpnprogram*>& ps(* rpnprogramstackstate().ps); 00364 ps.push_front(this); 00365 00366 if(!v.empty()) 00367 { 00368 for (unsigned int i=0,imax=v.size(); i<imax; ++i ) 00369 { 00370 v[i]->inc(); 00371 if (v[i]->isprogram()) 00372 ds.push_front(v[i]); 00373 else 00374 v[i]->eval(ds); 00375 } 00376 } 00377 00378 // Remove self from program stack. 00379 if (ps.front()==this) 00380 rpnprogramstackstate().pop(); 00381 else 00382 { 00383 unsigned int const imax=ps.size(); 00384 for (unsigned int i=1; i<imax; ++i) 00385 { 00386 if (ps[i]==this) 00387 { 00388 ps.erase(ps.begin()+i); 00389 i=imax; 00390 } 00391 } 00392 } 00393 } 00394 00395 void rpnprogram::eval_10() 00396 { 00397 deque<rpnprogram*>& ps(* rpnprogramstackstate().ps); 00398 ps.push_front(this); 00399 00400 if(!v.empty()) 00401 { 00402 for (unsigned int i=0,imax=v.size(); i<imax; ++i ) 00403 { 00404 v[i]->inc(); 00405 if (v[i]->isprogram()) 00406 rpnprogramstackstate().ds().push_front(v[i]); 00407 else 00408 v[i]->eval(rpnprogramstackstate().ds()); 00409 } 00410 } 00411 00412 // Remove self from program stack. 00413 if (ps.front()==this) 00414 rpnprogramstackstate().pop(); 00415 else 00416 { 00417 unsigned int const imax=ps.size(); 00418 for (unsigned int i=1; i<imax; ++i) 00419 { 00420 if (ps[i]==this) 00421 { 00422 ps.erase(ps.begin()+i); 00423 i=imax; 00424 } 00425 } 00426 } 00427 } 00428 00429 00430 void rpnprogram::eval( deque<rpnbase*>& ds ) 00431 { 00432 switch( state ) 00433 { 00434 case 3: eval_11(ds); break; 00435 case 1: eval_10(); break; 00436 case 2: eval_01(ds); break; 00437 case 0: eval_00(); break; 00438 } 00439 00440 dec(); 00441 00442 /* 00443 deque<rpnprogram*>& ps(* rpnprogramstackstate().ps); 00444 ps.push_front(this); 00445 // rpnprogramstackstate().push(this); 00446 00447 00448 00449 cout << "rpnprogram::eval( deque<rpnbase*>& ds )" << endl; 00450 00451 if(!v.empty()) 00452 { 00453 for (unsigned int i=0,imax=v.size(); i<imax; ++i ) 00454 { 00455 v[i]->inc(); 00456 if (v[i]->isprogram()) 00457 ds.push_front(v[i]); 00458 else 00459 v[i]->eval(ds); 00460 } 00461 } 00462 00463 //bool found=false; 00464 00465 // Remove self from program stack. 00466 if (ps.front()==this) 00467 { 00468 //found=true; 00469 rpnprogramstackstate().pop(); 00470 } 00471 else 00472 { 00473 unsigned int const imax=ps.size(); 00474 for (unsigned int i=1; i<imax; ++i) 00475 { 00476 if (ps[i]==this) 00477 { 00478 //found=true; 00479 ps.erase(ps.begin()+i); 00480 i=imax; 00481 } 00482 } 00483 } 00484 00485 //cout << "found=" << found << endl; 00486 00487 // rpnprogramstackstate().pop(); 00488 00489 dec(); 00490 */ 00491 } 00492 00493 00494 00495 void rpnvar::inc() 00496 { 00497 ++counter; 00498 x->inc(); 00499 } 00500 00501 rpnvar::~rpnvar() 00502 { 00503 if (x==0) 00504 return; 00505 00506 x->dec(); 00507 } 00508 00509 rpnvar::rpnvar(rpnprogram& prog, rpnbase* x_, string const & s) 00510 : varname(s), x(x_) 00511 { 00512 prog.variables.push_front(this); 00513 } 00514 00515 rpnvar::rpnvar(rpnbase* x_, string const & s) 00516 : varname(s), x(x_) 00517 { 00518 } 00519 00520 rpnbase* rpnvar::copy() const 00521 { 00522 return new rpnvar( x->copy(),varname); 00523 } 00524 00525 ostream& rpnvar::print(ostream& os) const 00526 { 00527 os << varname << " : "; 00528 return x->print(os); 00529 } 00530 00531 00532 rpnvector::rpnvector(int index) 00533 { 00534 reverseindex = indexcomplement(index); 00535 } 00536 00537 rpnbase* rpnvector::copy() const 00538 { 00539 /* I do not want a default contructor, so put a dummy 00540 argument in. The reverseindex should be preserved 00541 with a copy as they point to the same place. 00542 */ 00543 rpnvector* p = new rpnvector((int)0); 00544 p->reverseindex = reverseindex; 00545 return p; 00546 } 00547 00548 int const rpnvector::indexcomplement(int const n) const 00549 { 00550 int k = rpnprogramstackstate().ds().size(); 00551 k -= n; 00552 return k; 00553 } 00554 00555 const int rpnvector::index() const 00556 { 00557 return indexcomplement(reverseindex); 00558 } 00559 00560 00561 ostream& rpnvector::print(ostream& os) const 00562 { 00563 return os << " " << index() << " [] "; 00564 //return os << " " << indexcomplement(reverseindex) << " [] "; 00565 } 00566 00567 00568 rpnbase* rpnfunction::copy() const 00569 { 00570 return 0; 00571 } 00572 00573 00574 deque<rpnbase*> rpnprogramstackstate::ds2; 00575 deque<rpnprogram*>* rpnprogramstackstate::ps = 00576 new deque<rpnprogram*>(); 00577 rpnprogram rpnprogramstackstate::rpnhome; 00578 string rpnprogramstackstate::findprogrampath; 00579 00580 void rpnprogramstackstate::find 00581 ( 00582 bool & result, 00583 unsigned int & indexi, 00584 unsigned int & indexk, 00585 rpnvar* & x, 00586 string const & nm 00587 ) const 00588 { 00589 result=false; 00590 00591 for (unsigned int i=0, imax=ps->size(); i<imax; ++i) 00592 { 00593 deque<rpnprogram*>& w = *ps; // <TODO> optimize. 00594 if ( ! w[i]->variables.empty() ) 00595 { 00596 deque<rpnvar*>& z = w[i]->variables; 00597 for (unsigned int k=0, kmax=z.size(); k<kmax; ++k) 00598 { 00599 if (z[k]->varname==nm) 00600 { 00601 result=true; 00602 indexi = i; 00603 indexk = k; 00604 x = z[k]; 00605 00606 return; 00607 } 00608 } 00609 } 00610 } 00611 } 00612 00613 00614 00615 /* While developing rely on general find, optimize at a later date. */ 00616 00617 00618 00619 void rpnprogramstackstate::exists 00620 ( 00621 bool & res, 00622 string const & nm 00623 ) const 00624 { 00625 unsigned int i,k; 00626 rpnvar* x; 00627 00628 find(res,i,k,x,nm); 00629 } 00630 00631 00632 void rpnprogramstackstate::evaluate 00633 ( 00634 deque<rpnbase*>& ds, 00635 string const & nm 00636 ) const 00637 { 00638 bool res; 00639 unsigned int i,k; 00640 rpnvar* x; 00641 00642 find(res,i,k,x,nm); 00643 if (res) 00644 x->x->copy()->eval(ds); 00645 } 00646 00647 void rpnprogramstackstate::recall 00648 ( 00649 deque<rpnbase*>& ds, 00650 string const & nm 00651 ) const 00652 { 00653 bool res; 00654 unsigned int i,k; 00655 rpnvar* x; 00656 00657 find(res,i,k,x,nm); 00658 if (res) 00659 ds.push_front(x->x->copy()); 00660 } 00661 00662 void rpnprogramstackstate::recallpointer 00663 ( 00664 deque<rpnbase*>& ds, 00665 string const & nm 00666 ) const 00667 { 00668 bool res; 00669 unsigned int i,k; 00670 rpnvar* x; 00671 00672 find(res,i,k,x,nm); 00673 if (res) 00674 { 00675 x->x->inc(); 00676 ds.push_front(x->x); 00677 } 00678 } 00679 00680 00681 void rpnprogramstackstate::replace(rpnbase* x, string const & nm) 00682 { 00683 bool res; 00684 unsigned int i,k; 00685 rpnvar* x2; 00686 00687 find(res,i,k,x2,nm); 00688 if (res) 00689 { 00690 x2->x->dec(); 00691 x2->x = x; 00692 } 00693 else 00694 x->dec(); /* harsh */ 00695 } 00696 00697 void rpnprogramstackstate::erase(string const & nm) 00698 { 00699 bool res; 00700 unsigned int i,k; 00701 rpnvar* x2; 00702 00703 find(res,i,k,x2,nm); 00704 if (res) 00705 { 00706 deque<rpnprogram*>& w = *ps; 00707 w[i]->variables.erase( w[i]->variables.begin()+k ); 00708 } 00709 } 00710 00711 void rpnprogramstackstate::init() 00712 { 00713 ps->push_front( &rpnhome ); 00714 } 00715 00716 ostream& rpnprogramstackstate::print(ostream& os) const 00717 { 00718 for (unsigned int i=0, imax=ps->size(); i<imax; ++i) 00719 { 00720 os << "{ "; 00721 deque<rpnprogram*>& w = *ps; 00722 if ( ! w[i]->variables.empty() ) 00723 { 00724 deque<rpnvar*>& z = w[i]->variables; 00725 for (unsigned int k=0, kmax=z.size(); k<kmax; ++k) 00726 { 00727 os << "(" << z[k]->varname << ","; 00728 z[k]->x->print(os); 00729 os << ") "; 00730 } 00731 } 00732 os << "}" << endl; 00733 } 00734 return os; 00735 } 00736 00737 void rpnprogramstackstate::add(rpnbase* x, string const & s) 00738 { 00739 ps->front()->variables.push_front( new rpnvar(x,s) ); 00740 } 00741 00742 00743 void rpnprogramstackstate::findprogram 00744 ( 00745 bool& found, 00746 string& path, 00747 rpnprogram* targ 00748 ) 00749 { 00750 found = false; 00751 00752 00753 if (targ==&rpnhome) 00754 { 00755 findprogrampath = path = "/"; 00756 found = true; 00757 return; 00758 } 00759 00760 findprogram(found,&rpnhome,"",targ); 00761 00762 if (found) 00763 path = findprogrampath; 00764 } 00765 00766 void rpnprogramstackstate::findprogram 00767 ( 00768 bool& found, 00769 rpnprogram* p, 00770 string const path, 00771 rpnprogram* targ 00772 ) 00773 { 00774 /* Depth first search. */ 00775 /* Assume non-cyclic data structure. */ 00776 00777 if (!p->variables.empty()) 00778 { 00779 for (unsigned int i=0, imax=p->variables.size(); i<imax; ++i) 00780 { 00781 if (found) 00782 return; 00783 00784 if (p->variables[i]->x->isprogram()) 00785 { 00786 rpnprogram* pr = (rpnprogram*)(p->variables[i]->x); 00787 00788 string pathnew( path + string("/") + p->variables[i]->varname ); 00789 00790 if (pr == targ) 00791 { 00792 found = true; 00793 findprogrampath = pathnew; 00794 return; 00795 } 00796 else 00797 findprogram(found,pr,pathnew,targ); 00798 00799 } 00800 } 00801 } 00802 } 00803 00804 00805 ostream& operator << (ostream& os, rpnprogramstackstate const & ps) 00806 { return ps.print(os); } 00807 00808 00809 00810
1.5.8