colobot/src/CBot/CBotCompExpr.cpp

132 lines
3.7 KiB
C++
Raw Normal View History

2012-03-19 11:44:39 +00:00
// * This file is part of the COLOBOT source code
// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
// *
// * 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
2012-03-19 11:44:39 +00:00
// * along with this program. If not, see http://www.gnu.org/licenses/.///////////////////////////////////////////////////
// expression du genre Op<4F>rande1 > Op<4F>rande2
// Op<4F>rande1 != Op<4F>rande2
// etc.
#include "CBot.h"
// divers constructeurs
CBotCompExpr::CBotCompExpr()
{
m_leftop =
m_rightop = NULL;
name = "CBotCompExpr";
}
CBotCompExpr::~CBotCompExpr()
{
delete m_leftop;
delete m_rightop;
}
fichier plus utilise;
// compile une instruction de type A < B
CBotInstr* CBotCompExpr::Compile(CBotToken* &p, CBotCStack* pStack)
{
CBotCStack* pStk = pStack->AddStack();
2012-03-19 11:44:39 +00:00
CBotInstr* left = CBotAddExpr::Compile( p, pStk ); // expression A + B <20> gauche
if (left == NULL) return pStack->Return(NULL, pStk); // erreur
if ( p->GetType() == ID_HI ||
p->GetType() == ID_LO ||
p->GetType() == ID_HS ||
p->GetType() == ID_LS ||
p->GetType() == ID_EQ ||
p->GetType() == ID_NE) // les diverses comparaisons
{
2012-03-19 11:44:39 +00:00
CBotCompExpr* inst = new CBotCompExpr(); // <20>l<EFBFBD>ment pour op<6F>ration
inst->SetToken(p); // m<>morise l'op<6F>ration
int type1, type2;
type1 = pStack->GetType();
p = p->Next();
2012-03-19 11:44:39 +00:00
if ( NULL != (inst->m_rightop = CBotAddExpr::Compile( p, pStk )) ) // expression A + B <20> droite
{
type2 = pStack->GetType();
2012-03-19 11:44:39 +00:00
// les r<>sultats sont-ils compatibles
if ( type1 == type2 )
{
inst->m_leftop = left;
pStk->SetVar(new CBotVar(NULL, CBotTypBoolean));
2012-03-19 11:44:39 +00:00
// le r<>sultat est un boolean
return pStack->Return(inst, pStk);
}
}
delete left;
delete inst;
return pStack->Return(NULL, pStk);
}
return pStack->Return(left, pStk);
}
2012-03-19 11:44:39 +00:00
// fait l'op<6F>ration
bool CBotCompExpr::Execute(CBotStack* &pStack)
{
CBotStack* pStk1 = pStack->AddStack(this);
// if ( pStk1 == EOX ) return TRUE;
if ( pStk1->GetState() == 0 && !m_leftop->Execute(pStk1) ) return FALSE; // interrompu ici ?
2012-03-19 11:44:39 +00:00
pStk1->SetState(1); // op<6F>ration termin<69>e
2012-03-19 11:44:39 +00:00
// demande un peu plus de stack pour ne pas toucher le r<>sultat de gauche
CBotStack* pStk2 = pStk1->AddStack();
if ( !m_rightop->Execute(pStk2) ) return FALSE; // interrompu ici ?
int type1 = pStk1->GetType();
int type2 = pStk2->GetType();
CBotVar* result = new CBotVar( NULL, CBotTypBoolean );
switch (GetTokenType())
{
case ID_LO:
2012-03-19 11:44:39 +00:00
result->Lo(pStk1->GetVar(), pStk2->GetVar()); // inf<6E>rieur
break;
case ID_HI:
2012-03-19 11:44:39 +00:00
result->Hi(pStk1->GetVar(), pStk2->GetVar()); // sup<75>rieur
break;
case ID_LS:
2012-03-19 11:44:39 +00:00
result->Ls(pStk1->GetVar(), pStk2->GetVar()); // inf<6E>rieur ou <20>gal
break;
case ID_HS:
2012-03-19 11:44:39 +00:00
result->Hs(pStk1->GetVar(), pStk2->GetVar()); // sup<75>rieur ou <20>gal
break;
case ID_EQ:
2012-03-19 11:44:39 +00:00
result->Eq(pStk1->GetVar(), pStk2->GetVar()); // <20>gal
break;
case ID_NE:
2012-03-19 11:44:39 +00:00
result->Ne(pStk1->GetVar(), pStk2->GetVar()); // diff<66>rent
break;
}
2012-03-19 11:44:39 +00:00
pStk2->SetVar(result); // met le r<>sultat sur la pile
2012-03-19 11:44:39 +00:00
pStk1->Return(pStk2); // lib<69>re la pile
return pStack->Return(pStk1); // transmet le r<>sultat
}