CBotInstr* CBotIf::Compile(CBotToken* &p, CBotCStack* pStack) { CBotToken* pp = p; // preserves at the ^ token (starting instruction) if (!IsOfType(p, ID_IF)) return nullptr; // should never happen CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp CBotIf* inst = new CBotIf(); // create the object inst->SetToken( pp ); if ( nullptr != (inst->m_condition = CBotCondition::Compile(p, pStk )) ) { // the condition does exist inst->m_block = CBotBlock::CompileBlkOrInst(p, pStk, true ); if ( pStk->IsOk() ) { // the statement block is ok (can be empty) // see if the next instruction is the token "else" if (IsOfType(p, ID_ELSE)) { // if so, compiles the following statement block inst->m_blockElse = CBotBlock::CompileBlkOrInst(p, pStk, true ); if (!pStk->IsOk()) { // there is no correct block after the else // frees the object, and transmits the error that is on the stack delete inst; return pStack->Return(nullptr, pStk); } } // return the corrent object to the application return pStack->Return(inst, pStk); } } // error, frees the object delete inst; // and transmits the error that is on the stack. return pStack->Return(nullptr, pStk); }
CBotInstr* CBotIf::Compile(CBotToken* &p, CBotCStack* pStack) { CBotToken* pp = p; // conserve le ^au token (début instruction) if (!IsOfType(p, ID_IF)) return NULL; // ne doit jamais arriver CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp CBotIf* inst = new CBotIf(); // crée l'object inst->SetToken( pp ); if ( NULL != (inst->m_Condition = CBotCondition::Compile( p, pStk )) ) { // la condition existe bel et bien inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, TRUE ); if ( pStk->IsOk() ) { // le bloc d'instruction est ok (peut être vide) // regarde si l'instruction suivante est le token "else" if (IsOfType(p, ID_ELSE)) { // si oui, compile le bloc d'instruction qui suit inst->m_BlockElse = CBotBlock::CompileBlkOrInst( p, pStk, TRUE ); if (!pStk->IsOk()) { // il n'y a pas de bloc correct après le else // libère l'objet, et transmet l'erreur qui est sur la pile delete inst; return pStack->Return(NULL, pStk); } } // rend l'object correct à qui le demande. return pStack->Return(inst, pStk); } } // erreur, libère l'objet delete inst; // et transmet l'erreur qui se trouve sur la pile. return pStack->Return(NULL, pStk); }