1 #ifndef INC_GDLInterpreter_hpp_ 2 #define INC_GDLInterpreter_hpp_ 3 4 #include <antlr/config.hpp> 5 #include "GDLInterpreterTokenTypes.hpp" 6 /* $ANTLR 2.7.7 (2006-11-01): "gdlc.i.g" -> "GDLInterpreter.hpp"$ */ 7 #include <antlr/TreeParser.hpp> 8 9 10 // antlr header 11 12 // make sure it gets included before the 'tweak' 13 #include "GDLParser.hpp" 14 #include "GDLTreeParser.hpp" 15 16 #include <map> 17 #include <iomanip> 18 //#include <exception> 19 20 #include "datatypes.hpp" 21 #include "objects.hpp" 22 #include "dpro.hpp" 23 #include "accessdesc.hpp" 24 #include "initsysvar.hpp" 25 #include "gdljournal.hpp" 26 #include "nullgdl.hpp" 27 28 //class ProgNode; 29 //typedef ProgNode* ProgNodeP; 30 31 // tweaking ANTLR 32 #define RefAST( xxx) ConvertAST( xxx) /* antlr::RefAST( Ref type) */ 33 34 // print out AST tree 35 //#define GDL_DEBUG 36 //#undef GDL_DEBUG 37 //#define GDL_DEBUG_HEAP 38 bool IsEnabledGC(); // defined in GDLInterpreter.hpp with EnableGC(bool); 39 void EnableGC(bool); 40 41 class CUSTOM_API GDLInterpreter : public antlr::TreeParser, public GDLInterpreterTokenTypes 42 { 43 44 private: 45 // ASTNULL replacement 46 static ProgNode NULLProgNode; 47 static ProgNodeP NULLProgNodeP; 48 49 friend class BaseGDL; 50 friend class ProgNode; 51 friend class ARRAYDEFNode; 52 friend class ARRAYDEF_GENERALIZED_INDGENNode; 53 friend class STRUCNode; 54 friend class NSTRUCNode; 55 friend class NSTRUC_REFNode; 56 friend class ASSIGNNode; 57 friend class ASSIGN_ARRAYEXPR_MFCALLNode; 58 friend class ASSIGN_REPLACENode; 59 friend class PCALL_LIBNode;//: public CommandNode 60 friend class MPCALLNode;//: public CommandNode 61 friend class MPCALL_PARENTNode;//: public CommandNode 62 friend class PCALLNode;//: public CommandNode 63 friend class RETFNode; 64 friend class RETPNode; 65 friend class FORNode; 66 friend class FOR_LOOPNode; 67 friend class FOREACHNode; 68 friend class FOREACH_LOOPNode; 69 friend class FOREACH_INDEXNode; 70 friend class FOREACH_INDEX_LOOPNode; 71 friend class FOR_STEPNode; 72 friend class FOR_STEP_LOOPNode; 73 friend class KEYDEFNode; 74 friend class KEYDEF_REFNode; 75 friend class KEYDEF_REF_CHECKNode; 76 friend class KEYDEF_REF_EXPRNode; 77 friend class REFNode; 78 friend class REF_CHECKNode; 79 friend class REF_EXPRNode; 80 friend class ParameterNode; 81 friend class REFVNNode; 82 friend class REF_CHECKVNNode; 83 friend class REF_EXPRVNNode; 84 friend class ParameterVNNode; 85 friend class WRAPPED_FUNNode; 86 friend class WRAPPED_PRONode; 87 88 public: 89 // RetCode returnCode; GetNULLProgNodeP() const90 ProgNodeP GetNULLProgNodeP() const { return NULLProgNodeP;} 91 92 SetRetTree(ProgNodeP rT)93 void SetRetTree( ProgNodeP rT) 94 { 95 this->_retTree = rT; 96 } GetRetTree() const97 ProgNodeP GetRetTree() const 98 { 99 return this->_retTree; 100 } 101 // void SetReturnCode( RetCode rC) 102 // { 103 // this->returnCode = rC; 104 // } 105 106 // enum RetCode { 107 // RC_OK=0, 108 // RC_BREAK, 109 // RC_CONTINUE, 110 // RC_RETURN, 111 // RC_ABORT, // checked as retCode >= RC_RETURN 112 // }; 113 114 // code in: dinterpreter.cpp 115 // procedure (searchForPro == true) or function (searchForPro == false) 116 static bool SearchCompilePro(const std::string& pro, bool searchForPro); 117 static int GetFunIx( ProgNodeP); 118 static int GetFunIx( const std::string& subName); 119 static int GetProIx( ProgNodeP);//const std::string& subName); 120 static int GetProIx( const std::string& subName); 121 DStructGDL* ObjectStruct( DObjGDL* self, ProgNodeP mp); 122 void SetRootR( ProgNodeP tt, DotAccessDescT* aD, BaseGDL* r, ArrayIndexListT* aL); 123 void SetRootL( ProgNodeP tt, DotAccessDescT* aD, BaseGDL* r, ArrayIndexListT* aL); 124 // DStructGDL* ObjectStructCheckAccess( DObjGDL* self, ProgNodeP mp); 125 // DStructDesc* GDLObjectDesc( DObjGDL* self, ProgNodeP mp); 126 127 // code in: dinterpreter.cpp 128 static void SetFunIx( ProgNodeP f); // triggers read/compile 129 130 131 private: 132 133 static void SetProIx( ProgNodeP f); // triggers read/compile 134 static void AdjustTypes( BaseGDL*&, BaseGDL*&); 135 136 137 protected: 138 std::istringstream executeLine; // actual interactive executed line 139 140 // std::vector<BaseGDL*> tmpList; 141 // void ClearTmpList() 142 // { 143 // std::vector<BaseGDL*>::iterator i; 144 // for(i = tmpList.begin(); i != tmpList.end(); ++i) 145 // { delete *i;} 146 // tmpList.clear(); 147 // } 148 149 class RetAllException 150 { 151 public: 152 enum ExCode { 153 NONE=0 // normal RETALL 154 ,RUN // RETALL from .RUN command 155 ,RESET // RETALL from .RESET command 156 ,FULL_RESET // RETALL from .FULL_RESET command 157 }; 158 159 private: 160 ExCode code; 161 162 public: RetAllException(ExCode code_=NONE)163 RetAllException( ExCode code_=NONE): code( code_) {} 164 Code()165 ExCode Code() { return code;} 166 }; 167 168 // code in: dinterpreter.cpp 169 // static bool CompleteFileName(std::string& fn); -> str.cpp 170 171 BaseGDL* returnValue; // holding the return value for functions 172 BaseGDL** returnValueL; // holding the return value for l_functions 173 174 bool interruptEnable; 175 public: InterruptEnable() const176 bool InterruptEnable() const { return interruptEnable;} 177 // procedure (searchForPro == true) or function (searchForPro == false) 178 static bool CompileFile(const std::string& f, 179 const std::string& untilPro="", 180 bool searchForPro=true); 181 182 typedef RefHeap<BaseGDL> RefBaseGDL; 183 typedef RefHeap<DStructGDL> RefDStructGDL; 184 185 typedef std::map<SizeT, RefBaseGDL> HeapT; 186 typedef std::map<SizeT, RefDStructGDL> ObjHeapT; 187 188 protected: 189 // typedef std::map<SizeT, BaseGDL*> HeapT; 190 // typedef std::map<SizeT, DStructGDL*> ObjHeapT; 191 192 // the following must be all static because several interpreter might be active 193 // the heap for all dynamic variables 194 // ease the handling, no memory leaks, gc possible 195 static HeapT heap; 196 static ObjHeapT objHeap; 197 198 // index for newly allocated heap variables 199 static SizeT heapIx; 200 201 static EnvStackT callStack; 202 static bool noInteractive; 203 static DLong stepCount; 204 205 206 // smuggle optimizations in 207 //#include "GDLInterpreterOptimized.inc" 208 209 210 public: 211 // triggers read/compile/interpret 212 DStructDesc* GetStruct(const std::string& name, const ProgNodeP cN); 213 214 // bool Called( std::string proName) 215 // { 216 // for( EnvStackT::reverse_iterator env = callStack.rbegin(); 217 // env != callStack.rend(); 218 // ++env) 219 // { 220 // //std::cout << (*env)->GetPro()->ObjectFileName() << std::endl; 221 // if( proName == (*env)->GetPro()->ObjectFileName()) return true; 222 // } 223 // return false; 224 // } 225 226 // static bool IsEnabledGC() { return enable_GC;} IsEnabledGC()227 static bool IsEnabledGC() { return true;} 228 229 // the New... functions 'own' their BaseGDL* NewObjHeap(SizeT n=1,DStructGDL * var=NULL)230 SizeT NewObjHeap( SizeT n=1, DStructGDL* var=NULL) 231 { 232 SizeT tmpIx=heapIx; 233 for( SizeT i=0; i<n; i++) 234 objHeap.insert( objHeap.end(), 235 std::pair<SizeT, RefDStructGDL>( heapIx++, (DStructGDL*)var)); 236 return tmpIx; 237 } NewHeap(SizeT n=1,BaseGDL * var=NULL)238 SizeT NewHeap( SizeT n=1, BaseGDL* var=NULL) 239 { 240 SizeT tmpIx=heapIx; 241 for( SizeT i=0; i<n; i++) 242 heap.insert( heap.end(), 243 std::pair<SizeT, RefBaseGDL>( heapIx++, var)); 244 return tmpIx; 245 } FreeObjHeapDirect(DObj id,ObjHeapT::iterator it)246 static void FreeObjHeapDirect( DObj id, ObjHeapT::iterator it) 247 { 248 BaseGDL* del = (*it).second.get(); 249 objHeap.erase( id); 250 if (!NullGDL::IsNULLorNullGDL(del)) delete del; //avoid destroying !NULL 251 } FreeObjHeap(DObj id)252 static void FreeObjHeap( DObj id) 253 { 254 if( id != 0) 255 { 256 ObjHeapT::iterator it=objHeap.find( id); 257 if ( it != objHeap.end()) 258 { 259 FreeObjHeapDirect( id, it); 260 } 261 } 262 } FreeHeapDirect(DPtr id,HeapT::iterator it)263 static void FreeHeapDirect( DPtr id, HeapT::iterator it) 264 { 265 BaseGDL* del = (*it).second.get(); 266 heap.erase( id); 267 if (!NullGDL::IsNULLorNullGDL(del)) delete del; //avoid destroying !NULL 268 } FreeHeap(DPtr id)269 static void FreeHeap( DPtr id) 270 { 271 if( id != 0) 272 { 273 HeapT::iterator it=heap.find( id); 274 if( it != heap.end()) 275 { 276 FreeHeapDirect( id, it); 277 } 278 } 279 } HeapErase(DPtr id)280 static void HeapErase( DPtr id) // for LIST 281 { 282 if( id != 0) 283 { 284 heap.erase( id); 285 } 286 } 287 FreeHeap(DPtrGDL * p)288 static void FreeHeap( DPtrGDL* p) 289 { 290 SizeT nEl=p->N_Elements(); 291 for( SizeT ix=0; ix < nEl; ix++) 292 { 293 DPtr id= (*p)[ix]; 294 FreeHeap( id); 295 } 296 } 297 IsEnabledGC(DPtrGDL * p)298 static DByteGDL* IsEnabledGC( DPtrGDL* p) 299 { 300 SizeT nEl=p->N_Elements(); 301 if( nEl == 0) return new DByteGDL( 0); 302 DByteGDL* ret = new DByteGDL( p->Dim()); 303 Guard<DByteGDL> guard(ret); 304 for( SizeT ix=0; ix < nEl; ix++) 305 { 306 DPtr id= (*p)[ix]; 307 if( id != 0) 308 { 309 HeapT::iterator it=heap.find( id); 310 if( it != heap.end() and (*it).second.IsEnabledGC()) 311 (*ret)[ix] = 1; 312 } 313 } 314 return guard.release(); 315 } IsEnabledGCObj(DObjGDL * p)316 static DByteGDL* IsEnabledGCObj( DObjGDL* p) 317 { 318 SizeT nEl=p->N_Elements(); 319 if( nEl == 0) return new DByteGDL( 0); 320 DByteGDL* ret = new DByteGDL( p->Dim()); 321 Guard<DByteGDL> guard(ret); 322 for( SizeT ix=0; ix < nEl; ix++) 323 { 324 DObj id= (*p)[ix]; 325 if( id != 0) 326 { 327 ObjHeapT::iterator it=objHeap.find( id); 328 if( it != objHeap.end() and (*it).second.IsEnabledGC()) 329 (*ret)[ix] = 1; 330 } 331 } 332 return guard.release(); 333 } 334 EnableGC(DPtr id,bool set=true)335 static void EnableGC( DPtr id, bool set=true) 336 { 337 if( id != 0) 338 { 339 HeapT::iterator it=heap.find( id); 340 if( it != heap.end()) (*it).second.EnableGC(set); 341 } 342 } EnableGC(DPtrGDL * p,bool set=true)343 static void EnableGC( DPtrGDL* p, bool set=true) 344 { 345 SizeT nEl=p->N_Elements(); 346 for( SizeT ix=0; ix < nEl; ix++) 347 { 348 DPtr id= (*p)[ix]; 349 EnableGC( id, set); 350 } 351 } EnableAllGC()352 static void EnableAllGC() { 353 for( HeapT::iterator it=heap.begin(); it != heap.end(); ++it) 354 it->second.EnableGC(true); 355 for( ObjHeapT::iterator it=objHeap.begin(); it != objHeap.end(); ++it) 356 it->second.EnableGC(true); 357 } 358 EnableGCObj(DObj id,bool set=true)359 static void EnableGCObj( DObj id, bool set=true) 360 { 361 if( id != 0) 362 { 363 ObjHeapT::iterator it=objHeap.find( id); 364 if( it != objHeap.end()) (*it).second.EnableGC(set); 365 } 366 } EnableGCObj(DObjGDL * p,bool set=true)367 static void EnableGCObj( DObjGDL* p, bool set=true) 368 { 369 SizeT nEl=p->N_Elements(); 370 for( SizeT ix=0; ix < nEl; ix++) 371 { 372 DObj id= (*p)[ix]; 373 EnableGCObj( id, set); 374 } 375 } 376 DecRef(DPtr id)377 static void DecRef( DPtr id) 378 { 379 if( id != 0 and IsEnabledGC()) 380 { 381 #ifdef GDL_DEBUG_HEAP 382 std::cout << "-- <PtrHeapVar" << id << ">" << std::endl; 383 #endif 384 HeapT::iterator it=heap.find( id); 385 if( it != heap.end()) 386 { 387 if( (*it).second.Dec() and (*it).second.IsEnabledGC() ) 388 { 389 #ifdef GDL_DEBUG_HEAP 390 std::cout << "Out of scope (garbage collected): <PtrHeapVar" << id 391 << ">" 392 << " at: " << callStack.back()->GetProName() 393 << " line: " << callStack.back()->GetLineNumber() 394 << std::endl; 395 #endif 396 FreeHeapDirect( id, it); 397 } 398 #ifdef GDL_DEBUG_HEAP 399 else 400 std::cout << "<PtrHeapVar" << id << "> = " << (*it).second.Count() << std::endl; 401 #endif 402 } 403 } 404 } DecRef(DPtrGDL * p)405 static void DecRef( DPtrGDL* p) 406 { 407 SizeT nEl=p->N_Elements(); 408 for( SizeT ix=0; ix < nEl; ix++) 409 { 410 DPtr id= (*p)[ix]; 411 DecRef( id); 412 } 413 } DecRefObj(DObj id)414 static void DecRefObj( DObj id) 415 { 416 if( id != 0 and IsEnabledGC()) 417 { 418 #ifdef GDL_DEBUG_HEAP 419 std::cout << "-- <ObjHeapVar" << id << ">" << std::endl; 420 #endif 421 ObjHeapT::iterator it=objHeap.find( id); 422 if( it != objHeap.end()) 423 { 424 if( (*it).second.Dec() and (*it).second.IsEnabledGC() ) 425 { 426 #ifdef GDL_DEBUG_HEAP 427 std::cout << "Out of scope (garbage collected): <ObjHeapVar" << id 428 << ">" 429 << " at: " << callStack.back()->GetProName() 430 << " line: " << callStack.back()->GetLineNumber() 431 << std::endl; 432 #endif 433 callStack.back()->ObjCleanup( id); 434 // FreeObjHeapDirect( id, it); 435 } 436 #ifdef GDL_DEBUG_HEAP 437 else 438 std::cout << "<ObjHeapVar" << id << "> = " << (*it).second.Count() << std::endl; 439 #endif 440 441 } 442 } 443 } DecRefObj(DObjGDL * p)444 static void DecRefObj( DObjGDL* p) 445 { 446 SizeT nEl=p->Size();//N_Elements(); 447 for( SizeT ix=0; ix < nEl; ix++) 448 { 449 DObj id= (*p)[ix]; 450 DecRefObj( id); 451 } 452 } IncRef(DPtr id)453 static void IncRef( DPtr id) 454 { 455 if( id != 0 and IsEnabledGC()) 456 { 457 #ifdef GDL_DEBUG_HEAP 458 std::cout << "++ <PtrHeapVar" << id << ">" << std::endl; 459 #endif 460 HeapT::iterator it=heap.find( id); 461 if( it != heap.end()) 462 { 463 (*it).second.Inc(); 464 #ifdef GDL_DEBUG_HEAP 465 std::cout << "<PtrHeapVar" << id << "> = " << (*it).second.Count() << std::endl; 466 #endif 467 } 468 } 469 } AddRef(DPtr id,SizeT add)470 static void AddRef( DPtr id, SizeT add) 471 { 472 if( id != 0) 473 { 474 #ifdef GDL_DEBUG_HEAP 475 std::cout << add << " + <PtrHeapVar" << id << ">" << std::endl; 476 #endif 477 HeapT::iterator it=heap.find( id); 478 if( it != heap.end()) 479 { 480 (*it).second.Add(add); 481 } 482 } 483 } RefCountHeap(DPtr id)484 static SizeT RefCountHeap( DPtr id) 485 { 486 SizeT result = 0; 487 if( id != 0) 488 { 489 HeapT::iterator it=heap.find( id); 490 if( it != heap.end()) result = (*it).second.Count(); 491 } 492 return result; 493 } RefCountHeapObj(DObj id)494 static SizeT RefCountHeapObj( DObj id) 495 { 496 SizeT result = 0; 497 if( id != 0) 498 { 499 ObjHeapT::iterator it=objHeap.find( id); 500 if( it != objHeap.end()) result = (*it).second.Count(); 501 } 502 return result; 503 } IncRef(DPtrGDL * p)504 static void IncRef( DPtrGDL* p) 505 { 506 SizeT nEl=p->N_Elements(); 507 for( SizeT ix=0; ix < nEl; ix++) 508 { 509 DPtr id= (*p)[ix]; 510 IncRef( id); 511 } 512 } IncRefObj(DObj id)513 static void IncRefObj( DObj id) 514 { 515 if( id != 0 and IsEnabledGC()) 516 { 517 #ifdef GDL_DEBUG_HEAP 518 std::cout << "++ <ObjHeapVar" << id << ">" << std::endl; 519 #endif 520 ObjHeapT::iterator it=objHeap.find( id); 521 if( it != objHeap.end()) 522 { 523 (*it).second.Inc(); 524 } 525 } 526 } AddRefObj(DObj id,SizeT add)527 static void AddRefObj( DObj id, SizeT add) 528 { 529 if( id != 0) 530 { 531 #ifdef GDL_DEBUG_HEAP 532 std::cout << add << " + <ObjHeapVar" << id << ">" << std::endl; 533 #endif 534 ObjHeapT::iterator it=objHeap.find( id); 535 if( it != objHeap.end()) 536 { 537 (*it).second.Add(add); 538 } 539 } 540 } IncRefObj(DObjGDL * p)541 static void IncRefObj( DObjGDL* p) 542 { 543 SizeT nEl=p->Size();//N_Elements(); 544 for( SizeT ix=0; ix < nEl; ix++) 545 { 546 DObj id= (*p)[ix]; 547 IncRefObj( id); 548 } 549 } 550 551 class HeapException {}; 552 GetHeap(DPtr ID)553 static BaseGDL*& GetHeap( DPtr ID) 554 { 555 HeapT::iterator it=heap.find( ID); 556 if( it == heap.end()) 557 throw HeapException(); 558 return it->second.get(); 559 } GetHeapNoThrow(DPtr ID)560 static BaseGDL* GetHeapNoThrow( DPtr ID) 561 { 562 HeapT::iterator it=heap.find( ID); 563 if( it == heap.end()) return NULL; 564 return it->second.get(); 565 } GetObjHeap(DObj ID)566 static DStructGDL*& GetObjHeap( DObj ID) 567 { 568 ObjHeapT::iterator it=objHeap.find( ID); 569 if( it == objHeap.end()) 570 throw HeapException(); 571 return it->second.get(); 572 } 573 574 // for overload functions GetObjHeapOperator(DObj ID,int opIx)575 static DSubUD* GetObjHeapOperator( DObj ID, int opIx) 576 { 577 if( ID == 0) return NULL; 578 ObjHeapT::iterator it=objHeap.find( ID); 579 if( it == objHeap.end()) return NULL; 580 return it->second.get()->Desc()->GetOperator( opIx); 581 } GetObjHeapNoThrow(DObj ID)582 static DStructGDL* GetObjHeapNoThrow( DObj ID) 583 { 584 ObjHeapT::iterator it=objHeap.find( ID); 585 if( it == objHeap.end()) return NULL; 586 return it->second.get(); 587 } 588 // static DStructGDL*& GetObjHeap( DObj ID, ObjHeapT::iterator& it) 589 // { 590 // // ObjHeapT::iterator it=objHeap.find( ID); 591 // it=objHeap.find( ID); 592 // if( it == objHeap.end()) throw HeapException(); 593 // return it->second.get(); 594 // } 595 PtrValid(DPtr ID)596 static bool PtrValid( DPtr ID) 597 { 598 HeapT::iterator it=heap.find( ID); 599 return (it != heap.end()); 600 } 601 HeapSize()602 static SizeT HeapSize() 603 { 604 return heap.size(); 605 } 606 FindInHeap(BaseGDL ** p)607 static DPtr FindInHeap( BaseGDL** p) 608 { 609 for( HeapT::iterator it=heap.begin(); it != heap.end(); ++it) 610 { 611 if( &it->second.get() == p) 612 return it->first; 613 } 614 return 0; 615 } 616 // static BaseGDL** GetPtrToHeap( BaseGDL* p) 617 // { 618 // for( HeapT::iterator it=heap.begin(); it != heap.end(); ++it) 619 // { 620 // if( it->second.get() == p) 621 // return &it->second.get(); 622 // } 623 // return NULL; 624 // } GetAllHeap()625 static DPtrGDL* GetAllHeap() 626 { 627 SizeT nEl = heap.size(); 628 if( nEl == 0) return new DPtrGDL( 0); 629 DPtrGDL* ret = new DPtrGDL( dimension( &nEl, 1), BaseGDL::NOZERO); 630 SizeT i=0; 631 for( HeapT::iterator it=heap.begin(); it != heap.end(); ++it) 632 { 633 IncRef( it->first); 634 (*ret)[ i++] = it->first; 635 } 636 return ret; 637 } 638 639 // no ref counting here GetAllHeapSTL()640 static std::vector<DPtr>* GetAllHeapSTL() 641 { 642 SizeT nEl = heap.size(); 643 if( nEl == 0) return new std::vector<DPtr>(); 644 std::vector<DPtr>* ret = new std::vector<DPtr>( nEl); 645 SizeT i=0; 646 for( HeapT::iterator it=heap.begin(); it != heap.end(); ++it) 647 { 648 (*ret)[ i++] = it->first; 649 } 650 return ret; 651 } 652 ObjValid(DObj ID)653 static bool ObjValid( DObj ID) 654 { 655 ObjHeapT::iterator it=objHeap.find( ID); 656 return (it != objHeap.end()); 657 } 658 ObjHeapSize()659 static SizeT ObjHeapSize() 660 { 661 return objHeap.size(); 662 } 663 664 // static DObj FindInObjHeap( BaseGDL** p) 665 // { 666 // for( ObjHeapT::iterator it=objHeap.begin(); it != objHeap.end(); ++it) 667 // { 668 // if( &it->second == reinterpret_cast<DStructGDL**>(p)) 669 // return it->first; 670 // } 671 // return 0; 672 // } GetAllObjHeap()673 static DObjGDL* GetAllObjHeap() 674 { 675 SizeT nEl = objHeap.size(); 676 if( nEl == 0) return new DObjGDL( 0); 677 DObjGDL* ret = new DObjGDL( dimension( &nEl, 1), BaseGDL::NOZERO); 678 SizeT i=0; 679 for( ObjHeapT::iterator it=objHeap.begin(); it != objHeap.end(); ++it) 680 { 681 IncRefObj( it->first); 682 (*ret)[ i++] = it->first; 683 } 684 return ret; 685 } 686 687 // no ref counting here GetAllObjHeapSTL()688 static std::vector<DObj>* GetAllObjHeapSTL() 689 { 690 SizeT nEl = objHeap.size(); 691 if( nEl == 0) return new std::vector<DObj>(); 692 std::vector<DObj>* ret = new std::vector<DObj>( nEl); 693 SizeT i=0; 694 for( ObjHeapT::iterator it=objHeap.begin(); it != objHeap.end(); ++it) 695 { 696 (*ret)[ i++] = it->first; 697 } 698 return ret; 699 } 700 701 ResetHeap()702 static void ResetHeap() // purges both heaps 703 { 704 for( HeapT::iterator it=heap.begin(); it != heap.end(); ++it) 705 { 706 BaseGDL* del = (*it).second.get(); 707 if (!NullGDL::IsNULLorNullGDL(del)) delete del; //avoid destroying !NULL 708 heap.erase( it->first); 709 } 710 for( ObjHeapT::iterator it=objHeap.begin(); it != objHeap.end(); ++it) 711 { 712 BaseGDL* del = (*it).second.get(); 713 if (!NullGDL::IsNULLorNullGDL(del)) delete del; //avoid destroying !NULL 714 heap.erase( it->first); 715 } 716 // The counters are reset for easier human readability. 717 heapIx = 1; 718 } 719 720 // name of data Name(BaseGDL * p)721 static const std::string Name( BaseGDL* p) // const 722 { 723 return callStack.back()->GetString( p); 724 } 725 Name(BaseGDL ** p)726 static const std::string Name( BaseGDL** p) // const 727 { 728 assert( *p == NULL); 729 DPtr h = FindInHeap( p); 730 if( h != 0) return std::string("<PtrHeapVar")+i2s(h)+">"; 731 // DObj o = FindInObjHeap( p); 732 // if( o != 0) return std::string("<ObjHeapVar")+i2s(o)+">"; 733 return "<(ptr to undefined expression not found on the heap)>"; 734 } 735 736 737 738 739 // compiler (lexer, parser, treeparser) def in dinterpreter.cpp 740 static void ReportCompileError( GDLException& e, const std::string& file = ""); 741 742 // interpreter ReportError(GDLException & e,const std::string & emsg,bool dumpStack=true)743 static void ReportError( GDLException& e, const std::string &emsg, 744 bool dumpStack=true) 745 { 746 DString msgPrefix = SysVar::MsgPrefix(); 747 748 std::cout << std::flush; 749 if( dumpStack) 750 { 751 if( e.Prefix()) 752 { 753 std::cerr << msgPrefix << e.toString() << std::endl; 754 lib::write_journal_comment(msgPrefix+e.toString()); 755 } 756 else 757 { 758 std::cerr << e.toString() << std::endl; 759 lib::write_journal_comment(e.toString()); 760 } 761 } 762 763 std::cerr << msgPrefix << emsg << " " << 764 std::left << std::setw(16) << callStack.back()->GetProName(); 765 std::string file=callStack.back()->GetFilename(); 766 if( file != "") 767 { 768 SizeT line = e.getLine(); 769 if( line != 0) 770 { 771 std::cerr << std::right << std::setw(6) << line; 772 } 773 else 774 { 775 std::cerr << std::right << std::setw(6) << ""; 776 } 777 std::cerr << std::left << " " << file; 778 } 779 std::cerr << std::endl; 780 781 if( dumpStack) DumpStack( emsg.size() + 1); 782 if (noInteractive) exit(EXIT_SUCCESS); //strangely, IDL exits on error when non interactive with 0 not 1. 783 } 784 DumpStack(SizeT w)785 static void DumpStack( SizeT w) 786 { 787 DString msgPrefix = SysVar::MsgPrefix(); 788 789 // EnvStackT::reverse_iterator upEnv = callStack.rbegin(); 790 // //EnvStackT::reverse_iterator env = upEnv++; 791 // upEnv++; 792 // for(; 793 // upEnv != callStack.rend(); 794 // ++upEnv /*,++env*/) 795 796 long actIx = callStack.size() - 2; 797 for( ; actIx >= 0; --actIx) 798 { 799 EnvStackT::pointer_type upEnv = callStack[ actIx]; 800 801 std::cerr << msgPrefix << std::right << std::setw( w) << ""; 802 std::cerr << std::left << std::setw(16) << upEnv->GetProName(); 803 804 std::string file = upEnv->GetFilename(); 805 if( file != "") 806 { 807 // ProgNodeP cNode= (*env)->CallingNode(); 808 // if( cNode != NULL) 809 // { 810 // std::cerr << std::right << std::setw(6) << cNode->getLine(); 811 // } 812 // else 813 // { 814 // std::cerr << std::right << std::setw(6) << ""; 815 // } 816 // ProgNodeP cNode= (*env)->CallingNode(); 817 // if( cNode != NULL && cNode->getLine() != 0) 818 // { 819 // (*upEnv)->SetLineNumber( cNode->getLine()); 820 // } 821 822 int lineNumber = upEnv->GetLineNumber(); 823 if( lineNumber != 0) 824 { 825 std::cerr << std::right << std::setw(6) << lineNumber; 826 } 827 else 828 { 829 std::cerr << std::right << std::setw(6) << ""; 830 } 831 std::cerr << std::left << " " << file; 832 } 833 std::cerr << std::endl; 834 } 835 } 836 DebugMsg(ProgNodeP _t,const std::string & msg)837 static void DebugMsg( ProgNodeP _t, const std::string& msg) 838 { 839 DString msgPrefix = SysVar::MsgPrefix(); 840 841 std::cout << std::flush; 842 std::cerr << msgPrefix << msg 843 << std::left << std::setw(16) << callStack.back()->GetProName(); 844 std::string file=callStack.back()->GetFilename(); 845 if( file != "") 846 { 847 ProgNodeP eNode = _t; 848 if( eNode != NULL) 849 { 850 std::cerr << std::right << std::setw(6) << eNode->getLine(); 851 } 852 else 853 { 854 std::cerr << std::right << std::setw(6) << ""; 855 } 856 std::cerr << std::left << " " << file; 857 } 858 std::cerr << std::endl; 859 if (noInteractive) exit(EXIT_SUCCESS); 860 } 861 RetAll(RetAllException::ExCode c=RetAllException::NONE)862 static void RetAll( RetAllException::ExCode c=RetAllException::NONE) 863 { 864 throw RetAllException( c); 865 } 866 CallStack()867 static EnvStackT& CallStack() { return callStack;} // the callstack 868 // static EnvBaseT* CallStackBack() { return callStack.back();} CallStackBack()869 static EnvUDT* CallStackBack() { return callStack.back();} 870 GetClearActualLine()871 std::string GetClearActualLine() 872 { 873 std::string ret = executeLine.str(); 874 executeLine.str(""); 875 return ret; 876 } 877 878 RetCode NewInterpreterInstance(SizeT lineOffset); // code in dinterpreter.cpp 879 ~GDLInterpreter()880 ~GDLInterpreter() 881 { 882 } 883 public: 884 GDLInterpreter(); 885 static void initializeASTFactory( antlr::ASTFactory& factory ); getNumTokens() const886 int getNumTokens() const 887 { 888 return GDLInterpreter::NUM_TOKENS; 889 } getTokenName(int type) const890 const char* getTokenName( int type ) const 891 { 892 if( type > getNumTokens() ) return 0; 893 return GDLInterpreter::tokenNames[type]; 894 } getTokenNames() const895 const char* const* getTokenNames() const 896 { 897 return GDLInterpreter::tokenNames; 898 } 899 public: RetCode interactive(ProgNodeP _t); 900 public: RetCode statement(ProgNodeP _t); 901 public: RetCode execute(ProgNodeP _t); 902 public: RetCode statement_list(ProgNodeP _t); 903 public: BaseGDL* call_fun(ProgNodeP _t); 904 public: BaseGDL** call_lfun(ProgNodeP _t); 905 public: void call_pro(ProgNodeP _t); 906 public: BaseGDL** l_deref(ProgNodeP _t); 907 public: BaseGDL** l_decinc_indexable_expr(ProgNodeP _t, 908 BaseGDL*& res 909 ); 910 public: BaseGDL** l_function_call_internal(ProgNodeP _t); 911 public: BaseGDL** l_defined_simple_var(ProgNodeP _t); 912 public: BaseGDL** l_sys_var(ProgNodeP _t); 913 public: BaseGDL** l_decinc_array_expr(ProgNodeP _t, 914 int dec_inc, BaseGDL*& res 915 ); 916 public: BaseGDL* l_decinc_dot_expr(ProgNodeP _t, 917 int dec_inc 918 ); 919 public: BaseGDL** l_decinc_expr(ProgNodeP _t, 920 int dec_inc, BaseGDL*& res 921 ); 922 public: BaseGDL* expr(ProgNodeP _t); 923 public: BaseGDL* indexable_expr(ProgNodeP _t); 924 public: BaseGDL* indexable_tmp_expr(ProgNodeP _t); 925 public: BaseGDL* lib_function_call_internal(ProgNodeP _t); 926 public: BaseGDL** l_expr_internal(ProgNodeP _t, 927 BaseGDL* right 928 ); 929 public: BaseGDL* tmp_expr(ProgNodeP _t); 930 public: BaseGDL** l_simple_var(ProgNodeP _t); 931 public: void parameter_def(ProgNodeP _t, 932 EnvBaseT* actEnv 933 ); 934 public: BaseGDL* r_expr(ProgNodeP _t); 935 public: BaseGDL** l_indexable_expr(ProgNodeP _t); 936 public: BaseGDL** l_arrayexpr_mfcall_as_mfcall(ProgNodeP _t); 937 public: BaseGDL** unused_l_array_expr(ProgNodeP _t, 938 BaseGDL* right 939 ); 940 public: ArrayIndexListT* arrayindex_list(ProgNodeP _t, 941 bool noAssoc 942 ); 943 public: void l_dot_array_expr(ProgNodeP _t, 944 DotAccessDescT* aD 945 ); 946 public: BaseGDL** l_arrayexpr_mfcall(ProgNodeP _t, 947 BaseGDL* right 948 ); 949 public: void tag_expr(ProgNodeP _t, 950 DotAccessDescT* aD 951 ); 952 public: void tag_array_expr(ProgNodeP _t, 953 DotAccessDescT* aD 954 ); 955 public: BaseGDL* r_dot_indexable_expr(ProgNodeP _t, 956 DotAccessDescT* aD 957 ); 958 public: void r_dot_array_expr(ProgNodeP _t, 959 DotAccessDescT* aD 960 ); 961 public: BaseGDL* assign_expr(ProgNodeP _t); 962 public: BaseGDL* unused_function_call(ProgNodeP _t); 963 public: BaseGDL* lib_function_call_retnew_internal(ProgNodeP _t); 964 public: BaseGDL* simple_var(ProgNodeP _t); 965 public: BaseGDL* sys_var(ProgNodeP _t); 966 public: BaseGDL** l_arrayexpr_mfcall_as_arrayexpr(ProgNodeP _t, 967 BaseGDL* right 968 ); 969 public: void parameter_def_n_elements(ProgNodeP _t, 970 EnvBaseT* actEnv 971 ); 972 public: void parameter_def_nocheck(ProgNodeP _t, 973 EnvBaseT* actEnv 974 ); 975 public: void arrayindex_list_overload(ProgNodeP _t, 976 IxExprListT& indexList 977 ); 978 public: getAST()979 antlr::RefAST getAST() 980 { 981 return antlr::RefAST(returnAST); 982 } 983 984 protected: 985 ProgNodeP returnAST; 986 ProgNodeP _retTree; 987 private: 988 static const char* tokenNames[]; 989 #ifndef NO_STATIC_CONSTS 990 static const int NUM_TOKENS = 238; 991 #else 992 enum { 993 NUM_TOKENS = 238 994 }; 995 #endif 996 997 static const unsigned long _tokenSet_0_data_[]; 998 static const antlr::BitSet _tokenSet_0; 999 }; 1000 1001 #endif /*INC_GDLInterpreter_hpp_*/ 1002