Пример #1
0
bool CBotWhile::Execute(CBotStack* &pj)
{
    CBotStack* pile = pj->AddStack(this);   // adds an item to the stack
                                            // or find in case of recovery
//  if ( pile == EOX ) return true;

    if ( pile->IfStep() ) return false;

    while( true ) switch( pile->GetState() )    // executes the loop
    {                                           // there are two possible states (depending on recovery)
    case 0:
        // evaluates the condition
        if ( !m_condition->Execute(pile) ) return false; // interrupted here?

        // the result of the condition is on the stack

        // terminates if an error or if the condition is false
        if ( !pile->IsOk() || pile->GetVal() != true )
        {
            return pj->Return(pile);                    // sends the results and releases the stack
        }

        // the condition is true, pass in the second mode

        if (!pile->SetState(1)) return false;           // ready for further

    case 1:
        // evaluates the associated statement block
        if (m_block != nullptr &&
            !m_block->Execute(pile) )
        {
            if (pile->IfContinue(0, m_label)) continue; // if continued, will return to test
            return pj->BreakReturn(pile, m_label);      // sends the results and releases the stack
        }

        // terminates if there is an error
        if ( !pile->IsOk() )
        {
            return pj->Return(pile);                    // sends the results and releases the stack
        }

        // returns to the test again
        if (!pile->SetState(0, 0)) return false;
        continue;
    }
}
Пример #2
0
bool CBotIf :: Execute(CBotStack* &pj)
{
    CBotStack* pile = pj->AddStack(this);       // adds an item to the stack
                                                // or found in case of recovery
//  if ( pile == EOX ) return true;

    if ( pile->IfStep() ) return false;

    // according to recovery, it may be in one of two states
    if( pile->GetState() == 0 )
    {
        // evaluates the condition
        if ( !m_condition->Execute(pile) ) return false;    // interrupted here?

        // terminates if there is an error
        if ( !pile->IsOk() )
        {
            return pj->Return(pile);                        // returns the results and releases the stack
        }

        // passes into the second state
        if (!pile->SetState(1)) return false;               // ready for further
    }

    // second state, evaluates the associated instructions
    // the result of the condition is on the stack

    if ( pile->GetVal() == true )                           // condition was true?
    {
        if (m_block != nullptr &&                             // block may be absent
            !m_block->Execute(pile) ) return false;         // interrupted here?
    }
    else
    {
        if (m_blockElse != nullptr &&                         // if there is an alternate block
            !m_blockElse->Execute(pile) ) return false; // interrupted here
    }

    // sends the results and releases the stack
    return pj->Return(pile);
}
Пример #3
0
BOOL CBotIf :: Execute(CBotStack* &pj)
{
	CBotStack* pile = pj->AddStack(this);		// ajoute un élément à la pile
												// ou le retrouve en cas de reprise
//	if ( pile == EOX ) return TRUE;

	if ( pile->IfStep() ) return FALSE;

	// selon la reprise, on peut être dans l'un des 2 états
	if( pile->GivState() == 0 )
	{
		// évalue la condition
		if ( !m_Condition->Execute(pile) ) return FALSE;	// interrompu ici ?

		// termine s'il y a une erreur
		if ( !pile->IsOk() )
		{
			return pj->Return(pile);						// transmet le résultat et libère la pile
		}

		// passe dans le second état
		if (!pile->SetState(1)) return FALSE;				// prêt pour la suite
	}
	
	// second état, évalue les instructions associées
	// le résultat de la condition est sur la pile

	if ( pile->GivVal() == TRUE )							// condition était vraie ?
	{
		if ( m_Block != NULL &&								// bloc peut être absent
			!m_Block->Execute(pile) ) return FALSE;			// interrompu ici ?
	}
	else
	{
		if ( m_BlockElse != NULL &&							// s'il existe un bloc alternatif
			!m_BlockElse->Execute(pile) ) return FALSE;		// interrompu ici
	}

	// transmet le résultat et libère la pile
	return pj->Return(pile);
}
Пример #4
0
bool CBotFor :: Execute(CBotStack* &pj)
{
    CBotStack* pile = pj->AddStack(this, true);     // adds an item to the stack (variables locales)
                                                    // or find in case of recovery
//  if ( pile == EOX ) return true;

    if ( pile->IfStep() ) return false;

    while( true ) switch( pile->GetState() )    // executes the loop
    {                                           // there are four possible states (depending on recovery)
    case 0:
        // initialize
        if ( m_Init != nullptr &&
             !m_Init->Execute(pile) ) return false;     // interrupted here ?
        if (!pile->SetState(1)) return false;           // ready for further

    case 1:
        // evaluates the condition
        if ( m_Test != nullptr )                           // no strings attached? -> True!
        {
            if (!m_Test->Execute(pile) ) return false;  // interrupted here ?

            // the result of the condition is on the stack

            // terminates if an error or if the condition is false
            if ( !pile->IsOk() || pile->GetVal() != true )
            {
                return pj->Return(pile);                // sends the results and releases the stack
            }
        }

        // la condition est vrai, passe à la suite
        if (!pile->SetState(2)) return false;           // ready for further

    case 2:
        // evaluates the associated statement block
        if ( m_Block != nullptr &&
            !m_Block->Execute(pile) )
        {
            if (pile->IfContinue(3, m_label)) continue; // if continued, going on to incrementation
            return pj->BreakReturn(pile, m_label);      // sends the results and releases the stack
        }

        // terminates if there is an error
        if ( !pile->IsOk() )
        {
            return pj->Return(pile);                    // sends the results and releases the stack
        }

        if (!pile->SetState(3)) return false;           // ready for further

    case 3:
        // evalutate the incrementation
        if ( m_Incr != nullptr &&
            !m_Incr->Execute(pile) ) return false;      // interrupted here ?

        // returns to the test again
        if (!pile->SetState(1, 0)) return false;            // returns to the test
        continue;
    }
}
Пример #5
0
bool CBotClass::CompileDefItem(CBotToken* &p, CBotCStack* pStack, bool bSecond)
{
    bool    bStatic = false;
    int     mProtect = PR_PUBLIC;
    bool    bSynchro = false;

    while (IsOfType(p, ID_SEP)) ;

    CBotTypResult   type( -1 );

    if ( IsOfType(p, ID_SYNCHO) ) bSynchro = true;
    CBotToken*      pBase = p;

    if ( IsOfType(p, ID_STATIC) ) bStatic = true;
    if ( IsOfType(p, ID_PUBLIC) ) mProtect = PR_PUBLIC;
    if ( IsOfType(p, ID_PRIVATE) ) mProtect = PR_PRIVATE;
    if ( IsOfType(p, ID_PROTECTED) ) mProtect = PR_PROTECT;
    if ( IsOfType(p, ID_STATIC) ) bStatic = true;

//  CBotClass* pClass = NULL;
    type = TypeParam(p, pStack);        // type of the result

    if ( type.Eq(-1) )
    {
        pStack->SetError(TX_NOTYP, p);
        return false;
    }

    while (pStack->IsOk()) 
    {
        CBotToken*  pp = p;
        IsOfType(p, ID_NOT);    // skips ~ eventual (destructor)

        if (IsOfType(p, TokenTypVar))
        {
            CBotInstr* limites = NULL;
            while ( IsOfType( p, ID_OPBRK ) )   // a table?
            {
                CBotInstr* i = NULL;

                if ( p->GetType() != ID_CLBRK )
                    i = CBotExpression::Compile( p, pStack );           // expression for the value
                else
                    i = new CBotEmpty();                            // special if not a formula

                type = CBotTypResult(CBotTypArrayPointer, type);

                if (!pStack->IsOk() || !IsOfType( p, ID_CLBRK ) )
                {
                    pStack->SetError(TX_CLBRK, p->GetStart());
                    return false;
                }

/*              CBotVar* pv = pStack->GetVar();
                if ( pv->GetType()>= CBotTypBoolean )
                {
                    pStack->SetError(TX_BADTYPE, p->GetStart());
                    return false;
                }*/

                if (limites == NULL) limites = i;
                else limites->AddNext3(i);
            }

            if ( p->GetType() == ID_OPENPAR )
            {
                if ( !bSecond )
                {
                    p = pBase;
                    CBotFunction* f = 
                    CBotFunction::Compile1(p, pStack, this);

                    if ( f == NULL ) return false;

                    if (m_pMethod == NULL) m_pMethod = f;
                    else m_pMethod->AddNext(f);
                }
                else
                {
                    // return a method precompiled in pass 1
                    CBotFunction*   pf = m_pMethod;
                    CBotFunction*   prev = NULL;
                    while ( pf != NULL ) 
                    {
                        if (pf->GetName() == pp->GetString()) break;
                        prev = pf;
                        pf = pf->Next();
                    }

                    bool bConstructor = (pp->GetString() == GetName());
                    CBotCStack* pile = pStack->TokenStack(NULL, true);

                    // make "this" known
                    CBotToken TokenThis(CBotString("this"), CBotString());
                    CBotVar* pThis = CBotVar::Create(&TokenThis, CBotTypResult( CBotTypClass, this ) );
                    pThis->SetUniqNum(-2);
                    pile->AddVar(pThis);

                    if ( m_pParent )
                    {
                        // makes "super" known
                        CBotToken TokenSuper(CBotString("super"), CBotString());
                        CBotVar* pThis = CBotVar::Create(&TokenSuper, CBotTypResult( CBotTypClass, m_pParent ) );
                        pThis->SetUniqNum(-3);
                        pile->AddVar(pThis);
                    }

//                  int num = 1;
                    CBotClass*  my = this;
                    while (my != NULL)
                    {
                        // places a copy of variables of a class (this) on a stack
                        CBotVar* pv = my->m_pVar;
                        while (pv != NULL)
                        {
                            CBotVar* pcopy = CBotVar::Create(pv);
                            pcopy->SetInit(!bConstructor || pv->IsStatic());
                            pcopy->SetUniqNum(pv->GetUniqNum());
                            pile->AddVar(pcopy);
                            pv = pv->GetNext();
                        }
                        my = my->m_pParent;
                    }

                    // compiles a method
                    p = pBase;
                    CBotFunction* f = 
                    CBotFunction::Compile(p, pile, NULL/*, false*/);

                    if ( f != NULL )
                    {
                        f->m_pProg = pStack->GetBotCall();
                        f->m_bSynchro = bSynchro;
                        // replaces the element in the chain
                        f->m_next = pf->m_next;
                        pf->m_next = NULL;
                        delete pf;
                        if (prev == NULL) m_pMethod = f;
                        else prev->m_next = f;
                    }
                    pStack->Return(NULL, pile);
                }

                return pStack->IsOk();
            }

            // definition of an element
            if (type.Eq(0))
            {
                pStack->SetError(TX_ENDOF, p);
                return false;
            }

            CBotInstr* i = NULL;
            if ( IsOfType(p, ID_ASS ) )
            {
                if ( type.Eq(CBotTypArrayPointer) )
                {
                    i = CBotListArray::Compile(p, pStack, type.GetTypElem());
                }
                else
                {
                    // it has an assignmet to calculate
                    i = CBotTwoOpExpr::Compile(p, pStack);
                }
                if ( !pStack->IsOk() ) return false;
            }


            if ( !bSecond )
            {
                CBotVar*    pv = CBotVar::Create(pp->GetString(), type);
                pv -> SetStatic( bStatic );
                pv -> SetPrivate( mProtect );

                AddItem( pv );

                pv->m_InitExpr = i;
                pv->m_LimExpr = limites;


                if ( pv->IsStatic() && pv->m_InitExpr != NULL )
                {
                    CBotStack* pile = CBotStack::FirstStack();              // independent stack
                    while(pile->IsOk() && !pv->m_InitExpr->Execute(pile));  // evaluates the expression without timer
                    pv->SetVal( pile->GetVar() ) ;
                    pile->Delete();
                }
            }
            else
                delete i;

            if ( IsOfType(p, ID_COMMA) ) continue;
            if ( IsOfType(p, ID_SEP) ) break;
        }
        pStack->SetError(TX_ENDOF, p);
    }
    return pStack->IsOk();
}