Example #1
0
File: dpro.cpp Project: cenit/GDL
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();
      }
  }