summaryrefslogtreecommitdiffstats
path: root/src/CBot/CBotCompExpr.cpp
diff options
context:
space:
mode:
authoradiblol <adiblol@1tbps.org>2012-03-08 19:32:05 +0100
committeradiblol <adiblol@1tbps.org>2012-03-08 19:32:05 +0100
commita4c804b49ec872b71bd5a0167c3ad45704a3cc30 (patch)
tree8c931235247d662ca46a99695beb328fdfc8e8a8 /src/CBot/CBotCompExpr.cpp
downloadcolobot-a4c804b49ec872b71bd5a0167c3ad45704a3cc30.tar.gz
colobot-a4c804b49ec872b71bd5a0167c3ad45704a3cc30.tar.bz2
colobot-a4c804b49ec872b71bd5a0167c3ad45704a3cc30.zip
Initial commit, Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
Diffstat (limited to 'src/CBot/CBotCompExpr.cpp')
-rw-r--r--src/CBot/CBotCompExpr.cpp117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/CBot/CBotCompExpr.cpp b/src/CBot/CBotCompExpr.cpp
new file mode 100644
index 0000000..99abfb9
--- /dev/null
+++ b/src/CBot/CBotCompExpr.cpp
@@ -0,0 +1,117 @@
+///////////////////////////////////////////////////
+// expression du genre Opérande1 > Opérande2
+// Opérande1 != Opé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();
+
+ CBotInstr* left = CBotAddExpr::Compile( p, pStk ); // expression A + B à 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
+ {
+ CBotCompExpr* inst = new CBotCompExpr(); // élément pour opération
+ inst->SetToken(p); // mémorise l'opération
+
+ int type1, type2;
+ type1 = pStack->GetType();
+
+ p = p->Next();
+ if ( NULL != (inst->m_rightop = CBotAddExpr::Compile( p, pStk )) ) // expression A + B à droite
+ {
+ type2 = pStack->GetType();
+ // les résultats sont-ils compatibles
+ if ( type1 == type2 )
+ {
+ inst->m_leftop = left;
+ pStk->SetVar(new CBotVar(NULL, CBotTypBoolean));
+ // 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);
+}
+
+
+// fait l'opé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 ?
+
+ pStk1->SetState(1); // opération terminée
+
+ // 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:
+ result->Lo(pStk1->GetVar(), pStk2->GetVar()); // inférieur
+ break;
+ case ID_HI:
+ result->Hi(pStk1->GetVar(), pStk2->GetVar()); // supérieur
+ break;
+ case ID_LS:
+ result->Ls(pStk1->GetVar(), pStk2->GetVar()); // inférieur ou égal
+ break;
+ case ID_HS:
+ result->Hs(pStk1->GetVar(), pStk2->GetVar()); // supérieur ou égal
+ break;
+ case ID_EQ:
+ result->Eq(pStk1->GetVar(), pStk2->GetVar()); // égal
+ break;
+ case ID_NE:
+ result->Ne(pStk1->GetVar(), pStk2->GetVar()); // différent
+ break;
+ }
+ pStk2->SetVar(result); // met le résultat sur la pile
+
+ pStk1->Return(pStk2); // libère la pile
+ return pStack->Return(pStk1); // transmet le résultat
+}
+