proj home

Files   Classes   Functions   Hierarchy  

scopedependentfunctions.cpp

Go to the documentation of this file.
00001 
00002 
00003 #ifndef NDEBUG
00004 //#define DEBUG_SCOPEDEPENDENTFUNCTIONS_H
00005 #endif
00006 
00007 #include <cassert>
00008 #include <deque>
00009 #include <string>
00010 #include <iostream>
00011 #include <fstream>
00012 #include <sstream>
00013 using namespace std;
00014 
00015 #include <rpn.h>
00016 #include <rawinterpreter.h>
00017 #include <singleton.h>
00018 
00019 
00020 
00021 
00022 #include <scopedependentfunctions.h>
00023 
00024 
00025 
00026 // Implementation
00027 // ---------------------------------------------------------------
00028 //
00029 
00030 
00031 
00032 stateevalset::stateevalset(deque<rpnbase*>& ds, bool const evaluate)
00033 {
00034   if (evaluate)
00035     eval(ds);
00036   else
00037     ds.push_front(this);
00038 }
00039 
00040 rpnbase* stateevalset::copy() const
00041 {
00042   return new stateevalset(); 
00043 }
00044 
00045 void stateevalset::eval( deque<rpnbase*>& ds )
00046 {
00047   if (inputstatescope::cscope->evaloverride)
00048     inputstatescope::cscope->evalpreserved = true;
00049   else
00050     inputstatescope::cscope->evalimmediate = true;
00051 
00052   dec();
00053 }
00054 
00055 
00056 stateevalunset::stateevalunset(deque<rpnbase*>& ds, bool const evaluate)
00057 {
00058   if (evaluate)
00059     eval(ds);
00060   else
00061     ds.push_front(this);
00062 }
00063 
00064 rpnbase* stateevalunset::copy() const
00065 {
00066   return new stateevalunset(); 
00067 }
00068 
00069 void stateevalunset::eval( deque<rpnbase*>& ds )
00070 {
00071   if (inputstatescope::cscope->evaloverride)
00072     inputstatescope::cscope->evalpreserved = false;
00073   else
00074     inputstatescope::cscope->evalimmediate = false;
00075 
00076   dec();
00077 }
00078 
00079 
00080 stateevalquery::stateevalquery(deque<rpnbase*>& ds, bool const evaluate)
00081 {
00082   if (evaluate)
00083     eval(ds);
00084   else
00085     ds.push_front(this);
00086 }
00087 
00088 rpnbase* stateevalquery::copy() const
00089 {
00090   return new stateevalquery(); 
00091 }
00092 
00093 void stateevalquery::eval( deque<rpnbase*>& ds )
00094 {
00095   int val;
00096 
00097   if (inputstatescope::cscope->evaloverride)
00098   {
00099     if (inputstatescope::cscope->evalpreserved)
00100       val = 1;
00101     else 
00102       val = 0;
00103   }
00104   else
00105   {
00106     if (inputstatescope::cscope->evalimmediate)
00107       val = 1;
00108     else 
00109       val = 0;
00110   }
00111 
00112   new rpninteger(ds,val);
00113 
00114   dec();
00115 }
00116 
00117 load::load(deque<rpnbase*>& ds, bool const evaluate)
00118 {
00119   if (evaluate)
00120     eval(ds);
00121   else
00122     ds.push_front(this);
00123 }
00124 
00125 rpnbase* load::copy() const
00126 {
00127   return new load();
00128 }
00129 
00130 void load::eval( deque<rpnbase*>& ds )
00131 {
00132   if(ds.empty())
00133     return;
00134 
00135   ds[0]->accept(ds,*this);
00136 
00137   dec();
00138 }
00139 
00140 
00141 
00142 void load::visit(deque<rpnbase*>& ds,rpnstring& fname)
00143 {
00144   rpnbase* x0 = ds.front();
00145   ds.pop_front();
00146 
00147   ifstream input( fname.str.c_str() );
00148   if (!input) 
00149   {
00150     ds.push_front(x0);
00151     return;
00152   }
00153 
00154   SingletonPtr<inputstatescope>()->fd.reset();
00155 
00156   bool const preservedmode = SingletonPtr<inputstatescope>()->evalimmediate;
00157 
00158   //istream & is(input);
00159   SingletonPtr<inputstatescope>()->fd.process2_silent(input);
00160 
00161 
00162 /* // Killed 21/11/04 because using streams explicitly.
00163   bool getinput=true;
00164   string s;
00165   while ( getinput )
00166   {
00167     if (!input)
00168       break;
00169 
00170     getline(input,s);
00171     SingletonPtr<inputstatescope>()->fd.process(getinput,s);
00172   }
00173 */
00174 
00175 
00176 /*  // Preserved because it works. 21/12/03
00177   string s;
00178   bool getinput=true;
00179 
00180   vector<string> tokens;
00181   for ( ; getinput ; )
00182   {
00183     if (!input)
00184       break;
00185 
00186     getline(input,s);
00187       
00188     linesplit(tokens,s," ");
00189     if (!tokens.empty())
00190     {
00191       for (unsigned int i=0, imax=tokens.size(); i<imax; ++i)
00192       {
00193         if (tokens[i]=="quit")
00194         {
00195           getinput=false;
00196           break;
00197         }
00198 
00199         SingletonPtr<inputstatescope>()->eval(tokens[i]);
00200 
00201       }
00202     }
00203   }
00204 */
00205 
00206   SingletonPtr<inputstatescope>()->evalimmediate = preservedmode;
00207  
00208   // Load the user settings. 
00209   bin(); 
00210 
00211   x0->dec();
00212 }
00213 
00214 void load::bin()
00215 {
00216   rpnprogram* hm = rpnprogramstackstate().ps->back();
00217   if (hm->variables.empty())
00218     return;
00219 
00220   bool notfound=true;
00221   rpnprogram* bin;
00222   rpnvar* var;
00223   for (unsigned int i=0, imax=hm->variables.size(); i<imax; ++i)
00224   {
00225     var = hm->variables[i];
00226     if (var->varname=="bin")
00227     {
00228       if (! var->x->isprogram() )
00229         return;
00230 
00231       notfound=false;
00232       i=imax;
00233       bin = (rpnprogram*)(var->x);
00234     }
00235   }
00236 
00237   if (notfound)
00238     return;
00239 
00240   if (bin->variables.empty())
00241     return;
00242 
00243   /* Warning. This code is to do exactly what
00244      dictadd code does. So in essence I have
00245      the identical code functionality in two 
00246      different places of the source.
00247      This cost me about 4 hrs to track down.
00248 
00249      Someone could have done it much faster,
00250      but the point is that code functionality
00251      should always be unique. load shoud be
00252      transfering responsibility to dictadd.
00253 
00254      However dictadd builds the thing and so
00255      load and dictadd are coupled.
00256 
00257      Its the coupled relationship between
00258      load and dictadd that I failed to 
00259      understand. Its in the code only in that
00260      the classes are in the same file and this
00261      is just a hint.
00262     
00263   */
00264 
00265   for (unsigned int i=0, imax=bin->variables.size(); i<imax; ++i)
00266   {
00267     var = bin->variables[i];
00268     var->x->inc();
00269     SingletonPtr<inputstatescope>()->fd.add( new fbuilduser(var->x,var->varname) );
00270   }
00271 }
00272 
00273 
00274 rpnsave::rpnsave(deque<rpnbase*>& ds, bool const evaluate)
00275 {
00276   if (evaluate)
00277     eval(ds);
00278   else
00279     ds.push_front(this);
00280 }
00281 
00282 rpnbase* rpnsave::copy() const
00283 {
00284   return new rpnsave();
00285 }
00286 
00287 void rpnsave::eval( deque<rpnbase*>& ds )
00288 {
00289   if(ds.empty())
00290     return;
00291 
00292   ds[0]->accept(ds,*this);
00293 
00294   dec();
00295 }
00296 
00297 
00298 //
00299 //  Chelton  Oct 24th 2004 : readable file output
00300 //
00301 //  The code writevariables and writeprogram is hack and
00302 //    slash coding. Its human readable : matching braces
00303 //    appear at the start of a line. So by looking at the
00304 //    output you can determine what the variables are. 
00305 //
00306 //  The code was originally not written to be readable and
00307 //  just for file reading/writing but at some point editing 
00308 //  a file by hand is useful.
00309 //
00310 
00311 void rpnsave::writevariables(ostream& os, rpnprogram* p)
00312 {
00313 
00314   if (p->variables.empty())
00315     return;
00316 
00317   deque<rpnvar*>& var = p->variables;
00318 
00319   bool pwrite(false);
00320 
00321   for (unsigned int i=var.size(); i>0; )
00322   //for (unsigned int i=0, imax=var.size(); i<imax; ++i)
00323   {
00324     --i;
00325 
00326     if (var[i]->x->isprogram())
00327     {
00328       os << endl << "{ ";
00329       writeprogram(os, (rpnprogram*)(var[i]->x) );
00330       os << "} " << endl;
00331       pwrite=true;
00332     }
00333     else
00334       var[i]->x->print(os) << " ";
00335 
00336     os << var[i]->varname << " " << "@var ";
00337 
00338     if (pwrite)
00339       os << endl;
00340 
00341   }
00342 
00343 }
00344 
00345 void rpnsave::writeprogram(ostream& os, rpnprogram* p)
00346 {
00347 
00348   bool pwrite(false);
00349   
00350   /* Write the data stack. */
00351   if (!p->v.empty())
00352   {
00353     os << "@-" << " ";
00354     for (unsigned int i=0, imax=p->v.size(); i<imax; ++i )
00355     //for (unsigned int i=p->v.size(); i>0; )
00356     {
00357       //--i;
00358 
00359       rpnbase* x = p->v[i];
00360       if (x->isprogram())
00361       {
00362         os << endl << "{ ";
00363         writeprogram( os,(rpnprogram*)x );
00364         os << "} ";
00365         pwrite=true;
00366       }
00367       else
00368       {
00369         x->print(os) << " ";
00370       }
00371     
00372     }
00373 
00374     os << "@rev" << " ";    
00375     if (pwrite)
00376       os << endl;
00377 
00378   }
00379 
00380   writevariables(os,p);
00381 }
00382 
00383 void rpnsave::visit(deque<rpnbase*>& ds,rpnstring& fname)
00384 {
00385   rpnbase* x0 = ds.front();
00386   ds.pop_front();
00387 
00388   ofstream os( fname.str.c_str(), ios::out|ios::trunc );
00389   if (!os) 
00390   {
00391     ds.push_front(x0);
00392     return;
00393   }
00394 
00395   bool const preservedmode = SingletonPtr<inputstatescope>()->evalimmediate;
00396 
00397   writeprogram(os,rpnprogramstackstate().ps->front());
00398 
00399   os << endl;
00400 
00401   os.clear();
00402 
00403   SingletonPtr<inputstatescope>()->evalimmediate = preservedmode;
00404 
00405   x0->dec();
00406 }
00407 
00408 
00409 dictadd::dictadd(deque<rpnbase*>& ds, bool const evaluate)
00410 {
00411   if (evaluate)
00412     eval(ds);
00413   else
00414     ds.push_front(this);
00415 }
00416 
00417 rpnbase* dictadd::copy() const
00418 {
00419   return new dictadd();
00420 }
00421 
00422 void dictadd::eval( deque<rpnbase*>& ds )
00423 {
00424   if(ds.empty())
00425     return;
00426 
00427   ds[0]->accept(ds,*this);
00428 
00429   dec();
00430 }
00431 
00432 void dictadd::visit(deque<rpnbase*>& ds,rpnstring& fname)
00433 {
00434   if (ds.size()<2)
00435     return;
00436 
00437   rpnbase* x0 = ds.front();
00438   ds.pop_front();
00439   rpnbase* x1 = ds.front();
00440   ds.pop_front();
00441   
00442   rpnprogram* hm = rpnprogramstackstate().ps->back();
00443   rpnprogram* bin;
00444   bool notfound=true;
00445   if (!hm->variables.empty())
00446   {
00447     rpnvar* var;
00448     for (unsigned int i=0, imax=hm->variables.size(); i<imax; ++i)
00449     {
00450       var = hm->variables[i];
00451       if (var->varname=="bin")
00452       {
00453         notfound=false;
00454         i=imax;
00455         bin = (rpnprogram*)(var->x);
00456 
00457         if (! var->x->isprogram() ) /* Restore the stack. */
00458         {
00459           ds.push_front(x1);
00460           ds.push_front(x0);
00461 
00462           return;
00463         }
00464 
00465       }
00466     }
00467   }
00468   if (notfound)
00469   {
00470     bin = new rpnprogram();
00471     new rpnvar(*hm,bin,"bin");
00472   }
00473 
00474   /* x1 is now owned by the rpn variable. */
00475   new rpnvar(*bin,x1,fname.str);
00476 
00477   /* fbuild user has a pointer to x1. */
00478   x1->inc();
00479   SingletonPtr<inputstatescope>()->fd.add( new fbuilduser(x1,fname.str) );
00480 
00481   x0->dec();
00482 }
00483 
00484 
00485 rpninterp::rpninterp(deque<rpnbase*>& ds, bool const evaluate)
00486 {
00487   if (evaluate)
00488     eval(ds);
00489   else
00490     ds.push_front(this);
00491 }
00492 
00493 rpnbase* rpninterp::copy() const
00494 {
00495   return new rpninterp();
00496 }
00497 
00498 void rpninterp::eval( deque<rpnbase*>& ds )
00499 {
00500   if(ds.empty())
00501     return;
00502 
00503   ds[0]->accept(ds,*this);
00504 
00505   dec();
00506 }
00507 
00508 void rpninterp::visit(deque<rpnbase*>& ds,rpnstring& s)
00509 {
00510   stringstream ss(s.str.c_str());
00511   SingletonPtr<inputstatescope>()->fd.process2_silent(ss);
00512 }
00513 
00514 
00515 /*
00516 read::read(deque<rpnbase*>& ds, bool const evaluate)
00517 {
00518   if (evaluate)
00519     eval(ds);
00520   else
00521     ds.push_front(this);
00522 }
00523 
00524 rpnbase* read::copy() const
00525 {
00526   return new read();
00527 }
00528 
00529 void read::eval( deque<rpnbase*>& ds )
00530 {
00531   if(ds.empty())
00532     return;
00533 
00534   ds[0]->accept(ds,*this);
00535 
00536   dec();
00537 }
00538 
00539 void read::visit(deque<rpnbase*>& ds,rpnstring& fname)
00540 {
00541   rpnbase* x0 = ds.front();
00542   ds.pop_front();
00543 
00544   ifstream input( fname.str.c_str() );
00545   if (!input) 
00546   {
00547     ds.push_front(x0);
00548     return;
00549   }
00550 
00551   bool getinput=true;
00552   string s;
00553   while ( getinput )
00554   {
00555     if (!input)
00556       break;
00557 
00558     getline(input,s);
00559     SingletonPtr<inputstatescope>()->fd.process(getinput,s);
00560   }
00561 
00562   x0->dec();
00563 }
00564 */
00565 
00566 
00567 initscopedependentfunctions::initscopedependentfunctions()
00568 {
00569 #ifdef DEBUG_SCOPEDEPENDENTFUNCTIONS_H
00570 cout << "initscopedependentfunctions()" << endl;
00571 #endif
00572 
00573   addtothedictionary< dictadd >();
00574   addtothedictionary< stateevalset >();
00575   addtothedictionary< stateevalunset >();
00576   addtothedictionary< stateevalquery >();
00577   addtothedictionary< load >();
00578   addtothedictionary< rpnsave >();
00579   addtothedictionary< rpninterp >();
00580 //  addtothedictionary< read >();
00581 }
00582 
00583 
00584 

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