proj home

Files   Classes   Functions   Hierarchy  

rawinterpreter.cpp

Go to the documentation of this file.
00001 #include <cassert>
00002 #include <sstream>
00003 #include <map>
00004 #include <string>
00005 using namespace std;
00006 
00007 #include <rpn.h>
00008 #include <rpnfunc.h>
00009 #include <mathfunc.h>
00010 #include <singleton.h>
00011 
00012 #include <rawinterpreter.h>
00013 
00014 
00015 #ifndef NDEBUG
00016 //#define DEBUG_INTERPRETER
00017 #endif
00018 
00019 
00020 fbuildbase* fbuilduser::copy() const
00021 {
00022   x->inc();
00023   return new fbuilduser(x,nm);
00024 }
00025 
00026 void fbuilduser::make() const
00027 {
00028   x->inc();
00029   if (inputstatescope::cscope->evalimmediate)
00030     x->eval(rpnprogramstackstate().ds());
00031   else
00032     rpnprogramstackstate().ds().push_front(x);
00033 }
00034 
00035 fbuilduser::fbuilduser(rpnbase* _x, string const & _nm)
00036   : x(_x), nm(_nm)
00037 {
00038 }
00039 
00040 fbuilduser::~fbuilduser()
00041 {
00042   x->dec();
00043 }
00044 
00045 string const fbuilduser::name() const
00046 {
00047   return nm;
00048 }
00049     
00050 
00051 fdatainterp::fdatainterp()
00052 {
00053   init();
00054 }
00055 
00056 void fdatainterp::init()
00057 {
00058   addtodictionary( passtype<rpnprogset>() );
00059   addtodictionary( passtype<rpnpush>() );
00060   addtodictionary( passtype<rpnpop>() );
00061   addtodictionary( passtype<rpnpushn>() );
00062   addtodictionary( passtype<rpnpopn>() );
00063   addtodictionary( passtype<dssize2>() );
00064   addtodictionary( passtype<rpneval>() );
00065   addtodictionary( passtype<rpnclear>() );
00066   addtodictionary( passtype<rpnclearvar>() );
00067   addtodictionary( passtype<rpnclearboth>() );
00068   addtodictionary( passtype<rpndup>() );
00069   addtodictionary( passtype<rpndupn>() );
00070   addtodictionary( passtype<dssize>() );
00071   addtodictionary( passtype<rev>() );
00072   addtodictionary( passtype<rot>() );
00073   addtodictionary( passtype<rotn>() );
00074   addtodictionary( passtype<rpnswap>() );
00075   addtodictionary( passtype<rpnswap2>() );
00076   addtodictionary( passtype<drop>() );
00077   addtodictionary( passtype<dropi>() );
00078   addtodictionary( passtype<dropsymb>() );
00079   addtodictionary( passtype<dropn>() );
00080   addtodictionary( passtype<ifthen>() );
00081   addtodictionary( passtype<thenif>() );
00082   addtodictionary( passtype<ifthenelse>() );
00083   addtodictionary( passtype<thenelseif>() );
00084   addtodictionary( passtype<var>() );
00085   addtodictionary( passtype<vardel>() );
00086   addtodictionary( passtype<vareval>() );
00087   addtodictionary( passtype<varpushd>() );
00088   addtodictionary( passtype<varpopd>() );
00089   addtodictionary( passtype<depthd>() );
00090   addtodictionary( passtype<varls>() );
00091   addtodictionary( passtype<vartree>() );
00092   addtodictionary( passtype<varpwd>() );
00093   addtodictionary( passtype<pathtoggle>() );
00094   addtodictionary( passtype<varinc>() );
00095   addtodictionary( passtype<vardec>() );
00096   addtodictionary( passtype<varexists>() );
00097   addtodictionary( passtype<varreplace>() );
00098   addtodictionary( passtype<varrecall>() );
00099   addtodictionary( passtype<rpnnot>() );
00100   addtodictionary( passtype<rpnneg>() );
00101   addtodictionary( passtype<rpnadd>() );
00102   addtodictionary( passtype<rpnmultiply>() );
00103   addtodictionary( passtype<rpnsubtract>() );
00104   addtodictionary( passtype<rpndivide>() );
00105   addtodictionary( passtype<rpnlessthan>() );
00106   addtodictionary( passtype<rpnlessthanequal>() );
00107   addtodictionary( passtype<rpngreaterthan>() );
00108   addtodictionary( passtype<rpngreaterthanequal>() );
00109   addtodictionary( passtype<rpnequal>() );
00110   addtodictionary( passtype<rpnfor>() );
00111   addtodictionary( passtype<rpnforn>() );
00112   addtodictionary( passtype<prognew>() );
00113   addtodictionary( passtype<progdecompose>() );
00114   addtodictionary( passtype<progrev>() );
00115   addtodictionary( passtype<isrpnstring>() );
00116   addtodictionary( passtype<isrpninteger>() );
00117   addtodictionary( passtype<isrpnreal>() );
00118   addtodictionary( passtype<isrpncomplex>() );
00119   addtodictionary( passtype<isrpnprogram>() );
00120   addtodictionary( passtype<pathcd>() );
00121   addtodictionary( passtype<pathquery>() );
00122   addtodictionary( passtype<varmv>() );
00123   addtodictionary( passtype<rpncp>() );
00124   addtodictionary( passtype<rpninsert>() );
00125   addtodictionary( passtype<rpnerase>() );
00126   addtodictionary( passtype<rpnpointermake>() );
00127   addtodictionary( passtype<rpnvectormake>() );
00128   addtodictionary( passtype<rpnvectorpointermake>() );
00129   addtodictionary( passtype<pstream>() );
00130   addtodictionary( passtype<rpnintegerconvert>() );
00131   addtodictionary( passtype<rpnstringconvert>() );
00132   addtodictionary( passtype<rpnfactorial>() );
00133   addtodictionary( passtype<rpnmod>() );
00134   addtodictionary( passtype<rpngcd>() );
00135   addtodictionary( passtype<rpnascii>() );
00136 
00137   
00138   addtodictionary( passtype<rpnfcos>() );
00139   addtodictionary( passtype<rpnfsin>() );
00140   addtodictionary( passtype<rpnftan>() );
00141   addtodictionary( passtype<rpnflog>() );
00142   addtodictionary( passtype<rpnflog10>() );
00143   addtodictionary( passtype<rpnfexp>() );
00144   addtodictionary( passtype<rpnfsqrt>() );
00145   addtodictionary( passtype<rpnfcosh>() );
00146   addtodictionary( passtype<rpnfsinh>() );
00147   addtodictionary( passtype<rpnftanh>() );
00148   addtodictionary( passtype<rpnfacos>() );
00149   addtodictionary( passtype<rpnfasin>() );
00150   addtodictionary( passtype<rpnfatan>() );
00151   addtodictionary( passtype<rpnffloor>() );
00152   addtodictionary( passtype<rpnfceil>() );
00153   addtodictionary( passtype<rpnpow>() );
00154   addtodictionary( passtype<rpnfabs>() );
00155   addtodictionary( passtype<rpnfarg>() );
00156   addtodictionary( passtype<rpnfnorm>() );
00157   addtodictionary( passtype<rpnfimag>() );
00158   addtodictionary( passtype<rpnfconj>() );
00159   addtodictionary( passtype<rpnrealconvert>() );
00160   addtodictionary( passtype<rpnr_to_d>() );
00161   addtodictionary( passtype<rpnd_to_r>() );
00162   addtodictionary( passtype<rpnp_to_c>() );
00163   addtodictionary( passtype<rpnr_to_c>() );
00164 
00165 
00166 
00167   addtodictionary( passtype< rpnintegerhex >() );
00168   addtodictionary( passtype< rpnintegeroct >() );
00169   addtodictionary( passtype< rpnintegerdec >() );
00170   addtodictionary( passtype< rpnintegerbin >() );
00171   addtodictionary( passtype< rpnbitnot >() );
00172   addtodictionary( passtype< rpnbitxor>() );
00173   addtodictionary( passtype< rpnbitor >() );
00174   addtodictionary( passtype< rpnbitand>() );
00175   addtodictionary( passtype< rpnbitshiftleft>() );
00176   addtodictionary( passtype< rpnbitshiftright>() );
00177 
00178 
00179 }
00180 
00181 void fdatainterp::dictionarydelete()
00182 {
00183   if (!dict.empty())
00184   {
00185     for( map<string,fbuildbase*>::iterator i = dict.begin();
00186       i!=dict.end(); ++i )
00187       delete i->second; 
00188   
00189     dict.clear();
00190   }
00191 }
00192 
00193 void fdatainterp::reset()
00194 {
00195   dictionarydelete();
00196 
00197   // Build the dictionary.
00198   for (unsigned int i=0, n=dicttable.size(); i<n; ++i)
00199     add( dicttable[i]->copy() );
00200 }
00201 
00202 fdatainterp::~fdatainterp()
00203 {
00204   dictionarydelete();
00205 }
00206 
00207 rpnreal::type const fdatainterp::real(string const & word) const
00208 {
00209   stringstream ss(word);
00210   rpnreal::type var;
00211   ss >> var;
00212 
00213   return var;
00214 }
00215 
00216 rpninteger::type const fdatainterp::integer(string const & word) const
00217 {
00218   stringstream ss(word);
00219   rpninteger::type var;
00220   ss >> var;
00221 
00222   return var;
00223 }
00224 
00225 void fdatainterp::eval(string const & word)
00226 {
00227 // 1. Determine if word is a number else
00228 // 2. Determine if word is in the dictionary else
00229 // 3. assume word is a string.
00230   char ch = word[0];
00231 
00232   if ( (ch=='-') && (word.size()>1))
00233     ch = word[1];
00234 
00235   if ( (ch=='.') && (word.size()>1))
00236     ch = word[1];
00237 
00238   if ( isdigit(ch) )
00239   {
00240     // Is the number real or integer. 
00241     bool integertype=true;
00242     for (unsigned int i=0, imax=word.size(); i<imax; ++i)
00243     {
00244       if( word[i]=='.')
00245       {
00246         integertype=false;
00247         i=imax;
00248       }
00249     }
00250 
00251     // Construct the number.
00252     if (integertype)
00253       new rpninteger( rpnprogramstackstate().ds(), integer(word) );
00254     else
00255       new rpnreal( rpnprogramstackstate().ds(), real(word) ); 
00256    
00257     return;
00258   }
00259 
00260   // Not a number 
00261 
00262 #ifdef DEBUG_INTERPRETER
00263 cout << "Input: Not a number." << endl;
00264 #endif
00265 
00266   // The user can force a string onto the stack.
00267 /*
00268   if (ch=='"')
00269   {
00270     if (word.size()==1)
00271       return;
00272 
00273     string w(word.begin()+1,word.end());
00274     new rpnstring( rpnprogramstackstate().ds(), w );
00275 
00276     return;
00277   }
00278 */
00279 
00280   // Search the dictionary. 
00281 
00282   // The # symbol indicates the item should not be evaluated. 
00283   // The @ symbol indicates the item should be evaluated.     
00284   if ((ch=='#')||(ch=='@'))
00285   {
00286     if (word.size()<=2)
00287     {
00288       if (word.size()==1)
00289         return; // Ignore lone # or @ character.
00290 
00291       // Setting the mode was so important that I took it away
00292       // from the standard function system. 
00293       if (word=="@+")
00294       {  // Set immediate evaluation mode. 
00295         inputstatescope::cscope->evalimmediate = true;
00296         return;
00297       }
00298 
00299       if (word=="@-")
00300       { // Unset immediate evaluation mode.
00301         inputstatescope::cscope->evalimmediate = false;
00302         return;
00303       }
00304     }
00305 
00306     bool tmpeval = true;
00307     if (ch=='#')
00308       tmpeval = false;
00309 
00310     string word2(word.begin()+1,word.end());
00311       
00312     map<string,fbuildbase*>::iterator i = dict.find(word2);
00313     if (i!=dict.end())
00314     {
00315       inputstatescope::cscope->evaloverride = true;
00316       inputstatescope::cscope->evalpreserved = 
00317         inputstatescope::cscope->evalimmediate;
00318       inputstatescope::cscope->evalimmediate = tmpeval;
00319  
00320       i->second->make();
00321 
00322       inputstatescope::cscope->evalimmediate = 
00323           inputstatescope::cscope->evalpreserved;
00324       inputstatescope::cscope->evaloverride = false;
00325 
00326       return;
00327     }
00328 
00329   }
00330   else
00331   {
00332 
00333 #ifdef DEBUG_INTERPRETER
00334 cout << "Input: Not a evaluation directive, word=" << 
00335   word  << "." << endl;
00336 #endif
00337 
00338     map<string,fbuildbase*>::iterator i = dict.find(word);
00339     if (i!=dict.end())
00340     {
00341       i->second->make();
00342   
00343       return;
00344     }
00345   }
00346 
00347   // Assume a string
00348 
00349 #ifdef DEBUG_INTERPRETER
00350 cout << "Input: string*" << word << "*" << endl;
00351 #endif
00352 
00353   new rpnstring( rpnprogramstackstate().ds(), word );
00354 };
00355 
00356 
00357 class noaction
00358 {
00359 public:
00360 
00361   void operator()() {}
00362 };
00363 
00364 
00365 
00366 inputstatescope* inputstatescope::cscope = 0;
00367 inputstate*      inputstatescope::cstate = 0;
00368 
00369 inputstatescope::inputstatescope()
00370 {
00371   assert(cscope==0); // This is a singleton class. 
00372 
00373   inner = new innerinput();
00374   outer = new outerinput(); 
00375   error = false;
00376   evalimmediate = true;
00377   evaloverride=false;
00378 
00379   cscope = this;
00380 
00381   setinner();
00382 }
00383 
00384 inputstatescope::~inputstatescope()
00385 {
00386   delete inner;
00387   delete outer;
00388   cstate=0;
00389 }
00390 
00391 void inputstatescope::setinner()
00392 {
00393   cstate = inner;
00394 }
00395 
00396 void inputstatescope::setouter()
00397 {
00398   cstate = outer;
00399 }
00400 
00401 void inputstatescope::eval(string const & word)
00402 {
00403   cstate->eval(word);
00404 }
00405   
00406 
00407 void innerinput::eval(string const & word)
00408 {
00409 
00410   if (word=="{")
00411   {
00412     rpnprogram* p = new rpnprogram();
00413     rpnprogramstackstate().ds().push_front(p);   
00414     rpnprogramstackstate().push( p );
00415 
00416     // Commented out to treat all programs equally.    
00417     // inputstatescope::cscope->evalimmediate = false; 
00418     inputstatescope::cscope->setouter();
00419     return;
00420   }    
00421 
00422   inputstatescope::cscope->fd.eval(word);
00423 }
00424 
00425 
00426 void outerinput::eval(string const & word)
00427 {
00428   if (word=="}")
00429   {
00430     if(rpnprogramstackstate().ps->size() == 2)
00431     {
00432       rpnprogramstackstate().pop();
00433       // Expecting a program on the data stack. 
00434 
00435       // Programs are not evaluated when placed on the stack.
00436 
00437       inputstatescope::cscope->setinner();
00438       return;
00439     }
00440 
00441     // Assume rpnprogramstackstate().ps->size() > 2.
00442     rpnprogramstackstate().pop();
00443     return;
00444   }
00445 
00446   if (word=="{")
00447   {
00448     rpnprogram* p = new rpnprogram();
00449     rpnprogramstackstate().ds().push_front(p);   
00450     rpnprogramstackstate().push( p );
00451 
00452     return;
00453   } 
00454 
00455   inputstatescope::cscope->fd.eval(word);
00456 }
00457 
00458 
00459 //
00460 //  I am experimenting with streams.  In theory
00461 //  reading a file and getting user input are both
00462 //  istreams so should use the same code, but they
00463 //  behave differently.
00464 //
00465 //  The code is really similar. This version is
00466 //  getting from a file. The end of file needs to
00467 //  be checked so that an exit can occure. The keyboard
00468 //  read needs no such test.
00469 //
00470 //  quit will not work, it leaves the local stream only.
00471 void fdatainterp::process2_silent( istream & is )
00472 {
00473   char c;
00474   char const quote('"');
00475   char const space(' ');
00476   char const ret('\n');
00477 
00478   string s;
00479 
00480   string const quit("quit");
00481 
00482   while ((c = is.peek()))
00483   {
00484 //cout << "c=" << c << endl;
00485     s.clear();
00486 
00487     if (c==quote)
00488     {
00489       is.get(c);
00490       is.get(c);
00491       while (c!=quote)
00492       {
00493         s += c;
00494         is.get(c);
00495         if (!is)
00496           return;
00497       }
00498 
00499       new rpnstring( rpnprogramstackstate().ds(), s );
00500     }
00501     else
00502     if (c=='(')
00503     {
00504       complex< long double > x;
00505       is >> x;
00506      
00507       new rpncomplex( rpnprogramstackstate().ds(), x );
00508 
00509     }
00510     else
00511     {
00512       is.get(c);
00513       if ((c!=space)&&(c!=ret))
00514       {
00515         s += c;
00516         is.get(c);
00517 //cout << "c=" << c << endl;
00518         while ((c!=space)&&(c!=ret))
00519         {
00520           s += c;
00521           is.get(c);
00522 //cout << "c=" << c << endl;
00523           if (!is)
00524             return;
00525         }
00526       }
00527 
00528       if (!s.empty())
00529         SingletonPtr<inputstatescope>()->eval(s);
00530 
00531     }
00532 
00533     if (!is)
00534       return;
00535 
00536     if (s==quit)
00537       break;
00538   }
00539 }
00540 
00541 
00542 
00543 
00544 

Generated on Fri Mar 4 00:49:30 2011 for Chelton Evans Source by  doxygen 1.5.8