Beispiel #1
0
bool CBotClass::CheckCall(CBotToken* &pToken, CBotDefParam* pParam)
{
    CBotString  name = pToken->GetString();

    if ( CBotCall::CheckCall(name) ) return true;

    CBotFunction*   pp = m_pMethod;
    while ( pp != NULL )
    {
        if ( pToken->GetString() == pp->GetName() )
        {
            // are their parameters exactly the same?
            if ( pp->CheckParam( pParam ) )
                return true;
        }
        pp = pp->Next();
    }

    return false;
}
Beispiel #2
0
bool CBotCStack::CheckCall(CBotToken* &pToken, CBotDefParam* pParam)
{
    CBotString    name = pToken->GetString();

    if ( CBotCall::CheckCall(name) ) return true;

    CBotFunction*    pp = m_prog->GetFunctions();
    while ( pp != NULL )
    {
        if ( pToken->GetString() == pp->GetName() )
        {
            // are parameters exactly the same?
            if ( pp->CheckParam( pParam ) )
                return true;
        }
        pp = pp->Next();
    }

    pp = CBotFunction::m_listPublic;
    while ( pp != NULL )
    {
        if ( pToken->GetString() == pp->GetName() )
        {
            // are parameters exactly the same?
            if ( pp->CheckParam( pParam ) )
                return true;
        }
        pp = pp->m_nextpublic;
    }

    return false;
}
Beispiel #3
0
void CBotDebug::DumpCompiledProgram(CBotProgram* program)
{
    std::stringstream ss;
    ss << "digraph {" << std::endl;

    CBotFunction* func = program->GetFunctions();
    std::map<long, CBotFunction*> funcIdMap;
    while (func != nullptr)
    {
        funcIdMap[func->m_nFuncIdent] = func;
        func = func->Next();
    }

    std::set<CBotInstr*> finished;
    std::map<void*, int> instructions;
    int instructionsNextId = 0;
    auto GetPointerAsString = [&instructions, &instructionsNextId](void* ptr) -> std::string
    {
        if(instructions.count(ptr) == 0)
        {
            instructions[ptr] = instructionsNextId++;
        }

        char buffer[20];
        sprintf(buffer, "instr%d", instructions[ptr]);
        return std::string(buffer);
    };
    std::function<void(CBotInstr*)> DumpInstr = [&](CBotInstr* instr)
    {
        if (finished.find(instr) != finished.end()) return;
        finished.insert(instr);

        std::string label = "<b>"+instr->GetDebugName()+"</b>\n";
        std::string data = instr->GetDebugData();
        boost::algorithm::replace_all(data, "&", "&amp;");
        boost::algorithm::replace_all(data, "<", "&lt;");
        boost::algorithm::replace_all(data, ">", "&gt;");
        label += data;
        boost::algorithm::replace_all(label, "\n", "<br/>");

        std::string additional = "";
        if (instr->GetDebugName() == "CBotFunction")
        {
            label = instr->GetDebugData(); // hide the title
            CBotFunction* function = static_cast<CBotFunction*>(instr);
            if (function == program->m_entryPoint) additional += " shape=box3d";
            else additional += " shape=box";
            if (function->IsExtern()) additional += " color=cyan";
            else additional += " color=blue";
            additional += " group=func";
        }

        ss << GetPointerAsString(instr) << " [label=<" << label << ">" << additional << "]" << std::endl;

        if (instr->GetDebugName() == "CBotInstrCall")
        {
            CBotInstrCall* call = static_cast<CBotInstrCall*>(instr);
            if (funcIdMap.count(call->m_nFuncIdent) > 0)
            {
                ss << GetPointerAsString(instr) << " -> " << GetPointerAsString(funcIdMap[call->m_nFuncIdent]) << " [style=dotted color=gray weight=15]" << std::endl;
            }
        }

        for (const auto& it : instr->GetDebugLinks())
        {
            if (it.second == nullptr) continue;
            if (it.second->GetDebugName() == "CBotFunction") continue;
            DumpInstr(it.second);
            ss << GetPointerAsString(instr) << " -> " << GetPointerAsString(it.second) << " [label=\"" << it.first << "\"" << (it.first == "m_next" ? " weight=1" : " weight=5") << "]" << std::endl;
            if (it.first == "m_next" || (instr->GetDebugName() == "CBotFunction" && it.first == "m_block") || (instr->GetDebugName() == "CBotListInstr" && it.first == "m_instr"))
            {
                ss << "{ rank=same; " << GetPointerAsString(instr) << "; " << GetPointerAsString(it.second) << "; }" << std::endl;
            }
        }
    };

    if (program->m_entryPoint != nullptr)
    {
        DumpInstr(program->m_entryPoint);
    }
    func = program->GetFunctions();
    std::string prev = GetPointerAsString(program->m_entryPoint);
    while (func != nullptr)
    {
        if (func != program->m_entryPoint)
        {
            DumpInstr(func);

            //ss << prev << " -> " << GetPointerAsString(func) << " [style=invis]" << std::endl;
            prev = GetPointerAsString(func);
        }

        func = func->Next();
    }

    ss << "}" << std::endl;
    std::cout << ss.str() << std::endl;

    /* // Terrible platform-dependent code :P
    std::stringstream filename;
    filename << "compiled" << (program->m_entryPoint != nullptr ? "_"+program->m_entryPoint->GetName() : "") << ".png";

    int pipeOut[2];
    pipe(pipeOut);
    if (fork())
    {
        close(pipeOut[0]);
        write(pipeOut[1], ss.str().c_str(), ss.str().size());
        close(pipeOut[1]);
        int rv;
        wait(&rv);
        if(rv != 0) exit(rv);
    }
    else
    {
        dup2(pipeOut[0], 0);
        close(pipeOut[1]);
        execl("/usr/bin/dot", "dot", "-Tpng", "-o", filename.str().c_str(), nullptr);
        exit(1); // failed to start
    } */
}
Beispiel #4
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();
}