예제 #1
0
파일: CBotStack.cpp 프로젝트: PaweX/colobot
void CBotStack::GetRunPos(const char* &FunctionName, int &start, int &end)
{
    CBotProgram*    prog = m_prog;                        // Current program

    CBotInstr*        funct = NULL;                        // function found
    CBotInstr*        instr = NULL;                        // the highest intruction

    CBotStack*        p = this;

    while (p->m_next != NULL)
    {
        if ( p->m_instr != NULL ) instr = p->m_instr;
        if ( p->m_bFunc == 1 ) funct = p->m_instr;
        if ( p->m_next->m_prog != prog ) break ; 

        if (p->m_next2 && p->m_next2->m_state != 0) p = p->m_next2 ;
        else                                        p = p->m_next;
    }

    if ( p->m_instr != NULL ) instr = p->m_instr;
    if ( p->m_bFunc == 1 ) funct = p->m_instr;

    if ( funct == NULL ) return;

    CBotToken* t = funct->GetToken();
    FunctionName = t->GetString();

//    if ( p->m_instr != NULL ) instr = p->m_instr;

    t = instr->GetToken();
    start = t->GetStart();
    end      = t->GetEnd();
}
예제 #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
CBotInstr* CBotClassInst::Compile(CBotToken* &p, CBotCStack* pStack, CBotClass* pClass)
{
    // seeks the corresponding classes
    if ( pClass == NULL )
    {
        pStack->SetStartError(p->GetStart());
        pClass = CBotClass::Find(p);
        if ( pClass == NULL )
        {
            // not found? is bizare
            pStack->SetError(TX_NOCLASS, p);
            return NULL;
        }
        p = p->GetNext();
    }

    bool        bIntrinsic = pClass->IsIntrinsic();
    CBotTypResult type = CBotTypResult( bIntrinsic ? CBotTypIntrinsic : CBotTypPointer, pClass );
    CBotClassInst*  inst = static_cast<CBotClassInst*>(CompileArray(p, pStack, type));
    if ( inst != NULL || !pStack->IsOk() ) return inst;

    CBotCStack* pStk = pStack->TokenStack();

    inst = new CBotClassInst();
    /// \TODO Need to be revised and fixed after adding unit tests
    CBotToken token(pClass->GetName(), CBotString(), p->GetStart(), p->GetEnd());
    inst->SetToken(&token);
    CBotToken*  vartoken = p;

    if ( NULL != (inst->m_var = CBotLeftExprVar::Compile( p, pStk )) )
    {
        (static_cast<CBotLeftExprVar*>(inst->m_var))->m_typevar = type;
        if (pStk->CheckVarLocal(vartoken))                  // redefinition of the variable
        {
            pStk->SetStartError(vartoken->GetStart());
            pStk->SetError(TX_REDEFVAR, vartoken->GetEnd());
            goto error;
        }

        if (IsOfType(p,  ID_OPBRK))                         // with any clues?
        {
            delete inst;                                    // is not type CBotInt
            p = vartoken;                                   // returns to the variable name

            // compiles declaration an array

            inst = static_cast<CBotClassInst*>(CBotInstArray::Compile( p, pStk, type ));

            if (!pStk->IsOk() )
            {
                pStk->SetError(TX_CLBRK, p->GetStart());
                goto error;
            }
            goto suite;         // no assignment, variable already created
        }


        CBotVar*    var;
        var = CBotVar::Create(vartoken->GetString(), type); // creates the instance
//      var->SetClass(pClass);
        var->SetUniqNum(
            (static_cast<CBotLeftExprVar*>(inst->m_var))->m_nIdent = CBotVar::NextUniqNum());
                                                            // its attribute a unique number
        pStack->AddVar(var);                                // placed on the stack

        // look if there are parameters
        inst->m_hasParams = (p->GetType() == ID_OPENPAR);

        CBotVar*    ppVars[1000];
        inst->m_Parameters = CompileParams(p, pStk, ppVars);
        if ( !pStk->IsOk() ) goto error;

        // if there are parameters, is the equivalent to the stament "new"
        // CPoint A ( 0, 0 ) is equivalent to
        // CPoint A = new CPoint( 0, 0 )

//      if ( NULL != inst->m_Parameters )
        if ( inst->m_hasParams )
        {
            // the constructor is there?
//          CBotString  noname;
            CBotTypResult r = pClass->CompileMethode(pClass->GetName(), var, ppVars, pStk, inst->m_nMethodeIdent);
            delete pStk->TokenStack();                          // releases the supplement stack
            int typ = r.GetType();

            if (typ == TX_UNDEFCALL)
            {
                // si le constructeur n'existe pas
                if (inst->m_Parameters != NULL)                 // with parameters
                {
                    pStk->SetError(TX_NOCONST, vartoken);
                    goto error;
                }
                typ = 0;
            }

            if (typ>20)
            {
                pStk->SetError(typ, vartoken->GetEnd());
                goto error;
            }

        }

        if (IsOfType(p,  ID_ASS))                           // with a assignment?
        {
            if (inst->m_hasParams)
            {
                pStk->SetError(TX_ENDOF, p->GetStart());
                goto error;
            }

            if ( NULL == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )) )
            {
                goto error;
            }
            CBotClass* result = pStk->GetClass();
            if ( !pStk->GetTypResult(1).Eq(CBotTypNullPointer) &&
               ( !pStk->GetTypResult(1).Eq(CBotTypPointer) ||
                 ( result != NULL && !pClass->IsChildOf(result) )))     // type compatible ?
            {
                pStk->SetError(TX_BADTYPE, p->GetStart());
                goto error;
            }
//          if ( !bIntrinsic ) var->SetPointer(pStk->GetVar()->GetPointer());
            if ( !bIntrinsic )
            {
                // does not use the result on the stack, to impose the class
                CBotVar* pvar = CBotVar::Create("", pClass);
                var->SetPointer( pvar );                    // variable already declared instance pointer
                delete pvar;                                // removes the second pointer
            }
            var->SetInit(true);                         // marks the pointer as init
        }
        else if (inst->m_hasParams)
        {
            // creates the object on the "job" (\TODO "tas")
            // with a pointer to the object
            if ( !bIntrinsic )
            {
                CBotVar* pvar = CBotVar::Create("", pClass);
                var->SetPointer( pvar );                    // variable already declared instance pointer
                delete pvar;                                // removes the second pointer
            }
            var->SetInit(2);                            // marks the pointer as init
        }
suite:
        if (IsOfType(p,  ID_COMMA))                         // several chained definitions
        {
            if ( NULL != ( inst->m_next = CBotClassInst::Compile(p, pStk, pClass) ))    // compiles the following
            {
                return pStack->Return(inst, pStk);
            }
        }

        if (IsOfType(p,  ID_SEP))                           // complete instruction
        {
            return pStack->Return(inst, pStk);
        }

        pStk->SetError(TX_ENDOF, p->GetStart());
    }

error:
    delete inst;
    return pStack->Return(NULL, pStk);
}
예제 #4
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;
}