Files Classes Functions Hierarchy
00001 #ifndef RPN_H 00002 #define RPN_H 00003 00004 #include <iostream> 00005 #include <deque> 00006 #include <string> 00007 #include <complex> 00008 00009 using namespace std; 00010 00011 00012 00013 00014 class rpnfunction; 00015 00016 class rpnbase 00017 { 00018 public: 00019 00020 /* Reference counting for memory management. */ 00021 unsigned int counter; 00022 virtual void inc() 00023 { ++counter; } 00024 void dec() 00025 { --counter; if (counter==0) delete this; } 00026 00027 /* Constructors, destructors and deep copy. */ 00028 rpnbase() : counter(1) {} 00029 virtual ~rpnbase()=0; 00030 virtual rpnbase* copy() const=0; 00031 00032 virtual ostream& print(ostream& os) const 00033 { return os << this->name(); } 00034 /* Associated symbol with the class. */ 00035 virtual string const name() const 00036 { return string("undefined"); } 00037 00038 /* Evaluation on the stack. */ 00039 virtual void eval( deque<rpnbase*>& ds ) 00040 { ds.push_front(this); } 00041 00042 /* Visitor patterns accept function forwards data type. */ 00043 virtual void accept(deque<rpnbase*>& ds,rpnfunction& f) {} 00044 00045 /* Real time type information. */ 00046 virtual bool const isinteger() const { return false; } 00047 virtual bool const isreal() const { return false; } 00048 virtual bool const iscomplex() const { return false; } 00049 virtual bool const isstring() const { return false; } 00050 virtual bool const isprogram() const { return false; } 00051 virtual bool const isvariable() const { return false; } 00052 virtual bool const isvector() const { return false; } 00053 bool const isnumber() const 00054 { return this->isreal() || this->isinteger(); } 00055 00056 }; 00057 00058 ostream& operator << (ostream& os, rpnbase* const p); 00059 00060 class rpnprogram; 00061 class rpnstring; 00062 class rpnreal; 00063 class rpncomplex; 00064 class rpninteger; 00065 class rpnvar; 00066 class rpnvector; 00067 00068 00069 /* Derive functions */ 00070 class rpnfunction : public rpnbase 00071 { 00072 public: 00073 00074 rpnfunction() {} 00075 ~rpnfunction() {} 00076 rpnbase* copy() const; 00077 00078 virtual void visit(deque<rpnbase*>& ds,rpnprogram& p) {} 00079 virtual void visit(deque<rpnbase*>& ds,rpnstring& s) {} 00080 virtual void visit(deque<rpnbase*>& ds,rpnreal& n) {} 00081 virtual void visit(deque<rpnbase*>& ds,rpncomplex& n) {} 00082 virtual void visit(deque<rpnbase*>& ds,rpninteger& n) {} 00083 virtual void visit(deque<rpnbase*>& ds,rpnvar& n) {} 00084 virtual void visit(deque<rpnbase*>& ds,rpnvector& v) {} 00085 00086 void eval( deque<rpnbase*>& ds ) 00087 { 00088 if (!ds.empty()) 00089 ds[0]->accept(ds,*this); 00090 00091 dec(); 00092 }; 00093 00094 string const name() const 00095 { return string("rpnfunction"); } 00096 }; 00097 00098 00099 class rpnreal : public rpnbase 00100 { 00101 public: 00102 00103 long double num; 00104 typedef long double type; 00105 00106 rpnreal() {} 00107 rpnreal(long double const n) : num(n) {} /* <TODO> Is this necessary? */ 00108 rpnreal(deque<rpnbase*>& ds,long double const n); 00109 ~rpnreal() {} 00110 rpnbase* copy() const; 00111 00112 void accept(deque<rpnbase*>& ds,rpnfunction& f) 00113 { f.visit(ds,*this); } 00114 00115 ostream& print(ostream& os) const; 00116 string const name() const 00117 { return string("rpnreal"); } 00118 00119 bool const isreal() const 00120 { return true; } 00121 }; 00122 00123 00124 class rpncomplex: public rpnbase 00125 { 00126 public: 00127 00128 complex< long double > num; 00129 00130 rpncomplex() {} 00131 rpncomplex 00132 ( 00133 deque<rpnbase*>& ds, 00134 long double const x, 00135 long double const y 00136 ); 00137 rpncomplex 00138 ( 00139 deque<rpnbase*>& ds, 00140 complex<long double> const & x 00141 ); 00142 ~rpncomplex() {} 00143 rpnbase* copy() const; 00144 00145 void accept(deque<rpnbase*>& ds,rpnfunction& f) 00146 { f.visit(ds,*this); } 00147 00148 ostream& print(ostream& os) const; 00149 string const name() const 00150 { return string("rpncomplex"); } 00151 00152 bool const iscomplex() const 00153 { return true; } 00154 }; 00155 00156 00157 class rpninteger: public rpnbase 00158 { 00159 public: 00160 00161 long int num; 00162 typedef long int type; 00163 00164 static unsigned int displaybase; 00165 00166 rpninteger() {} 00167 rpninteger(deque<rpnbase*>& ds,long int const n); 00168 ~rpninteger() {} 00169 rpnbase* copy() const; 00170 00171 void accept(deque<rpnbase*>& ds,rpnfunction& f) 00172 { f.visit(ds,*this); } 00173 00174 ostream& print(ostream& os) const; 00175 string const name() const 00176 { return string("rpninteger"); } 00177 00178 bool const isinteger() const 00179 { return true; } 00180 }; 00181 00182 00183 class rpnstring : public rpnbase 00184 { 00185 public: 00186 00187 string str; 00188 00189 rpnstring() {} 00190 rpnstring(deque<rpnbase*>& ds,string const & s); 00191 ~rpnstring() {} 00192 rpnbase* copy() const; 00193 00194 void accept(deque<rpnbase*>& ds,rpnfunction& f) 00195 { f.visit(ds,*this); } 00196 00197 ostream& print(ostream& os) const; 00198 00199 void eval( deque<rpnbase*>& ds ); 00200 00201 bool const isstring() const 00202 { return true; } 00203 }; 00204 00205 00206 /* <TODO> Restrict to access by rpnprogram, don't create on the stack. */ 00207 00208 /* Rpn Variable class. - Used by rpnprogram. 00209 */ 00210 class rpnvar : public rpnbase 00211 { 00212 public: 00213 00214 string varname; 00215 rpnbase* x; 00216 00217 void inc(); 00218 00219 rpnvar(rpnbase* x_, string const & s); 00220 rpnvar(rpnprogram& prog, rpnbase* x_, string const & s); 00221 ~rpnvar(); 00222 00223 rpnbase* copy() const; 00224 void accept(deque<rpnbase*>& ds,rpnfunction& f) 00225 { f.visit(ds,*this); } 00226 00227 void eval( deque<rpnbase*>& ds ) 00228 { rpnbase* w = x->copy(); w->eval(ds); } 00229 00230 ostream& print(ostream& os) const; 00231 string const name() const 00232 { return varname; } 00233 00234 bool const isvariable() const 00235 { return true; } 00236 }; 00237 00238 00239 class rpnvector : public rpnbase 00240 { 00241 /* Counting from the stack bottom is 0 as the first element. 00242 Counting from the stack end is 1 as the first element. 00243 Then can convert between the two with the same formula: 00244 f(k) = n-k eg n=6, k=1 then f(1)=5 which is 1: ,f( f(1) ) = 1. 00245 */ 00246 public: 00247 00248 /* Counting from the end of the stack. */ 00249 int reverseindex; 00250 00251 rpnvector(int index); 00252 00253 rpnbase* copy() const; 00254 void accept(deque<rpnbase*>& ds,rpnfunction& f) 00255 { f.visit(ds,*this); } 00256 00257 ostream& print(ostream& os) const; 00258 string const name() const 00259 { return "rpnvector"; } 00260 00261 /* Convert between counting from the start of the stack 00262 and the end of the stack. */ 00263 int const indexcomplement(int const n) const; 00264 /* Return the index relative to the current stack. */ 00265 //const int rpnvector::index() const; 00266 const int index() const; 00267 00268 bool const isvector() const 00269 { return true; } 00270 }; 00271 00272 00273 00274 class rpnprogram : public rpnbase 00275 { 00276 void vinc(); 00277 public: 00278 00279 deque<rpnbase*> v; 00280 deque<rpnvar*> variables; 00281 00282 // How the program is interpreted. 00283 // bit 0 on has the program pushed onto the program stack. 00284 // bit 1 on has a constant data stack, 00285 // off uses the top programs data stack. 00286 // By default both bits are on. 00287 unsigned int state; 00288 00289 void eval_11( deque<rpnbase*>& ds ); 00290 void eval_10(); 00291 void eval_01( deque<rpnbase*>& ds ); 00292 void eval_00(); 00293 00294 void inc(); 00295 00296 bool const valid() const; 00297 00298 rpnprogram(); 00299 rpnprogram(deque<rpnbase*>& ds); 00300 rpnprogram 00301 ( 00302 deque<rpnbase*>& ds, 00303 deque<rpnbase*>& ds2, 00304 bool const evaluate=true 00305 ); 00306 ~rpnprogram(); 00307 rpnbase* copy() const; 00308 00309 void accept(deque<rpnbase*>& ds,rpnfunction& f) 00310 { f.visit(ds,*this); } 00311 00312 ostream& print(ostream& os) const; 00313 00314 void eval( deque<rpnbase*>& ds ); 00315 00316 00317 00318 bool const isprogram() const 00319 { return true; } 00320 }; 00321 00322 00323 /* Access the programs state. Its a singleton class 00324 * which holds pointers to the systems state. 00325 * Also supports variable operations for var suggesting 00326 * that this class should be made into two classes. */ 00327 00328 class rpnprogramstackstate 00329 { 00330 static string findprogrampath; 00331 void findprogram 00332 ( 00333 bool& found, 00334 rpnprogram* p, 00335 string const path, 00336 rpnprogram* targ 00337 ); 00338 public: 00339 00340 static rpnprogram rpnhome; 00341 00342 /* The primary program pointer, is never empty. */ 00343 static deque<rpnprogram*>* ps; 00344 00345 /* Minor stack. */ 00346 static deque<rpnbase*> ds2; 00347 00348 rpnprogramstackstate() {} 00349 00350 /* Client must call before and after use. */ 00351 void init(); 00352 00353 /* Access the most recent program's stack. */ 00354 deque<rpnbase*>& ds() 00355 { return ps->front()->v; } 00356 /* Access the most recent programs's variables. */ 00357 deque<rpnvar*>& vs() 00358 { return ps->front()->variables; } 00359 00360 ostream& print(ostream& os) const; 00361 00362 /* Control scoping/visability of programs and consequently variables. */ 00363 void push(rpnprogram* p) 00364 { ps->push_front(p); } 00365 void pop() 00366 { if(ps->size()>1) ps->pop_front(); } 00367 00368 /* Add a variable to the most rescent stack program. */ 00369 void add(rpnbase* x, string const & s); 00370 00371 /* Find the program in the rpnhome tree. */ 00372 void findprogram(bool& found, string& path, rpnprogram* targ); 00373 00374 /* Searches for a named variable, in the stack order. */ 00375 void find 00376 ( 00377 bool & result, 00378 unsigned int & indexi, 00379 unsigned int & indexk, 00380 rpnvar* & x, 00381 string const & nm 00382 ) const; 00383 00384 /* Support operations on variables. */ 00385 void erase(string const &nm); 00386 void replace(rpnbase* x, string const & nm); 00387 void exists(bool& res, string const & nm) const; 00388 void evaluate(deque<rpnbase*>& ds, string const & nm) const; 00389 void recall(deque<rpnbase*>& ds, string const & nm) const; 00390 void recallpointer(deque<rpnbase*>& ds, string const & nm) const; 00391 00392 }; 00393 00394 ostream& operator << (ostream& os, rpnprogramstackstate const & ps); 00395 00396 00397 00398 00399 #endif 00400 00401 00402
1.5.8