diff --git a/src/CBot/CBot.h b/src/CBot/CBot.h index 901edad8..baebe04c 100644 --- a/src/CBot/CBot.h +++ b/src/CBot/CBot.h @@ -497,25 +497,6 @@ public: void RestoreState(CBotStack* &pj, bool bMain) override; }; -class CBotCatch : public CBotInstr -{ -private: - CBotInstr* m_Block; // instructions - CBotInstr* m_Cond; //condition - CBotCatch* m_next; //following catch - friend class CBotTry; - -public: - CBotCatch(); - ~CBotCatch(); - static - CBotCatch* Compile(CBotToken* &p, CBotCStack* pStack); - bool TestCatch(CBotStack* &pj, int val); - bool Execute(CBotStack* &pj) override; - void RestoreState(CBotStack* &pj, bool bMain) override; - void RestoreCondState(CBotStack* &pj, bool bMain); -}; - class CBotThrow : public CBotInstr { private: diff --git a/src/CBot/CBotInstr/CBotCatch.cpp b/src/CBot/CBotInstr/CBotCatch.cpp new file mode 100644 index 00000000..4c63e029 --- /dev/null +++ b/src/CBot/CBotInstr/CBotCatch.cpp @@ -0,0 +1,107 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +// Modules inlcude +#include "CBotCatch.h" + +// Local include + +// Global include + +//////////////////////////////////////////////////////////////////////////////// +CBotCatch::CBotCatch() +{ + m_Cond = + m_Block = nullptr; // nullptr so that delete is not possible further + m_next = nullptr; + + name = "CBotCatch"; // debug +} + +//////////////////////////////////////////////////////////////////////////////// +CBotCatch::~CBotCatch() +{ + delete m_Cond; // frees the list + delete m_Block; // frees the instruction block + delete m_next; // and subsequent +} + +//////////////////////////////////////////////////////////////////////////////// +CBotCatch* CBotCatch::Compile(CBotToken* &p, CBotCStack* pStack) +{ + CBotCatch* inst = new CBotCatch(); // creates the object + pStack->SetStartError(p->GetStart()); + + inst->SetToken(p); + if (!IsOfType(p, ID_CATCH)) return nullptr; // should never happen + + if (IsOfType(p, ID_OPENPAR)) + { + inst->m_Cond = CBotExpression::Compile(p, pStack); + if (( pStack->GetType() < CBotTypLong || + pStack->GetTypResult().Eq(CBotTypBoolean) )&& pStack->IsOk() ) + { + if (IsOfType(p, ID_CLOSEPAR)) + { + inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStack ); + if ( pStack->IsOk() ) + return inst; // return an object to the application + } + pStack->SetError(TX_CLOSEPAR, p->GetStart()); + } + pStack->SetError(TX_BADTYPE, p->GetStart()); + } + pStack->SetError(TX_OPENPAR, p->GetStart()); + delete inst; // error, frees up + return nullptr; // no object, the error is on the stack +} + +//////////////////////////////////////////////////////////////////////////////// +bool CBotCatch :: Execute(CBotStack* &pj) +{ + if ( m_Block == nullptr ) return true; + return m_Block->Execute(pj); // executes the associated block +} + +//////////////////////////////////////////////////////////////////////////////// +void CBotCatch :: RestoreState(CBotStack* &pj, bool bMain) +{ + if ( bMain && m_Block != nullptr ) m_Block->RestoreState(pj, bMain); +} + +//////////////////////////////////////////////////////////////////////////////// +void CBotCatch :: RestoreCondState(CBotStack* &pj, bool bMain) +{ + m_Cond->RestoreState(pj, bMain); +} + +//////////////////////////////////////////////////////////////////////////////// +bool CBotCatch :: TestCatch(CBotStack* &pile, int val) +{ + if ( !m_Cond->Execute(pile) ) return false; + + if ( val > 0 || pile->GetType() != CBotTypBoolean ) + { + CBotVar* var = CBotVar::Create(static_cast(nullptr), CBotTypBoolean); + var->SetValInt( pile->GetVal() == val ); + pile->SetVar(var); // calls on the stack + } + + return true; +} diff --git a/src/CBot/CBotInstr/CBotCatch.h b/src/CBot/CBotInstr/CBotCatch.h new file mode 100644 index 00000000..9756c8b8 --- /dev/null +++ b/src/CBot/CBotInstr/CBotCatch.h @@ -0,0 +1,93 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#pragma once + +// Modules inlcude +#include "CBot.h" + +// Local include + +// Global include + +/*! + * \brief The CBotCatch class. Compiles instruction "catch". + */ +class CBotCatch : public CBotInstr +{ +public: + + /*! + * \brief CBotCatch + */ + CBotCatch(); + + /*! + * \brief CBotCatch + */ + ~CBotCatch(); + + /*! + * \brief Compile + * \param p + * \param pStack + * \return + */ + static CBotCatch* Compile(CBotToken* &p, CBotCStack* pStack); + + /*! + * \brief TestCatch Routine to see if the catch is to do or not. + * \param pj + * \param val + * \return + */ + bool TestCatch(CBotStack* &pj, int val); + + /*! + * \brief Execute Execution of "catch". + * \param pj + * \return + */ + bool Execute(CBotStack* &pj) override; + + /*! + * \brief RestoreState + * \param pj + * \param bMain + */ + void RestoreState(CBotStack* &pj, bool bMain) override; + + /*! + * \brief RestoreCondState + * \param pj + * \param bMain + */ + void RestoreCondState(CBotStack* &pj, bool bMain); + + +private: + //! Instructions + CBotInstr* m_Block; + //! Condition + CBotInstr* m_Cond; + //! Following catch + CBotCatch* m_next; + + friend class CBotTry; +}; diff --git a/src/CBot/CBotInstr/CBotTry.h b/src/CBot/CBotInstr/CBotTry.h index f12de20f..0a8d2b9a 100644 --- a/src/CBot/CBotInstr/CBotTry.h +++ b/src/CBot/CBotInstr/CBotTry.h @@ -19,6 +19,7 @@ // Modules inlcude #include "CBot.h" +#include "CBotCatch.h" // Local include diff --git a/src/CBot/CBotWhile.cpp b/src/CBot/CBotWhile.cpp index c3084be3..89647e2a 100644 --- a/src/CBot/CBotWhile.cpp +++ b/src/CBot/CBotWhile.cpp @@ -157,90 +157,6 @@ void CBotWhile :: RestoreState(CBotStack* &pj, bool bMain) } } -/////////////////////////////////////////////////////////////////////////// -// compiles instruction "catch" - -CBotCatch::CBotCatch() -{ - m_Cond = - m_Block = nullptr; // nullptr so that delete is not possible further - m_next = nullptr; - - name = "CBotCatch"; // debug -} - -CBotCatch::~CBotCatch() -{ - delete m_Cond; // frees the list - delete m_Block; // frees the instruction block - delete m_next; // and subsequent -} - -CBotCatch* CBotCatch::Compile(CBotToken* &p, CBotCStack* pStack) -{ - CBotCatch* inst = new CBotCatch(); // creates the object - pStack->SetStartError(p->GetStart()); - - inst->SetToken(p); - if (!IsOfType(p, ID_CATCH)) return nullptr; // should never happen - - if (IsOfType(p, ID_OPENPAR)) - { - inst->m_Cond = CBotExpression::Compile(p, pStack); - if (( pStack->GetType() < CBotTypLong || - pStack->GetTypResult().Eq(CBotTypBoolean) )&& pStack->IsOk() ) - { - if (IsOfType(p, ID_CLOSEPAR)) - { - inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStack ); - if ( pStack->IsOk() ) - return inst; // return an object to the application - } - pStack->SetError(TX_CLOSEPAR, p->GetStart()); - } - pStack->SetError(TX_BADTYPE, p->GetStart()); - } - pStack->SetError(TX_OPENPAR, p->GetStart()); - delete inst; // error, frees up - return nullptr; // no object, the error is on the stack -} - -// execution of "catch" - -bool CBotCatch :: Execute(CBotStack* &pj) -{ - if ( m_Block == nullptr ) return true; - return m_Block->Execute(pj); // executes the associated block -} - -void CBotCatch :: RestoreState(CBotStack* &pj, bool bMain) -{ - if ( bMain && m_Block != nullptr ) m_Block->RestoreState(pj, bMain); -} - -void CBotCatch :: RestoreCondState(CBotStack* &pj, bool bMain) -{ - m_Cond->RestoreState(pj, bMain); -} - -// routine to see if the catch is to do or not - -bool CBotCatch :: TestCatch(CBotStack* &pile, int val) -{ - if ( !m_Cond->Execute(pile) ) return false; - - if ( val > 0 || pile->GetType() != CBotTypBoolean ) - { - CBotVar* var = CBotVar::Create(static_cast(nullptr), CBotTypBoolean); - var->SetValInt( pile->GetVal() == val ); - pile->SetVar(var); // calls on the stack - } - - return true; -} - -/////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////// // compiles instruction "throw" diff --git a/src/CBot/CMakeLists.txt b/src/CBot/CMakeLists.txt index 3d1244d6..cd17d7ba 100644 --- a/src/CBot/CMakeLists.txt +++ b/src/CBot/CMakeLists.txt @@ -17,6 +17,7 @@ set(SOURCES CBotInstr/CBotCase.cpp CBotInstr/CBotBreak.cpp CBotInstr/CBotTry.cpp + CBotInstr/CBotCatch.cpp ) # Includes