Пример #1
0
bool CBotInstrCall::Execute(CBotStack* &pj)
{
    CBotVar*    ppVars[1000];
    CBotStack*  pile  = pj->AddStack(this);
    if ( pile->StackOver() ) return pj->Return( pile );

//    CBotStack*  pile1 = pile;

    int     i = 0;

    CBotInstr*  p = m_Parameters;
    // evaluates parameters
    // and places the values ​​on the stack
    // for allow of interruption at any time
    if ( p != NULL) while ( true )
    {
        pile = pile->AddStack();                        // place on the stack for the results
        if ( pile->GetState() == 0 )
        {
            if (!p->Execute(pile)) return false;        // interrupted here?
            pile->SetState(1);                          // mark as special for reknowed parameters \TODO marque spéciale pour reconnaîre parameters
        }
        ppVars[i++] = pile->GetVar();
        p = p->GetNext();
        if ( p == NULL) break;
    }
    ppVars[i] = NULL;

    CBotStack* pile2 = pile->AddStack();
    if ( pile2->IfStep() ) return false;

    if ( !pile2->ExecuteCall(m_nFuncIdent, GetToken(), ppVars, m_typRes)) return false; // interrupt

    return pj->Return(pile2);   // release the entire stack
}
Пример #2
0
bool CBotInstrCall::Execute(CBotStack* &pj)
{
    CBotVar*    ppVars[1000];
    CBotStack*  pile  = pj->AddStack(this);
    if ( pile->StackOver() ) return pj->Return( pile );

    CBotStack* pile3 = nullptr;
    if (m_exprRetVar != nullptr) // func().member
    {
        pile3 = pile->AddStack2();
        if (pile3->GetState() == 1) // function call is done?
        {
            if (!m_exprRetVar->Execute(pile3)) return false;
            return pj->Return(pile3);
        }
    }

//    CBotStack*  pile1 = pile;

    int     i = 0;

    CBotInstr*  p = m_parameters;
    // evaluates parameters
    // and places the values ​​on the stack
    // for allow of interruption at any time
    if ( p != nullptr) while ( true )
    {
        pile = pile->AddStack();                        // place on the stack for the results
        if ( pile->GetState() == 0 )
        {
            if (!p->Execute(pile)) return false;        // interrupted here?
            pile->SetState(1);                          // set state to remember that parameters were executed
        }
        ppVars[i++] = pile->GetVar();
        p = p->GetNext();
        if ( p == nullptr) break;
    }
    ppVars[i] = nullptr;

    CBotStack* pile2 = pile->AddStack();
    if ( pile2->IfStep() ) return false;

    if ( !pile2->ExecuteCall(m_nFuncIdent, GetToken(), ppVars, m_typRes)) return false; // interrupt

    if (m_exprRetVar != nullptr) // func().member
    {
        pile3->SetCopyVar( pile2->GetVar() ); // copy the result
        pile2->SetVar(nullptr);
        pile3->SetState(1);      // set call is done
        return false;            // go back to the top ^^^
    }

    return pj->Return(pile2);   // release the entire stack
}
Пример #3
0
bool CBotNew::Execute(CBotStack* &pj)
{
    CBotStack*    pile = pj->AddStack(this);    //main stack

    if (m_exprRetVar != nullptr) // new Class().method()
    {
        if (pile->GetState() == 2)
        {
            CBotStack* pile3 = pile->AddStack();
            if (!m_exprRetVar->Execute(pile3)) return false;
            return pj->Return(pile3);
        }
    }

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

    CBotStack*    pile1 = pj->AddStack2();  //secondary stack

    CBotVar*    pThis = nullptr;

    CBotToken*    pt = &m_vartoken;
    CBotClass*    pClass = CBotClass::Find(pt);

    // create the variable "this" pointer type to the stack

    if ( pile->GetState()==0)
    {
        // create an instance of the requested class
        // and initialize the pointer to that object


        pThis = CBotVar::Create("this", pClass);
        pThis->SetUniqNum(-2) ;

        pile1->SetVar(pThis);   // place on stack1
        pile->IncState();
    }

    // fetch the this pointer if it was interrupted
    if ( pThis == nullptr)
    {
        pThis = pile1->GetVar();    // find the pointer
    }

    // is there an assignment or parameters (constructor)
    if ( pile->GetState()==1)
    {
        // evaluates the constructor of the instance

        CBotVar*    ppVars[1000];
        CBotStack*    pile2 = pile;

        int        i = 0;

        CBotInstr*    p = m_parameters;
        // evaluate the parameters
        // and places the values on the stack
        // to be interrupted at any time

        if (p != nullptr) while ( true)
        {
            pile2 = pile2->AddStack();  // space on the stack for the result
            if (pile2->GetState() == 0)
            {
                if (!p->Execute(pile2)) return false;   // interrupted here?
                pile2->SetState(1);
            }
            ppVars[i++] = pile2->GetVar();
            p = p->GetNext();
            if ( p == nullptr) break;
        }
        ppVars[i] = nullptr;

        // create a variable for the result
        CBotVar*    pResult = nullptr;     // constructos still void

        if ( !pClass->ExecuteMethode(m_nMethodeIdent, pClass->GetName(),
                                     pThis, ppVars,
                                     pResult, pile2, GetToken())) return false;    // interrupt

        pThis->ConstructorSet();    // indicates that the constructor has been called
    }

    if (m_exprRetVar != nullptr) // new Class().method()
    {
        pile->AddStack()->Delete();          // release pile2 stack
        CBotStack* pile3 = pile->AddStack(); // add new stack
        pile3->SetCopyVar(pThis); // copy the pointer (from pile1)
        pile1->Delete();          // release secondary stack(pile1)
        pile->SetState(2);
        return false;             // go back to the top ^^^
    }

    return pj->Return(pile1);   // passes below
}
Пример #4
0
bool CBotDefArray::Execute(CBotStack* &pj)
{
    CBotStack*    pile1 = pj->AddStack(this);

    CBotStack*    pile  = pile1;

    if (pile1->GetState() == 0)
    {
        // seek the maximum dimension of the table
        CBotInstr*    p  = GetNext3b();                             // the different formulas
        int            nb = 0;

        while (p != nullptr)
        {
            pile = pile->AddStack();                                // little room to work
            nb++;
            if (pile->GetState() == 0)
            {
                if (!p->Execute(pile)) return false;                // size calculation //interrupted?
                pile->IncState();
            }
            p = p->GetNext3b();
        }

        p     = GetNext3b();
        pile = pile1;                                               // returns to the stack
        int     n = 0;
        int     max[100];

        while (p != nullptr)
        {
            pile = pile->AddStack();
            CBotVar*    v = pile->GetVar();                         // result
            max[n] = v->GetValInt();                                // value
            if (max[n]>MAXARRAYSIZE)
            {
                pile->SetError(CBotErrOutArray, &m_token);
                return pj->Return (pile);
            }
            n++;
            p = p->GetNext3b();
        }
        while (n<100) max[n++] = 0;

        m_typevar.SetArray(max);                                    // store the limitations

        // create simply a nullptr pointer
        CBotVar*    var = CBotVar::Create(*(m_var->GetToken()), m_typevar);
        var->SetPointer(nullptr);
        var->SetUniqNum((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent);
        pj->AddVar(var);

#if        STACKMEM
        pile1->AddStack()->Delete();
#else
        delete pile1->AddStack();                                   // need more indices
#endif
        pile1->IncState();
    }

    if (pile1->GetState() == 1)
    {
        if (m_listass != nullptr)                                      // there is the assignment for this table
        {
            CBotVar* pVar = pj->FindVar((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent, false);

            if (!m_listass->Execute(pile1, pVar)) return false;
        }
        pile1->IncState();
    }

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

    if ( m_next2b &&
         !m_next2b->Execute(pile1 )) return false;

    return pj->Return(pile1);
}
Пример #5
0
int CBotFunction::DoCall(long& nIdent, const char* name, CBotVar* pThis, CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken, CBotClass* pClass)
{
    CBotTypResult   type;
    CBotProgram*    pProgCurrent = pStack->GetBotCall();

    CBotFunction*   pt = FindLocalOrPublic(nIdent, name, ppVars, type, false);

    if ( pt != NULL )
    {
//      DEBUG( "CBotFunction::DoCall" + pt->GetName(), 0, pStack);

        CBotStack*  pStk = pStack->AddStack(pt, 2);
//      if ( pStk == EOX ) return true;

        pStk->SetBotCall(pt->m_pProg);                  // it may have changed module
        CBotStack*  pStk3 = pStk->AddStack(NULL, true); // to set parameters passed

        // preparing parameters on the stack

        if ( pStk->GetState() == 0 )
        {
            // sets the variable "this" on the stack
            CBotVar* pthis = CBotVar::Create("this", CBotTypNullPointer);
            pthis->Copy(pThis, false);
            pthis->SetUniqNum(-2);      // special value
            pStk->AddVar(pthis);

            CBotClass*  pClass = pThis->GetClass()->GetParent();
            if ( pClass )
            {
                // sets the variable "super" on the stack
                CBotVar* psuper = CBotVar::Create("super", CBotTypNullPointer);
                psuper->Copy(pThis, false); // in fact identical to "this"
                psuper->SetUniqNum(-3);     // special value
                pStk->AddVar(psuper);
            }
            // initializes the variables as parameters
            pt->m_Param->Execute(ppVars, pStk3);            // cannot be interrupted
            pStk->IncState();
        }

        if ( pStk->GetState() == 1 )
        {
            if ( pt->m_bSynchro )
            {
                CBotProgram* pProgBase = pStk->GetBotCall(true);
                if ( !pClass->Lock(pProgBase) ) return false;       // expected to power \TODO attend de pouvoir
            }
            pStk->IncState();
        }
        // finally calls the found function

        if ( !pStk3->GetRetVar(                         // puts the result on the stack
            pt->m_Block->Execute(pStk3) ))          // GetRetVar said if it is interrupted
        {
            if ( !pStk3->IsOk() )
            {
                if ( pt->m_bSynchro )
                {
                    pClass->Unlock();                   // release function
                }

                if ( pt->m_pProg != pProgCurrent )
                {
                    pStk3->SetPosError(pToken);         // indicates the error on the procedure call
                }
            }
            return false;   // interrupt !
        }

        if ( pt->m_bSynchro )
        {
            pClass->Unlock();                           // release function
        }

        return pStack->Return( pStk3 );
    }
    return -1;
}