Пример #1
0
CBotInstr* CompileParams(CBotToken* &p, CBotCStack* pStack, CBotVar** ppVars)
{
    bool        first = true;
    CBotInstr*    ret = nullptr;   // to return to the list

    CBotCStack*    pile = pStack;
    int            i = 0;

    if (IsOfType(p, ID_OPENPAR))
    {
        int    start, end;
        if (!IsOfType(p, ID_CLOSEPAR)) while (true)
        {
            start = p->GetStart();
            pile = pile->TokenStack();  // keeps the result on the stack

            if (first) pStack->SetStartError(start);
            first = false;

            CBotInstr*    param = CBotExpression::Compile(p, pile);
            end      = p->GetStart();

            if (!pile->IsOk())
            {
                return pStack->Return(nullptr, pile);
            }

            if (ret == nullptr) ret = param;
            else ret->AddNext(param);   // construct the list

            if (param != nullptr)
            {
                if (pile->GetTypResult().Eq(99))
                {
                    delete pStack->TokenStack();
                    pStack->SetError(CBotErrVoid, p->GetStart());
                    return nullptr;
                }
                ppVars[i] = pile->GetVar();
                ppVars[i]->GetToken()->SetPos(start, end);
                i++;

                if (IsOfType(p, ID_COMMA)) continue;    // skips the comma
                if (IsOfType(p, ID_CLOSEPAR)) break;
            }

            pStack->SetError(CBotErrClosePar, p->GetStart());
            delete pStack->TokenStack();
            return nullptr;
        }
    }
    ppVars[i] = nullptr;
    return    ret;
}
Пример #2
0
CBotInstr* CBotInstrCall::Compile(CBotToken* &p, CBotCStack* pStack)
{
    CBotVar*    ppVars[1000];

    int         i = 0;

    CBotToken*  pp = p; 
    p = p->GetNext();

    pStack->SetStartError(p->GetStart());
    CBotCStack* pile = pStack;

    if ( IsOfType(p, ID_OPENPAR) )
    {
        int start, end;
        CBotInstrCall* inst = new CBotInstrCall();
        inst->SetToken(pp);

        // compile la list of parameters
        if (!IsOfType(p, ID_CLOSEPAR)) while (true)
        {
            start = p->GetStart();
            pile = pile->TokenStack();                      // keeps the results on the stack

            CBotInstr*  param = CBotExpression::Compile(p, pile);
            end   = p->GetStart();
            if ( inst->m_Parameters == NULL ) inst->m_Parameters = param;
            else inst->m_Parameters->AddNext(param);            // constructs the list

            if ( !pile->IsOk() )
            {
                delete inst;
                return pStack->Return(NULL, pile);
            }

            if ( param != NULL )
            {
                if ( pile->GetTypResult().Eq(99) )
                {
                    delete pStack->TokenStack();
                    pStack->SetError(TX_VOID, p->GetStart());
                    delete inst;
                    return NULL;
                }
                ppVars[i] = pile->GetVar();
                ppVars[i]->GetToken()->SetPos(start, end);
                i++;

                if (IsOfType(p, ID_COMMA)) continue;            // skips the comma
                if (IsOfType(p, ID_CLOSEPAR)) break;
            }

            pStack->SetError(TX_CLOSEPAR, p->GetStart());
            delete pStack->TokenStack();
            delete inst;
            return NULL;
        }
        ppVars[i] = NULL;

        // the routine is known?
//      CBotClass*  pClass = NULL;
        inst->m_typRes = pStack->CompileCall(pp, ppVars, inst->m_nFuncIdent);
        if ( inst->m_typRes.GetType() >= 20 )
        {
//          if (pVar2!=NULL) pp = pVar2->RetToken();
            pStack->SetError( inst->m_typRes.GetType(), pp );
            delete pStack->TokenStack();
            delete inst;
            return NULL;
        }

        delete pStack->TokenStack();
        if ( inst->m_typRes.GetType() > 0 )
        {
            CBotVar* pRes = CBotVar::Create("", inst->m_typRes);
            pStack->SetVar(pRes);   // for knowing the type of the result
        }
        else pStack->SetVar(NULL);          // routine returns void

        return inst;
    }
    p = pp;
    delete pStack->TokenStack();
    return NULL;
}