예제 #1
0
파일: CBotWhile.cpp 프로젝트: BTML/colobot
CBotInstr* CBotCase::Compile(CBotToken* &p, CBotCStack* pStack)
{
    CBotCase*   inst = new CBotCase();          // creates the object
    CBotToken*  pp = p;                         // preserves at the ^ token (starting position)

    inst->SetToken(p);
    if (!IsOfType(p, ID_CASE, ID_DEFAULT)) return nullptr;     // should never happen

    if ( pp->GetType() == ID_CASE )
    {
        pp = p;
        inst->m_Value = CBotExprNum::Compile(p, pStack);
        if ( inst->m_Value == nullptr )
        {
            pStack->SetError( TX_BADNUM, pp );
            delete inst;
            return nullptr;
        }
    }
    if ( !IsOfType( p, ID_DOTS ))
    {
        pStack->SetError( TX_MISDOTS, p->GetStart() );
        delete inst;
        return nullptr;
    }

    return inst;
}
예제 #2
0
파일: script.cpp 프로젝트: Tellus/colobot
void CScript::ColorizeScript(Ui::CEdit* edit)
{
    CBotToken*  bt;
    CBotString  bs;
    const char* token;
    int         error, type, cursor1, cursor2;
    Gfx::FontHighlight color;

    edit->ClearFormat();

    bt = CBotToken::CompileTokens(edit->GetText(), error);
    while ( bt != 0 )
    {
        bs = bt->GetString();
        token = bs;
        type = bt->GetType();

        cursor1 = bt->GetStart();
        cursor2 = bt->GetEnd();
        color = Gfx::FONT_HIGHLIGHT_NONE;
        if ( type >= TokenKeyWord && type < TokenKeyWord+100 )
        {
            color = Gfx::FONT_HIGHLIGHT_TOKEN;
        }
        if ( type >= TokenKeyDeclare && type < TokenKeyDeclare+100 )
        {
            color = Gfx::FONT_HIGHLIGHT_TYPE;
        }
        if ( type >= TokenKeyVal && type < TokenKeyVal+100 )
        {
            color = Gfx::FONT_HIGHLIGHT_CONST;
        }
        if ( type == TokenTypVar )
        {
            if ( IsType(token) )
            {
                color = Gfx::FONT_HIGHLIGHT_TYPE;
            }
            else if ( IsFunction(token) )
            {
                color = Gfx::FONT_HIGHLIGHT_TOKEN;
            }
        }
        if ( type == TokenTypDef )
        {
            color =Gfx::FONT_HIGHLIGHT_CONST;
        }

        if ( cursor1 < cursor2 && color != Gfx::FONT_HIGHLIGHT_NONE )
        {
            edit->SetFormat(cursor1, cursor2, color);
        }

        bt = bt->GetNext();
    }

    CBotToken::Delete(bt);
}
예제 #3
0
bool CBotProgram::Compile(const std::string& program, std::vector<std::string>& externFunctions, void* pUser)
{
    // Cleanup the previously compiled program
    Stop();

    for (CBotClass* c : m_classes)
        c->Purge();      // purge the old definitions of classes
                         // but without destroying the object

    m_classes.clear();
    for (CBotFunction* f : m_functions) delete f;
    m_functions.clear();

    externFunctions.clear();
    m_error = CBotNoErr;

    // Step 1. Process the code into tokens
    auto tokens = CBotToken::CompileTokens(program);
    if (tokens == nullptr) return false;

    auto pStack = std::unique_ptr<CBotCStack>(new CBotCStack(nullptr));
    CBotToken* p = tokens.get()->GetNext();                 // skips the first token (separator)

    pStack->SetProgram(this);                               // defined used routines
    m_externalCalls->SetUserPtr(pUser);

    // Step 2. Find all function and class definitions
    while ( pStack->IsOk() && p != nullptr && p->GetType() != 0)
    {
        if ( IsOfType(p, ID_SEP) ) continue;                // semicolons lurking

        if ( p->GetType() == ID_CLASS ||
            ( p->GetType() == ID_PUBLIC && p->GetNext()->GetType() == ID_CLASS ))
        {
            m_classes.push_back(CBotClass::Compile1(p, pStack.get()));
        }
        else
        {
            m_functions.push_back(CBotFunction::Compile1(p, pStack.get(), nullptr));
        }
    }

    // Define fields and pre-compile methods for each class in this program
    if (pStack->IsOk()) CBotClass::DefineClasses(m_classes, pStack.get());

    if ( !pStack->IsOk() )
    {
        m_error = pStack->GetError(m_errorStart, m_errorEnd);
        for (CBotFunction* f : m_functions) delete f;
        m_functions.clear();
        return false;
    }

    // Step 3. Real compilation
    std::list<CBotFunction*>::iterator next = m_functions.begin();
    p  = tokens.get()->GetNext();                             // returns to the beginning
    while ( pStack->IsOk() && p != nullptr && p->GetType() != 0 )
    {
        if ( IsOfType(p, ID_SEP) ) continue;                // semicolons lurking

        if ( p->GetType() == ID_CLASS ||
            ( p->GetType() == ID_PUBLIC && p->GetNext()->GetType() == ID_CLASS ))
        {
            CBotClass::Compile(p, pStack.get());                  // completes the definition of the class
        }
        else
        {
            CBotFunction::Compile(p, pStack.get(), *next);
            if ((*next)->IsExtern()) externFunctions.push_back((*next)->GetName()/* + next->GetParams()*/);
            if ((*next)->IsPublic()) CBotFunction::AddPublic(*next);
            (*next)->m_pProg = this;                           // keeps pointers to the module
            ++next;
        }
    }

    if ( !pStack->IsOk() )
    {
        m_error = pStack->GetError(m_errorStart, m_errorEnd);
        for (CBotFunction* f : m_functions) delete f;
        m_functions.clear();
    }

    return !m_functions.empty();
}