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