1 /***************************************************************************
2                           dnode.hpp  -  the node used for the AST
3                              -------------------
4     begin                : July 22 2002
5     copyright            : (C) 2002 by Marc Schellens
6     email                : m_schellens@users.sf.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #ifndef dnode_hpp__
19 #define dnode_hpp__
20 
21 #include <cmath>
22 #include <memory>
23 #include <iostream>
24 
25 #include "typedefs.hpp"
26 
27 #include "GDLTokenTypes.hpp"
28 
29 #include <antlr/CommonAST.hpp>
30 
31 //ANTLR_USING_NAMESPACE(std)
32 //ANTLR_USING_NAMESPACE(antlr)
33 
34 // used together with some defines do
35 // allow using non-ref nodes with ANTLR
36 // see gdlc.i.g
37 class ProgNode;
38 typedef ProgNode* ProgNodeP;
39 namespace antlr {
40 
41 RefAST ConvertAST( ProgNodeP p);
42 }
43 
44 class DInterpreter;
45 
46 class DNode;
47 typedef antlr::ASTRefCount<DNode> RefDNode;
48 
49 class DVar;
50 class DPro;
51 
52 class DLibFun;
53 class DLibPro;
54 
55 class BaseGDL;
56 
57 class ArrayIndexListT;
58 
59 class DNode : public antlr::CommonAST {
60 
61 public:
62 
63   ~DNode();
64 
DNode()65   DNode(): CommonAST(), //down(), right(),
66 // 	keepRight( false),
67 	   lineNumber(0), cData(NULL),
68 	   var(NULL),
69 	   libFun(NULL),
70 	   libPro(NULL),
71 	   arrIxList(NULL),arrIxListNoAssoc(NULL), labelStart( -1), labelEnd( -1)
72   {
73   }
74 
75   DNode( const DNode& cp);
76 
DNode(antlr::RefToken t)77   DNode(antlr::RefToken t) : antlr::CommonAST(t) //, down(), right()
78 //   	, keepRight( false)
79 {
80     //    antlr::CommonAST::setType(t->getType() );
81     //    antlr::CommonAST::setText(t->getText() );
82     DNode::SetLine(t->getLine() );
83   }
84 
85 // 	void DoKeepRight() { keepRight = true;}
86 
initialize(int t,const std::string & txt)87   void initialize(int t, const std::string& txt)
88   {
89     antlr::CommonAST::setType(t);
90     antlr::CommonAST::setText(txt);
91 
92 // 	keepRight = false;
93 
94     lineNumber = 0;
95     cData=NULL;
96     libFun=NULL;
97     libPro=NULL;
98     labelStart = -1;
99     labelEnd   = -1;
100     var=NULL;
101     arrIxList=NULL;
102     arrIxListNoAssoc=NULL;
103   }
104 
105   // used by DNodeFactory
106   void initialize( RefDNode t );
107 
108   // we deal only with RefDNode here
initialize(antlr::RefAST t)109   void initialize( antlr::RefAST t )
110   {
111     //    antlr::CommonAST::initialize(t);
112     initialize(static_cast<RefDNode>(t));
113   }
114 
initialize(antlr::RefToken t)115   void initialize( antlr::RefToken t )
116   {
117     antlr::CommonAST::initialize(t);
118 
119     //    DNode::SetLine( t->getLine());
120     SetLine( t->getLine());
121   }
122 
clone(void) const123   antlr::RefAST clone( void ) const
124   {
125     DNode *newNode = new DNode( *this);
126     return antlr::RefAST( newNode);
127   }
128 
setText(const std::string & txt)129   void setText(const std::string& txt)
130   {
131     antlr::CommonAST::setText(txt);
132   }
133 
setType(int type)134   void setType(int type)
135   {
136     antlr::CommonAST::setType(type);
137   }
138 
addChild(RefDNode c)139   void addChild( RefDNode c )
140   {
141     BaseAST::addChild( static_cast<antlr::RefAST>(c) );
142   }
143 
factory()144   static antlr::RefAST factory()
145   {
146     antlr::RefAST ret = static_cast<antlr::RefAST>(RefDNode(new DNode));
147     return ret;
148   }
149 
GetFirstChild() const150   RefDNode GetFirstChild() const
151   {
152     return static_cast<RefDNode>(BaseAST::getFirstChild());
153   }
154 
GetNextSibling() const155   RefDNode GetNextSibling() const
156   {
157     return static_cast<RefDNode>(BaseAST::getNextSibling());
158   }
159 
160   void RemoveNextSibling();
161 
162   // Extensions
SetLine(int l_)163   void SetLine(int l_)
164   {
165     lineNumber = l_;
166   }
167 
getLine() const168   int getLine() const
169   {
170     if( lineNumber != 0 || BaseAST::getFirstChild() == NULL)
171       return lineNumber;
172     // this handles inserted nodes
173     return static_cast<RefDNode>(BaseAST::getFirstChild())->getLine();
174 
175 // This was just too clever :-)
176 //     if( lineNumber != 0)
177 //       return lineNumber;
178 //     else
179 //       {
180 // 	if( BaseAST::getFirstChild() == NULL)
181 // 	  {
182 // 	    if( BaseAST::getNextSibling() == NULL)
183 // 	      {
184 // 		return lineNumber;
185 // 	      }
186 // 	    else
187 // 	      {
188 // 		return
189 // 		  static_cast<RefDNode>(BaseAST::getNextSibling())->getLine();
190 // 	      }
191 // 	    return lineNumber;
192 // 	  }
193 // 	else
194 // 	  {
195 // 	    return
196 // 	      static_cast<RefDNode>(BaseAST::getFirstChild())->getLine();
197 // 	  }
198 //       }
199   }
200 
SetVarIx(int vIx)201   void SetVarIx(int vIx)
202   {
203     varIx=vIx;
204   }
205 
SetVar(DVar * v)206   void SetVar(DVar* v)
207   {
208     var=v;
209   }
210 
Text2Number(T & out,int base)211   template<typename T> bool Text2Number( T& out, int base)
212   {
213     bool noOverflow = true;
214 
215     T number=0;
216 
217     for(unsigned i=0; i < text.size(); ++i)
218       {
219 	char c=text[i];
220 	if( c >= '0' && c <= '9')
221 	  {
222 	    c -= '0';
223 	  }
224 	else if( c >= 'a' &&  c <= 'f')
225 	  {
226 	    c -= 'a'-10;
227 	  }
228 	else
229 	  {
230 	    c -= 'A'-10;
231 	  }
232 
233 	T newNumber = base * number + c;
234 
235 	// check for overflow
236 	if( newNumber < number)
237 	  {
238 	    noOverflow = false;
239 	  }
240 
241 	number=newNumber;
242       }
243     out=number;
244 
245     return noOverflow;
246   }
247 
Text2Number(DByte & out,int base)248   bool Text2Number( DByte& out, int base)
249   {
250     bool noOverflow = true;
251 
252     DByte number=0;
253 
254     for(unsigned i=0; i < text.size(); ++i)
255       {
256 	char c=text[i];
257 	if( c >= '0' && c <= '9')
258 	  {
259 	    c -= '0';
260 	  }
261 	else if( c >= 'a' &&  c <= 'f')
262 	  {
263 	    c -= 'a'-10;
264 	  }
265 	else
266 	  {
267 	    c -= 'A'-10;
268 	  }
269 
270 	DInt newNumber = base * number + c;
271 
272 	// check for overflow
273 	if( newNumber > 255)
274 	  {
275 	    noOverflow = false;
276 	  }
277 
278 	number=newNumber;
279       }
280     out=number;
281 
282     return noOverflow;
283   }
284 
285   void Text2Byte(int base);
286   // promote: use Long if number to large
287   void Text2Int(int base, bool promote=false);
288   void Text2UInt(int base, bool promote=false);
289   void Text2Long(int base, bool promote=false);
290   void Text2ULong(int base, bool promote=false);
291   void Text2Long64(int base);
292   void Text2ULong64(int base);
293   void Text2Float();
294   void Text2Double();
295   void Text2String();
296 
SetNumBranch(const int nB)297   void SetNumBranch(const int nB) { numBranch=nB;}
SetArrayDepth(const int aD)298   void SetArrayDepth(const int aD) { arrayDepth=aD;}
299 
300   void SetFunIx(const int ix);
301   void SetProIx(const int ix);
SetLibFun(DLibFun * const l)302   void SetLibFun(DLibFun* const l) { libFun=l;}
SetLibPro(DLibPro * const l)303   void SetLibPro(DLibPro* const l) { libPro=l;}
SetNDot(const int n)304   void SetNDot(const int n) { nDot=n;}
GetNDot() const305   int GetNDot() const { return nDot;}
SetNParam(const int n)306   void SetNParam(const int n) { nParam=n;}
GetNParam() const307   int GetNParam() const { return nParam;}
308 
SetCompileOpt(const int n)309   void SetCompileOpt(const int n) { compileOpt=n; }
GetCompileOpt()310   int GetCompileOpt() { return compileOpt; }
311 
SetLabelRange(const int s,const int e)312   void SetLabelRange( const int s, const int e)
313   { labelStart = s; labelEnd = e;}
314 
315   //  bool LabelInRange( const int lIx)
316   //  { return (lIx >= labelStart) && (lIx < labelEnd);}
317 
DefinedStruct(const bool noTagName)318   void DefinedStruct( const bool noTagName)
319   { if( noTagName) structDefined = 1; else structDefined = 0;}
320 
SetArrayIndexList(ArrayIndexListT * aL,ArrayIndexListT * aLNoAssoc)321   void SetArrayIndexList( ArrayIndexListT* aL, ArrayIndexListT* aLNoAssoc)
322   {
323     arrIxList = aL;
324     arrIxListNoAssoc = aLNoAssoc;
325   }
326 
CData()327   BaseGDL* CData() { return cData;}
328   void     ResetCData( BaseGDL* newCData);
329 
GetVar()330   DVar*    GetVar()   { return var;}
GetVarIx()331   int      GetVarIx() { return varIx;}
332 
333 private:
334 
StealCData()335   BaseGDL* StealCData() { BaseGDL* res = cData; cData=NULL; return res;}
336 
StealArrIxList()337   ArrayIndexListT* StealArrIxList()
338   { ArrayIndexListT* res = arrIxList; arrIxList=NULL; return res;}
339   ArrayIndexListT* CloneArrIxList();
340 
StealArrIxNoAssocList()341   ArrayIndexListT* StealArrIxNoAssocList()
342   { ArrayIndexListT* res = arrIxListNoAssoc; arrIxListNoAssoc=NULL; return res;}
343   ArrayIndexListT* CloneArrIxNoAssocList();
344 
345 // 	bool keepRight; // for passing to ProgNode, nodes here are reference counted
346 
347   //  RefDNode down;
348   //  RefDNode right;
349 
350   // track line number in node
351   int lineNumber;
352 
353   // void*     initPtr;    // for c-i not actaully used
354   BaseGDL*   cData;        // constant data
355   //  DNode*     gotoTarget;   // for goto statement
356   DVar*      var;          // ptr to variable (for system variables and common blocks)
357 
358   DLibFun*   libFun;
359   DLibPro*   libPro;
360 
361   ArrayIndexListT* arrIxList; // ptr to array index list
362   ArrayIndexListT* arrIxListNoAssoc; // ptr to array index list
363 //  ArrayIndexT*     arrIx;     // ptr to array index (1-dim)
364 
365   union {
366     int        initInt;    // for c-i not actually used
367 
368     int        numBranch;  // number of branches in switch/case statements
369     int        nDot;       // nesting level for tag access
370     int        arrayDepth; // dimension to cat
371 
372     int        proIx;      // Index into proList
373     int        funIx;      // Index into funList
374     int        varIx;      // Index into variable list
375     int        targetIx;   // Index into label list
376 
377     int        structDefined; // struct contains entry with no tag name
378 
379     int        nParam;	// number of positional parameters in this parameter list,
380 			// stored at first parameter (keyword or positional)
381 
382     int        compileOpt; // for PRO and FUNCTION nodes
383   };
384 
385   int labelStart; // for loops to determine if to bail out
386   int labelEnd; // for loops to determine if to bail out
387 
388   friend class ProgNode;
389   friend class DCompiler;
390   friend class GDLTreeParser;
391 
392 // private:
393 //   // forbid usage of these
394 //   DNode& operator=( const DNode& r)
395 //   { return *this;} // make c++ compiler shut up
396 //   DNode( const DNode& cp)
397 //   {}
398 };
399 
400 #endif
401 
402