1 /***************************************************************************
2 prognode.hpp - the node used for the running program
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 prognode_hpp__
19 #define prognode_hpp__
20
21 #include "dnode.hpp"
22
23 //#include "GDLInterpreter.hpp"
24
25 enum RetCode {
26 RC_OK=0,
27 RC_BREAK,
28 RC_CONTINUE,
29 RC_RETURN,
30 RC_ABORT, // checked as retCode >= RC_RETURN
31 };
32
33 class EnvT;
34 typedef void (*LibPro)(EnvT*);
35 typedef BaseGDL* (*LibFun)(EnvT*);
36 typedef BaseGDL* (*LibFunDirect)(BaseGDL* param,bool canGrab);
37
38 class ProgNode;
39 typedef ProgNode* ProgNodeP;
40
41 // inline bool* GetNonCopyNodeLookupArray()
42 // {
43 // static bool nonCopyNodeLookupArray[ GDLTokenTypes::MAX_TOKEN_NUMBER];
44 // for( int i=0; i<GDLTokenTypes::MAX_TOKEN_NUMBER; ++i)
45 // nonCopyNodeLookupArray[ i] = false;
46 // nonCopyNodeLookupArray[ GDLTokenTypes::VAR] = true;
47 // nonCopyNodeLookupArray[ GDLTokenTypes::VARPTR] = true;
48 // nonCopyNodeLookupArray[ GDLTokenTypes::DEREF] = true;
49 // nonCopyNodeLookupArray[ GDLTokenTypes::CONSTANT] = true;
50 // nonCopyNodeLookupArray[ GDLTokenTypes::SYSVAR] = true;
51 // return nonCopyNodeLookupArray;
52 // }
53 bool* GetNonCopyNodeLookupArray();
54
NonCopyNode(int type)55 inline bool NonCopyNode( int type)
56 {
57 static bool* nonCopyNodeLookupArray = GetNonCopyNodeLookupArray();
58 return nonCopyNodeLookupArray[ type];
59 // return
60 // (type == GDLTokenTypes::VAR) ||
61 // (type == GDLTokenTypes::VARPTR) ||
62 // (type == GDLTokenTypes::DEREF) ||
63 // (type == GDLTokenTypes::CONSTANT) ||
64 // (type == GDLTokenTypes::SYSVAR) ;
65
66 // are always copy nodes:
67 // (type == GDLTokenTypes::ARRAYDEF)
68 // (type == GDLTokenTypes::STRUC)
69 // (type == GDLTokenTypes::NSTRUC)
70 // (type == GDLTokenTypes::NSTRUC_REF)
71 }
72
73 class BreakableNode;
74
75 // the nodes the programs are made of
76 class ProgNode
77 {
78 protected:
79 static DInterpreter* interpreter;
80
81 private:
82 int ttype;
83 std::string text;
84
85 protected:
86 bool keepRight;
87 bool keepDown;
88
89 ProgNodeP breakTarget;
90
91 ProgNodeP down;
92 ProgNodeP right;
93
94 static void AdjustTypes(Guard<BaseGDL>& a,
95 Guard<BaseGDL>& b);
96 // for overloaded operators
97 static void AdjustTypesObj(Guard<BaseGDL>& a,
98 Guard<BaseGDL>& b);
99
100 BaseGDL* cData; // constant data
101 DVar* var; // ptr to variable
102
103 DLibFun* libFun;
104 DLibPro* libPro;
105 LibFun libFunFun;
106 LibPro libProPro;
107
108 union {
109 int initInt; // for c-i not actually used
110 int numBranch; // number of branches in switch/case statements
111 int nDot; // nesting level for tag access
112 int nParam; // number of parameters in this parameter list (stored in 1st par)
113 int arrayDepth; // dimension to cat
114 int proIx; // Index into proList
115 int funIx; // Index into funList
116 int varIx; // Index into variable list
117 int targetIx; // Index into label list
118 int structDefined; // struct contains entry with no tag name
119 int compileOpt; // for PRO and FUNCTION nodes
120 int forLoopIx; // acessing loop variables
121 };
122
SetType(int tt,const std::string & txt)123 void SetType( int tt, const std::string& txt) { ttype = tt; text = txt;}
124
125 static ProgNodeP GetNULLProgNodeP();
126
127 public:
GetVarIx() const128 int GetVarIx() const { return varIx;}
129
130 private:
131 // from DNode (see there)
132 int lineNumber;
133 ArrayIndexListT* arrIxList; // ptr to array index list
134 ArrayIndexListT* arrIxListNoAssoc; // ptr to array index list
135 int labelStart; // for loops to determine if to bail out
136 int labelEnd; // for loops to determine if to bail out
137
138 // disable usage
ProgNode(const ProgNode & p)139 ProgNode( const ProgNode& p) {}
140
141 public:
142 ProgNode();
143
144 explicit ProgNode( const RefDNode& refNode);
145
146 // tree translation takes place here
147 // see newprognode.cpp
148 static ProgNodeP NewProgNode( const RefDNode& refNode);
NumberForLoops(ProgNodeP tree,int offset=0)149 static int NumberForLoops( ProgNodeP tree, int offset = 0)
150 {
151 if( tree == NULL)
152 return offset;
153
154 return tree->NumberForLoops( offset);
155 }
156
NumberForLoops(int actNum)157 virtual int NumberForLoops( int actNum)
158 {
159 if( down != NULL && !keepDown)
160 {
161 actNum = down->NumberForLoops( actNum);
162 }
163
164 if( right != NULL && !keepRight)
165 {
166 actNum = right->NumberForLoops( actNum);
167 }
168 return actNum;
169 }
170
171 virtual ~ProgNode();
172
173 void SetRightDown( const ProgNodeP right, const ProgNodeP down);
174
IsWrappedNode()175 virtual bool IsWrappedNode() { return false;} // internally defined UD subroutine (overloads)
176
177 virtual BaseGDL** LExpr( BaseGDL* right);
178 // virtual BaseGDL** LExprGrab( BaseGDL* right); // take ownership of right
179 virtual BaseGDL** LEval();
180 virtual BaseGDL** EvalRefCheck( BaseGDL*& rEval); // returns NULL if r-value with rEval set
181 virtual BaseGDL* Eval(); // caller receives ownership
182 virtual BaseGDL* EvalNC(); // non-copy used by all operators (and in other places)
183 virtual BaseGDL* EvalNCNull(); // non-copy might return NULL
184 virtual RetCode Run();
185
186 // RetCode (*RunP)();
187
188 bool ConstantNode();
189
getFirstChild() const190 ProgNodeP getFirstChild() const
191 {
192 return down;
193 }
GetFirstChild() const194 ProgNodeP GetFirstChild() const
195 {
196 return down;//getFirstChild();
197 }
SetFirstChild(ProgNodeP d)198 void SetFirstChild( ProgNodeP d)
199 {
200 down = d;
201 }
getNextSibling() const202 ProgNodeP getNextSibling() const
203 {
204 return right;
205 }
GetLastSibling() const206 ProgNodeP GetLastSibling() const
207 {
208 ProgNodeP act = const_cast<ProgNodeP>(this);
209 while(!act->KeepRight() && act->GetNextSibling() != NULL) act = act->GetNextSibling();
210 return act;
211 }
GetNextSibling() const212 ProgNodeP GetNextSibling() const
213 {
214 return right;//getNextSibling();
215 }
SetNextSibling(ProgNodeP r)216 void SetNextSibling( ProgNodeP r)
217 {
218 right = r;
219 }
220
StealCData()221 BaseGDL* StealCData()
222 {
223 BaseGDL* d = cData;
224 cData = NULL;
225 return d;
226 }
CData()227 BaseGDL* CData()
228 {
229 return cData;
230 }
231
StealNextSibling()232 ProgNodeP StealNextSibling()
233 {
234 ProgNodeP n = right;
235 right = NULL;
236 return n;
237 }
StealFirstChild()238 ProgNodeP StealFirstChild()
239 {
240 ProgNodeP n = down;
241 down = NULL;
242 return n;
243 }
244
KeepRight() const245 bool KeepRight() const { return keepRight;}
KeepDown() const246 bool KeepDown() const { return keepDown;}
247
KeepDown(ProgNodeP d)248 void KeepDown( ProgNodeP d)
249 {
250 down = d;
251 keepDown = true;
252 }
KeepRight(ProgNodeP r)253 virtual void KeepRight( ProgNodeP r)
254 {
255 right = r;
256 keepRight = true;
257 }
258
SetRight(ProgNodeP r)259 void SetRight( ProgNodeP r)
260 {
261 right = r;
262 // keepRight = false;
263 }
264
SetAllBreak(ProgNodeP target)265 virtual void SetAllBreak( ProgNodeP target)
266 {
267 if( down != NULL && !keepDown)
268 {
269 down->SetAllBreak( target);
270 }
271
272 if( right != NULL && !keepRight)
273 {
274 right->SetAllBreak( target);
275 }
276 }
SetAllContinue(ProgNodeP target)277 virtual void SetAllContinue( ProgNodeP target)
278 {
279 if( down != NULL && !keepDown)
280 {
281 down->SetAllContinue( target);
282 }
283
284 if( right != NULL && !keepRight)
285 {
286 right->SetAllContinue( target);
287 }
288 }
289
getType() const290 int getType() const { return ttype;}
setType(int t)291 void setType( int t) { ttype=t;}
292 // std::string getText() { return text;}
getText() const293 const std::string& getText() const { return text;}
setText(const std::string & t)294 void setText(const std::string& t) { text = t;} // (performance) Function parameter 't' should be passed by reference.
getLine() const295 int getLine() const { return lineNumber;}
setLine(int l)296 void setLine( int l) { lineNumber = l;}
SetGotoIx(int ix)297 void SetGotoIx( int ix) { targetIx=ix;}
298
GetNParam() const299 int GetNParam() const { return nParam;}
300
BreakTarget() const301 ProgNodeP BreakTarget() const { return breakTarget;}
302
303 // bool LabelInRange( int lIx) const
304 // {
305 // // std::cout << "LabelInRange: " << ((lIx >= labelStart) && (lIx < labelEnd)) << " " << lIx << " [" << labelStart << "," << labelEnd << ")" << std::endl;
306 // return (lIx >= labelStart) && (lIx < labelEnd);
307 // }
308
309 friend class GDLInterpreter;
310 friend class DInterpreter;
311
312 friend class NSTRUCNode;
313 friend class ASSIGNNode;
314 friend class ASSIGN_REPLACENode;
315 friend class PCALL_LIBNode;//: public CommandNode
316 friend class MPCALLNode;//: public CommandNode
317 friend class MPCALL_PARENTNode;//: public CommandNode
318 friend class PCALLNode;//: public CommandNode
319 friend class ARRAYEXPR_MFCALLNode;
320 friend class KEYDEF_Node;
321 friend class KEYDEF_REFNode;
322 friend class KEYDEF_REF_CHECKNode;
323 friend class KEYDEF_REF_EXPRNode;
324 friend class REFNode;
325 friend class REF_CHECKNode;
326 friend class REF_EXPRNode;
327 friend class ParameterNode;
328 friend class ARRAYEXPRNode;
329 friend class ARRAYEXPR_FCALLNode;
330 friend class EXPRNode;
331 friend class SYSVARNode;
332 friend class DOTNode;
333 };
334
335
336
337 class DefaultNode: public ProgNode
338 {
339 public:
DefaultNode()340 DefaultNode(): ProgNode() {}
341
DefaultNode(const RefDNode & refNode)342 explicit DefaultNode( const RefDNode& refNode): ProgNode( refNode)
343 {
344 if( refNode->GetFirstChild() != RefDNode(antlr::nullAST))
345 {
346 down = NewProgNode( refNode->GetFirstChild());
347 }
348 if( refNode->GetNextSibling() != RefDNode(antlr::nullAST))
349 {
350 right = NewProgNode( refNode->GetNextSibling());
351 }
352 }
353 };
354
355 class RETPNode: public DefaultNode
356 {
357 public:
358 RetCode Run();
359
360 public:
RETPNode()361 RETPNode(): DefaultNode() {}
362
RETPNode(const RefDNode & refNode)363 explicit RETPNode( const RefDNode& refNode): DefaultNode( refNode)
364 {}
365 };
366 class RETFNode: public DefaultNode
367 {
368 public:
369 RetCode Run();
370
371 public:
RETFNode()372 RETFNode(): DefaultNode() {}
373
RETFNode(const RefDNode & refNode)374 explicit RETFNode( const RefDNode& refNode): DefaultNode( refNode)
375 {}
376 };
377 class GOTONode: public DefaultNode
378 {
379 public:
380 RetCode Run();
381
SetAllBreak(ProgNodeP target)382 void SetAllBreak( ProgNodeP target)
383 {
384 // breakTarget = target;
385
386 if( right != NULL && !keepRight)
387 {
388 right->SetAllBreak( target);
389 }
390 }
391 public:
GOTONode()392 GOTONode(): DefaultNode() {}
393
GOTONode(const RefDNode & refNode)394 explicit GOTONode( const RefDNode& refNode): DefaultNode( refNode)
395 {}
396 };
397 class CONTINUENode: public DefaultNode
398 {
399 public:
400 RetCode Run();
401
402
SetAllContinue(ProgNodeP target)403 void SetAllContinue( ProgNodeP target)
404 {
405 assert( target != NULL);
406 breakTarget = target;
407
408 if( right != NULL && !keepRight)
409 {
410 right->SetAllContinue( target);
411 }
412 }
413 public:
CONTINUENode()414 CONTINUENode(): DefaultNode() {}
415
CONTINUENode(const RefDNode & refNode)416 explicit CONTINUENode( const RefDNode& refNode): DefaultNode( refNode)
417 {}
418 };
419 class BREAKNode: public DefaultNode
420 {
421 private:
422 bool breakTargetSet;
423
424 public:
425 RetCode Run();
426
427
SetAllBreak(ProgNodeP target)428 void SetAllBreak( ProgNodeP target)
429 {
430 breakTarget = target;
431 breakTargetSet = true;
432
433 if( right != NULL && !keepRight)
434 {
435 right->SetAllBreak( target);
436 }
437 }
438 public:
BREAKNode()439 BREAKNode(): DefaultNode(), breakTargetSet(false) {}
440
BREAKNode(const RefDNode & refNode)441 explicit BREAKNode( const RefDNode& refNode): DefaultNode( refNode), breakTargetSet(false)
442 {}
443 };
444 class LABELNode: public DefaultNode
445 {
446 public:
447 RetCode Run();
448
449
450 public:
LABELNode()451 LABELNode(): DefaultNode() {}
452
LABELNode(const RefDNode & refNode)453 explicit LABELNode( const RefDNode& refNode): DefaultNode( refNode)
454 {}
455 };
456 class ON_IOERROR_NULLNode: public DefaultNode
457 {
458 public:
459 RetCode Run();
460
461
462 public:
ON_IOERROR_NULLNode()463 ON_IOERROR_NULLNode(): DefaultNode() {}
464
ON_IOERROR_NULLNode(const RefDNode & refNode)465 explicit ON_IOERROR_NULLNode( const RefDNode& refNode): DefaultNode( refNode)
466 {}
467 };
468 class ON_IOERRORNode: public DefaultNode
469 {
470 public:
471 RetCode Run();
472
473
474 public:
ON_IOERRORNode()475 ON_IOERRORNode(): DefaultNode() {}
476
ON_IOERRORNode(const RefDNode & refNode)477 explicit ON_IOERRORNode( const RefDNode& refNode): DefaultNode( refNode)
478 {}
479 };
480
481
482 class BreakableNode: public ProgNode
483 {
484 public:
SetAllBreak(ProgNodeP target)485 void SetAllBreak( ProgNodeP target)
486 {
487 // down: do NOT descent into own loop tree here
488
489 if( right != NULL && !keepRight)
490 {
491 right->SetAllBreak( target);
492 }
493 }
SetAllContinue(ProgNodeP target)494 void SetAllContinue( ProgNodeP target)
495 {
496 // down: do NOT descent into own loop tree here
497
498 if( right != NULL && !keepRight)
499 {
500 right->SetAllContinue( target);
501 }
502 }
503
504 public:
BreakableNode()505 BreakableNode(): ProgNode() {}
506
BreakableNode(const RefDNode & refNode)507 explicit BreakableNode( const RefDNode& refNode): ProgNode( refNode)
508 {
509 if( refNode->GetFirstChild() != RefDNode(antlr::nullAST))
510 {
511 down = NewProgNode( refNode->GetFirstChild());
512 }
513 if( refNode->GetNextSibling() != RefDNode(antlr::nullAST))
514 {
515 right = NewProgNode( refNode->GetNextSibling());
516 }
517 }
518 };
519
520
521
522
523 class FOR_LOOPNode: public BreakableNode
524 {
525 public:
526 RetCode Run();
527
528 ProgNodeP statementList;
529
GetStatementList()530 ProgNodeP GetStatementList()
531 {
532 return down->GetNextSibling();//->GetNextSibling()->GetNextSibling();
533 }
534
535 public:
KeepRight(ProgNodeP r)536 void KeepRight( ProgNodeP r)
537 {
538 right = r;
539 keepRight = true;
540 assert( this->GetStatementList() != NULL);
541 // if( this->GetStatementList() != NULL)
542 this->GetStatementList()->SetAllBreak( right);
543 }
544
NumberForLoops(int actNum)545 int NumberForLoops( int actNum)
546 {
547 this->forLoopIx = actNum;
548 actNum++;
549 ProgNodeP statementList = this->GetStatementList();
550 if( statementList != NULL && !down->KeepRight())
551 {
552 actNum = statementList->NumberForLoops( actNum);
553 }
554 if( right != NULL && !keepRight)
555 {
556 actNum = right->NumberForLoops( actNum);
557 }
558 return actNum;
559 }
560
561 public:
FOR_LOOPNode(ProgNodeP r,ProgNodeP d)562 FOR_LOOPNode( ProgNodeP r, ProgNodeP d): BreakableNode()
563 {
564 SetType( GDLTokenTypes::FOR_LOOP, "for_loop");
565 SetRightDown( r, d);
566
567 assert( down != NULL);
568
569 statementList = this->GetStatementList();
570 if( statementList != NULL)
571 {
572 statementList->SetAllContinue( this);
573 statementList->GetLastSibling()->KeepRight( this);
574 // also NULL is fine for "right" when the FOR statement
575 // is the last in the subroutine
576 // it is important, that breakTargetSet is set hence
577 // this call must be done even with right == NULL
578 statementList->SetAllBreak( right);
579 // if( right != NULL) statementList->SetAllBreak( right);
580 }
581 else
582 {
583 down->KeepRight( this);
584 statementList = this;
585 }
586 }
587
588 };
589
590
591 class FORNode: public BreakableNode
592 {
593 public:
594 RetCode Run();
595
596 void KeepRight( ProgNodeP r);
597
NumberForLoops(int actNum)598 int NumberForLoops( int actNum)
599 {
600 this->forLoopIx = actNum;
601
602 // assert( down == NULL);
603
604 assert( right != NULL && !keepRight);
605
606 actNum = right->NumberForLoops( actNum);
607
608 return actNum;
609 }
610
611 public:
FORNode()612 FORNode(): BreakableNode() {}
613
FORNode(const RefDNode & refNode)614 explicit FORNode( const RefDNode& refNode): BreakableNode( refNode)
615 {
616 ProgNodeP keep = down->GetNextSibling();
617 down->SetRight( down->GetNextSibling()->GetNextSibling()->GetNextSibling());
618
619 keep->GetNextSibling()->SetRight( NULL);
620
621 FOR_LOOPNode* forLoop = new FOR_LOOPNode( right, down);
622 forLoop->setLine( getLine());
623
624 down = keep;
625
626 right = forLoop;
627 // if( this->GetStatementList() != NULL && right != NULL)
628 // this->GetStatementList()->GetLastSibling()->KeepRight( right);
629 }
630 };
631
632
633
634 class FOR_STEP_LOOPNode: public BreakableNode
635 {
636 public:
637 RetCode Run();
638
GetStatementList()639 ProgNodeP GetStatementList()
640 {
641 return down->GetNextSibling();//->GetNextSibling()->GetNextSibling()->GetNextSibling();
642 }
643
644 public:
KeepRight(ProgNodeP r)645 void KeepRight( ProgNodeP r)
646 {
647 right = r;
648 keepRight = true;
649 if( this->GetStatementList() != NULL)
650 this->GetStatementList()->SetAllBreak( right);
651 }
652
NumberForLoops(int actNum)653 int NumberForLoops( int actNum)
654 {
655 this->forLoopIx = actNum;
656 actNum++;
657 ProgNodeP statementList = this->GetStatementList();
658 if( statementList != NULL && !down->KeepRight())
659 {
660 actNum = statementList->NumberForLoops( actNum);
661 }
662 if( right != NULL && !keepRight)
663 {
664 actNum = right->NumberForLoops( actNum);
665 }
666 return actNum;
667 }
668
669 public:
FOR_STEP_LOOPNode(ProgNodeP r,ProgNodeP d)670 FOR_STEP_LOOPNode( ProgNodeP r, ProgNodeP d): BreakableNode()
671 {
672 SetType( GDLTokenTypes::FOR_STEP_LOOP, "for_step_loop");
673 SetRightDown( r, d);
674
675 assert( down != NULL);
676
677 ProgNodeP statementList = this->GetStatementList();
678 if( statementList != NULL)
679 {
680 statementList->SetAllContinue( this);
681 statementList->GetLastSibling()->KeepRight( this);
682 // also NULL is fine for "right" when the FOR statement
683 // is the last in the subroutine
684 // it is important, that breakTargetSet is set hence
685 // this call must be done even with right == NULL
686 statementList->SetAllBreak( right);
687 // if( right != NULL) statementList->SetAllBreak( right);
688 }
689 else
690 {
691 down->KeepRight( this);
692 }
693 }
694
695 };
696
697
698
699 class FOR_STEPNode: public BreakableNode
700 {
701 public:
702 RetCode Run();
703
704 void KeepRight( ProgNodeP r);
705
NumberForLoops(int actNum)706 int NumberForLoops( int actNum)
707 {
708 this->forLoopIx = actNum;
709
710 //assert( down == NULL);
711
712 assert( right != NULL && !keepRight);
713
714 actNum = right->NumberForLoops( actNum);
715
716 return actNum;
717 }
718
719 public:
FOR_STEPNode()720 FOR_STEPNode(): BreakableNode() {}
721
FOR_STEPNode(const RefDNode & refNode)722 explicit FOR_STEPNode( const RefDNode& refNode): BreakableNode( refNode)
723 {
724 ProgNodeP keep = down->GetNextSibling();
725 down->SetRight( down->GetNextSibling()->GetNextSibling()->GetNextSibling()->GetNextSibling());
726
727 keep->GetNextSibling()->GetNextSibling()->SetRight( NULL);
728
729 FOR_STEP_LOOPNode* forLoop = new FOR_STEP_LOOPNode( right, down);
730 forLoop->setLine( getLine());
731
732 down = keep;
733
734 right = forLoop;
735
736 // if( this->GetStatementList() != NULL && right != NULL)
737 // this->GetStatementList()->GetLastSibling()->KeepRight( right);
738 }
739 };
740
741 class FOREACH_LOOPNode: public BreakableNode
742 {
743 public:
744 RetCode Run();
745
GetStatementList()746 ProgNodeP GetStatementList()
747 {
748 return down->GetNextSibling();
749 }
750
751 public:
KeepRight(ProgNodeP r)752 void KeepRight( ProgNodeP r)
753 {
754 right = r;
755 keepRight = true;
756 if( this->GetStatementList() != NULL)
757 this->GetStatementList()->SetAllBreak( right);
758 }
759
NumberForLoops(int actNum)760 int NumberForLoops( int actNum)
761 {
762 this->forLoopIx = actNum;
763 actNum++;
764 ProgNodeP statementList = this->GetStatementList();
765 if( statementList != NULL && !down->KeepRight())
766 {
767 actNum = statementList->NumberForLoops( actNum);
768 }
769 if( right != NULL && !keepRight)
770 {
771 actNum = right->NumberForLoops( actNum);
772 }
773 return actNum;
774 }
775
776 public:
FOREACH_LOOPNode(ProgNodeP r,ProgNodeP d)777 FOREACH_LOOPNode( ProgNodeP r, ProgNodeP d): BreakableNode()
778 {
779 SetType( GDLTokenTypes::FOREACH_LOOP, "foreach_loop");
780 SetRightDown( r, d);
781
782 assert( down != NULL);
783
784 ProgNodeP statementList = this->GetStatementList();
785 if( statementList != NULL)
786 {
787 statementList->SetAllContinue( this);
788 statementList->GetLastSibling()->KeepRight( this);
789 // must be called even with right == NULL, see FOR_LOOPNode
790 statementList->SetAllBreak( right);
791 // if( right != NULL) statementList->SetAllBreak( right);
792 }
793 else
794 {
795 down->KeepRight( this);
796 }
797 }
798
799 };
800
801
802
803 class FOREACHNode: public BreakableNode
804 {
805 public:
806 RetCode Run();
807
808 void KeepRight( ProgNodeP r);
809
NumberForLoops(int actNum)810 int NumberForLoops( int actNum)
811 {
812 this->forLoopIx = actNum;
813
814 // assert( down == NULL);
815
816 assert( right != NULL && !keepRight);
817
818 actNum = right->NumberForLoops( actNum);
819
820 return actNum;
821 }
822
823 public:
FOREACHNode()824 FOREACHNode(): BreakableNode() {}
825
FOREACHNode(const RefDNode & refNode)826 explicit FOREACHNode( const RefDNode& refNode): BreakableNode( refNode)
827 {
828 ProgNodeP keep = down->GetNextSibling();
829 down->SetRight( down->GetNextSibling()->GetNextSibling());
830
831 keep->SetRight( NULL);
832
833 FOREACH_LOOPNode* forLoop = new FOREACH_LOOPNode( right, down);
834 forLoop->setLine( getLine());
835
836 down = keep;
837
838 right = forLoop;
839 }
840 };
841
842
843
844 class FOREACH_INDEX_LOOPNode: public BreakableNode
845 {
846 public:
847 RetCode Run();
848
GetStatementList()849 ProgNodeP GetStatementList()
850 {
851 return down->GetNextSibling();
852 }
853
854 public:
KeepRight(ProgNodeP r)855 void KeepRight( ProgNodeP r)
856 {
857 right = r;
858 keepRight = true;
859 if( this->GetStatementList() != NULL)
860 this->GetStatementList()->SetAllBreak( right);
861 }
862
NumberForLoops(int actNum)863 int NumberForLoops( int actNum)
864 {
865 this->forLoopIx = actNum;
866 actNum++;
867 ProgNodeP statementList = this->GetStatementList();
868 if( statementList != NULL && !down->KeepRight())
869 {
870 actNum = statementList->NumberForLoops( actNum);
871 }
872 if( right != NULL && !keepRight)
873 {
874 actNum = right->NumberForLoops( actNum);
875 }
876 return actNum;
877 }
878
879 public:
FOREACH_INDEX_LOOPNode(ProgNodeP r,ProgNodeP d)880 FOREACH_INDEX_LOOPNode( ProgNodeP r, ProgNodeP d): BreakableNode()
881 {
882 SetType( GDLTokenTypes::FOREACH_INDEX_LOOP, "foreach_index_loop");
883 SetRightDown( r, d);
884
885 assert( down != NULL);
886
887 ProgNodeP statementList = this->GetStatementList();
888 if( statementList != NULL)
889 {
890 statementList->SetAllContinue( this);
891 statementList->GetLastSibling()->KeepRight( this);
892 // must be called even with right == NULL, see FOR_LOOPNode
893 statementList->SetAllBreak( right);
894 // if( right != NULL) statementList->SetAllBreak( right);
895 }
896 else
897 {
898 down->KeepRight( this);
899 }
900 }
901
902 };
903
904
905
906 class FOREACH_INDEXNode: public BreakableNode
907 {
908 public:
909 RetCode Run();
910
911 void KeepRight( ProgNodeP r);
912
NumberForLoops(int actNum)913 int NumberForLoops( int actNum)
914 {
915 this->forLoopIx = actNum;
916
917 // assert( down == NULL);
918
919 assert( right != NULL && !keepRight);
920
921 actNum = right->NumberForLoops( actNum);
922
923 return actNum;
924 }
925
926 public:
FOREACH_INDEXNode()927 FOREACH_INDEXNode(): BreakableNode() {}
928
FOREACH_INDEXNode(const RefDNode & refNode)929 explicit FOREACH_INDEXNode( const RefDNode& refNode): BreakableNode( refNode)
930 {
931 // down is variable,array,variable
932 ProgNodeP keep = down->GetNextSibling(); // the array to loop over
933
934 ProgNodeP index = down->GetNextSibling()->GetNextSibling(); // the index variable
935
936 down->SetRight( index); // jump over array
937
938 // cut away everything after the array from keep
939 keep->SetRight( NULL);
940
941 FOREACH_INDEX_LOOPNode* forLoop = new FOREACH_INDEX_LOOPNode( right, down);
942 forLoop->setLine( getLine());
943
944 down = keep;
945
946 right = forLoop;
947 }
948 };
949
950
951
952 class WHILENode: public BreakableNode
953 {
954 public:
955 RetCode Run();
956
GetStatementList()957 ProgNodeP GetStatementList()
958 {
959 return down->GetNextSibling();
960 }
961
KeepRight(ProgNodeP r)962 void KeepRight( ProgNodeP r)
963 {
964 right = r;
965 keepRight = true;
966 if( this->GetStatementList() != NULL)
967 this->GetStatementList()->SetAllBreak( right);
968 }
969
970 public:
WHILENode()971 WHILENode(): BreakableNode() {}
972
WHILENode(const RefDNode & refNode)973 explicit WHILENode( const RefDNode& refNode): BreakableNode( refNode)
974 {
975 assert( down != NULL);
976
977 // down->GetLastSibling()->KeepRight( this); // for empty body
978
979 ProgNodeP statementList = this->GetStatementList();
980 if( statementList != NULL)
981 {
982 statementList->SetAllContinue( this);
983 // must be called even with right == NULL, see FOR_LOOPNode
984 statementList->SetAllBreak( right);
985 // if( right != NULL) statementList->SetAllBreak( right);
986 statementList->GetLastSibling()->KeepRight( this); // for empty body
987 }
988 }
989 };
990
991
992
993 class REPEAT_LOOPNode: public BreakableNode
994 {
995 public:
996 RetCode Run();
997
GetStatementList()998 ProgNodeP GetStatementList()
999 {
1000 return down->GetNextSibling();
1001 }
1002
1003 public:
KeepRight(ProgNodeP r)1004 void KeepRight( ProgNodeP r)
1005 {
1006 right = r;
1007 keepRight = true;
1008 if( this->GetStatementList() != NULL)
1009 this->GetStatementList()->SetAllBreak( right);
1010 }
1011
1012 public:
REPEAT_LOOPNode(ProgNodeP r,ProgNodeP d)1013 REPEAT_LOOPNode( ProgNodeP r, ProgNodeP d): BreakableNode()
1014 {
1015 SetType( GDLTokenTypes::REPEAT_LOOP, "repeat_loop");
1016 SetRightDown( r, d);
1017
1018 assert( down != NULL);
1019
1020 ProgNodeP statementList = this->GetStatementList();
1021 if( statementList != NULL)
1022 {
1023 statementList->SetAllContinue( this);
1024 statementList->GetLastSibling()->KeepRight( this);
1025 // must be called even with right == NULL, see FOR_LOOPNode
1026 statementList->SetAllBreak( right);
1027 // if( right != NULL) statementList->SetAllBreak( right);
1028 }
1029 }
1030
1031 };
1032
1033
1034
1035 class REPEATNode: public BreakableNode
1036 {
1037 public:
1038 RetCode Run();
1039
KeepRight(ProgNodeP r)1040 void KeepRight( ProgNodeP r)
1041 {
1042 right = r;
1043 keepRight = true;
1044 down->KeepRight( right); // REPEAT_LOOP
1045 }
1046
1047 public:
REPEATNode()1048 REPEATNode(): BreakableNode() {}
1049
REPEATNode(const RefDNode & refNode)1050 explicit REPEATNode( const RefDNode& refNode): BreakableNode( refNode)
1051 {
1052 REPEAT_LOOPNode* repeatLoop = new REPEAT_LOOPNode( NULL, down);
1053 repeatLoop->KeepRight( right);
1054 repeatLoop->setLine( getLine());
1055
1056 down = repeatLoop;
1057 }
1058 };
1059
1060
1061
1062 class CASENode: public BreakableNode
1063 {
1064 public:
1065 RetCode Run();
1066
GetStatementList()1067 ProgNodeP GetStatementList()
1068 {
1069 return down->GetNextSibling();
1070 }
1071
KeepRight(ProgNodeP r)1072 void KeepRight( ProgNodeP r)
1073 {
1074 assert( down != NULL);
1075 right = r;
1076 keepRight = true;
1077 // down is expr
1078 ProgNodeP csBlock = GetStatementList();
1079 while( csBlock != NULL)
1080 {
1081 if( csBlock->getType() == GDLTokenTypes::ELSEBLK)
1082 {
1083 ProgNodeP statementList = csBlock->GetFirstChild();
1084 if( statementList != NULL)
1085 {
1086 statementList->GetLastSibling()->KeepRight( right);
1087 }
1088 }
1089 else
1090 {
1091 // keep expr in case of empty statement
1092 ProgNodeP statementList = csBlock->GetFirstChild()->GetNextSibling();
1093 if( statementList != NULL)
1094 {
1095 statementList->GetLastSibling()->KeepRight( right);
1096 }
1097 }
1098 csBlock = csBlock->GetNextSibling();
1099 }
1100 GetStatementList()->SetAllBreak( right);
1101 }
1102
1103 public:
CASENode()1104 CASENode(): BreakableNode() {}
1105
CASENode(const RefDNode & refNode)1106 explicit CASENode( const RefDNode& refNode): BreakableNode( refNode)
1107 {
1108 assert( down != NULL);
1109
1110 ProgNodeP statementList = this->GetStatementList();
1111 if( statementList == NULL) return; // we say nothing at the compilation
1112
1113 statementList->SetAllBreak( right);
1114
1115 // down is expr
1116 ProgNodeP csBlock = GetStatementList();
1117
1118 while( csBlock != NULL)
1119 {
1120 if( csBlock->getType() == GDLTokenTypes::ELSEBLK)
1121 {
1122 ProgNodeP statementList = csBlock->GetFirstChild();
1123 if( statementList != NULL)
1124 {
1125 statementList->GetLastSibling()->KeepRight( right);
1126 }
1127 }
1128 else
1129 {
1130 // keep expr in case of empty statement
1131 ProgNodeP statementList = csBlock->GetFirstChild()->GetNextSibling();
1132 if( statementList != NULL)
1133 {
1134 statementList->GetLastSibling()->KeepRight( right);
1135 }
1136 }
1137
1138 // if( csBlock->GetNextSibling() == NULL)
1139 // {
1140 // csBlock->KeepRight( right);
1141 // break;
1142 // }
1143
1144 csBlock = csBlock->GetNextSibling();
1145 }
1146 }
1147 };
1148
1149
1150
1151 class SWITCHNode: public BreakableNode
1152 {
1153 public:
1154 RetCode Run();
1155
GetStatementList()1156 ProgNodeP GetStatementList()
1157 {
1158 return down->GetNextSibling();
1159 }
1160
KeepRight(ProgNodeP r)1161 void KeepRight( ProgNodeP r)
1162 {
1163 right = r;
1164 keepRight = true;
1165 ProgNodeP csBlock = GetStatementList();
1166 ProgNodeP lastStatementList = NULL;
1167 while( csBlock != NULL)
1168 {
1169 if( csBlock->getType() == GDLTokenTypes::ELSEBLK)
1170 {
1171 ProgNodeP statementList = csBlock->GetFirstChild();
1172 if( statementList != NULL)
1173 {
1174 lastStatementList = statementList;
1175 }
1176 }
1177 else
1178 {
1179 // keep expr in case of empty statement
1180 ProgNodeP statementList = csBlock->GetFirstChild()->GetNextSibling();
1181 if( statementList != NULL)
1182 {
1183 lastStatementList = statementList;
1184 }
1185 }
1186 csBlock = csBlock->GetNextSibling();
1187 }
1188 if( lastStatementList != NULL)
1189 lastStatementList->GetLastSibling()->KeepRight( right);
1190 GetStatementList()->SetAllBreak( right);
1191 }
1192
1193 public:
SWITCHNode()1194 SWITCHNode(): BreakableNode() {}
1195
SWITCHNode(const RefDNode & refNode)1196 explicit SWITCHNode( const RefDNode& refNode): BreakableNode( refNode)
1197 {
1198 assert( down != NULL);
1199
1200 ProgNodeP statementList = this->GetStatementList();
1201 statementList->SetAllBreak( right);
1202
1203 // down is expr
1204 ProgNodeP csBlock = GetStatementList();
1205
1206 ProgNodeP lastStatementList = NULL;
1207
1208 while( csBlock != NULL)
1209 {
1210 if( csBlock->getType() == GDLTokenTypes::ELSEBLK)
1211 {
1212 ProgNodeP statementList = csBlock->GetFirstChild();
1213 if( statementList != NULL)
1214 {
1215 if( lastStatementList != NULL)
1216 lastStatementList->GetLastSibling()->KeepRight( statementList);
1217
1218 lastStatementList = statementList;
1219 }
1220 }
1221 else
1222 {
1223 // keep expr in case of empty statement
1224 ProgNodeP statementList = csBlock->GetFirstChild()->GetNextSibling();
1225 if( statementList != NULL)
1226 {
1227 if( lastStatementList != NULL)
1228 lastStatementList->GetLastSibling()->KeepRight( statementList);
1229
1230 lastStatementList = statementList;
1231 }
1232 }
1233 if( csBlock->GetNextSibling() == NULL)
1234 {
1235 if( lastStatementList != NULL)
1236 lastStatementList->GetLastSibling()->KeepRight( right);
1237 break;
1238 }
1239 csBlock = csBlock->GetNextSibling();
1240 }
1241 }
1242
1243 };
1244
1245
1246
1247 class BLOCKNode: public ProgNode
1248 {
1249 public:
1250 RetCode Run();
1251
KeepRight(ProgNodeP r)1252 void KeepRight( ProgNodeP r)
1253 {
1254 right = r;
1255 keepRight = true;
1256 // must recursively set dependents here
1257 if( down != NULL && !KeepDown())
1258 down->GetLastSibling()->KeepRight( right);
1259 else
1260 this->KeepDown( right);
1261 }
1262
1263 public:
BLOCKNode()1264 BLOCKNode(): ProgNode() {}
1265
BLOCKNode(const RefDNode & refNode)1266 explicit BLOCKNode( const RefDNode& refNode): ProgNode( refNode)
1267 {
1268 if( refNode->GetFirstChild() != RefDNode(antlr::nullAST))
1269 {
1270 down = NewProgNode( refNode->GetFirstChild());
1271 }
1272 if( refNode->GetNextSibling() != RefDNode(antlr::nullAST))
1273 {
1274 right = NewProgNode( refNode->GetNextSibling());
1275
1276 // first statement
1277 if( down != NULL)
1278 down->GetLastSibling()->KeepRight( right);
1279 else
1280 this->KeepDown( right);
1281 }
1282 }
1283
1284 };
1285
1286
1287
1288 class IFNode: public ProgNode
1289 {
1290 public:
1291 RetCode Run();
1292
KeepRight(ProgNodeP r)1293 void KeepRight( ProgNodeP r)
1294 {
1295 assert( down != NULL);
1296 right = r;
1297 keepRight = true;
1298 down->GetLastSibling()->KeepRight( right);
1299 }
1300 public:
IFNode()1301 IFNode(): ProgNode() {}
1302
IFNode(const RefDNode & refNode)1303 explicit IFNode( const RefDNode& refNode): ProgNode( refNode)
1304 {
1305 if( refNode->GetFirstChild() != RefDNode(antlr::nullAST))
1306 {
1307 down = NewProgNode( refNode->GetFirstChild());
1308 }
1309 if( refNode->GetNextSibling() != RefDNode(antlr::nullAST))
1310 {
1311 right = NewProgNode( refNode->GetNextSibling());
1312 }
1313
1314 assert( down != NULL);
1315
1316 // first alternative
1317 if( right != NULL)
1318 {
1319 ProgNodeP s1 = down->GetNextSibling(); // skip expr
1320 s1->GetLastSibling()->KeepRight( right);
1321 }
1322 }
1323 };
1324
1325
1326
1327 class IF_ELSENode: public ProgNode
1328 {
1329 public:
1330 RetCode Run();
1331
KeepRight(ProgNodeP r)1332 void KeepRight( ProgNodeP r)
1333 {
1334 // must recursively set dependents here
1335 assert( down != NULL);
1336
1337 right = r;
1338 keepRight = true;
1339
1340 ProgNodeP s1 = down->GetNextSibling(); // skip expr
1341 if( s1->GetFirstChild() == NULL || s1->KeepDown())
1342 {
1343 s1->KeepDown( right);
1344 }
1345 else
1346 {
1347 s1->GetFirstChild()->GetLastSibling()->KeepRight( right);
1348 }
1349
1350 // 2nd alternative
1351 ProgNodeP s2 = s1->GetNextSibling();
1352 s2->GetLastSibling()->KeepRight( right);
1353 }
1354
1355 public:
IF_ELSENode()1356 IF_ELSENode(): ProgNode() {}
1357
IF_ELSENode(const RefDNode & refNode)1358 explicit IF_ELSENode( const RefDNode& refNode): ProgNode( refNode)
1359 {
1360 // std::cout << "IF_ELSENode" << std::endl;
1361 if( refNode->GetFirstChild() != RefDNode(antlr::nullAST))
1362 {
1363 down = NewProgNode( refNode->GetFirstChild());
1364 }
1365 if( refNode->GetNextSibling() != RefDNode(antlr::nullAST))
1366 {
1367 right = NewProgNode( refNode->GetNextSibling());
1368 }
1369
1370 assert( down != NULL);
1371
1372 // IF expr s1 s2
1373 // first alternative
1374 // s1 is always a BLOCK (gdlc.tree.g, if_statement)
1375 // right MUST be set here even if NULL as it IS set to 2nd alternative
1376 ProgNodeP s1 = down->GetNextSibling(); // skip expr
1377 if( s1->GetFirstChild() == NULL || s1->KeepDown())
1378 {
1379 s1->KeepDown( right);
1380 }
1381 else
1382 {
1383 s1->GetFirstChild()->GetLastSibling()->KeepRight( right);
1384 }
1385
1386 if( right != NULL)
1387 {
1388 // 2nd alternative
1389 ProgNodeP s2 = s1->GetNextSibling();
1390
1391 s2->GetLastSibling()->KeepRight( right); // disconnect s2
1392 }
1393 }
1394 };
1395
1396 //#undef GDL_UNDEF
1397 //#ifdef GDL_UNDEF
1398 class EnvBaseT;
1399
1400 class ParameterNode: public DefaultNode
1401 {
1402 public:
ParameterNode(const RefDNode & refNode)1403 explicit ParameterNode( const RefDNode& refNode): DefaultNode( refNode) {}
1404 virtual void Parameter( EnvBaseT* actEnv);
1405 virtual bool ParameterDirect( BaseGDL*& paramP); // returns isReference
1406 // virtual void ParameterVarNum( EnvBaseT* actEnv); // for variable number of parameters
1407 };
1408
1409 class ParameterVNNode: public ParameterNode
1410 {
1411 public:
ParameterVNNode(const RefDNode & refNode)1412 explicit ParameterVNNode( const RefDNode& refNode): ParameterNode( refNode) {}
1413 void Parameter( EnvBaseT* actEnv);
1414 // virtual void ParameterVarNum( EnvBaseT* actEnv); // for variable number of parameters
1415 };
1416
1417 class KEYDEF_REFNode: public ParameterNode
1418 {
1419 public:
KEYDEF_REFNode(const RefDNode & refNode)1420 explicit KEYDEF_REFNode( const RefDNode& refNode): ParameterNode( refNode) {}
1421 void Parameter( EnvBaseT* actEnv);
1422 // void ParameterVarNum( EnvBaseT* actEnv); // for variable number of parameters
1423 };
1424
1425 class KEYDEF_REF_EXPRNode: public ParameterNode
1426 {
1427 public:
KEYDEF_REF_EXPRNode(const RefDNode & refNode)1428 explicit KEYDEF_REF_EXPRNode( const RefDNode& refNode): ParameterNode( refNode) {}
1429 void Parameter( EnvBaseT* actEnv);
1430 // void ParameterVarNum( EnvBaseT* actEnv); // for variable number of parameters
1431 };
1432
1433 class KEYDEF_REF_CHECKNode: public ParameterNode
1434 {
1435 public:
KEYDEF_REF_CHECKNode(const RefDNode & refNode)1436 explicit KEYDEF_REF_CHECKNode( const RefDNode& refNode): ParameterNode( refNode) {}
1437 void Parameter( EnvBaseT* actEnv);
1438 // void ParameterVarNum( EnvBaseT* actEnv); // for variable number of parameters
1439 };
1440
1441 class KEYDEFNode: public ParameterNode
1442 {
1443 public:
KEYDEFNode(const RefDNode & refNode)1444 explicit KEYDEFNode( const RefDNode& refNode): ParameterNode( refNode) {}
1445 void Parameter( EnvBaseT* actEnv);
1446 // void ParameterVarNum( EnvBaseT* actEnv); // for variable number of parameters
1447 };
1448
1449 class REF_EXPRNode: public ParameterNode
1450 {
1451 public:
REF_EXPRNode(const RefDNode & refNode)1452 explicit REF_EXPRNode( const RefDNode& refNode): ParameterNode( refNode) {}
1453 void Parameter( EnvBaseT* actEnv);
1454 bool ParameterDirect( BaseGDL*& paramP);// returns isReference
1455 // void ParameterVarNum( EnvBaseT* actEnv); // for variable number of parameters
1456 };
1457 class REF_EXPRVNNode: public ParameterNode
1458 {
1459 public:
REF_EXPRVNNode(const RefDNode & refNode)1460 explicit REF_EXPRVNNode( const RefDNode& refNode): ParameterNode( refNode) {}
1461 void Parameter( EnvBaseT* actEnv);
1462 // void ParameterVarNum( EnvBaseT* actEnv); // for variable number of parameters
1463 };
1464
1465 class REF_CHECKNode: public ParameterNode
1466 {
1467 public:
REF_CHECKNode(const RefDNode & refNode)1468 explicit REF_CHECKNode( const RefDNode& refNode): ParameterNode( refNode) {}
1469 void Parameter( EnvBaseT* actEnv);
1470 bool ParameterDirect( BaseGDL*& paramP);// returns isReference
1471 // void ParameterVarNum( EnvBaseT* actEnv); // for variable number of parameters
1472 };
1473 class REF_CHECKVNNode: public ParameterNode
1474 {
1475 public:
REF_CHECKVNNode(const RefDNode & refNode)1476 explicit REF_CHECKVNNode( const RefDNode& refNode): ParameterNode( refNode) {}
1477 void Parameter( EnvBaseT* actEnv);
1478 // void ParameterVarNum( EnvBaseT* actEnv); // for variable number of parameters
1479 };
1480
1481 class REFNode: public ParameterNode
1482 {
1483 public:
REFNode(const RefDNode & refNode)1484 explicit REFNode( const RefDNode& refNode): ParameterNode( refNode) {}
1485 void Parameter( EnvBaseT* actEnv);
1486 bool ParameterDirect( BaseGDL*& paramP);// returns isReference
1487 // void ParameterVarNum( EnvBaseT* actEnv); // for variable number of parameters
1488 };
1489 class REFVNNode: public ParameterNode
1490 {
1491 public:
REFVNNode(const RefDNode & refNode)1492 explicit REFVNNode( const RefDNode& refNode): ParameterNode( refNode) {}
1493 void Parameter( EnvBaseT* actEnv);
1494 // void ParameterVarNum( EnvBaseT* actEnv); // for variable number of parameters
1495 };
1496
1497
1498
1499 class CommandNode: public DefaultNode
1500 {
1501 protected:
CommandNode()1502 CommandNode(): DefaultNode() {}
1503 public:
CommandNode(const RefDNode & refNode)1504 explicit CommandNode( const RefDNode& refNode): DefaultNode( refNode) {}
1505 };
1506
1507 // call C++ function as GDL FUNCTION
1508 // for internal member functions (like GDL_OBJECT::_overload...)
1509 // this has some overhead compared to calling library subroutines,
1510 // but this way, only one list of functions has to be searched.
1511 // Otherwise we would need an additional list for library member functions
1512 // For member calls this search must be done a runtime (as the object
1513 // definition is not available at compile time).
1514 // While library subroutine calls are resolved at compile time.
1515 class EnvUDT;
1516 class WRAPPED_FUNNode: public CommandNode
1517 {
1518 BaseGDL* (*fun)( EnvUDT*);
1519 public:
IsWrappedNode()1520 bool IsWrappedNode() { return true;}
WRAPPED_FUNNode(BaseGDL * (* fun_)(EnvUDT *))1521 explicit WRAPPED_FUNNode( BaseGDL* (*fun_)( EnvUDT*)): CommandNode(), fun(fun_) {}
1522 RetCode Run();
1523 };
1524 // call C++ function as GDL PRO
1525 class WRAPPED_PRONode: public CommandNode
1526 {
1527 void (*pro)( EnvUDT*);
1528 public:
IsWrappedNode()1529 bool IsWrappedNode() { return true;}
WRAPPED_PRONode(void (* pro_)(EnvUDT *))1530 explicit WRAPPED_PRONode( void (*pro_)( EnvUDT*)): CommandNode(), pro(pro_) {}
1531 RetCode Run();
1532 };
1533
1534 class ASSIGNNode: public CommandNode
1535 {
1536 public:
ASSIGNNode(const RefDNode & refNode)1537 explicit ASSIGNNode( const RefDNode& refNode): CommandNode( refNode) {}
1538 RetCode Run();
1539 BaseGDL** LExpr( BaseGDL* right);
1540 // BaseGDL** LExprGrab( BaseGDL* right);
1541 BaseGDL* Eval();
1542 };
1543 class ASSIGN_ARRAYEXPR_MFCALLNode: public CommandNode
1544 {
1545 public:
ASSIGN_ARRAYEXPR_MFCALLNode(const RefDNode & refNode)1546 explicit ASSIGN_ARRAYEXPR_MFCALLNode( const RefDNode& refNode): CommandNode( refNode) {}
1547 RetCode Run();
1548 BaseGDL** LExpr( BaseGDL* right);
1549 // BaseGDL** LExprGrab( BaseGDL* right);
1550 BaseGDL* Eval();
1551 };
1552 class ASSIGN_REPLACENode: public CommandNode
1553 {
1554 public:
ASSIGN_REPLACENode(const RefDNode & refNode)1555 explicit ASSIGN_REPLACENode( const RefDNode& refNode): CommandNode( refNode) {}
1556 RetCode Run();
1557 BaseGDL** LExpr( BaseGDL* right);
1558 // BaseGDL** LExprGrab( BaseGDL* right);
1559 BaseGDL* Eval();
1560 BaseGDL** LEval();
1561 };
1562 class PCALL_LIBNode: public CommandNode
1563 {
1564 public:
PCALL_LIBNode(const RefDNode & refNode)1565 explicit PCALL_LIBNode( const RefDNode& refNode): CommandNode( refNode) {}
1566 RetCode Run();
1567 };
1568 class MPCALLNode: public CommandNode
1569 {
1570 public:
MPCALLNode(const RefDNode & refNode)1571 explicit MPCALLNode( const RefDNode& refNode): CommandNode( refNode) {}
1572 RetCode Run();
1573 };
1574 class MPCALL_PARENTNode: public CommandNode
1575 {
1576 public:
MPCALL_PARENTNode(const RefDNode & refNode)1577 explicit MPCALL_PARENTNode( const RefDNode& refNode): CommandNode( refNode) {}
1578 RetCode Run();
1579 };
1580 class PCALLNode: public CommandNode
1581 {
1582 public:
PCALLNode(const RefDNode & refNode)1583 explicit PCALLNode( const RefDNode& refNode): CommandNode( refNode) {}
1584 RetCode Run();
1585 };
1586 class DECNode: public CommandNode
1587 { public:
DECNode(const RefDNode & refNode)1588 explicit DECNode( const RefDNode& refNode): CommandNode( refNode){}
1589 BaseGDL** EvalRefCheck( BaseGDL*& res);
1590 BaseGDL** LEval();
1591 BaseGDL* Eval();
1592 RetCode Run();
1593 };
1594 class INCNode: public CommandNode
1595 { public:
INCNode(const RefDNode & refNode)1596 explicit INCNode( const RefDNode& refNode): CommandNode( refNode){}
1597 BaseGDL** EvalRefCheck( BaseGDL*& res);
1598 BaseGDL** LEval();
1599 BaseGDL* Eval();
1600 RetCode Run();
1601 };
1602 class POSTDECNode: public CommandNode
1603 { public:
POSTDECNode(const RefDNode & refNode)1604 explicit POSTDECNode( const RefDNode& refNode): CommandNode( refNode){}
1605 BaseGDL* Eval();
1606 // BaseGDL** LEval();
1607 };
1608 class POSTINCNode: public CommandNode
1609 { public:
POSTINCNode(const RefDNode & refNode)1610 explicit POSTINCNode( const RefDNode& refNode): CommandNode( refNode){}
1611 BaseGDL* Eval();
1612 // BaseGDL** LEval();
1613 };
1614
1615 class ARRAYEXPRNode: public DefaultNode
1616 {
1617 public:
ARRAYEXPRNode(const RefDNode & refNode)1618 explicit ARRAYEXPRNode( const RefDNode& refNode): DefaultNode( refNode) {}
1619 BaseGDL* Eval(); // caller receives ownership
1620 BaseGDL** LExpr(BaseGDL* r);
1621 //BaseGDL** LEval();
1622 };
1623
1624 class EXPRNode: public DefaultNode
1625 {
1626 public:
EXPRNode(const RefDNode & refNode)1627 explicit EXPRNode( const RefDNode& refNode): DefaultNode( refNode) {}
1628 BaseGDL** EvalRefCheck( BaseGDL*& rEval); // calls LEval()
1629 BaseGDL** LEval();
1630 };
1631
1632 class DOTNode: public DefaultNode
1633 {
1634 public:
DOTNode(const RefDNode & refNode)1635 explicit DOTNode( const RefDNode& refNode): DefaultNode( refNode) {}
1636 BaseGDL* Eval();
1637 BaseGDL** LExpr( BaseGDL* right);
1638
1639 };
1640
1641 #endif
1642