proj home

Files   Classes   Functions   Hierarchy  

rawinterpreter.h

Go to the documentation of this file.
00001 #ifndef RAWINTERPRETER_H
00002 #define RAWINTERPRETER_H
00003 
00004 #include <cassert>
00005 #include <string>
00006 #include <map>
00007 #include <vector>
00008 #include <iostream>
00009 using namespace std;
00010 
00011 #include <rpn.h>
00012 #include <singleton.h>
00013 
00014 
00015 // Helper class for fdatainterp.
00016 // Funtion builder - build function and instanciate. 
00017 class fbuildbase
00018 {
00019 public:
00020 
00021   virtual ~fbuildbase() {}
00022 
00023   // Name of function. 
00024   virtual string const name() const { return string(); }
00025   // Create a function and transfer/execute on the data stack.
00026   virtual void make() const = 0;
00027 
00028   // Make a copy of the class through new. 
00029   virtual fbuildbase* copy() const = 0;
00030 
00031 };
00032 
00033 // Helper class for fdatainterp. 
00034 // Automate code generation for rpn functions. 
00035 template< typename F >
00036 class fbuild : public fbuildbase
00037 {
00038 public:
00039 
00040   string const name() const
00041     { return F().name(); }
00042   void make() const;
00043 
00044   fbuildbase* copy() const
00045     { return new fbuild<F>(); }
00046 
00047 };
00048 
00049 // Helper class for fdatainterp.
00050 // Allow rpn data type functions which are runtime in nature. 
00051 class fbuilduser : public fbuildbase
00052 {
00053   rpnbase* x;
00054   string nm;
00055 public:
00056 
00057   fbuilduser(rpnbase* _x, string const & _nm);
00058   ~fbuilduser();
00059 
00060   string const name() const;
00061   void make() const;
00062 
00063   fbuildbase* copy() const;
00064 
00065 };
00066 
00067 
00068 // Function templates need type passed through arguments. 
00069 //  Avoid construction of T as is the case with dummy arguments.
00070 template< typename T >
00071 class passtype
00072 {
00073 public:
00074 
00075   typedef T type;
00076 };
00077 
00078 //
00079 //  Brief:  function/data interpreter. Contains the dictionary. 
00080 //
00081 class fdatainterp
00082 {
00083   // Load dicttable and build the dictionary.
00084   void init();
00085 
00086   void dictionarydelete();
00087 
00088   // Conversions. 
00089   rpnreal::type const real(string const & word) const;
00090   rpninteger::type const integer(string const & word) const;
00091 public:
00092 
00093   // The dictionary table can be used to build the dictionary.
00094   vector< fbuildbase* > dicttable;
00095   // The dictionary. 
00096   map<string,fbuildbase*> dict;
00097 
00098   // Construct an instance.
00099   fdatainterp();
00100   ~fdatainterp();
00101 
00102   // From the dictionary table build the dictionary.
00103   void reset();
00104 
00105   // Interpret the word. 
00106   void eval(string const &word);
00107 
00108   // Process the input. 
00109   void process2_silent( istream & is);
00110   template< typename T >
00111   void process2( istream & is, T& prnt );
00112 
00113   // Add a function to the dictionary. 
00114   void add(fbuildbase* x)
00115     { dict.insert( make_pair(x->name(),x) ); }
00116   
00117   // Add a function to the dictionary table and dictionary. 
00118   template< typename T >
00119   void addtodictionary(T)
00120   {
00121     // No support for inc() dec() with building
00122     // functions. fn is copied twice and the
00123     // functions themselves are not persistant
00124     // with a reset.
00125     fbuildbase* fn = new fbuild< typename T::type>();
00126     dicttable.push_back(fn);
00127     add(fn->copy());
00128   }
00129 
00130 };
00131 
00132 class inputstate;
00133 class innerinput;
00134 class outerinput;
00135 
00136 // Brief: The interface and state machine for token parsing.
00137 //
00138 
00139 // <TODO> The difference in the two states is trivial and
00140 // they could be merged to one.  This was made possible by
00141 // a change in design where the dhome directory/program 
00142 // is treated like anyother directory and doesn't get
00143 // a special evaluation mode.  Instead the client is responsible
00144 // for the evaluation mode.
00145 //
00146 // Implemented as a singleton state machine interface. 
00147 class inputstatescope
00148 {
00149   innerinput* inner;  // Inner input state. 
00150   outerinput* outer;  // Outer input state.
00151 public:
00152 
00153   static inputstatescope* cscope;  // The current scope. 
00154   static inputstate*      cstate;  // The current state.
00155 
00156   bool evaloverride;
00157   bool evalpreserved;
00158   bool evalimmediate; // The evaluation mode is either immediate or not. 
00159 
00160   bool error;         // Was there an error in processng the token? 
00161   
00162   inputstatescope();   // Initialize the scope. 
00163   ~inputstatescope();  // Release the scopes rescources.
00164 
00165   // Forward the processing of the word to the current state. 
00166   void eval(string const & word);
00167 
00168   fdatainterp fd; // The states need to access the interpreter. 
00169 
00170   // Change states.
00171   void setinner();
00172   void setouter();
00173 
00174 };
00175 
00176   
00177 // The input state is contained within a scope. 
00178 class inputstate
00179 {
00180 public:
00181 
00182   inputstate() {}
00183 
00184   // Process the word in the current state. 
00185   virtual void eval(string const & word) = 0;
00186 
00187 };
00188 
00189 class innerinput : public inputstate
00190 {
00191 public:
00192 
00193   void eval(string const & word);
00194 };
00195 
00196 class outerinput : public inputstate
00197 {
00198 public:
00199 
00200   void eval(string const & word);
00201 };
00202 
00203 // 
00204 // Functions derived from rpnfunction can call this class to
00205 // add themselves to the dictoinary and hence the interpreters scope.
00206 //
00207 template< typename T >
00208 class addtothedictionary
00209 {
00210 public:
00211 
00212   addtothedictionary();
00213 };
00214 
00215 
00216 
00217 
00218 // ---------------------------------------------------------------
00219 // Implementation
00220 
00221 
00222 template< typename T >
00223 addtothedictionary<T>::addtothedictionary()
00224 {
00225   fdatainterp& fd = SingletonPtr<inputstatescope>()->fd;
00226   fd.addtodictionary(passtype<T>());
00227 }
00228 
00229 
00230 template< typename F >
00231 void fbuild<F>::make() const
00232 { 
00233   new F
00234   ( 
00235     rpnprogramstackstate().ds(), 
00236     inputstatescope::cscope->evalimmediate 
00237   ); 
00238 }
00239 
00240 
00241 template< typename T >
00242 void fdatainterp::process2( istream & is, T& prnt )
00243 {
00244   char c;
00245   char const quote('"');
00246   char const space(' ');
00247   char const ret('\n');
00248 
00249   string s;
00250 
00251   string const quit("quit");
00252 
00253   while ((c = is.peek()))
00254   {
00255     s.clear();
00256 
00257     if (c==quote)
00258     {
00259       is.get(c);
00260       is.get(c);
00261       while (c!=quote)
00262       {
00263         s += c;
00264         is.get(c);
00265       }
00266 
00267       new rpnstring( rpnprogramstackstate().ds(), s );
00268     }
00269     else
00270     if (c=='(')
00271     {
00272       complex< long double > x;
00273       is >> x;
00274      
00275       new rpncomplex( rpnprogramstackstate().ds(), x );
00276 
00277 
00278     }
00279     else
00280     {
00281       is.get(c);
00282       if ((c!=space)&&(c!=ret))
00283       {
00284         s += c;
00285         is.get(c);
00286         while ((c!=space)&&(c!=ret))
00287         {
00288           s += c;
00289           is.get(c);
00290         }
00291       }
00292 
00293       if (!s.empty())
00294         SingletonPtr<inputstatescope>()->eval(s);
00295 
00296     }
00297 
00298     if (s==quit)
00299       break;
00300 
00301     prnt();
00302   }
00303 }
00304 
00305 
00306 
00307 
00308 #endif
00309 
00310 
00311 

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