Moving CBotExpression class in its own header and source files.
parent
d44df45d26
commit
3c1296b4b9
|
@ -58,6 +58,7 @@
|
|||
#include "CBotInstr/CBotExprUnaire.h"
|
||||
#include "CBotInstr/CBotBoolExpr.h"
|
||||
#include "CBotInstr/CBotTwoOpExpr.h"
|
||||
#include "CBotInstr/CBotExpression.h"
|
||||
|
||||
// Local include
|
||||
|
||||
|
@ -1345,276 +1346,6 @@ void CBotIString::RestoreState(CBotStack* &pj, bool bMain)
|
|||
m_next2b->RestoreState(pile, bMain);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// compiles a statement such as " x = 123 " ou " z * 5 + 4 "
|
||||
// with or without assignment
|
||||
|
||||
CBotExpression::CBotExpression()
|
||||
{
|
||||
m_leftop = nullptr;
|
||||
m_rightop = nullptr;
|
||||
name = "CBotExpression";
|
||||
}
|
||||
|
||||
CBotExpression::~CBotExpression()
|
||||
{
|
||||
delete m_leftop;
|
||||
delete m_rightop;
|
||||
}
|
||||
|
||||
CBotInstr* CBotExpression::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotToken* pp = p;
|
||||
|
||||
CBotExpression* inst = new CBotExpression();
|
||||
|
||||
inst->m_leftop = CBotLeftExpr::Compile(p, pStack);
|
||||
|
||||
inst->SetToken(p);
|
||||
int OpType = p->GetType();
|
||||
|
||||
if ( pStack->IsOk() &&
|
||||
IsOfTypeList(p, ID_ASS, ID_ASSADD, ID_ASSSUB, ID_ASSMUL, ID_ASSDIV, ID_ASSMODULO,
|
||||
ID_ASSAND, ID_ASSXOR, ID_ASSOR,
|
||||
ID_ASSSL , ID_ASSSR, ID_ASSASR, 0 ))
|
||||
{
|
||||
if (inst->m_leftop == nullptr)
|
||||
{
|
||||
pStack->SetError(TX_BADLEFT, p->GetEnd());
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inst->m_rightop = CBotExpression::Compile(p, pStack);
|
||||
if (inst->m_rightop == nullptr)
|
||||
{
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CBotTypResult type1 = pStack->GetTypResult();
|
||||
|
||||
// get the variable assigned to mark
|
||||
CBotVar* var = nullptr;
|
||||
inst->m_leftop->ExecuteVar(var, pStack);
|
||||
if (var == nullptr)
|
||||
{
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (OpType != ID_ASS && !var->IsDefined())
|
||||
{
|
||||
pStack->SetError(TX_NOTINIT, pp);
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CBotTypResult type2 = var->GetTypResult();
|
||||
|
||||
// what types are acceptable?
|
||||
switch (OpType)
|
||||
{
|
||||
case ID_ASS:
|
||||
// if (type2 == CBotTypClass) type2 = -1;
|
||||
if ((type1.Eq(CBotTypPointer) && type2.Eq(CBotTypPointer)) ||
|
||||
(type1.Eq(CBotTypClass) && type2.Eq(CBotTypClass) ) )
|
||||
{
|
||||
/* CBotClass* c1 = type1.GetClass();
|
||||
CBotClass* c2 = type2.GetClass();
|
||||
if (!c1->IsChildOf(c2)) type2.SetType(-1);
|
||||
//- if (!type1.Eq(CBotTypClass)) var->SetPointer(pStack->GetVar()->GetPointer());*/
|
||||
var->SetInit(CBotVar::InitType::IS_POINTER);
|
||||
}
|
||||
else
|
||||
var->SetInit(CBotVar::InitType::DEF);
|
||||
|
||||
break;
|
||||
case ID_ASSADD:
|
||||
if (type2.Eq(CBotTypBoolean) ||
|
||||
type2.Eq(CBotTypPointer) ) type2 = -1; // numbers and strings
|
||||
break;
|
||||
case ID_ASSSUB:
|
||||
case ID_ASSMUL:
|
||||
case ID_ASSDIV:
|
||||
case ID_ASSMODULO:
|
||||
if (type2.GetType() >= CBotTypBoolean) type2 = -1; // numbers only
|
||||
break;
|
||||
}
|
||||
|
||||
if (!TypeCompatible(type1, type2, OpType))
|
||||
{
|
||||
pStack->SetError(TX_BADTYPE, &inst->m_token);
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return inst; // compatible type?
|
||||
}
|
||||
|
||||
delete inst;
|
||||
int start, end, error = pStack->GetError(start, end);
|
||||
|
||||
p = pp; // returns to the top
|
||||
pStack->SetError(0,0); // forget the error
|
||||
|
||||
CBotInstr* i = CBotTwoOpExpr::Compile(p, pStack); // tries without assignment
|
||||
if (i != nullptr && error == TX_PRIVATE && p->GetType() == ID_ASS)
|
||||
pStack->ResetError(error, start, end);
|
||||
return i;
|
||||
}
|
||||
|
||||
// executes an expression with assignment
|
||||
|
||||
bool CBotExpression::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
|
||||
// CBotToken* pToken = m_leftop->GetToken();
|
||||
|
||||
CBotVar* pVar = nullptr;
|
||||
|
||||
CBotStack* pile1 = pile;
|
||||
|
||||
CBotVar::InitType initKind = CBotVar::InitType::DEF;
|
||||
CBotVar* result = nullptr;
|
||||
|
||||
// must be done before any indexes (stack can be changed)
|
||||
if (!m_leftop->ExecuteVar(pVar, pile, nullptr, false)) return false; // variable before accessing the value on the right
|
||||
|
||||
if ( pile1->GetState()==0)
|
||||
{
|
||||
pile1->SetCopyVar(pVar); // keeps the copy on the stack (if interrupted)
|
||||
pile1->IncState();
|
||||
}
|
||||
|
||||
CBotStack* pile2 = pile->AddStack();
|
||||
|
||||
if ( pile2->GetState()==0)
|
||||
{
|
||||
if (m_rightop && !m_rightop->Execute(pile2)) return false; // initial value // interrupted?
|
||||
pile2->IncState();
|
||||
}
|
||||
|
||||
if (pile1->GetState() == 1)
|
||||
{
|
||||
if (m_token.GetType() != ID_ASS)
|
||||
{
|
||||
pVar = pile1->GetVar(); // recovers if interrupted
|
||||
initKind = pVar->GetInit();
|
||||
if (initKind == CBotVar::InitType::IS_NAN)
|
||||
{
|
||||
pile2->SetError(TX_OPNAN, m_leftop->GetToken());
|
||||
return pj->Return(pile2);
|
||||
}
|
||||
result = CBotVar::Create("", pVar->GetTypResult(2));
|
||||
}
|
||||
|
||||
switch (m_token.GetType())
|
||||
{
|
||||
case ID_ASS:
|
||||
break;
|
||||
case ID_ASSADD:
|
||||
result->Add(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSSUB:
|
||||
result->Sub(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSMUL:
|
||||
result->Mul(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSDIV:
|
||||
if (initKind != CBotVar::InitType::UNDEF &&
|
||||
result->Div(pile1->GetVar(), pile2->GetVar()))
|
||||
pile2->SetError(TX_DIVZERO, &m_token);
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSMODULO:
|
||||
if (initKind != CBotVar::InitType::UNDEF &&
|
||||
result->Modulo(pile1->GetVar(), pile2->GetVar()))
|
||||
pile2->SetError(TX_DIVZERO, &m_token);
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSAND:
|
||||
result->And(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSXOR:
|
||||
result->XOr(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSOR:
|
||||
result->Or(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSSL:
|
||||
result->SL(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSSR:
|
||||
result->SR(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSASR:
|
||||
result->ASR(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
if (initKind == CBotVar::InitType::UNDEF)
|
||||
pile2->SetError(TX_NOTINIT, m_leftop->GetToken());
|
||||
|
||||
pile1->IncState();
|
||||
}
|
||||
|
||||
if (!m_leftop->Execute( pile2, pile1 ))
|
||||
return false;
|
||||
|
||||
return pj->Return(pile2);
|
||||
}
|
||||
|
||||
|
||||
void CBotExpression::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (bMain)
|
||||
{
|
||||
// CBotToken* pToken = m_leftop->GetToken();
|
||||
// CBotVar* pVar = nullptr;
|
||||
|
||||
CBotStack* pile = pj->RestoreStack(this);
|
||||
if (pile == nullptr) return;
|
||||
|
||||
CBotStack* pile1 = pile;
|
||||
|
||||
if ( pile1->GetState()==0)
|
||||
{
|
||||
m_leftop->RestoreStateVar(pile, true);
|
||||
return;
|
||||
}
|
||||
|
||||
m_leftop->RestoreStateVar(pile, false);
|
||||
|
||||
CBotStack* pile2 = pile->RestoreStack();
|
||||
if (pile2 == nullptr) return;
|
||||
|
||||
if ( pile2->GetState()==0)
|
||||
{
|
||||
if (m_rightop) m_rightop->RestoreState(pile2, bMain);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// compile a statement such as "(condition)"
|
||||
|
|
|
@ -708,25 +708,6 @@ public:
|
|||
void RestoreStateVar(CBotStack* &pj, bool bMain) override;
|
||||
};
|
||||
|
||||
// expressions like
|
||||
// x = a;
|
||||
// x * y + 3;
|
||||
|
||||
class CBotExpression : public CBotInstr
|
||||
{
|
||||
private:
|
||||
CBotLeftExpr* m_leftop; // left operand
|
||||
CBotInstr* m_rightop; // right operant
|
||||
|
||||
public:
|
||||
CBotExpression();
|
||||
~CBotExpression();
|
||||
static
|
||||
CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
bool Execute(CBotStack* &pStack) override;
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
};
|
||||
|
||||
#define MAX(a,b) ((a>b) ? a : b)
|
||||
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "CBotInstr/CBotBlock.h"
|
||||
#include "CBotInstr/CBotTwoOpExpr.h"
|
||||
#include "CBotInstr/CBotExpression.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
// Modules inlcude
|
||||
#include "CBotCatch.h"
|
||||
#include "CBotBlock.h"
|
||||
#include "CBotExpression.h"
|
||||
|
||||
// Local include
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
// Modules inlcude
|
||||
#include "CBotExprVar.h"
|
||||
#include "CBotInstrMethode.h"
|
||||
#include "CBotExpression.h"
|
||||
|
||||
// Local include
|
||||
|
||||
|
|
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
* 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 "CBotExpression.h"
|
||||
#include "CBotTwoOpExpr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
#include <cassert>
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExpression::CBotExpression()
|
||||
{
|
||||
m_leftop = nullptr;
|
||||
m_rightop = nullptr;
|
||||
name = "CBotExpression";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExpression::~CBotExpression()
|
||||
{
|
||||
delete m_leftop;
|
||||
delete m_rightop;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotExpression::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotToken* pp = p;
|
||||
|
||||
CBotExpression* inst = new CBotExpression();
|
||||
|
||||
inst->m_leftop = CBotLeftExpr::Compile(p, pStack);
|
||||
|
||||
inst->SetToken(p);
|
||||
int OpType = p->GetType();
|
||||
|
||||
if ( pStack->IsOk() &&
|
||||
IsOfTypeList(p, ID_ASS, ID_ASSADD, ID_ASSSUB, ID_ASSMUL, ID_ASSDIV, ID_ASSMODULO,
|
||||
ID_ASSAND, ID_ASSXOR, ID_ASSOR,
|
||||
ID_ASSSL , ID_ASSSR, ID_ASSASR, 0 ))
|
||||
{
|
||||
if (inst->m_leftop == nullptr)
|
||||
{
|
||||
pStack->SetError(TX_BADLEFT, p->GetEnd());
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inst->m_rightop = CBotExpression::Compile(p, pStack);
|
||||
if (inst->m_rightop == nullptr)
|
||||
{
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CBotTypResult type1 = pStack->GetTypResult();
|
||||
|
||||
// get the variable assigned to mark
|
||||
CBotVar* var = nullptr;
|
||||
inst->m_leftop->ExecuteVar(var, pStack);
|
||||
if (var == nullptr)
|
||||
{
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (OpType != ID_ASS && !var->IsDefined())
|
||||
{
|
||||
pStack->SetError(TX_NOTINIT, pp);
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CBotTypResult type2 = var->GetTypResult();
|
||||
|
||||
// what types are acceptable?
|
||||
switch (OpType)
|
||||
{
|
||||
case ID_ASS:
|
||||
// if (type2 == CBotTypClass) type2 = -1;
|
||||
if ((type1.Eq(CBotTypPointer) && type2.Eq(CBotTypPointer)) ||
|
||||
(type1.Eq(CBotTypClass) && type2.Eq(CBotTypClass) ) )
|
||||
{
|
||||
/* CBotClass* c1 = type1.GetClass();
|
||||
CBotClass* c2 = type2.GetClass();
|
||||
if (!c1->IsChildOf(c2)) type2.SetType(-1);
|
||||
//- if (!type1.Eq(CBotTypClass)) var->SetPointer(pStack->GetVar()->GetPointer());*/
|
||||
var->SetInit(CBotVar::InitType::IS_POINTER);
|
||||
}
|
||||
else
|
||||
var->SetInit(CBotVar::InitType::DEF);
|
||||
|
||||
break;
|
||||
case ID_ASSADD:
|
||||
if (type2.Eq(CBotTypBoolean) ||
|
||||
type2.Eq(CBotTypPointer) ) type2 = -1; // numbers and strings
|
||||
break;
|
||||
case ID_ASSSUB:
|
||||
case ID_ASSMUL:
|
||||
case ID_ASSDIV:
|
||||
case ID_ASSMODULO:
|
||||
if (type2.GetType() >= CBotTypBoolean) type2 = -1; // numbers only
|
||||
break;
|
||||
}
|
||||
|
||||
if (!TypeCompatible(type1, type2, OpType))
|
||||
{
|
||||
pStack->SetError(TX_BADTYPE, &inst->m_token);
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return inst; // compatible type?
|
||||
}
|
||||
|
||||
delete inst;
|
||||
int start, end, error = pStack->GetError(start, end);
|
||||
|
||||
p = pp; // returns to the top
|
||||
pStack->SetError(0,0); // forget the error
|
||||
|
||||
CBotInstr* i = CBotTwoOpExpr::Compile(p, pStack); // tries without assignment
|
||||
if (i != nullptr && error == TX_PRIVATE && p->GetType() == ID_ASS)
|
||||
pStack->ResetError(error, start, end);
|
||||
return i;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotExpression::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
|
||||
// CBotToken* pToken = m_leftop->GetToken();
|
||||
|
||||
CBotVar* pVar = nullptr;
|
||||
|
||||
CBotStack* pile1 = pile;
|
||||
|
||||
CBotVar::InitType initKind = CBotVar::InitType::DEF;
|
||||
CBotVar* result = nullptr;
|
||||
|
||||
// must be done before any indexes (stack can be changed)
|
||||
if (!m_leftop->ExecuteVar(pVar, pile, nullptr, false)) return false; // variable before accessing the value on the right
|
||||
|
||||
if ( pile1->GetState()==0)
|
||||
{
|
||||
pile1->SetCopyVar(pVar); // keeps the copy on the stack (if interrupted)
|
||||
pile1->IncState();
|
||||
}
|
||||
|
||||
CBotStack* pile2 = pile->AddStack();
|
||||
|
||||
if ( pile2->GetState()==0)
|
||||
{
|
||||
if (m_rightop && !m_rightop->Execute(pile2)) return false; // initial value // interrupted?
|
||||
pile2->IncState();
|
||||
}
|
||||
|
||||
if (pile1->GetState() == 1)
|
||||
{
|
||||
if (m_token.GetType() != ID_ASS)
|
||||
{
|
||||
pVar = pile1->GetVar(); // recovers if interrupted
|
||||
initKind = pVar->GetInit();
|
||||
if (initKind == CBotVar::InitType::IS_NAN)
|
||||
{
|
||||
pile2->SetError(TX_OPNAN, m_leftop->GetToken());
|
||||
return pj->Return(pile2);
|
||||
}
|
||||
result = CBotVar::Create("", pVar->GetTypResult(2));
|
||||
}
|
||||
|
||||
switch (m_token.GetType())
|
||||
{
|
||||
case ID_ASS:
|
||||
break;
|
||||
case ID_ASSADD:
|
||||
result->Add(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSSUB:
|
||||
result->Sub(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSMUL:
|
||||
result->Mul(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSDIV:
|
||||
if (initKind != CBotVar::InitType::UNDEF &&
|
||||
result->Div(pile1->GetVar(), pile2->GetVar()))
|
||||
pile2->SetError(TX_DIVZERO, &m_token);
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSMODULO:
|
||||
if (initKind != CBotVar::InitType::UNDEF &&
|
||||
result->Modulo(pile1->GetVar(), pile2->GetVar()))
|
||||
pile2->SetError(TX_DIVZERO, &m_token);
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSAND:
|
||||
result->And(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSXOR:
|
||||
result->XOr(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSOR:
|
||||
result->Or(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSSL:
|
||||
result->SL(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSSR:
|
||||
result->SR(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSASR:
|
||||
result->ASR(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
if (initKind == CBotVar::InitType::UNDEF)
|
||||
pile2->SetError(TX_NOTINIT, m_leftop->GetToken());
|
||||
|
||||
pile1->IncState();
|
||||
}
|
||||
|
||||
if (!m_leftop->Execute( pile2, pile1 ))
|
||||
return false;
|
||||
|
||||
return pj->Return(pile2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotExpression::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (bMain)
|
||||
{
|
||||
// CBotToken* pToken = m_leftop->GetToken();
|
||||
// CBotVar* pVar = nullptr;
|
||||
|
||||
CBotStack* pile = pj->RestoreStack(this);
|
||||
if (pile == nullptr) return;
|
||||
|
||||
CBotStack* pile1 = pile;
|
||||
|
||||
if ( pile1->GetState()==0)
|
||||
{
|
||||
m_leftop->RestoreStateVar(pile, true);
|
||||
return;
|
||||
}
|
||||
|
||||
m_leftop->RestoreStateVar(pile, false);
|
||||
|
||||
CBotStack* pile2 = pile->RestoreStack();
|
||||
if (pile2 == nullptr) return;
|
||||
|
||||
if ( pile2->GetState()==0)
|
||||
{
|
||||
if (m_rightop) m_rightop->RestoreState(pile2, bMain);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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 CBotExpression class Compiles a statement with or without
|
||||
* assignment.
|
||||
* eg :
|
||||
* - x = a;
|
||||
* - x * y + 3;
|
||||
* - x = 123
|
||||
* - z * 5 + 4
|
||||
*/
|
||||
|
||||
|
||||
// compiles a statement such as " " ou " z * 5 + 4 "
|
||||
//
|
||||
|
||||
class CBotExpression : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotExpression
|
||||
*/
|
||||
CBotExpression();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotExpression
|
||||
*/
|
||||
~CBotExpression();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute Executes an expression with assignment.
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pStack) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
//! Left operand
|
||||
CBotLeftExpr* m_leftop;
|
||||
//! Right operand
|
||||
CBotInstr* m_rightop;
|
||||
};
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
// Modules inlcude
|
||||
#include "CBotInstrCall.h"
|
||||
#include "CBotExpression.h"
|
||||
|
||||
// Local include
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
// Modules inlcude
|
||||
#include "CBotListExpression.h"
|
||||
#include "CBotExpression.h"
|
||||
|
||||
// Local include
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "CBotNew.h"
|
||||
#include "CBotExprNull.h"
|
||||
#include "CBotExprNan.h"
|
||||
#include "CBotExpression.h"
|
||||
|
||||
// Local include
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "CBotSwitch.h"
|
||||
#include "CBotCase.h"
|
||||
#include "CBotBlock.h"
|
||||
#include "CBotExpression.h"
|
||||
|
||||
// Local include
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
// Modules inlcude
|
||||
#include "CBotThrow.h"
|
||||
#include "CBotExpression.h"
|
||||
|
||||
// Local include
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "CBotTwoOpExpr.h"
|
||||
#include "CBotParExpr.h"
|
||||
#include "CBotLogicExpr.h"
|
||||
#include "CBotExpression.h"
|
||||
#include "CBot.h"
|
||||
|
||||
// Local include
|
||||
|
|
|
@ -37,6 +37,7 @@ set(SOURCES
|
|||
CBotInstr/CBotBoolExpr.cpp
|
||||
CBotInstr/CBotLogicExpr.cpp
|
||||
CBotInstr/CBotTwoOpExpr.cpp
|
||||
CBotInstr/CBotExpression.cpp
|
||||
)
|
||||
|
||||
# Includes
|
||||
|
|
Loading…
Reference in New Issue