Exemple #1
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;
}
Exemple #2
0
bool CBotExprRetVar::Execute(CBotStack* &pj)
{

    CBotStack* pile = pj->AddStack();
    CBotStack* pile1 = pile;
    CBotVar* pVar;

    if (pile1->GetState() == 0)
    {
        pVar = pj->GetVar();
        pVar->Update(pj->GetUserPtr());
        if (pVar->GetType(CBotVar::GetTypeMode::CLASS_AS_POINTER) == CBotTypNullPointer)
        {
            pile1->SetError(CBotErrNull, &m_token);
            return pj->Return(pile1);
        }

        if ( !m_next3->ExecuteVar(pVar, pile, &m_token, true, false) )
            return false;

        if (pVar)
            pile1->SetCopyVar(pVar);
        else
            return pj->Return(pile1);

        pile1->IncState();
    }
    pVar = pile1->GetVar();

    if (pVar == nullptr)
    {
        return pj->Return(pile1);
    }

    if (pVar->IsUndefined())
    {
        pile1->SetError(CBotErrNotInit, &m_token);
        return pj->Return(pile1);
    }
    return pj->Return(pile1);
}
Exemple #3
0
CBotLeftExpr* CBotLeftExpr::Compile(CBotToken* &p, CBotCStack* pStack)
{
    CBotCStack* pStk = pStack->TokenStack();

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

    // is it a variable name?
    if (p->GetType() == TokenTypVar)
    {
        CBotLeftExpr* inst = new CBotLeftExpr();    // creates the object

        inst->SetToken(p);

        CBotVar*     var;

        if (nullptr != (var = pStk->FindVar(p)))   // seek if known variable
        {
            inst->m_nIdent = var->GetUniqNum();
            if (inst->m_nIdent > 0 && inst->m_nIdent < 9000)
            {
                if (CBotFieldExpr::CheckProtectionError(pStk, nullptr, var, CBotVar::ProtectionLevel::ReadOnly))
                {
                    pStk->SetError(CBotErrPrivate, p);
                    goto err;
                }
                // this is an element of the current class
                // adds the equivalent of this. before
                CBotToken pthis("this");
                inst->SetToken(&pthis);
                inst->m_nIdent = -2;    // indent for this

                CBotFieldExpr* i = new CBotFieldExpr();     // new element
                i->SetToken(p);     // keeps the name of the token
                inst->AddNext3(i);  // add after

                var = pStk->FindVar(pthis);
                var = var->GetItem(p->GetString());
                i->SetUniqNum(var->GetUniqNum());
            }
            p = p->GetNext();   // next token

            while (true)
            {
                if (var->GetType() == CBotTypArrayPointer)
                {
                    if (IsOfType( p, ID_OPBRK ))
                    {
                        CBotIndexExpr* i = new CBotIndexExpr();
                        i->m_expr = CBotExpression::Compile(p, pStk);
                        inst->AddNext3(i);  // add to the chain

                        var = (static_cast<CBotVarArray*>(var))->GetItem(0,true);    // gets the component [0]

                        if (i->m_expr == nullptr)
                        {
                            pStk->SetError(CBotErrBadIndex, p->GetStart());
                            goto err;
                        }

                        if (!pStk->IsOk() || !IsOfType( p, ID_CLBRK ))
                        {
                            pStk->SetError(CBotErrCloseIndex, p->GetStart());
                            goto err;
                        }
                        continue;
                    }
                }

                if (var->GetType(CBotVar::GetTypeMode::CLASS_AS_POINTER) == CBotTypPointer)                // for classes
                {
                    if (IsOfType(p, ID_DOT))
                    {
                        CBotToken* pp = p;

                        CBotFieldExpr* i = new CBotFieldExpr();            // new element
                        i->SetToken(pp);                                // keeps the name of the token
                        inst->AddNext3(i);                                // adds after

                        if (p->GetType() == TokenTypVar)                // must be a name
                        {
                            CBotVar*   preVar = var;
                            var = var->GetItem(p->GetString());            // get item correspondent
                            if (var != nullptr)
                            {
                                if (CBotFieldExpr::CheckProtectionError(pStk, preVar, var,
                                                                        CBotVar::ProtectionLevel::ReadOnly))
                                {
                                    pStk->SetError(CBotErrPrivate, pp);
                                    goto err;
                                }

                                i->SetUniqNum(var->GetUniqNum());
                                p = p->GetNext();                        // skips the name
                                continue;
                            }
                            pStk->SetError(CBotErrUndefItem, p);
                        }
                        pStk->SetError(CBotErrUndefClass, p->GetStart());
                        goto err;
                    }
                }
                break;
            }


            if (pStk->IsOk()) return static_cast<CBotLeftExpr*> (pStack->Return(inst, pStk));
        }
        pStk->SetError(CBotErrUndefVar, p);
err:
        delete inst;
        return static_cast<CBotLeftExpr*> ( pStack->Return(nullptr, pStk));
    }

    return static_cast<CBotLeftExpr*> ( pStack->Return(nullptr, pStk));
}
Exemple #4
0
CBotInstr* CBotExprRetVar::Compile(CBotToken*& p, CBotCStack* pStack, bool bMethodsOnly)
{
    if (p->GetType() == ID_DOT)
    {
        CBotVar*     var = pStack->GetVar();

        if (var == nullptr) return nullptr;

        CBotCStack* pStk = pStack->TokenStack();
        CBotInstr* inst = new CBotExprRetVar();

        while (true)
        {
            pStk->SetStartError(p->GetStart());
            if (var->GetType() == CBotTypArrayPointer)
            {
                if (bMethodsOnly) goto err;

                if (IsOfType( p, ID_OPBRK ))
                {
                    CBotIndexExpr* i = new CBotIndexExpr();
                    i->m_expr = CBotExpression::Compile(p, pStk);
                    inst->AddNext3(i);

                    var = var->GetItem(0,true);

                    if (i->m_expr == nullptr || pStk->GetType() != CBotTypInt)
                    {
                        pStk->SetError(CBotErrBadIndex, p->GetStart());
                        goto err;
                    }
                    if (!pStk->IsOk() || !IsOfType( p, ID_CLBRK ))
                    {
                        pStk->SetError(CBotErrCloseIndex, p->GetStart());
                        goto err;
                    }
                    continue;
                }
            }
            if (var->GetType(CBotVar::GetTypeMode::CLASS_AS_POINTER) == CBotTypPointer)
            {
                if (IsOfType(p, ID_DOT))
                {
                    CBotToken* pp = p;

                    if (p->GetType() == TokenTypVar)
                    {
                        if (p->GetNext()->GetType() == ID_OPENPAR)
                        {
                            CBotInstr* i = CBotInstrMethode::Compile(p, pStk, var, bMethodsOnly);
                            if (!pStk->IsOk()) goto err;
                            inst->AddNext3(i);
                            return pStack->Return(inst, pStk);
                        }
                        else if (bMethodsOnly)
                        {
                            p = p->GetPrev();
                            goto err;
                        }
                        else
                        {
                            CBotFieldExpr* i = new CBotFieldExpr();
                            i->SetToken(pp);
                            inst->AddNext3(i);
                            CBotVar*   preVar = var;
                            var = var->GetItem(p->GetString());
                            if (var != nullptr)
                            {
                                i->SetUniqNum(var->GetUniqNum());
                                if (CBotFieldExpr::CheckProtectionError(pStk, preVar, var))
                                {
                                    pStk->SetError(CBotErrPrivate, pp);
                                    goto err;
                                }
                            }
                        }

                        if (var != nullptr)
                        {
                            p = p->GetNext();
                            continue;
                        }
                        pStk->SetError(CBotErrUndefItem, p);
                        goto err;
                    }
                    pStk->SetError(CBotErrUndefClass, p);
                    goto err;
                }
            }
            break;
        }

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

        pStk->SetError(CBotErrUndefVar, p);
err:
        delete inst;
        return pStack->Return(nullptr, pStk);
    }
    return nullptr;
}
Exemple #5
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 #6
0
CBotFunction* CBotFunction::FindLocalOrPublic(long& nIdent, const char* name, CBotVar** ppVars, CBotTypResult& TypeOrError, bool bPublic)
{
    TypeOrError.SetType(TX_UNDEFCALL);      // no routine of the name
    CBotFunction*   pt;

    if ( nIdent )
    {
        if ( this != NULL ) for ( pt = this ; pt != NULL ; pt = pt->m_next )
        {
            if ( pt->m_nFuncIdent == nIdent )
            {
                TypeOrError = pt->m_retTyp;
                return pt;
            }
        }

        // search the list of public functions

        for ( pt = m_listPublic ; pt != NULL ; pt = pt->m_nextpublic )
        {
            if ( pt->m_nFuncIdent == nIdent )
            {
                TypeOrError = pt->m_retTyp;
                return pt;
            }
        }
    }

    if ( name == NULL ) return NULL;

    int     delta   = 99999;                // seeks the lowest signature
    CBotFunction*   pFunc = NULL;           // the best function found

    if ( this != NULL )
    {
        for ( pt = this ; pt != NULL ; pt = pt->m_next )
        {
            if ( pt->m_token.GetString() == name )
            {
                int i = 0;
                int alpha = 0;                          // signature of parameters
                // parameters are compatible?
                CBotDefParam* pv = pt->m_Param;         // expected list of parameters
                CBotVar* pw = ppVars[i++];              // provided list parameter
                while ( pv != NULL && pw != NULL)
                {
                    if (!TypesCompatibles(pv->GetTypResult(), pw->GetTypResult()))
                    {
                        if ( pFunc == NULL ) TypeOrError = TX_BADPARAM;
                        break;
                    }
                    int d = pv->GetType() - pw->GetType(2);
                    alpha += d>0 ? d : -10*d;       // quality loss, 10 times more expensive!

                    pv = pv->GetNext();
                    pw = ppVars[i++];
                }
                if ( pw != NULL ) 
                {
                    if ( pFunc != NULL ) continue;
                    if ( TypeOrError.Eq(TX_LOWPARAM) ) TypeOrError.SetType(TX_NUMPARAM);
                    if ( TypeOrError.Eq(TX_UNDEFCALL)) TypeOrError.SetType(TX_OVERPARAM);
                    continue;                   // too many parameters
                }
                if ( pv != NULL )
                {
                    if ( pFunc != NULL ) continue;
                    if ( TypeOrError.Eq(TX_OVERPARAM) ) TypeOrError.SetType(TX_NUMPARAM);
                    if ( TypeOrError.Eq(TX_UNDEFCALL) ) TypeOrError.SetType(TX_LOWPARAM);
                    continue;                   // not enough parameters
                }

                if (alpha == 0)                 // perfect signature
                {
                    nIdent = pt->m_nFuncIdent;
                    TypeOrError = pt->m_retTyp;
                    return pt;
                }

                if ( alpha < delta )            // a better signature?
                {
                    pFunc = pt;
                    delta = alpha;
                }
            }
        }
    }

    if ( bPublic )
    {
        for ( pt = m_listPublic ; pt != NULL ; pt = pt->m_nextpublic )
        {
            if ( pt->m_token.GetString() == name )
            {
                int i = 0;
                int alpha = 0;                          // signature of parameters
                // parameters sont-ils compatibles ?
                CBotDefParam* pv = pt->m_Param;         // list of expected parameters
                CBotVar* pw = ppVars[i++];              // list of provided parameters
                while ( pv != NULL && pw != NULL)
                {
                    if (!TypesCompatibles(pv->GetTypResult(), pw->GetTypResult()))
                    {
                        if ( pFunc == NULL ) TypeOrError = TX_BADPARAM;
                        break;
                    }
                    int d = pv->GetType() - pw->GetType(2);
                    alpha += d>0 ? d : -10*d;       // quality loss, 10 times more expensive!

                    pv = pv->GetNext();
                    pw = ppVars[i++];
                }
                if ( pw != NULL ) 
                {
                    if ( pFunc != NULL ) continue;
                    if ( TypeOrError.Eq(TX_LOWPARAM) ) TypeOrError.SetType(TX_NUMPARAM);
                    if ( TypeOrError.Eq(TX_UNDEFCALL)) TypeOrError.SetType(TX_OVERPARAM);
                    continue;                   // to many parameters
                }
                if ( pv != NULL )
                {
                    if ( pFunc != NULL ) continue;
                    if ( TypeOrError.Eq(TX_OVERPARAM) ) TypeOrError.SetType(TX_NUMPARAM);
                    if ( TypeOrError.Eq(TX_UNDEFCALL) ) TypeOrError.SetType(TX_LOWPARAM);
                    continue;                   // not enough parameters
                }

                if (alpha == 0)                 // perfect signature
                {
                    nIdent = pt->m_nFuncIdent;
                    TypeOrError = pt->m_retTyp;
                    return pt;
                }

                if ( alpha < delta )            // a better signature?
                {
                    pFunc = pt;
                    delta = alpha;
                }
            }
        }
    }

    if ( pFunc != NULL )
    {
        nIdent = pFunc->m_nFuncIdent;
        TypeOrError = pFunc->m_retTyp;
        return pFunc;
    }
    return NULL;
}