Exemple #1
0
void CBotFunction::RestoreState(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInstance)
{
    CBotStack*  pile = pj->RestoreStack(this);          // one end of stack local to this function
    if ( pile == NULL ) return;
    CBotStack*  pile2 = pile;

    pile->SetBotCall(m_pProg);                          // bases for routines

    if ( pile->GetBlock() < 2 )
    {
        CBotStack*  pile2 = pile->RestoreStack(NULL);       // one end of stack local to this function
        if ( pile2 == NULL ) return;
        pile->SetState(pile->GetState() + pile2->GetState());
        pile2->Delete();
    }

    m_Param->RestoreState(pile2, true);                 // parameters

    if ( !m_MasterClass.IsEmpty() )
    {
        CBotVar* pThis = pile->FindVar("this");
        pThis->SetInit(2);
        pThis->SetUniqNum(-2);
    }

    m_Block->RestoreState(pile2, true);
}
Exemple #2
0
void CBotFunction::RestoreCall(long& nIdent, const char* name, CBotVar* pThis, CBotVar** ppVars, CBotStack* pStack, CBotClass* pClass)
{
    CBotTypResult   type;
    CBotFunction*   pt = FindLocalOrPublic(nIdent, name, ppVars, type);

    if ( pt != NULL )
    {
        CBotStack*  pStk = pStack->RestoreStack(pt);
        if ( pStk == NULL ) return;
        pStk->SetBotCall(pt->m_pProg);                  // it may have changed module

        CBotVar*    pthis = pStk->FindVar("this");
        pthis->SetUniqNum(-2);

        CBotStack*  pStk3 = pStk->RestoreStack(NULL);   // to set parameters passed
        if ( pStk3 == NULL ) return;

        pt->m_Param->RestoreState(pStk3, true);                 // parameters

        if ( pStk->GetState() > 1 &&                        // latching is effective?
             pt->m_bSynchro )
            {
                CBotProgram* pProgBase = pStk->GetBotCall(true);
                pClass->Lock(pProgBase);                    // locks the class
            }

        // finally calls the found function

        pt->m_Block->RestoreState(pStk3, true);                 // interrupt !
    }
}
Exemple #3
0
// compiles a list of parameters
CBotDefParam* CBotDefParam::Compile(CBotToken* &p, CBotCStack* pStack)
{
    // mainly not pStack->TokenStack here
    // declared variables must remain visible thereafter

    pStack->SetStartError(p->GetStart());

    if (IsOfType(p, ID_OPENPAR))
    {
        CBotDefParam* list = NULL;
    
        while (!IsOfType(p, ID_CLOSEPAR))
        {
            CBotDefParam* param = new CBotDefParam();
            if (list == NULL) list = param;
            else list->AddNext(param);          // added to the list

//            CBotClass*  pClass = NULL;//= CBotClass::Find(p);
            param->m_typename = p->GetString();
            CBotTypResult type = param->m_type = TypeParam(p, pStack);
//          if ( type == CBotTypPointer ) type = CBotTypClass;          // we must create a new object

            if (param->m_type.GetType() > 0)
            {
                CBotToken*  pp = p;
                param->m_token = *p;
                if (pStack->IsOk() && IsOfType(p, TokenTypVar) )
                {

                    // variable already declared?
                    if (pStack->CheckVarLocal(pp))
                    {
                        pStack->SetError(TX_REDEFVAR, pp);
                        break;
                    }

                    if ( type.Eq(CBotTypArrayPointer) ) type.SetType(CBotTypArrayBody);
                    CBotVar*    var = CBotVar::Create(pp->GetString(), type);       // creates the variable
//                  if ( pClass ) var->SetClass(pClass);
                    var->SetInit(2);                                    // mark initialized
                    param->m_nIdent = CBotVar::NextUniqNum();
                    var->SetUniqNum(param->m_nIdent);
                    pStack->AddVar(var);                                // place on the stack

                    if (IsOfType(p, ID_COMMA) || p->GetType() == ID_CLOSEPAR)
                        continue;
                }
                pStack->SetError(TX_CLOSEPAR, p->GetStart());
            }
            pStack->SetError(TX_NOTYP, p);
            delete list;
            return NULL;
        }
        return list;
    }
    pStack->SetError(TX_OPENPAR, p->GetStart());
    return NULL;
}
Exemple #4
0
void CBotFunction::RestoreCall(long& nIdent, const char* name, CBotVar** ppVars, CBotStack* pStack)
{
    CBotTypResult   type;
    CBotFunction*   pt = NULL;
    CBotStack*      pStk1;
    CBotStack*      pStk3;

    // search function to return the ok identifier

    pt = FindLocalOrPublic(nIdent, name, ppVars, type);

    if ( pt != NULL )
    {
        pStk1 = pStack->RestoreStack(pt);
        if ( pStk1 == NULL ) return;

        pStk1->SetBotCall(pt->m_pProg);                 // it may have changed module

        if ( pStk1->GetBlock() < 2 )
        {
            CBotStack* pStk2 = pStk1->RestoreStack(NULL); // used more
            if ( pStk2 == NULL ) return;
            pStk3 = pStk2->RestoreStack(NULL);
            if ( pStk3 == NULL ) return;
        }
        else
        {
            pStk3 = pStk1->RestoreStack(NULL);
            if ( pStk3 == NULL ) return;
        }

        // preparing parameters on the stack

        {
            if ( !pt->m_MasterClass.IsEmpty() )
            {
//                CBotVar* pInstance = m_pProg->m_pInstance;
                // make "this" known
                CBotVar* pThis = pStk1->FindVar("this");
                pThis->SetInit(2);
                pThis->SetUniqNum(-2);
            }
        }

        if ( pStk1->GetState() == 0 )
        {
            pt->m_Param->RestoreState(pStk3, true);
            return;
        }

        // initializes the variables as parameters
        pt->m_Param->RestoreState(pStk3, false);
        pt->m_Block->RestoreState(pStk3, true);
    }
}
Exemple #5
0
void CBotDefParam::RestoreState(CBotStack* &pj, bool bMain)
{
//    int             i = 0;
    CBotDefParam*   p = this;

    while ( p != NULL )
    {
        // creates a local variable on the stack
        CBotVar*    var = pj->FindVar(p->m_token.GetString());
        var->SetUniqNum(p->m_nIdent);
        p = p->m_next;
    }
}
Exemple #6
0
bool CBotFunction::Execute(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInstance)
{
    CBotStack*  pile = pj->AddStack(this, 2);               // one end of stack local to this function
//  if ( pile == EOX ) return true;

    pile->SetBotCall(m_pProg);                              // bases for routines

    if ( pile->GetState() == 0 )
    {
        if ( !m_Param->Execute(ppVars, pile) ) return false;    // define parameters
        pile->IncState();
    }

    if ( pile->GetState() == 1 && !m_MasterClass.IsEmpty() )
    {
        // makes "this" known
        CBotVar* pThis ;
        if ( pInstance == NULL )
        {
            pThis = CBotVar::Create("this", CBotTypResult( CBotTypClass, m_MasterClass ));
            pThis->SetInit(2);
        }
        else
        {
            pThis = CBotVar::Create("this", CBotTypResult( CBotTypPointer, m_MasterClass ));
            pThis->SetPointer(pInstance);
            pThis->SetInit(2);
        }

//      pThis->SetUniqNum(m_nThisIdent);
        pThis->SetUniqNum(-2);
        pile->AddVar(pThis);

        pile->IncState();
    }

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

    if ( !m_Block->Execute(pile) )
    {
        if ( pile->GetError() < 0 )
            pile->SetError( 0 );
        else
            return false;
    }

    return pj->Return(pile);
}
Exemple #7
0
bool CBotDefParam::Execute(CBotVar** ppVars, CBotStack* &pj)
{
    int             i = 0;
    CBotDefParam*   p = this;

    while ( p != NULL )
    {
        // creates a local variable on the stack
        CBotVar*    newvar = CBotVar::Create(p->m_token.GetString(), p->m_type);

        // serves to make the transformation of types:
        if ( ppVars != NULL && ppVars[i] != NULL )
        {
            switch (p->m_type.GetType())
            {
            case CBotTypInt:
                newvar->SetValInt(ppVars[i]->GetValInt());
                break;
            case CBotTypFloat:
                newvar->SetValFloat(ppVars[i]->GetValFloat());
                break;
            case CBotTypString:
                newvar->SetValString(ppVars[i]->GetValString());
                break;
            case CBotTypBoolean:
                newvar->SetValInt(ppVars[i]->GetValInt());
                break;
            case CBotTypIntrinsic:
                (static_cast<CBotVarClass*>(newvar))->Copy(ppVars[i], false);
                break;
            case CBotTypPointer:
            case CBotTypArrayPointer:
                {
                    newvar->SetPointer(ppVars[i]->GetPointer());
                }
                break;
            default:
                ASM_TRAP();
            }
        }
        newvar->SetUniqNum(p->m_nIdent);
        pj->AddVar(newvar);     // add a variable
        p = p->m_next;
        i++;
    }

    return true;
}
Exemple #8
0
void CBotDefArray::RestoreState(CBotStack* &pj, bool bMain)
{
    CBotStack*    pile1 = pj;

    CBotVar*    var = pj->FindVar(m_var->GetToken()->GetString());
    if (var != nullptr) var->SetUniqNum((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent);

    if (bMain)
    {
        pile1 = pj->RestoreStack(this);
        CBotStack*    pile  = pile1;
        if (pile == nullptr) return;

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

            while (p != nullptr)
            {
                pile = pile->RestoreStack();
                if (pile == nullptr) return;
                if (pile->GetState() == 0)
                {
                    p->RestoreState(pile, bMain);
                    return;
                }
                p = p->GetNext3b();
            }
        }
        if (pile1->GetState() == 1 && m_listass != nullptr)
        {
            m_listass->RestoreState(pile1, bMain);
        }

    }

    if (m_next2b ) m_next2b->RestoreState( pile1, bMain);
}
Exemple #9
0
void CBotNew::RestoreState(CBotStack* &pj, bool bMain)
{
    if (!bMain) return;

    CBotStack*    pile = pj->RestoreStack(this);    //primary stack
    if (pile == nullptr) return;

    if (m_exprRetVar != nullptr)    // new Class().method()
    {
        if (pile->GetState() == 2)
        {
            CBotStack* pile3 = pile->RestoreStack();
            m_exprRetVar->RestoreState(pile3, bMain);
            return;
        }
    }

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

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

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

    if ( pile->GetState()==0)
    {
        return;
    }

    CBotVar* pThis = pile1->GetVar();   // find the pointer
    pThis->SetUniqNum(-2);

    // is ther 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->RestoreStack();  // space on the stack for the result
            if (pile2 == nullptr) return;

            if (pile2->GetState() == 0)
            {
                p->RestoreState(pile2, bMain);  // interrupt here!
                return;
            }
            ppVars[i++] = pile2->GetVar();
            p = p->GetNext();
            if ( p == nullptr) break;
        }
        ppVars[i] = nullptr;

        pClass->RestoreMethode(m_nMethodeIdent, m_vartoken.GetString(), pThis,
                               ppVars, pile2)    ;        // interrupt here!
    }
}
Exemple #10
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
}
Exemple #11
0
void CBotClassInst::RestoreState(CBotStack* &pj, bool bMain)
{
    CBotVar*    pThis = NULL;

    CBotStack*  pile = pj;
    if ( bMain ) pile = pj->RestoreStack(this);
    if ( pile == NULL ) return;

    // creates the variable of type pointer to the object
    {
        CBotString  name = m_var->m_token.GetString();
        pThis = pile->FindVar(name);
        pThis->SetUniqNum((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent); // its attribute a unique number
    }

    CBotToken*  pt = &m_token;
    CBotClass*  pClass = CBotClass::Find(pt);
    bool bIntrincic = pClass->IsIntrinsic();

    if ( bMain && pile->GetState()<3)
    {
        // is there an assignment or parameters (constructor)

//      CBotVarClass* pInstance = NULL;

        if ( m_expr != NULL )
        {
            // evaluates the expression for the assignment
            m_expr->RestoreState(pile, bMain);
            return;
        }

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

            if ( !bIntrincic && pile->GetState() == 1)
            {
                return;
            }

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

            int     i = 0;

            CBotInstr*  p = m_Parameters;
            // evaluates the parameters
            // and the values an the stack
            // for the ability to be interrupted at any time (\TODO pour pouvoir être interrompu n'importe quand)

            if ( p != NULL) while ( true )
            {
                pile2 = pile2->RestoreStack();                      // place on the stack for the results
                if ( pile2 == NULL ) return;

                if ( pile2->GetState() == 0 )
                {
                    p->RestoreState(pile2, bMain);      // interrupted here?
                    return;
                }
                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

            pClass->RestoreMethode(m_nMethodeIdent, pClass->GetName(), pThis, ppVars, pile2);
            return;
        }
    }

    if ( m_next2b != NULL )
         m_next2b->RestoreState(pile, bMain);                   // other(s) definition(s)
}
Exemple #12
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)
}
Exemple #13
0
CBotInstr* CBotClassInst::Compile(CBotToken* &p, CBotCStack* pStack, CBotClass* pClass)
{
    // seeks the corresponding classes
    if ( pClass == NULL )
    {
        pStack->SetStartError(p->GetStart());
        pClass = CBotClass::Find(p);
        if ( pClass == NULL )
        {
            // not found? is bizare
            pStack->SetError(TX_NOCLASS, p);
            return NULL;
        }
        p = p->GetNext();
    }

    bool        bIntrinsic = pClass->IsIntrinsic();
    CBotTypResult type = CBotTypResult( bIntrinsic ? CBotTypIntrinsic : CBotTypPointer, pClass );
    CBotClassInst*  inst = static_cast<CBotClassInst*>(CompileArray(p, pStack, type));
    if ( inst != NULL || !pStack->IsOk() ) return inst;

    CBotCStack* pStk = pStack->TokenStack();

    inst = new CBotClassInst();
    /// \TODO Need to be revised and fixed after adding unit tests
    CBotToken token(pClass->GetName(), CBotString(), p->GetStart(), p->GetEnd());
    inst->SetToken(&token);
    CBotToken*  vartoken = p;

    if ( NULL != (inst->m_var = CBotLeftExprVar::Compile( p, pStk )) )
    {
        (static_cast<CBotLeftExprVar*>(inst->m_var))->m_typevar = type;
        if (pStk->CheckVarLocal(vartoken))                  // redefinition of the variable
        {
            pStk->SetStartError(vartoken->GetStart());
            pStk->SetError(TX_REDEFVAR, vartoken->GetEnd());
            goto error;
        }

        if (IsOfType(p,  ID_OPBRK))                         // with any clues?
        {
            delete inst;                                    // is not type CBotInt
            p = vartoken;                                   // returns to the variable name

            // compiles declaration an array

            inst = static_cast<CBotClassInst*>(CBotInstArray::Compile( p, pStk, type ));

            if (!pStk->IsOk() )
            {
                pStk->SetError(TX_CLBRK, p->GetStart());
                goto error;
            }
            goto suite;         // no assignment, variable already created
        }


        CBotVar*    var;
        var = CBotVar::Create(vartoken->GetString(), type); // creates the instance
//      var->SetClass(pClass);
        var->SetUniqNum(
            (static_cast<CBotLeftExprVar*>(inst->m_var))->m_nIdent = CBotVar::NextUniqNum());
                                                            // its attribute a unique number
        pStack->AddVar(var);                                // placed on the stack

        // look if there are parameters
        inst->m_hasParams = (p->GetType() == ID_OPENPAR);

        CBotVar*    ppVars[1000];
        inst->m_Parameters = CompileParams(p, pStk, ppVars);
        if ( !pStk->IsOk() ) goto error;

        // if there are parameters, is the equivalent to the stament "new"
        // CPoint A ( 0, 0 ) is equivalent to
        // CPoint A = new CPoint( 0, 0 )

//      if ( NULL != inst->m_Parameters )
        if ( inst->m_hasParams )
        {
            // the constructor is there?
//          CBotString  noname;
            CBotTypResult r = pClass->CompileMethode(pClass->GetName(), var, ppVars, pStk, inst->m_nMethodeIdent);
            delete pStk->TokenStack();                          // releases the supplement stack
            int typ = r.GetType();

            if (typ == TX_UNDEFCALL)
            {
                // si le constructeur n'existe pas
                if (inst->m_Parameters != NULL)                 // with parameters
                {
                    pStk->SetError(TX_NOCONST, vartoken);
                    goto error;
                }
                typ = 0;
            }

            if (typ>20)
            {
                pStk->SetError(typ, vartoken->GetEnd());
                goto error;
            }

        }

        if (IsOfType(p,  ID_ASS))                           // with a assignment?
        {
            if (inst->m_hasParams)
            {
                pStk->SetError(TX_ENDOF, p->GetStart());
                goto error;
            }

            if ( NULL == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )) )
            {
                goto error;
            }
            CBotClass* result = pStk->GetClass();
            if ( !pStk->GetTypResult(1).Eq(CBotTypNullPointer) &&
               ( !pStk->GetTypResult(1).Eq(CBotTypPointer) ||
                 ( result != NULL && !pClass->IsChildOf(result) )))     // type compatible ?
            {
                pStk->SetError(TX_BADTYPE, p->GetStart());
                goto error;
            }
//          if ( !bIntrinsic ) var->SetPointer(pStk->GetVar()->GetPointer());
            if ( !bIntrinsic )
            {
                // does not use the result on the stack, to impose the class
                CBotVar* pvar = CBotVar::Create("", pClass);
                var->SetPointer( pvar );                    // variable already declared instance pointer
                delete pvar;                                // removes the second pointer
            }
            var->SetInit(true);                         // marks the pointer as init
        }
        else if (inst->m_hasParams)
        {
            // creates the object on the "job" (\TODO "tas")
            // with a pointer to the object
            if ( !bIntrinsic )
            {
                CBotVar* pvar = CBotVar::Create("", pClass);
                var->SetPointer( pvar );                    // variable already declared instance pointer
                delete pvar;                                // removes the second pointer
            }
            var->SetInit(2);                            // marks the pointer as init
        }
suite:
        if (IsOfType(p,  ID_COMMA))                         // several chained definitions
        {
            if ( NULL != ( inst->m_next = CBotClassInst::Compile(p, pStk, pClass) ))    // compiles the following
            {
                return pStack->Return(inst, pStk);
            }
        }

        if (IsOfType(p,  ID_SEP))                           // complete instruction
        {
            return pStack->Return(inst, pStk);
        }

        pStk->SetError(TX_ENDOF, p->GetStart());
    }

error:
    delete inst;
    return pStack->Return(NULL, pStk);
}
Exemple #14
0
CBotInstr* CBotDefArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResult type)
{
    CBotCStack* pStk = pStack->TokenStack(p);

    CBotDefArray*    inst = new CBotDefArray();

    CBotToken*    vartoken = p;
    inst->SetToken(vartoken);

    // determinse the expression is valid for the item on the left side
    if (nullptr != (inst->m_var = CBotLeftExprVar::Compile( p, pStk )))
    {
        if (pStk->CheckVarLocal(vartoken))                              // redefinition of the variable?
        {
            pStk->SetError(CBotErrRedefVar, vartoken);
            goto error;
        }

        CBotInstr*    i;
        while (IsOfType(p,  ID_OPBRK))
        {
            pStk->SetStartError(p->GetStart());
            if (p->GetType() != ID_CLBRK)
            {
                i = CBotExpression::Compile(p, pStk);                  // expression for the value
                if (i == nullptr || pStk->GetType() != CBotTypInt)     // must be a number
                {
                    pStk->SetError(CBotErrBadIndex, p->GetStart());
                    goto error;
                }
            }
            else
                i = new CBotEmpty();                                    // if no special formula

            inst->AddNext3b(i);                                         // construct a list
            type = CBotTypResult(CBotTypArrayPointer, type);

            if (IsOfType(p, ID_CLBRK)) continue;

            pStk->SetError(CBotErrCloseIndex, p->GetStart());
            goto error;
        }

        CBotVar*   var = CBotVar::Create(*vartoken, type);               // create an instance
        inst->m_typevar = type;

        var->SetUniqNum(
            (static_cast<CBotLeftExprVar*>(inst->m_var))->m_nIdent = CBotVar::NextUniqNum());
        pStack->AddVar(var);                                            // place it on the stack

        if (IsOfType(p, ID_ASS))                                        // with an assignment
        {
            pStk->SetStartError(p->GetStart());
            if ( IsOfType(p, ID_SEP) )
            {
                pStk->SetError(CBotErrNoExpression, p->GetPrev());
                goto error;
            }
            if ( nullptr == (inst->m_listass = CBotListArray::Compile(p, pStk, type.GetTypElem())) )
            {
                if (pStk->IsOk())
                {
                    inst->m_listass = CBotTwoOpExpr::Compile(p, pStk);
                    if (inst->m_listass == nullptr || !pStk->GetTypResult().Compare(type))  // compatible type ?
                    {
                        pStk->SetError(CBotErrBadType1, p->GetStart());
                        goto error;
                    }
                }
            }

            if (pStk->IsOk()) while (true)       // mark initialized
            {
                var = var->GetItem(0, true);
                if (var == nullptr) break;
                if (var->GetType() == CBotTypArrayPointer) continue;
                if (var->GetType() <= CBotTypString) var->SetInit(CBotVar::InitType::DEF);
                break;
            }
        }

        if (pStk->IsOk()) return pStack->Return(inst, pStk);
    }

error:
    delete inst;
    return pStack->Return(nullptr, pStk);
}
Exemple #15
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);
}
Exemple #16
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();
}
Exemple #17
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);
}
Exemple #18
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;
}
Exemple #19
0
int CBotFunction::DoCall(long& nIdent, const char* name, CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken)
{
    CBotTypResult   type;
    CBotFunction*   pt = NULL;
    
    pt = FindLocalOrPublic(nIdent, name, ppVars, type);

    if ( pt != NULL )
    {
        CBotStack*  pStk1 = pStack->AddStack(pt, 2);    // to put "this"
//      if ( pStk1 == EOX ) return true;

        pStk1->SetBotCall(pt->m_pProg);                 // it may have changed module

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

        CBotStack*  pStk3 = pStk1->AddStack(NULL, true);    // parameters

        // preparing parameters on the stack

        if ( pStk1->GetState() == 0 )
        {
            if ( !pt->m_MasterClass.IsEmpty() )
            {
                CBotVar* pInstance = m_pProg->m_pInstance;
                // make "this" known
                CBotVar* pThis ;
                if ( pInstance == NULL )
                {
                    pThis = CBotVar::Create("this", CBotTypResult( CBotTypClass, pt->m_MasterClass ));
                    pThis->SetInit(2);
                }
                else
                {
                    pThis = CBotVar::Create("this", CBotTypResult( CBotTypPointer, pt->m_MasterClass ));
                    pThis->SetPointer(pInstance);
                    pThis->SetInit(2);
                }

                pThis->SetUniqNum(-2);
                pStk1->AddVar(pThis);

            }

            // initializes the variables as parameters
            pt->m_Param->Execute(ppVars, pStk3);            // cannot be interrupted

            pStk1->IncState();
        }

        // finally execution of 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() && pt->m_pProg != m_pProg )
            {
#ifdef _DEBUG
                if ( m_pProg->GetFunctions()->GetName() == "LaCommande" ) return false;
#endif
                pStk3->SetPosError(pToken);         // indicates the error on the procedure call
            }
            return false;   // interrupt !
        }

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