예제 #1
0
bool CBotClass::SaveStaticState(FILE* pf)
{
    if (!WriteWord( pf, CBOTVERSION*2)) return false;

    // saves the state of static variables in classes
    CBotClass*  p = m_ExClass;

    while ( p != NULL )
    {
        if (!WriteWord( pf, 1)) return false;
        // save the name of the class
        if (!WriteString( pf, p->GetName() )) return false;

        CBotVar*    pv = p->GetVar();
        while( pv != NULL )
        {
            if ( pv->IsStatic() )
            {
                if (!WriteWord( pf, 1)) return false;
                if (!WriteString( pf, pv->GetName() )) return false;

                if ( !pv->Save0State(pf)) return false;             // common header
                if ( !pv->Save1State(pf) ) return false;                // saves as the child class
                if ( !WriteWord( pf, 0)) return false;
            }
            pv = pv->GetNext();
        }

        if (!WriteWord( pf, 0)) return false;
        p = p->m_ExNext;
    }

    if (!WriteWord( pf, 0)) return false;
    return true;
}
예제 #2
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();
}