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