Files Classes Functions Hierarchy
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
1.5.8