CBotInstr* CBotFor::Compile(CBotToken* &p, CBotCStack* pStack) { CBotFor* inst = new CBotFor(); // creates the object CBotToken* pp = p; // preserves at the ^ token (starting position) if ( IsOfType( p, TokenTypVar ) && IsOfType( p, ID_DOTS ) ) { inst->m_label = pp->GetString(); // register the name of label } inst->SetToken(p); if (!IsOfType(p, ID_FOR)) return nullptr; // should never happen if ( !IsOfType(p, ID_OPENPAR)) // missing parenthesis ? { pStack->SetError(TX_OPENPAR, p->GetStart()); return nullptr; } CBotCStack* pStk = pStack->TokenStack(pp, true); // un petit bout de pile svp // compiles instructions for initialization inst->m_Init = CBotListExpression::Compile( p, pStk ); if ( pStk->IsOk() ) { if ( !IsOfType(p, ID_SEP)) // lack the semicolon? { pStack->SetError(TX_OPENPAR, p->GetStart()); delete inst; return pStack->Return(nullptr, pStk); // no object, the error is on the stack } inst->m_Test = CBotBoolExpr::Compile( p, pStk ); if ( pStk->IsOk() ) { if ( !IsOfType(p, ID_SEP)) // lack the semicolon? { pStack->SetError(TX_OPENPAR, p->GetStart()); delete inst; return pStack->Return(nullptr, pStk); // no object, the error is on the stack } inst->m_Incr = CBotListExpression::Compile( p, pStk ); if ( pStk->IsOk() ) { if ( IsOfType(p, ID_CLOSEPAR)) // missing parenthesis ? { IncLvl(inst->m_label); inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true ); DecLvl(); if ( pStk->IsOk() ) return pStack->Return(inst, pStk);; } pStack->SetError(TX_CLOSEPAR, p->GetStart()); } } } delete inst; // error, frees up return pStack->Return(nullptr, pStk); // no object, the error is on the stack }
CBotInstr* CBotDo::Compile(CBotToken* &p, CBotCStack* pStack) { CBotDo* inst = new CBotDo(); // creates the object CBotToken* pp = p; // preserves at the ^ token (starting position) if ( IsOfType( p, TokenTypVar ) && IsOfType( p, ID_DOTS ) ) { inst->m_label = pp->GetString(); // register the name of label } inst->SetToken(p); if (!IsOfType(p, ID_DO)) return nullptr; // should never happen CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp // looking for a statement block after the do IncLvl(inst->m_label); inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true ); DecLvl(); if ( pStk->IsOk() ) { if (IsOfType(p, ID_WHILE)) { if ( nullptr != (inst->m_Condition = CBotCondition::Compile( p, pStk )) ) { // the condition exists if (IsOfType(p, ID_SEP)) { return pStack->Return(inst, pStk); // return an object to the application } pStk->SetError(TX_ENDOF, p->GetStart()); } } pStk->SetError(TX_WHILE, p->GetStart()); } delete inst; // error, frees up return pStack->Return(nullptr, pStk); // no object, the error is on the stack }
CBotInstr* CBotWhile::Compile(CBotToken* &p, CBotCStack* pStack) { CBotWhile* inst = new CBotWhile(); // creates the object CBotToken* pp = p; // preserves at the ^ token (starting position) if ( IsOfType( p, TokenTypVar ) && IsOfType( p, ID_DOTS ) ) { inst->m_label = pp->GetString(); // records the name of the label } inst->SetToken(p); if (!IsOfType(p, ID_WHILE)) return nullptr; // should never happen CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp // a bit of battery please (??) if ( nullptr != (inst->m_condition = CBotCondition::Compile(p, pStk )) ) { // the condition exists IncLvl(inst->m_label); inst->m_block = CBotBlock::CompileBlkOrInst(p, pStk, true ); DecLvl(); if ( pStk->IsOk() ) { // the statement block is ok (it may be empty! return pStack->Return(inst, pStk); // return an object to the application // makes the object to which the application } } delete inst; // error, frees the place return pStack->Return(nullptr, pStk); // no object, the error is on the stack }
CBotInstr* CBotSwitch::Compile(CBotToken* &p, CBotCStack* pStack) { CBotSwitch* inst = new CBotSwitch(); // creates the object CBotToken* pp = p; // preserves at the ^ token (starting position) inst->SetToken(p); if (!IsOfType(p, ID_SWITCH)) return nullptr; // should never happen CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp if ( IsOfType(p, ID_OPENPAR ) ) { if ( nullptr != (inst->m_Value = CBotExpression::Compile( p, pStk )) ) { if ( pStk->GetType() < CBotTypLong ) { if ( IsOfType(p, ID_CLOSEPAR ) ) { if ( IsOfType(p, ID_OPBLK ) ) { IncLvl(); while( !IsOfType( p, ID_CLBLK ) ) { if ( p->GetType() == ID_CASE || p->GetType() == ID_DEFAULT) { CBotCStack* pStk2 = pStk->TokenStack(p); // un petit bout de pile svp CBotInstr* i = CBotCase::Compile( p, pStk2 ); if (i == nullptr) { delete inst; return pStack->Return(nullptr, pStk2); } delete pStk2; if ( inst->m_Block == nullptr ) inst->m_Block = i; else inst->m_Block->AddNext(i); continue; } if ( inst->m_Block == nullptr ) { pStk->SetError(TX_NOCASE, p->GetStart()); delete inst; return pStack->Return(nullptr, pStk); } CBotInstr* i = CBotBlock::CompileBlkOrInst( p, pStk, true ); if ( !pStk->IsOk() ) { delete inst; return pStack->Return(nullptr, pStk); } inst->m_Block->AddNext(i); if ( p == nullptr ) { pStk->SetError(TX_CLOSEBLK, -1); delete inst; return pStack->Return(nullptr, pStk); } } DecLvl(); if ( inst->m_Block == nullptr ) { pStk->SetError(TX_NOCASE, p->GetStart()); delete inst; return pStack->Return(nullptr, pStk); } // the statement block is ok return pStack->Return(inst, pStk); // return an object to the application } pStk->SetError( TX_OPENBLK, p->GetStart() ); } pStk->SetError( TX_CLOSEPAR, p->GetStart() ); } pStk->SetError( TX_BADTYPE, p->GetStart() ); } } pStk->SetError( TX_OPENPAR, p->GetStart()); delete inst; // error, frees up return pStack->Return(nullptr, pStk); // no object, the error is on the stack }