summaryrefslogtreecommitdiffstats
path: root/src/CBot/old CBotCompExpr.cpp
blob: e7439b76747c996e3693d27c9d1d800331448d4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
///////////////////////////////////////////////////
// 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;
}


// compile une instruction de type A < B

CBotInstr* CBotCompExpr::Compile(CBotToken* &p, CBotCStack* pStack)
{
	CBotCStack* pStk = pStack->TokenStack();

	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 = pStk->GetType(CBotTypChar);

		p = p->Next();
		if ( NULL != (inst->m_rightop = CBotAddExpr::Compile( p, pStk )) )	// expression A + B � droite
		{
			type2 = pStk->GetType(CBotTypChar);
			// les r�sultats sont-ils compatibles
			if ( type1 == type2 && type1 != CBotTypBoolean && type1 != CBotTypClass)
			{
				inst->m_leftop = left;
				pStk->SetVar(new CBotVar(NULL, CBotTypBoolean));
															// le r�sultat est un boolean
				return pStack->Return(inst, pStk);
			}
			pStk->SetError(TX_BAD2TYPE, &inst->m_token);
		}

		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();

	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*	temp   = CBotVar::Create( NULL, MAX(type1, type2) );
	CBotVar*	result = CBotVar::Create( NULL, CBotTypBoolean );

	switch (GetTokenType())
	{
	case ID_LO:
		temp->Lo(pStk1->GetVar(), pStk2->GetVar());		// inf�rieur
		break;
	case ID_HI:
		temp->Hi(pStk1->GetVar(), pStk2->GetVar());		// sup�rieur
		break;
	case ID_LS:
		temp->Ls(pStk1->GetVar(), pStk2->GetVar());		// inf�rieur ou �gal
		break;
	case ID_HS:
		temp->Hs(pStk1->GetVar(), pStk2->GetVar());		// sup�rieur ou �gal
		break;
	case ID_EQ:
		temp->Eq(pStk1->GetVar(), pStk2->GetVar());		// �gal
		break;
	case ID_NE:
		temp->Ne(pStk1->GetVar(), pStk2->GetVar());		// diff�rent
		break;
	}
	result->SetValInt(temp->GetValInt());				// converti le r�sultat
	delete temp;

	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
}