void DSubUD::ResolveLabel( ProgNodeP p) { if( p == NULL) return; // if( p->getNextSibling() != NULL) // std::cout << "Resolve("<< p->getLine()<<"): " << p << " keepRight: " << p->KeepRight()<< ": "<< p->getText() <<" r: "<< p->GetNextSibling()->getText() << std::endl; // else // std::cout << "Resolve("<< p->getLine()<<"): " << p << " keepRight: " << p->KeepRight()<< ": "<< p->getText() <<" r: NULL"<< std::endl; if( p->getType() == GDLTreeParser::ON_IOERROR || p->getType() == GDLTreeParser::GOTO) { int ix = labelList.Find( p->getText()); if( ix == -1) throw GDLException( p, ObjectName()+": Undefined label "+p->getText()+ " referenced in GOTO statement.",false,false); p->SetGotoIx( ix); } else if( p->getType() == GDLTreeParser::LABEL) { labelList.SetLabelNode( p); } if( !p->KeepDown()) ResolveLabel( p->getFirstChild()); if( !p->KeepRight()) ResolveLabel( p->getNextSibling()); // else // ResolveLabel( p->getNextSibling()); }
virtual void SetAllContinue( ProgNodeP target) { if( down != NULL && !keepDown) { down->SetAllContinue( target); } if( right != NULL && !keepRight) { right->SetAllContinue( target); } }
virtual int NumberForLoops( int actNum) { if( down != NULL && !keepDown) { actNum = down->NumberForLoops( actNum); } if( right != NULL && !keepRight) { actNum = right->NumberForLoops( actNum); } return actNum; }
FOREACHNode( const RefDNode& refNode): BreakableNode( refNode) { ProgNodeP keep = down->GetNextSibling(); down->SetRight( down->GetNextSibling()->GetNextSibling()); keep->SetRight( NULL); FOREACH_LOOPNode* forLoop = new FOREACH_LOOPNode( right, down); forLoop->setLine( getLine()); down = keep; right = forLoop; }
int NumberForLoops( int actNum) { this->forLoopIx = actNum; actNum++; ProgNodeP statementList = this->GetStatementList(); if( statementList != NULL && !down->KeepRight()) { actNum = statementList->NumberForLoops( actNum); } if( right != NULL && !keepRight) { actNum = right->NumberForLoops( actNum); } return actNum; }
WHILENode( const RefDNode& refNode): BreakableNode( refNode) { assert( down != NULL); // down->GetLastSibling()->KeepRight( this); // for empty body ProgNodeP statementList = this->GetStatementList(); if( statementList != NULL) { statementList->SetAllContinue( this); // must be called even with right == NULL, see FOR_LOOPNode statementList->SetAllBreak( right); // if( right != NULL) statementList->SetAllBreak( right); statementList->GetLastSibling()->KeepRight( this); // for empty body } }
static int NumberForLoops( ProgNodeP tree, int offset = 0) { if( tree == NULL) return offset; return tree->NumberForLoops( offset); }
FORNode( const RefDNode& refNode): BreakableNode( refNode) { ProgNodeP keep = down->GetNextSibling(); down->SetRight( down->GetNextSibling()->GetNextSibling()->GetNextSibling()); keep->GetNextSibling()->SetRight( NULL); FOR_LOOPNode* forLoop = new FOR_LOOPNode( right, down); forLoop->setLine( getLine()); down = keep; right = forLoop; // if( this->GetStatementList() != NULL && right != NULL) // this->GetStatementList()->GetLastSibling()->KeepRight( right); }
REPEAT_LOOPNode( ProgNodeP r, ProgNodeP d): BreakableNode() { SetType( GDLTokenTypes::REPEAT_LOOP, "repeat_loop"); SetRightDown( r, d); assert( down != NULL); ProgNodeP statementList = this->GetStatementList(); if( statementList != NULL) { statementList->SetAllContinue( this); statementList->GetLastSibling()->KeepRight( this); // must be called even with right == NULL, see FOR_LOOPNode statementList->SetAllBreak( right); // if( right != NULL) statementList->SetAllBreak( right); } }
void KeepRight( ProgNodeP r) { right = r; keepRight = true; ProgNodeP csBlock = GetStatementList(); ProgNodeP lastStatementList = NULL; while( csBlock != NULL) { if( csBlock->getType() == GDLTokenTypes::ELSEBLK) { ProgNodeP statementList = csBlock->GetFirstChild(); if( statementList != NULL) { lastStatementList = statementList; } } else { // keep expr in case of empty statement ProgNodeP statementList = csBlock->GetFirstChild()->GetNextSibling(); if( statementList != NULL) { lastStatementList = statementList; } } csBlock = csBlock->GetNextSibling(); } if( lastStatementList != NULL) lastStatementList->GetLastSibling()->KeepRight( right); GetStatementList()->SetAllBreak( right); }
FOREACH_INDEXNode( const RefDNode& refNode): BreakableNode( refNode) { // down is variable,array,variable ProgNodeP keep = down->GetNextSibling(); // the array to loop over ProgNodeP index = down->GetNextSibling()->GetNextSibling(); // the index variable down->SetRight( index); // jump over array // cut away everything after the array from keep keep->SetRight( NULL); FOREACH_INDEX_LOOPNode* forLoop = new FOREACH_INDEX_LOOPNode( right, down); forLoop->setLine( getLine()); down = keep; right = forLoop; }
SizeT getLine() const { if( line != 0) return line; if( errorNodeP != NULL) return errorNodeP->getLine(); if( errorNode != static_cast<RefDNode>(antlr::nullAST)) return errorNode->getLine(); return 0; }
FOR_STEP_LOOPNode( ProgNodeP r, ProgNodeP d): BreakableNode() { SetType( GDLTokenTypes::FOR_STEP_LOOP, "for_step_loop"); SetRightDown( r, d); assert( down != NULL); ProgNodeP statementList = this->GetStatementList(); if( statementList != NULL) { statementList->SetAllContinue( this); statementList->GetLastSibling()->KeepRight( this); // also NULL is fine for "right" when the FOR statement // is the last in the subroutine // it is important, that breakTargetSet is set hence // this call must be done even with right == NULL statementList->SetAllBreak( right); // if( right != NULL) statementList->SetAllBreak( right); } else { down->KeepRight( this); } }
int GDLInterpreter::GetFunIx( ProgNodeP f) { string subName = f->getText(); int funIx=FunIx(subName); if( funIx == -1) { // trigger reading/compiling of source file /*bool found=*/ SearchCompilePro(subName, false); funIx=FunIx(subName); if( funIx == -1) { throw GDLException(f, "Function not found: "+subName, true, false); } } return funIx; }
int GDLInterpreter::GetProIx( ProgNodeP f) { string subName = f->getText(); int proIx=ProIx(subName); if( proIx == -1) { // trigger reading/compiling of source file /*bool found=*/ SearchCompilePro(subName, true); proIx=ProIx(subName); if( proIx == -1) { throw GDLException(f,"Procedure not found: "+subName,true,false); } } return proIx; }
ProgNodeP GetLastSibling() const { ProgNodeP act = const_cast<ProgNodeP>(this); while(!act->KeepRight() && act->GetNextSibling() != NULL) act = act->GetNextSibling(); return act; }
SWITCHNode( const RefDNode& refNode): BreakableNode( refNode) { assert( down != NULL); ProgNodeP statementList = this->GetStatementList(); statementList->SetAllBreak( right); // down is expr ProgNodeP csBlock = GetStatementList(); ProgNodeP lastStatementList = NULL; while( csBlock != NULL) { if( csBlock->getType() == GDLTokenTypes::ELSEBLK) { ProgNodeP statementList = csBlock->GetFirstChild(); if( statementList != NULL) { if( lastStatementList != NULL) lastStatementList->GetLastSibling()->KeepRight( statementList); lastStatementList = statementList; } } else { // keep expr in case of empty statement ProgNodeP statementList = csBlock->GetFirstChild()->GetNextSibling(); if( statementList != NULL) { if( lastStatementList != NULL) lastStatementList->GetLastSibling()->KeepRight( statementList); lastStatementList = statementList; } } if( csBlock->GetNextSibling() == NULL) { if( lastStatementList != NULL) lastStatementList->GetLastSibling()->KeepRight( right); break; } csBlock = csBlock->GetNextSibling(); } }