예제 #1
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);
}
예제 #2
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();
}
예제 #3
0
파일: script.cpp 프로젝트: Tellus/colobot
bool CScript::CheckToken()
{
    CBotToken*  bt;
    CBotToken*  allBt;
    CBotString  bs;
    const char* token;
    int         error, cursor1, cursor2, i;
    char        used[100];

    if ( !m_object->GetCheckToken() )  return true;

    m_error = 0;
    m_title[0] = 0;
    m_mainFunction[0] = 0;
    m_token[0] = 0;
    m_bCompile = false;

    for ( i=0 ; i<m_main->GetObligatoryToken() ; i++ )
    {
        used[i] = 0;  // token not used
    }

    allBt = CBotToken::CompileTokens(m_script, error);
    bt = allBt;
    while ( bt != 0 )
    {
        bs = bt->GetString();
        token = bs;

        cursor1 = bt->GetStart();
        cursor2 = bt->GetEnd();

        i = m_main->IsObligatoryToken(token);
        if ( i != -1 )
        {
            used[i] = 1;  // token used
        }

        if ( !m_main->IsProhibitedToken(token) )
        {
            m_error = ERR_PROHIBITEDTOKEN;
            m_cursor1 = cursor1;
            m_cursor2 = cursor2;
            strcpy(m_title, "<prohibited>");
            m_mainFunction[0] = 0;
            CBotToken::Delete(allBt);
            return false;
        }

        bt = bt->GetNext();
    }

    // At least once every obligatory instruction?
    for ( i=0 ; i<m_main->GetObligatoryToken() ; i++ )
    {
        if ( used[i] == 0 )  // token not used?
        {
            strcpy(m_token, m_main->GetObligatoryToken(i));
            m_error = ERR_OBLIGATORYTOKEN;
            strcpy(m_title, "<obligatory>");
            m_mainFunction[0] = 0;
            CBotToken::Delete(allBt);
            return false;
        }
    }

    CBotToken::Delete(allBt);
    return true;
}