Пример #1
0
CBotVar* CBotStack::GetCopyVar()
{
    if (m_var == NULL) return NULL;
    CBotVar*    v = CBotVar::Create("", m_var->GetType());
    v->Copy( m_var );
    return v;
}
Пример #2
0
CBotVar* CBotStack::CopyVar(CBotToken& Token, bool bUpdate)
{
    CBotVar*    pVar = FindVar( Token, bUpdate );

    if ( pVar == NULL) return NULL;

    CBotVar*    pCopy = CBotVar::Create(pVar);
    pCopy->Copy(pVar);
    return    pCopy;
}
Пример #3
0
CBotVar* CBotCStack::CopyVar(CBotToken& Token)
{
    CBotVar*    pVar = FindVar( Token );

    if ( pVar == NULL) return NULL;

    CBotVar*    pCopy = CBotVar::Create( "", pVar->GetType() );
    pCopy->Copy(pVar);
    return    pCopy;
}
Пример #4
0
bool CBotClass::RestoreStaticState(FILE* pf)
{
    CBotString      ClassName, VarName;
    CBotClass*      pClass;
    unsigned short  w;

    if (!ReadWord( pf, w )) return false;
    if ( w != CBOTVERSION*2 ) return false;

    while (true)
    {
        if (!ReadWord( pf, w )) return false;
        if ( w == 0 ) return true;

        if (!ReadString( pf, ClassName )) return false;
        pClass = Find(ClassName);

        while (true)
        {
            if (!ReadWord( pf, w )) return false;
            if ( w == 0 ) break;

            CBotVar*    pVar = NULL;
            CBotVar*    pv = NULL;

            if (!ReadString( pf, VarName )) return false;
            if ( pClass != NULL ) pVar = pClass->GetItem(VarName);

            if (!CBotVar::RestoreState(pf, pv)) return false;   // the temp variable

            if ( pVar != NULL ) pVar->Copy(pv);
            delete pv;
        }
    }
    return true;
}
Пример #5
0
bool CBotClassInst::Execute(CBotStack* &pj)
{
    CBotVar*    pThis = NULL;

    CBotStack*  pile = pj->AddStack(this);//essential for SetState()
//  if ( pile == EOX ) return true;

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

    bool bIntrincic = pClass->IsIntrinsic();

    // creates the variable of type pointer to the object

    if ( pile->GetState()==0)
    {
        CBotString  name = m_var->m_token.GetString();
        if ( bIntrincic )
        {
            pThis = CBotVar::Create(name, CBotTypResult( CBotTypIntrinsic, pClass ));
        }
        else
        {
            pThis = CBotVar::Create(name, CBotTypResult( CBotTypPointer, pClass ));
        }

        pThis->SetUniqNum((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent); // its attribute as unique number
        pile->AddVar(pThis);                                    // place on the stack
        pile->IncState();
    }

    if ( pThis == NULL ) pThis = pile->FindVar((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent);

    if ( pile->GetState()<3)
    {
        // ss there an assignment or parameters (contructor)

//      CBotVarClass* pInstance = NULL;

        if ( m_expr != NULL )
        {
            // evaluates the expression for the assignment
            if (!m_expr->Execute(pile)) return false;

            if ( bIntrincic )
            {
                CBotVar*    pv = pile->GetVar();
                if ( pv == NULL || pv->GetPointer() == NULL )
                {
                    pile->SetError(TX_NULLPT, &m_token);
                    return pj->Return(pile);
                }
                pThis->Copy(pile->GetVar(), false);
            }
            else
            {
                CBotVarClass* pInstance;
                pInstance = (static_cast<CBotVarPointer*>(pile->GetVar()))->GetPointer();    // value for the assignment
                pThis->SetPointer(pInstance);
            }
            pThis->SetInit(true);
        }

        else if ( m_hasParams )
        {
            // evaluates the constructor of an instance

            if ( !bIntrincic && pile->GetState() == 1)
            {
                CBotToken*  pt = &m_token;
                CBotClass* pClass = CBotClass::Find(pt);

                // creates an instance of the requested class

                CBotVarClass* pInstance;
                pInstance = static_cast<CBotVarClass*>(CBotVar::Create("", pClass));
                pThis->SetPointer(pInstance);
                delete pInstance;

                pile->IncState();
            }

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

            int     i = 0;

            CBotInstr*  p = m_Parameters;
            // evaluates the parameters
            // and places the values ​​on the stack
            // to (can) be interrupted (broken) at any time

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

            // creates a variable for the result
            CBotVar*    pResult = NULL;     // constructor still void

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

            pThis->SetInit(true);
            pThis->ConstructorSet();        // indicates that the constructor has been called
            pile->Return(pile2);                                // releases a piece of stack

//          pInstance = pThis->GetPointer();

        }

//      if ( !bIntrincic ) pThis->SetPointer(pInstance);        // a pointer to the instance

        pile->SetState(3);                                  // finished this part
    }

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

    if ( m_next2b != NULL &&
        !m_next2b->Execute(pile)) return false;             // other (s) definition (s)

    return pj->Return( pile );                              // transmits below (further)
}
Пример #6
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;
}
Пример #7
0
// compiles a new function
// bLocal allows of the declaration of parameters on the same level
// as the elements belonging to the class for methods
CBotFunction* CBotFunction::Compile(CBotToken* &p, CBotCStack* pStack, CBotFunction* finput, bool bLocal)
{
    CBotToken*      pp;
    CBotFunction* func = finput;
    if ( func == NULL ) func = new CBotFunction();

    CBotCStack* pStk = pStack->TokenStack(p, bLocal);

//  func->m_nFuncIdent = CBotVar::NextUniqNum();

    while (true)
    {
        if ( IsOfType(p, ID_PUBLIC) )
        {
            func->m_bPublic = true;
            continue;
        }
        pp = p;
        if ( IsOfType(p, ID_EXTERN) )
        {
            func->m_extern = pp;        // for the position of the word "extern"
            func->m_bExtern = true;
//          func->m_bPublic = true;     // therefore also public!
            continue;
        }
        break;
    }

    func->m_retToken = *p;
//  CBotClass*  pClass;
    func->m_retTyp = TypeParam(p, pStk);        // type of the result

    if (func->m_retTyp.GetType() >= 0)
    {
        CBotToken*  pp = p;
        func->m_token = *p;

        if ( IsOfType(p, ID_NOT) )
        {
            CBotToken d("~" + p->GetString());
            func->m_token = d;
        }

        // un nom de fonction est-il là ?
        if (IsOfType(p, TokenTypVar))
        {
            if ( IsOfType( p, ID_DBLDOTS ) )        // method for a class
            {
                func->m_MasterClass = pp->GetString();
                CBotClass* pClass = CBotClass::Find(pp);
                if ( pClass == NULL ) goto bad;

//              pp = p;
                func->m_token = *p;
                if (!IsOfType(p, TokenTypVar)) goto bad;

            }
            func->m_openpar = p;
            func->m_Param = CBotDefParam::Compile( p, pStk );
            func->m_closepar = p->GetPrev();
            if (pStk->IsOk())
            {
                pStk->SetRetType(func->m_retTyp);   // for knowledge what type returns

                if (!func->m_MasterClass.IsEmpty())
                {
                    // return "this" known
                    CBotVar* pThis = CBotVar::Create("this", CBotTypResult( CBotTypClass, func->m_MasterClass ));
                    pThis->SetInit(2);
//                  pThis->SetUniqNum(func->m_nThisIdent = -2); //CBotVar::NextUniqNum() will not
                    pThis->SetUniqNum(-2);
                    pStk->AddVar(pThis);

                    // initialize variables acording to This
                    // only saves the pointer to the first,
                    // the rest is chained
                    CBotVar* pv = pThis->GetItemList();
//                  int num = 1;
                    while (pv != NULL)
                    {
                        CBotVar* pcopy = CBotVar::Create(pv);
//                      pcopy->SetInit(2);
                        pcopy->Copy(pv);
                        pcopy->SetPrivate(pv->GetPrivate());
//                      pcopy->SetUniqNum(pv->GetUniqNum()); //num++);
                        pStk->AddVar(pcopy);
                        pv = pv->GetNext();
                    }
                }

                // and compiles the following instruction block 
                func->m_openblk = p;
                func->m_Block   = CBotBlock::Compile(p, pStk, false);
                func->m_closeblk = p->GetPrev();
                if ( pStk->IsOk() )
                {
                    if ( func->m_bPublic )  // public function, return known for all
                    {
                        CBotFunction::AddPublic(func);
                    }
                    return pStack->ReturnFunc(func, pStk);
                }
            }
        }
bad:
        pStk->SetError(TX_NOFONC, p);
    }
    pStk->SetError(TX_NOTYP, p);
    if ( finput == NULL ) delete func;
    return pStack->ReturnFunc(NULL, pStk);
}