summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/CBot/CBotAddExpr.cpp144
-rw-r--r--src/CBot/CBotClass.cpp1236
-rw-r--r--src/CBot/CBotCompExpr.cpp172
-rw-r--r--src/CBot/CBotFunction.cpp2744
-rw-r--r--src/CBot/CBotIf.cpp224
-rw-r--r--src/CBot/CBotProgram.cpp1462
-rw-r--r--src/CBot/CBotString.cpp1384
-rw-r--r--src/CBot/CBotToken.cpp1124
-rw-r--r--src/CBot/CBotToken.h76
-rw-r--r--src/CBot/CBotTwoOpExpr.cpp932
-rw-r--r--src/CBot/CBotWhile.cpp2012
-rw-r--r--src/CBot/ClassFILE.cpp856
-rw-r--r--src/CBot/StringFunctions.cpp494
-rw-r--r--src/CBot/resource.h354
14 files changed, 6607 insertions, 6607 deletions
diff --git a/src/CBot/CBotAddExpr.cpp b/src/CBot/CBotAddExpr.cpp
index 8e4ed85..231f008 100644
--- a/src/CBot/CBotAddExpr.cpp
+++ b/src/CBot/CBotAddExpr.cpp
@@ -16,7 +16,7 @@
///////////////////////////////////////////////////
// expressions of type Operand1 + Operand2
-// Operand1 - Operand2
+// Operand1 - Operand2
#include "CBot.h"
@@ -24,15 +24,15 @@
CBotAddExpr::CBotAddExpr()
{
- m_leftop =
- m_rightop = NULL; // NULL to be able to delete without further
- name = "CBotAddExpr"; // debug
+ m_leftop =
+ m_rightop = NULL; // NULL to be able to delete without further
+ name = "CBotAddExpr"; // debug
}
CBotAddExpr::~CBotAddExpr()
{
- delete m_leftop;
- delete m_rightop;
+ delete m_leftop;
+ delete m_rightop;
}
@@ -40,54 +40,54 @@ CBotAddExpr::~CBotAddExpr()
CBotInstr* CBotAddExpr::Compile(CBotToken* &p, CBotStack* pStack)
{
- CBotStack* pStk = pStack->TokenStack(); // one end of stack please
+ CBotStack* pStk = pStack->TokenStack(); // one end of stack please
- // looking statements that may be suitable to the left of the operation + or -
+ // looking statements that may be suitable to the left of the operation + or -
- CBotInstr* left = CBotMulExpr::Compile( p, pStk ); // expression A * B left
- if (left == NULL) return pStack->Return(NULL, pStk); // if error, transmit
+ CBotInstr* left = CBotMulExpr::Compile( p, pStk ); // expression A * B left
+ if (left == NULL) return pStack->Return(NULL, pStk); // if error, transmit
- // do we have the token + or - next?
+ // do we have the token + or - next?
- if ( p->GetType() == ID_ADD ||
- p->GetType() == ID_SUB) // more or less
- {
- CBotAddExpr* inst = new CBotAddExpr(); // element for operation
- inst->SetToken(p); // stores the operation
+ if ( p->GetType() == ID_ADD ||
+ p->GetType() == ID_SUB) // more or less
+ {
+ CBotAddExpr* inst = new CBotAddExpr(); // element for operation
+ inst->SetToken(p); // stores the operation
- int type1, type2;
- type1 = pStack->GetType(); // what kind of the first operand?
+ int type1, type2;
+ type1 = pStack->GetType(); // what kind of the first operand?
- p = p->Next(); // skip the token of the operation
+ p = p->Next(); // skip the token of the operation
- // looking statements that may be suitable for right
+ // looking statements that may be suitable for right
- if ( NULL != (inst->m_rightop = CBotAddExpr::Compile( p, pStk )) ) // expression (...) rigth
- {
- // there is an acceptable second operand
+ if ( NULL != (inst->m_rightop = CBotAddExpr::Compile( p, pStk )) ) // expression (...) rigth
+ {
+ // there is an acceptable second operand
- type2 = pStack->GetType(); // what kind of results?
+ type2 = pStack->GetType(); // what kind of results?
- if ( type1 == type2 ) // are the results consistent ?
- {
- // ok so, saves the operand in the object
- inst->m_leftop = left;
- // and makes the object on demand
- return pStack->Return(inst, pStk);
- }
- }
+ if ( type1 == type2 ) // are the results consistent ?
+ {
+ // ok so, saves the operand in the object
+ inst->m_leftop = left;
+ // and makes the object on demand
+ return pStack->Return(inst, pStk);
+ }
+ }
- // in case of error, free the elements
- delete left;
- delete inst;
- // and transmits the error that is on the stack
- return pStack->Return(NULL, pStk);
- }
+ // in case of error, free the elements
+ delete left;
+ delete inst;
+ // and transmits the error that is on the stack
+ return pStack->Return(NULL, pStk);
+ }
- // if we are not dealing with an operation + or -
+ // if we are not dealing with an operation + or -
// goes to that requested, the operand (left) found
- // place the object "addition"
- return pStack->Return(left, pStk);
+ // place the object "addition"
+ return pStack->Return(left, pStk);
}
@@ -97,48 +97,48 @@ CBotInstr* CBotAddExpr::Compile(CBotToken* &p, CBotStack* pStack)
bool CBotAddExpr::Execute(CBotStack* &pStack)
{
- CBotStack* pStk1 = pStack->AddStack(this); // adds an item to the stack
- // or is found in case of recovery
-// if ( pSk1 == EOX ) return TRUE;
+ CBotStack* pStk1 = pStack->AddStack(this); // adds an item to the stack
+ // or is found in case of recovery
+// if ( pSk1 == EOX ) return TRUE;
- // according to recovery, it may be in one of two states
+ // according to recovery, it may be in one of two states
- if ( pStk1->GetState() == 0 && // first state, evaluates the left operand
- !m_leftop->Execute(pStk1) ) return FALSE; // interrupted here?
+ if ( pStk1->GetState() == 0 && // first state, evaluates the left operand
+ !m_leftop->Execute(pStk1) ) return FALSE; // interrupted here?
- // passes to the next step
- pStk1->SetState(1); // ready for further
+ // passes to the next step
+ pStk1->SetState(1); // ready for further
- // requires a little more stack to not touch the result of the left
- // which is on the stack, precisely.
+ // requires a little more stack to not touch the result of the left
+ // which is on the stack, precisely.
- CBotStack* pStk2 = pStk1->AddStack(); // adds an item to the stack
- // or is found in case of recovery
+ CBotStack* pStk2 = pStk1->AddStack(); // adds an item to the stack
+ // or is found in case of recovery
- // Second state, evaluates the right operand
- if ( !m_rightop->Execute(pStk2) ) return FALSE; // interrupted here?
+ // Second state, evaluates the right operand
+ if ( !m_rightop->Execute(pStk2) ) return FALSE; // interrupted here?
- int type1 = pStk1->GetType(); // what kind of results?
- int type2 = pStk2->GetType();
+ int type1 = pStk1->GetType(); // what kind of results?
+ int type2 = pStk2->GetType();
- // creates a temporary variable to put the result
- CBotVar* result = new CBotVar( NULL, MAX(type1, type2));
+ // creates a temporary variable to put the result
+ CBotVar* result = new CBotVar( NULL, MAX(type1, type2));
- // is the operation as requested
- switch (GetTokenType())
- {
- case ID_ADD:
- result->Add(pStk1->GetVar(), pStk2->GetVar()); // addition
- break;
- case ID_SUB:
- result->Sub(pStk1->GetVar(), pStk2->GetVar()); // subtraction
- break;
- }
- pStk2->SetVar(result); // puts the result on the stack
+ // is the operation as requested
+ switch (GetTokenType())
+ {
+ case ID_ADD:
+ result->Add(pStk1->GetVar(), pStk2->GetVar()); // addition
+ break;
+ case ID_SUB:
+ result->Sub(pStk1->GetVar(), pStk2->GetVar()); // subtraction
+ break;
+ }
+ pStk2->SetVar(result); // puts the result on the stack
- pStk1->Return(pStk2); // frees the stack
- return pStack->Return(pStk1); // transmits the result
+ pStk1->Return(pStk2); // frees the stack
+ return pStack->Return(pStk1); // transmits the result
}
diff --git a/src/CBot/CBotClass.cpp b/src/CBot/CBotClass.cpp
index 692d3c7..a524a8e 100644
--- a/src/CBot/CBotClass.cpp
+++ b/src/CBot/CBotClass.cpp
@@ -25,349 +25,349 @@ CBotClass* CBotClass::m_ExClass = NULL;
CBotClass::CBotClass(const char* name, CBotClass* pPapa, bool bIntrinsic)
{
- m_pParent = pPapa;
- m_name = name;
- m_pVar = NULL;
- m_next = NULL;
- m_pCalls = NULL;
- m_pMethod = NULL;
- m_rMaj = NULL;
- m_IsDef = true;
- m_bIntrinsic= bIntrinsic;
- m_cptLock = 0;
- m_cptOne = 0;
- m_nbVar = m_pParent == NULL ? 0 : m_pParent->m_nbVar;
+ m_pParent = pPapa;
+ m_name = name;
+ m_pVar = NULL;
+ m_next = NULL;
+ m_pCalls = NULL;
+ m_pMethod = NULL;
+ m_rMaj = NULL;
+ m_IsDef = true;
+ m_bIntrinsic= bIntrinsic;
+ m_cptLock = 0;
+ m_cptOne = 0;
+ m_nbVar = m_pParent == NULL ? 0 : m_pParent->m_nbVar;
- for ( int j= 0; j< 5 ; j++ )
- {
- m_ProgInLock[j] = NULL;
- }
+ for ( int j= 0; j< 5 ; j++ )
+ {
+ m_ProgInLock[j] = NULL;
+ }
- // is located alone in the list
- if (m_ExClass) m_ExClass->m_ExPrev = this;
- m_ExNext = m_ExClass;
- m_ExPrev = NULL;
- m_ExClass = this;
+ // is located alone in the list
+ if (m_ExClass) m_ExClass->m_ExPrev = this;
+ m_ExNext = m_ExClass;
+ m_ExPrev = NULL;
+ m_ExClass = this;
}
CBotClass::~CBotClass()
{
- // removes the list of class
- if ( m_ExPrev ) m_ExPrev->m_ExNext = m_ExNext;
- else m_ExClass = m_ExNext;
+ // removes the list of class
+ if ( m_ExPrev ) m_ExPrev->m_ExNext = m_ExNext;
+ else m_ExClass = m_ExNext;
- if ( m_ExNext ) m_ExNext->m_ExPrev = m_ExPrev;
- m_ExPrev = NULL;
- m_ExNext = NULL;
+ if ( m_ExNext ) m_ExNext->m_ExPrev = m_ExPrev;
+ m_ExPrev = NULL;
+ m_ExNext = NULL;
- delete m_pVar;
- delete m_pCalls;
- delete m_pMethod;
+ delete m_pVar;
+ delete m_pCalls;
+ delete m_pMethod;
- delete m_next; // releases all of them on this level
+ delete m_next; // releases all of them on this level
}
void CBotClass::Free()
{
- while ( m_ExClass != NULL )
- {
- delete m_ExClass;
- }
+ while ( m_ExClass != NULL )
+ {
+ delete m_ExClass;
+ }
}
void CBotClass::Purge()
{
- if ( this == NULL ) return;
+ if ( this == NULL ) return;
- delete m_pVar;
- m_pVar = NULL;
- delete m_pCalls;
- m_pCalls = NULL;
- delete m_pMethod;
- m_pMethod = NULL;
- m_IsDef = false;
+ delete m_pVar;
+ m_pVar = NULL;
+ delete m_pCalls;
+ m_pCalls = NULL;
+ delete m_pMethod;
+ m_pMethod = NULL;
+ m_IsDef = false;
- m_nbVar = m_pParent == NULL ? 0 : m_pParent->m_nbVar;
+ m_nbVar = m_pParent == NULL ? 0 : m_pParent->m_nbVar;
- m_next->Purge();
- m_next = NULL; // no longer belongs to this chain
+ m_next->Purge();
+ m_next = NULL; // no longer belongs to this chain
}
bool CBotClass::Lock(CBotProgram* p)
{
- int i = m_cptLock++;
-
- if ( i == 0 )
- {
- m_cptOne = 1;
- m_ProgInLock[0] = p;
- return true;
- }
- if ( p == m_ProgInLock[0] )
- {
- m_cptOne++;
- m_cptLock--; // has already been counted
- return true;
- }
-
- for ( int j = 1 ; j <= i ; j++)
- {
- if ( p == m_ProgInLock[j] )
- {
- m_cptLock--;
- return false; // already pending
- }
- }
-
- if ( i < 5 ) // max 5 in query
- {
- m_ProgInLock[i] = p; // located in a queue
- }
- else
- m_cptLock--;
-
- return false;
+ int i = m_cptLock++;
+
+ if ( i == 0 )
+ {
+ m_cptOne = 1;
+ m_ProgInLock[0] = p;
+ return true;
+ }
+ if ( p == m_ProgInLock[0] )
+ {
+ m_cptOne++;
+ m_cptLock--; // has already been counted
+ return true;
+ }
+
+ for ( int j = 1 ; j <= i ; j++)
+ {
+ if ( p == m_ProgInLock[j] )
+ {
+ m_cptLock--;
+ return false; // already pending
+ }
+ }
+
+ if ( i < 5 ) // max 5 in query
+ {
+ m_ProgInLock[i] = p; // located in a queue
+ }
+ else
+ m_cptLock--;
+
+ return false;
}
void CBotClass::Unlock()
{
- if ( --m_cptOne > 0 ) return ;
+ if ( --m_cptOne > 0 ) return ;
- int i = --m_cptLock;
- if ( i<0 )
- {
- m_cptLock = 0;
- return;
- }
+ int i = --m_cptLock;
+ if ( i<0 )
+ {
+ m_cptLock = 0;
+ return;
+ }
- for ( int j= 0; j< i ; j++ )
- {
- m_ProgInLock[j] = m_ProgInLock[j+1];
- }
- m_ProgInLock[i] = 0;
+ for ( int j= 0; j< i ; j++ )
+ {
+ m_ProgInLock[j] = m_ProgInLock[j+1];
+ }
+ m_ProgInLock[i] = 0;
}
void CBotClass::FreeLock(CBotProgram* p)
{
- CBotClass* pClass = m_ExClass;
+ CBotClass* pClass = m_ExClass;
- while ( pClass != NULL )
- {
- if ( p == pClass->m_ProgInLock[0] )
- {
- pClass->m_cptLock -= pClass->m_cptOne;
- pClass->m_cptOne = 0;
- }
+ while ( pClass != NULL )
+ {
+ if ( p == pClass->m_ProgInLock[0] )
+ {
+ pClass->m_cptLock -= pClass->m_cptOne;
+ pClass->m_cptOne = 0;
+ }
- for ( int j = 1; j < 5 ; j++ )
- if ( p == pClass->m_ProgInLock[j] )
- pClass->m_cptLock--;
+ for ( int j = 1; j < 5 ; j++ )
+ if ( p == pClass->m_ProgInLock[j] )
+ pClass->m_cptLock--;
- pClass = pClass->m_ExNext;
- }
+ pClass = pClass->m_ExNext;
+ }
}
bool CBotClass::AddItem(CBotString name, CBotTypResult type, int mPrivate)
{
- CBotToken token(name, CBotString());
- CBotClass* pClass = type.GivClass();
+ CBotToken token(name, CBotString());
+ CBotClass* pClass = type.GivClass();
- CBotVar* pVar = CBotVar::Create( name, type );
-/// pVar->SetUniqNum(CBotVar::NextUniqNum());
- pVar->SetPrivate( mPrivate );
+ CBotVar* pVar = CBotVar::Create( name, type );
+/// pVar->SetUniqNum(CBotVar::NextUniqNum());
+ pVar->SetPrivate( mPrivate );
- if ( pClass != NULL )
- {
-// pVar->SetClass(pClass);
- if ( type.Eq(CBotTypClass) )
- {
- // adds a new statement for the object initialization
- pVar->m_InitExpr = new CBotNew() ;
- CBotToken nom( pClass->GivName() );
- pVar->m_InitExpr->SetToken(&nom);
- }
- }
- return AddItem( pVar );
+ if ( pClass != NULL )
+ {
+// pVar->SetClass(pClass);
+ if ( type.Eq(CBotTypClass) )
+ {
+ // adds a new statement for the object initialization
+ pVar->m_InitExpr = new CBotNew() ;
+ CBotToken nom( pClass->GivName() );
+ pVar->m_InitExpr->SetToken(&nom);
+ }
+ }
+ return AddItem( pVar );
}
bool CBotClass::AddItem(CBotVar* pVar)
{
- pVar->SetUniqNum(++m_nbVar);
+ pVar->SetUniqNum(++m_nbVar);
- if ( m_pVar == NULL ) m_pVar = pVar;
- else m_pVar->AddNext(pVar);
+ if ( m_pVar == NULL ) m_pVar = pVar;
+ else m_pVar->AddNext(pVar);
- return true;
+ return true;
}
void CBotClass::AddNext(CBotClass* pClass)
{
- CBotClass* p = this;
- while (p->m_next != NULL) p = p->m_next;
+ CBotClass* p = this;
+ while (p->m_next != NULL) p = p->m_next;
- p->m_next = pClass;
+ p->m_next = pClass;
}
CBotString CBotClass::GivName()
{
- return m_name;
+ return m_name;
}
CBotClass* CBotClass::GivParent()
{
- if ( this == NULL ) return NULL;
- return m_pParent;
+ if ( this == NULL ) return NULL;
+ return m_pParent;
}
bool CBotClass::IsChildOf(CBotClass* pClass)
{
- CBotClass* p = this;
- while ( p != NULL )
- {
- if ( p == pClass ) return true;
- p = p->m_pParent;
- }
- return false;
+ CBotClass* p = this;
+ while ( p != NULL )
+ {
+ if ( p == pClass ) return true;
+ p = p->m_pParent;
+ }
+ return false;
}
CBotVar* CBotClass::GivVar()
{
- return m_pVar;
+ return m_pVar;
}
CBotVar* CBotClass::GivItem(const char* name)
{
- CBotVar* p = m_pVar;
+ CBotVar* p = m_pVar;
- while ( p != NULL )
- {
- if ( p->GivName() == name ) return p;
- p = p->GivNext();
- }
- if ( m_pParent != NULL ) return m_pParent->GivItem(name);
- return NULL;
+ while ( p != NULL )
+ {
+ if ( p->GivName() == name ) return p;
+ p = p->GivNext();
+ }
+ if ( m_pParent != NULL ) return m_pParent->GivItem(name);
+ return NULL;
}
CBotVar* CBotClass::GivItemRef(int nIdent)
{
- CBotVar* p = m_pVar;
+ CBotVar* p = m_pVar;
- while ( p != NULL )
- {
- if ( p->GivUniqNum() == nIdent ) return p;
- p = p->GivNext();
- }
- if ( m_pParent != NULL ) return m_pParent->GivItemRef(nIdent);
- return NULL;
+ while ( p != NULL )
+ {
+ if ( p->GivUniqNum() == nIdent ) return p;
+ p = p->GivNext();
+ }
+ if ( m_pParent != NULL ) return m_pParent->GivItemRef(nIdent);
+ return NULL;
}
bool CBotClass::IsIntrinsic()
{
- return m_bIntrinsic;
+ return m_bIntrinsic;
}
CBotClass* CBotClass::Find(CBotToken* &pToken)
{
- return Find(pToken->GivString());
+ return Find(pToken->GivString());
}
CBotClass* CBotClass::Find(const char* name)
{
- CBotClass* p = m_ExClass;
+ CBotClass* p = m_ExClass;
- while ( p != NULL )
- {
- if ( p->GivName() == name ) return p;
- p = p->m_ExNext;
- }
+ while ( p != NULL )
+ {
+ if ( p->GivName() == name ) return p;
+ p = p->m_ExNext;
+ }
- return NULL;
+ return NULL;
}
bool CBotClass::AddFunction(const char* name,
- bool rExec (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception),
- CBotTypResult rCompile (CBotVar* pThis, CBotVar* &pVar))
-{
- // stores pointers to the two functions
- CBotCallMethode* p = m_pCalls;
- CBotCallMethode* pp = NULL;
-
- while ( p != NULL )
- {
- if ( name == p->GivName() )
- {
- if ( pp == NULL ) m_pCalls = p->m_next;
- else pp->m_next = p->m_next;
- delete p;
- break;
- }
- pp = p;
- p = p->m_next;
- }
-
- p = new CBotCallMethode(name, rExec, rCompile);
-
- if (m_pCalls == NULL) m_pCalls = p;
- else m_pCalls->AddNext(p); // added to the list
-
- return true;
+ bool rExec (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception),
+ CBotTypResult rCompile (CBotVar* pThis, CBotVar* &pVar))
+{
+ // stores pointers to the two functions
+ CBotCallMethode* p = m_pCalls;
+ CBotCallMethode* pp = NULL;
+
+ while ( p != NULL )
+ {
+ if ( name == p->GivName() )
+ {
+ if ( pp == NULL ) m_pCalls = p->m_next;
+ else pp->m_next = p->m_next;
+ delete p;
+ break;
+ }
+ pp = p;
+ p = p->m_next;
+ }
+
+ p = new CBotCallMethode(name, rExec, rCompile);
+
+ if (m_pCalls == NULL) m_pCalls = p;
+ else m_pCalls->AddNext(p); // added to the list
+
+ return true;
}
bool CBotClass::AddUpdateFunc( void rMaj ( CBotVar* pThis, void* pUser ) )
{
- m_rMaj = rMaj;
- return true;
+ m_rMaj = rMaj;
+ return true;
}
// compiles a method associated with an instance of class
// the method can be declared by the user or AddFunction
CBotTypResult CBotClass::CompileMethode(const char* name,
- CBotVar* pThis, CBotVar** ppParams,
- CBotCStack* pStack, long& nIdent)
+ CBotVar* pThis, CBotVar** ppParams,
+ CBotCStack* pStack, long& nIdent)
{
- nIdent = 0; // forget the previous one if necessary
+ nIdent = 0; // forget the previous one if necessary
- // find the methods declared by AddFunction
+ // find the methods declared by AddFunction
- CBotTypResult r = m_pCalls->CompileCall(name, pThis, ppParams, pStack, nIdent);
- if ( r.GivType() >= 0) return r;
+ CBotTypResult r = m_pCalls->CompileCall(name, pThis, ppParams, pStack, nIdent);
+ if ( r.GivType() >= 0) return r;
- // find the methods declared by user
+ // find the methods declared by user
- r = m_pMethod->CompileCall(name, ppParams, nIdent);
- if ( r.Eq(TX_UNDEFCALL) && m_pParent != NULL )
- return m_pParent->m_pMethod->CompileCall(name, ppParams, nIdent);
- return r;
+ r = m_pMethod->CompileCall(name, ppParams, nIdent);
+ if ( r.Eq(TX_UNDEFCALL) && m_pParent != NULL )
+ return m_pParent->m_pMethod->CompileCall(name, ppParams, nIdent);
+ return r;
}
// executes a method
bool CBotClass::ExecuteMethode(long& nIdent, const char* name,
- CBotVar* pThis, CBotVar** ppParams,
- CBotVar* &pResult, CBotStack* &pStack,
- CBotToken* pToken)
+ CBotVar* pThis, CBotVar** ppParams,
+ CBotVar* &pResult, CBotStack* &pStack,
+ CBotToken* pToken)
{
- int ret = m_pCalls->DoCall(nIdent, name, pThis, ppParams, pResult, pStack, pToken);
- if (ret>=0) return ret;
+ int ret = m_pCalls->DoCall(nIdent, name, pThis, ppParams, pResult, pStack, pToken);
+ if (ret>=0) return ret;
- ret = m_pMethod->DoCall(nIdent, name, pThis, ppParams, pStack, pToken, this);
- return ret;
+ ret = m_pMethod->DoCall(nIdent, name, pThis, ppParams, pStack, pToken, this);
+ return ret;
}
// restored the execution stack
void CBotClass::RestoreMethode(long& nIdent, const char* name, CBotVar* pThis,
- CBotVar** ppParams, CBotStack* &pStack)
+ CBotVar** ppParams, CBotStack* &pStack)
{
- m_pMethod->RestoreCall(nIdent, name, pThis, ppParams, pStack, this);
+ m_pMethod->RestoreCall(nIdent, name, pThis, ppParams, pStack, this);
}
@@ -375,75 +375,75 @@ void CBotClass::RestoreMethode(long& nIdent, const char* name, CBotVar* pThis,
bool CBotClass::SaveStaticState(FILE* pf)
{
- if (!WriteWord( pf, CBOTVERSION*2)) return false;
+ if (!WriteWord( pf, CBOTVERSION*2)) return false;
- // saves the state of static variables in classes
- CBotClass* p = m_ExClass;
+ // saves the state of static variables in classes
+ CBotClass* p = m_ExClass;
- while ( p != NULL )
- {
- if (!WriteWord( pf, 1)) return false;
- // save the name of the class
- if (!WriteString( pf, p->GivName() )) return false;
+ while ( p != NULL )
+ {
+ if (!WriteWord( pf, 1)) return false;
+ // save the name of the class
+ if (!WriteString( pf, p->GivName() )) return false;
- CBotVar* pv = p->GivVar();
- while( pv != NULL )
- {
- if ( pv->IsStatic() )
- {
- if (!WriteWord( pf, 1)) return false;
- if (!WriteString( pf, pv->GivName() )) return false;
+ CBotVar* pv = p->GivVar();
+ while( pv != NULL )
+ {
+ if ( pv->IsStatic() )
+ {
+ if (!WriteWord( pf, 1)) return false;
+ if (!WriteString( pf, pv->GivName() )) return false;
- if ( !pv->Save0State(pf)) return false; // common header
- if ( !pv->Save1State(pf) ) return false; // saves as the child class
- if ( !WriteWord( pf, 0)) return false;
- }
- pv = pv->GivNext();
- }
+ if ( !pv->Save0State(pf)) return false; // common header
+ if ( !pv->Save1State(pf) ) return false; // saves as the child class
+ if ( !WriteWord( pf, 0)) return false;
+ }
+ pv = pv->GivNext();
+ }
- if (!WriteWord( pf, 0)) return false;
- p = p->m_ExNext;
- }
+ if (!WriteWord( pf, 0)) return false;
+ p = p->m_ExNext;
+ }
- if (!WriteWord( pf, 0)) return false;
- return true;
+ if (!WriteWord( pf, 0)) return false;
+ return true;
}
bool CBotClass::RestoreStaticState(FILE* pf)
{
- CBotString ClassName, VarName;
- CBotClass* pClass;
- unsigned short w;
+ CBotString ClassName, VarName;
+ CBotClass* pClass;
+ unsigned short w;
- if (!ReadWord( pf, w )) return false;
- if ( w != CBOTVERSION*2 ) return false;
+ if (!ReadWord( pf, w )) return false;
+ if ( w != CBOTVERSION*2 ) return false;
- while (true)
- {
- if (!ReadWord( pf, w )) return false;
- if ( w == 0 ) return true;
+ while (true)
+ {
+ if (!ReadWord( pf, w )) return false;
+ if ( w == 0 ) return true;
- if (!ReadString( pf, ClassName )) return false;
- pClass = Find(ClassName);
+ if (!ReadString( pf, ClassName )) return false;
+ pClass = Find(ClassName);
- while (true)
- {
- if (!ReadWord( pf, w )) return false;
- if ( w == 0 ) break;
+ while (true)
+ {
+ if (!ReadWord( pf, w )) return false;
+ if ( w == 0 ) break;
- CBotVar* pVar = NULL;
- CBotVar* pv = NULL;
+ CBotVar* pVar = NULL;
+ CBotVar* pv = NULL;
- if (!ReadString( pf, VarName )) return false;
- if ( pClass != NULL ) pVar = pClass->GivItem(VarName);
+ if (!ReadString( pf, VarName )) return false;
+ if ( pClass != NULL ) pVar = pClass->GivItem(VarName);
- if (!CBotVar::RestoreState(pf, pv)) return false; // the temp variable
+ if (!CBotVar::RestoreState(pf, pv)) return false; // the temp variable
- if ( pVar != NULL ) pVar->Copy(pv);
- delete pv;
- }
- }
- return true;
+ if ( pVar != NULL ) pVar->Copy(pv);
+ delete pv;
+ }
+ }
+ return true;
}
@@ -451,19 +451,19 @@ bool CBotClass::RestoreStaticState(FILE* pf)
CBotClassInst::CBotClassInst()
{
- m_next = NULL;
- m_var = NULL;
- m_Parameters = NULL;
- m_expr = NULL;
- m_hasParams = false;
- m_nMethodeIdent = 0;
- name = "CBotClassInst";
+ m_next = NULL;
+ m_var = NULL;
+ m_Parameters = NULL;
+ m_expr = NULL;
+ m_hasParams = false;
+ m_nMethodeIdent = 0;
+ name = "CBotClassInst";
}
CBotClassInst::~CBotClassInst()
{
- delete m_var;
-// delete m_next; // done by the destructor of the base class ~CBotInstr()
+ delete m_var;
+// delete m_next; // done by the destructor of the base class ~CBotInstr()
}
// definition of pointer (s) to an object
@@ -472,388 +472,388 @@ CBotClassInst::~CBotClassInst()
CBotInstr* CBotClassInst::Compile(CBotToken* &p, CBotCStack* pStack, CBotClass* pClass)
{
- // seeks the corresponding classes
- if ( pClass == NULL )
- {
- pStack->SetStartError(p->GivStart());
- pClass = CBotClass::Find(p);
- if ( pClass == NULL )
- {
- // not found? is bizare
- pStack->SetError(TX_NOCLASS, p);
- return NULL;
- }
- p = p->GivNext();
- }
-
- bool bIntrinsic = pClass->IsIntrinsic();
- CBotTypResult type = CBotTypResult( bIntrinsic ? CBotTypIntrinsic : CBotTypPointer, pClass );
- CBotClassInst* inst = (CBotClassInst*)CompileArray(p, pStack, type);
- if ( inst != NULL || !pStack->IsOk() ) return inst;
-
- CBotCStack* pStk = pStack->TokenStack();
-
- inst = new CBotClassInst();
+ // seeks the corresponding classes
+ if ( pClass == NULL )
+ {
+ pStack->SetStartError(p->GivStart());
+ pClass = CBotClass::Find(p);
+ if ( pClass == NULL )
+ {
+ // not found? is bizare
+ pStack->SetError(TX_NOCLASS, p);
+ return NULL;
+ }
+ p = p->GivNext();
+ }
+
+ bool bIntrinsic = pClass->IsIntrinsic();
+ CBotTypResult type = CBotTypResult( bIntrinsic ? CBotTypIntrinsic : CBotTypPointer, pClass );
+ CBotClassInst* inst = (CBotClassInst*)CompileArray(p, pStack, type);
+ if ( inst != NULL || !pStack->IsOk() ) return inst;
+
+ CBotCStack* pStk = pStack->TokenStack();
+
+ inst = new CBotClassInst();
/// \TODO Need to be revised and fixed after adding unit tests
CBotToken token(pClass->GivName(), CBotString(), p->GivStart(), p->GivEnd());
- inst->SetToken(&token);
- CBotToken* vartoken = p;
-
- if ( NULL != (inst->m_var = CBotLeftExprVar::Compile( p, pStk )) )
- {
- ((CBotLeftExprVar*)inst->m_var)->m_typevar = type;
- if (pStk->CheckVarLocal(vartoken)) // redefinition of the variable
- {
- pStk->SetStartError(vartoken->GivStart());
- pStk->SetError(TX_REDEFVAR, vartoken->GivEnd());
- goto error;
- }
-
- if (IsOfType(p, ID_OPBRK)) // with any clues?
- {
- delete inst; // is not type CBotInt
- p = vartoken; // returns to the variable name
-
- // compiles declaration an array
-
- inst = (CBotClassInst*)CBotInstArray::Compile( p, pStk, type );
-
- if (!pStk->IsOk() )
- {
- pStk->SetError(TX_CLBRK, p->GivStart());
- goto error;
- }
- goto suite; // no assignment, variable already created
- }
-
-
- CBotVar* var;
- var = CBotVar::Create(vartoken->GivString(), type); // creates the instance
-// var->SetClass(pClass);
- var->SetUniqNum(
- ((CBotLeftExprVar*)inst->m_var)->m_nIdent = CBotVar::NextUniqNum());
- // its attribute a unique number
- pStack->AddVar(var); // placed on the stack
-
- // look if there are parameters
- inst->m_hasParams = (p->GivType() == ID_OPENPAR);
-
- CBotVar* ppVars[1000];
- inst->m_Parameters = CompileParams(p, pStk, ppVars);
- if ( !pStk->IsOk() ) goto error;
-
- // if there are parameters, is the equivalent to the stament "new"
- // CPoint A ( 0, 0 ) is equivalent to
- // CPoint A = new CPoint( 0, 0 )
-
-// if ( NULL != inst->m_Parameters )
- if ( inst->m_hasParams )
- {
- // the constructor is there?
-// CBotString noname;
- CBotTypResult r = pClass->CompileMethode(pClass->GivName(), var, ppVars, pStk, inst->m_nMethodeIdent);
- delete pStk->TokenStack(); // releases the supplement stack
- int typ = r.GivType();
-
- if (typ == TX_UNDEFCALL)
- {
- // si le constructeur n'existe pas
- if (inst->m_Parameters != NULL) // with parameters
- {
- pStk->SetError(TX_NOCONST, vartoken);
- goto error;
- }
- typ = 0;
- }
-
- if (typ>20)
- {
- pStk->SetError(typ, vartoken->GivEnd());
- goto error;
- }
-
- }
-
- if (IsOfType(p, ID_ASS)) // with a assignment?
- {
- if (inst->m_hasParams)
- {
- pStk->SetError(TX_ENDOF, p->GivStart());
- goto error;
- }
-
- if ( NULL == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )) )
- {
- goto error;
- }
- CBotClass* result = pStk->GivClass();
- if ( !pStk->GivTypResult(1).Eq(CBotTypNullPointer) &&
- ( !pStk->GivTypResult(1).Eq(CBotTypPointer) ||
- ( result != NULL && !pClass->IsChildOf(result) ))) // type compatible ?
- {
- pStk->SetError(TX_BADTYPE, p->GivStart());
- goto error;
- }
-// if ( !bIntrinsic ) var->SetPointer(pStk->GivVar()->GivPointer());
- if ( !bIntrinsic )
- {
- // does not use the result on the stack, to impose the class
- CBotVar* pvar = CBotVar::Create("", pClass);
- var->SetPointer( pvar ); // variable already declared instance pointer
- delete pvar; // removes the second pointer
- }
- var->SetInit(true); // marks the pointer as init
- }
- else if (inst->m_hasParams)
- {
- // creates the object on the "job" (\TODO "tas")
- // with a pointer to the object
- if ( !bIntrinsic )
- {
- CBotVar* pvar = CBotVar::Create("", pClass);
- var->SetPointer( pvar ); // variable already declared instance pointer
- delete pvar; // removes the second pointer
- }
- var->SetInit(2); // marks the pointer as init
- }
+ inst->SetToken(&token);
+ CBotToken* vartoken = p;
+
+ if ( NULL != (inst->m_var = CBotLeftExprVar::Compile( p, pStk )) )
+ {
+ ((CBotLeftExprVar*)inst->m_var)->m_typevar = type;
+ if (pStk->CheckVarLocal(vartoken)) // redefinition of the variable
+ {
+ pStk->SetStartError(vartoken->GivStart());
+ pStk->SetError(TX_REDEFVAR, vartoken->GivEnd());
+ goto error;
+ }
+
+ if (IsOfType(p, ID_OPBRK)) // with any clues?
+ {
+ delete inst; // is not type CBotInt
+ p = vartoken; // returns to the variable name
+
+ // compiles declaration an array
+
+ inst = (CBotClassInst*)CBotInstArray::Compile( p, pStk, type );
+
+ if (!pStk->IsOk() )
+ {
+ pStk->SetError(TX_CLBRK, p->GivStart());
+ goto error;
+ }
+ goto suite; // no assignment, variable already created
+ }
+
+
+ CBotVar* var;
+ var = CBotVar::Create(vartoken->GivString(), type); // creates the instance
+// var->SetClass(pClass);
+ var->SetUniqNum(
+ ((CBotLeftExprVar*)inst->m_var)->m_nIdent = CBotVar::NextUniqNum());
+ // its attribute a unique number
+ pStack->AddVar(var); // placed on the stack
+
+ // look if there are parameters
+ inst->m_hasParams = (p->GivType() == ID_OPENPAR);
+
+ CBotVar* ppVars[1000];
+ inst->m_Parameters = CompileParams(p, pStk, ppVars);
+ if ( !pStk->IsOk() ) goto error;
+
+ // if there are parameters, is the equivalent to the stament "new"
+ // CPoint A ( 0, 0 ) is equivalent to
+ // CPoint A = new CPoint( 0, 0 )
+
+// if ( NULL != inst->m_Parameters )
+ if ( inst->m_hasParams )
+ {
+ // the constructor is there?
+// CBotString noname;
+ CBotTypResult r = pClass->CompileMethode(pClass->GivName(), var, ppVars, pStk, inst->m_nMethodeIdent);
+ delete pStk->TokenStack(); // releases the supplement stack
+ int typ = r.GivType();
+
+ if (typ == TX_UNDEFCALL)
+ {
+ // si le constructeur n'existe pas
+ if (inst->m_Parameters != NULL) // with parameters
+ {
+ pStk->SetError(TX_NOCONST, vartoken);
+ goto error;
+ }
+ typ = 0;
+ }
+
+ if (typ>20)
+ {
+ pStk->SetError(typ, vartoken->GivEnd());
+ goto error;
+ }
+
+ }
+
+ if (IsOfType(p, ID_ASS)) // with a assignment?
+ {
+ if (inst->m_hasParams)
+ {
+ pStk->SetError(TX_ENDOF, p->GivStart());
+ goto error;
+ }
+
+ if ( NULL == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )) )
+ {
+ goto error;
+ }
+ CBotClass* result = pStk->GivClass();
+ if ( !pStk->GivTypResult(1).Eq(CBotTypNullPointer) &&
+ ( !pStk->GivTypResult(1).Eq(CBotTypPointer) ||
+ ( result != NULL && !pClass->IsChildOf(result) ))) // type compatible ?
+ {
+ pStk->SetError(TX_BADTYPE, p->GivStart());
+ goto error;
+ }
+// if ( !bIntrinsic ) var->SetPointer(pStk->GivVar()->GivPointer());
+ if ( !bIntrinsic )
+ {
+ // does not use the result on the stack, to impose the class
+ CBotVar* pvar = CBotVar::Create("", pClass);
+ var->SetPointer( pvar ); // variable already declared instance pointer
+ delete pvar; // removes the second pointer
+ }
+ var->SetInit(true); // marks the pointer as init
+ }
+ else if (inst->m_hasParams)
+ {
+ // creates the object on the "job" (\TODO "tas")
+ // with a pointer to the object
+ if ( !bIntrinsic )
+ {
+ CBotVar* pvar = CBotVar::Create("", pClass);
+ var->SetPointer( pvar ); // variable already declared instance pointer
+ delete pvar; // removes the second pointer
+ }
+ var->SetInit(2); // marks the pointer as init
+ }
suite:
- if (IsOfType(p, ID_COMMA)) // several chained definitions
- {
- if ( NULL != ( inst->m_next = CBotClassInst::Compile(p, pStk, pClass) )) // compiles the following
- {
- return pStack->Return(inst, pStk);
- }
- }
-
- if (IsOfType(p, ID_SEP)) // complete instruction
- {
- return pStack->Return(inst, pStk);
- }
-
- pStk->SetError(TX_ENDOF, p->GivStart());
- }
+ if (IsOfType(p, ID_COMMA)) // several chained definitions
+ {
+ if ( NULL != ( inst->m_next = CBotClassInst::Compile(p, pStk, pClass) )) // compiles the following
+ {
+ return pStack->Return(inst, pStk);
+ }
+ }
+
+ if (IsOfType(p, ID_SEP)) // complete instruction
+ {
+ return pStack->Return(inst, pStk);
+ }
+
+ pStk->SetError(TX_ENDOF, p->GivStart());
+ }
error:
- delete inst;
- return pStack->Return(NULL, pStk);
+ delete inst;
+ return pStack->Return(NULL, pStk);
}
// declaration of the instance of a class, for example:
-// CPoint A, B;
+// CPoint A, B;
bool CBotClassInst::Execute(CBotStack* &pj)
{
- CBotVar* pThis = NULL;
-
- CBotStack* pile = pj->AddStack(this);//essential for SetState()
-// if ( pile == EOX ) return true;
-
- CBotToken* pt = &m_token;
- CBotClass* pClass = CBotClass::Find(pt);
-
- bool bIntrincic = pClass->IsIntrinsic();
-
- // creates the variable of type pointer to the object
-
- if ( pile->GivState()==0)
- {
- CBotString name = m_var->m_token.GivString();
- if ( bIntrincic )
- {
- pThis = CBotVar::Create(name, CBotTypResult( CBotTypIntrinsic, pClass ));
- }
- else
- {
- pThis = CBotVar::Create(name, CBotTypResult( CBotTypPointer, pClass ));
- }
-
- pThis->SetUniqNum(((CBotLeftExprVar*)m_var)->m_nIdent); // its attribute as unique number
- pile->AddVar(pThis); // place on the stack
- pile->IncState();
- }
-
- if ( pThis == NULL ) pThis = pile->FindVar(((CBotLeftExprVar*)m_var)->m_nIdent);
-
- if ( pile->GivState()<3)
- {
- // ss there an assignment or parameters (contructor)
+ CBotVar* pThis = NULL;
+
+ CBotStack* pile = pj->AddStack(this);//essential for SetState()
+// if ( pile == EOX ) return true;
+
+ CBotToken* pt = &m_token;
+ CBotClass* pClass = CBotClass::Find(pt);
+
+ bool bIntrincic = pClass->IsIntrinsic();
+
+ // creates the variable of type pointer to the object
+
+ if ( pile->GivState()==0)
+ {
+ CBotString name = m_var->m_token.GivString();
+ if ( bIntrincic )
+ {
+ pThis = CBotVar::Create(name, CBotTypResult( CBotTypIntrinsic, pClass ));
+ }
+ else
+ {
+ pThis = CBotVar::Create(name, CBotTypResult( CBotTypPointer, pClass ));
+ }
+
+ pThis->SetUniqNum(((CBotLeftExprVar*)m_var)->m_nIdent); // its attribute as unique number
+ pile->AddVar(pThis); // place on the stack
+ pile->IncState();
+ }
+
+ if ( pThis == NULL ) pThis = pile->FindVar(((CBotLeftExprVar*)m_var)->m_nIdent);
+
+ if ( pile->GivState()<3)
+ {
+ // ss there an assignment or parameters (contructor)
-// CBotVarClass* pInstance = NULL;
+// CBotVarClass* pInstance = NULL;
- if ( m_expr != NULL )
- {
- // evaluates the expression for the assignment
- if (!m_expr->Execute(pile)) return false;
-
- if ( bIntrincic )
- {
- CBotVar* pv = pile->GivVar();
- if ( pv == NULL || pv->GivPointer() == NULL )
- {
- pile->SetError(TX_NULLPT, &m_token);
- return pj->Return(pile);
- }
- pThis->Copy(pile->GivVar(), false);
- }
- else
- {
- CBotVarClass* pInstance;
- pInstance = ((CBotVarPointer*)pile->GivVar())->GivPointer(); // value for the assignment
- pThis->SetPointer(pInstance);
- }
- pThis->SetInit(true);
- }
+ if ( m_expr != NULL )
+ {
+ // evaluates the expression for the assignment
+ if (!m_expr->Execute(pile)) return false;
+
+ if ( bIntrincic )
+ {
+ CBotVar* pv = pile->GivVar();
+ if ( pv == NULL || pv->GivPointer() == NULL )
+ {
+ pile->SetError(TX_NULLPT, &m_token);
+ return pj->Return(pile);
+ }
+ pThis->Copy(pile->GivVar(), false);
+ }
+ else
+ {
+ CBotVarClass* pInstance;
+ pInstance = ((CBotVarPointer*)pile->GivVar())->GivPointer(); // value for the assignment
+ pThis->SetPointer(pInstance);
+ }
+ pThis->SetInit(true);
+ }
- else if ( m_hasParams )
- {
- // evaluates the constructor of an instance
+ else if ( m_hasParams )
+ {
+ // evaluates the constructor of an instance
- if ( !bIntrincic && pile->GivState() == 1)
- {
- CBotToken* pt = &m_token;
- CBotClass* pClass = CBotClass::Find(pt);
+ if ( !bIntrincic && pile->GivState() == 1)
+ {
+ CBotToken* pt = &m_token;
+ CBotClass* pClass = CBotClass::Find(pt);
- // creates an instance of the requested class
+ // creates an instance of the requested class
- CBotVarClass* pInstance;
- pInstance = (CBotVarClass*)CBotVar::Create("", pClass);
- pThis->SetPointer(pInstance);
- delete pInstance;
+ CBotVarClass* pInstance;
+ pInstance = (CBotVarClass*)CBotVar::Create("", pClass);
+ pThis->SetPointer(pInstance);
+ delete pInstance;
- pile->IncState();
- }
+ pile->IncState();
+ }
- CBotVar* ppVars[1000];
- CBotStack* pile2 = pile;
+ CBotVar* ppVars[1000];
+ CBotStack* pile2 = pile;
- int i = 0;
+ int i = 0;
- CBotInstr* p = m_Parameters;
- // evaluates the parameters
- // and places the values ​​on the stack
- // to (can) be interrupted (broken) at any time
+ CBotInstr* p = m_Parameters;
+ // evaluates the parameters
+ // and places the values ​​on the stack
+ // to (can) be interrupted (broken) at any time
- if ( p != NULL) while ( true )
- {
- pile2 = pile2->AddStack(); // place on the stack for the results
- if ( pile2->GivState() == 0 )
- {
- if (!p->Execute(pile2)) return false; // interrupted here?
- pile2->SetState(1);
- }
- ppVars[i++] = pile2->GivVar();
- p = p->GivNext();
- if ( p == NULL) break;
- }
- ppVars[i] = NULL;
+ if ( p != NULL) while ( true )
+ {
+ pile2 = pile2->AddStack(); // place on the stack for the results
+ if ( pile2->GivState() == 0 )
+ {
+ if (!p->Execute(pile2)) return false; // interrupted here?
+ pile2->SetState(1);
+ }
+ ppVars[i++] = pile2->GivVar();
+ p = p->GivNext();
+ if ( p == NULL) break;
+ }
+ ppVars[i] = NULL;
- // creates a variable for the result
- CBotVar* pResult = NULL; // constructor still void
-
- if ( !pClass->ExecuteMethode(m_nMethodeIdent, pClass->GivName(),
- pThis, ppVars,
- pResult, pile2, GivToken())) return false; // interrupt
-
- pThis->SetInit(true);
- pThis->ConstructorSet(); // indicates that the constructor has been called
- pile->Return(pile2); // releases a piece of stack
-
-// pInstance = pThis->GivPointer();
-
- }
-
-// if ( !bIntrincic ) pThis->SetPointer(pInstance); // a pointer to the instance
+ // creates a variable for the result
+ CBotVar* pResult = NULL; // constructor still void
+
+ if ( !pClass->ExecuteMethode(m_nMethodeIdent, pClass->GivName(),
+ pThis, ppVars,
+ pResult, pile2, GivToken())) return false; // interrupt
+
+ pThis->SetInit(true);
+ pThis->ConstructorSet(); // indicates that the constructor has been called
+ pile->Return(pile2); // releases a piece of stack
+
+// pInstance = pThis->GivPointer();
+
+ }
+
+// if ( !bIntrincic ) pThis->SetPointer(pInstance); // a pointer to the instance
- pile->SetState(3); // finished this part
- }
+ pile->SetState(3); // finished this part
+ }
- if ( pile->IfStep() ) return false;
+ if ( pile->IfStep() ) return false;
- if ( m_next2b != NULL &&
- !m_next2b->Execute(pile)) return false; // other (s) definition (s)
+ if ( m_next2b != NULL &&
+ !m_next2b->Execute(pile)) return false; // other (s) definition (s)
- return pj->Return( pile ); // transmits below (further)
+ return pj->Return( pile ); // transmits below (further)
}
void CBotClassInst::RestoreState(CBotStack* &pj, bool bMain)
{
- CBotVar* pThis = NULL;
+ CBotVar* pThis = NULL;
- CBotStack* pile = pj;
- if ( bMain ) pile = pj->RestoreStack(this);
- if ( pile == NULL ) return;
+ CBotStack* pile = pj;
+ if ( bMain ) pile = pj->RestoreStack(this);
+ if ( pile == NULL ) return;
- // creates the variable of type pointer to the object
- {
- CBotString name = m_var->m_token.GivString();
- pThis = pile->FindVar(name);
- pThis->SetUniqNum(((CBotLeftExprVar*)m_var)->m_nIdent); // its attribute a unique number
- }
+ // creates the variable of type pointer to the object
+ {
+ CBotString name = m_var->m_token.GivString();
+ pThis = pile->FindVar(name);
+ pThis->SetUniqNum(((CBotLeftExprVar*)m_var)->m_nIdent); // its attribute a unique number
+ }
- CBotToken* pt = &m_token;
- CBotClass* pClass = CBotClass::Find(pt);
- bool bIntrincic = pClass->IsIntrinsic();
+ CBotToken* pt = &m_token;
+ CBotClass* pClass = CBotClass::Find(pt);
+ bool bIntrincic = pClass->IsIntrinsic();
- if ( bMain && pile->GivState()<3)
- {
- // is there an assignment or parameters (constructor)
+ if ( bMain && pile->GivState()<3)
+ {
+ // is there an assignment or parameters (constructor)
-// CBotVarClass* pInstance = NULL;
+// CBotVarClass* pInstance = NULL;
- if ( m_expr != NULL )
- {
- // evaluates the expression for the assignment
- m_expr->RestoreState(pile, bMain);
- return;
- }
+ if ( m_expr != NULL )
+ {
+ // evaluates the expression for the assignment
+ m_expr->RestoreState(pile, bMain);
+ return;
+ }
- else if ( m_hasParams )
- {
- // evaluates the constructor of an instance
+ else if ( m_hasParams )
+ {
+ // evaluates the constructor of an instance
- if ( !bIntrincic && pile->GivState() == 1)
- {
- return;
- }
+ if ( !bIntrincic && pile->GivState() == 1)
+ {
+ return;
+ }
- CBotVar* ppVars[1000];
- CBotStack* pile2 = pile;
+ CBotVar* ppVars[1000];
+ CBotStack* pile2 = pile;
- int i = 0;
+ int i = 0;
- CBotInstr* p = m_Parameters;
- // evaluates the parameters
- // and the values an the stack
- // for the ability to be interrupted at any time (\TODO pour pouvoir être interrompu n'importe quand)
+ CBotInstr* p = m_Parameters;
+ // evaluates the parameters
+ // and the values an the stack
+ // for the ability to be interrupted at any time (\TODO pour pouvoir être interrompu n'importe quand)
- if ( p != NULL) while ( true )
- {
- pile2 = pile2->RestoreStack(); // place on the stack for the results
- if ( pile2 == NULL ) return;
+ if ( p != NULL) while ( true )
+ {
+ pile2 = pile2->RestoreStack(); // place on the stack for the results
+ if ( pile2 == NULL ) return;
- if ( pile2->GivState() == 0 )
- {
- p->RestoreState(pile2, bMain); // interrupted here?
- return;
- }
- ppVars[i++] = pile2->GivVar();
- p = p->GivNext();
- if ( p == NULL) break;
- }
- ppVars[i] = NULL;
+ if ( pile2->GivState() == 0 )
+ {
+ p->RestoreState(pile2, bMain); // interrupted here?
+ return;
+ }
+ ppVars[i++] = pile2->GivVar();
+ p = p->GivNext();
+ if ( p == NULL) break;
+ }
+ ppVars[i] = NULL;
- // creates a variable for the result
- CBotVar* pResult = NULL; // constructor still void
+ // creates a variable for the result
+ CBotVar* pResult = NULL; // constructor still void
- pClass->RestoreMethode(m_nMethodeIdent, pClass->GivName(), pThis, ppVars, pile2);
- return;
- }
- }
+ pClass->RestoreMethode(m_nMethodeIdent, pClass->GivName(), pThis, ppVars, pile2);
+ return;
+ }
+ }
- if ( m_next2b != NULL )
- m_next2b->RestoreState(pile, bMain); // other(s) definition(s)
+ if ( m_next2b != NULL )
+ m_next2b->RestoreState(pile, bMain); // other(s) definition(s)
}
@@ -861,22 +861,22 @@ void CBotClassInst::RestoreState(CBotStack* &pj, bool bMain)
bool CBotClass::CheckCall(CBotToken* &pToken, CBotDefParam* pParam)
{
- CBotString name = pToken->GivString();
+ CBotString name = pToken->GivString();
- if ( CBotCall::CheckCall(name) ) return true;
+ if ( CBotCall::CheckCall(name) ) return true;
- CBotFunction* pp = m_pMethod;
- while ( pp != NULL )
- {
- if ( pToken->GivString() == pp->GivName() )
- {
- // are their parameters exactly the same?
- if ( pp->CheckParam( pParam ) )
- return true;
- }
- pp = pp->Next();
- }
+ CBotFunction* pp = m_pMethod;
+ while ( pp != NULL )
+ {
+ if ( pToken->GivString() == pp->GivName() )
+ {
+ // are their parameters exactly the same?
+ if ( pp->CheckParam( pParam ) )
+ return true;
+ }
+ pp = pp->Next();
+ }
- return false;
+ return false;
}
diff --git a/src/CBot/CBotCompExpr.cpp b/src/CBot/CBotCompExpr.cpp
index 8ae507f..2daf53f 100644
--- a/src/CBot/CBotCompExpr.cpp
+++ b/src/CBot/CBotCompExpr.cpp
@@ -16,7 +16,7 @@
///////////////////////////////////////////////////
// expression of type Opérande1 > Opérande2
-// Opérande1 != Opérande2
+// Opérande1 != Opérande2
// etc.
#include "CBot.h"
@@ -25,15 +25,15 @@
CBotCompExpr::CBotCompExpr()
{
- m_leftop =
- m_rightop = NULL;
- name = "CBotCompExpr";
+ m_leftop =
+ m_rightop = NULL;
+ name = "CBotCompExpr";
}
CBotCompExpr::~CBotCompExpr()
{
- delete m_leftop;
- delete m_rightop;
+ delete m_leftop;
+ delete m_rightop;
}
fichier plus utilise;
@@ -42,44 +42,44 @@ fichier plus utilise;
CBotInstr* CBotCompExpr::Compile(CBotToken* &p, CBotCStack* pStack)
{
- CBotCStack* pStk = pStack->AddStack();
-
- CBotInstr* left = CBotAddExpr::Compile( p, pStk ); // expression A + B left
- if (left == NULL) return pStack->Return(NULL, pStk); // error
-
- 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) // the various comparisons
- {
- CBotCompExpr* inst = new CBotCompExpr(); // element for operation
- inst->SetToken(p); // stores the operation
-
- int type1, type2;
- type1 = pStack->GetType();
-
- p = p->Next();
- if ( NULL != (inst->m_rightop = CBotAddExpr::Compile( p, pStk )) ) // expression A + B right
- {
- type2 = pStack->GetType();
- // are the results compatible
- if ( type1 == type2 )
- {
- inst->m_leftop = left;
- pStk->SetVar(new CBotVar(NULL, CBotTypBoolean));
- // the result is a boolean
- return pStack->Return(inst, pStk);
- }
- }
-
- delete left;
- delete inst;
- return pStack->Return(NULL, pStk);
- }
-
- return pStack->Return(left, pStk);
+ CBotCStack* pStk = pStack->AddStack();
+
+ CBotInstr* left = CBotAddExpr::Compile( p, pStk ); // expression A + B left
+ if (left == NULL) return pStack->Return(NULL, pStk); // error
+
+ 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) // the various comparisons
+ {
+ CBotCompExpr* inst = new CBotCompExpr(); // element for operation
+ inst->SetToken(p); // stores the operation
+
+ int type1, type2;
+ type1 = pStack->GetType();
+
+ p = p->Next();
+ if ( NULL != (inst->m_rightop = CBotAddExpr::Compile( p, pStk )) ) // expression A + B right
+ {
+ type2 = pStack->GetType();
+ // are the results compatible
+ if ( type1 == type2 )
+ {
+ inst->m_leftop = left;
+ pStk->SetVar(new CBotVar(NULL, CBotTypBoolean));
+ // the result is a boolean
+ return pStack->Return(inst, pStk);
+ }
+ }
+
+ delete left;
+ delete inst;
+ return pStack->Return(NULL, pStk);
+ }
+
+ return pStack->Return(left, pStk);
}
@@ -87,47 +87,47 @@ CBotInstr* CBotCompExpr::Compile(CBotToken* &p, CBotCStack* pStack)
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; // interrupted here ?
-
- pStk1->SetState(1); // finished
-
- // requires a little more stack to not touch the result of the left
- CBotStack* pStk2 = pStk1->AddStack();
-
- if ( !m_rightop->Execute(pStk2) ) return FALSE; // interrupted here ?
-
- 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()); // lower
- break;
- case ID_HI:
- result->Hi(pStk1->GetVar(), pStk2->GetVar()); // higher
- break;
- case ID_LS:
- result->Ls(pStk1->GetVar(), pStk2->GetVar()); // lower or equal
- break;
- case ID_HS:
- result->Hs(pStk1->GetVar(), pStk2->GetVar()); // higher of equal
- break;
- case ID_EQ:
- result->Eq(pStk1->GetVar(), pStk2->GetVar()); // equal
- break;
- case ID_NE:
- result->Ne(pStk1->GetVar(), pStk2->GetVar()); // not equal
- break;
- }
- pStk2->SetVar(result); // puts the result on the stack
-
- pStk1->Return(pStk2); // frees the stack
- return pStack->Return(pStk1); // transmit the result
+ CBotStack* pStk1 = pStack->AddStack(this);
+// if ( pStk1 == EOX ) return TRUE;
+
+ if ( pStk1->GetState() == 0 && !m_leftop->Execute(pStk1) ) return FALSE; // interrupted here ?
+
+ pStk1->SetState(1); // finished
+
+ // requires a little more stack to not touch the result of the left
+ CBotStack* pStk2 = pStk1->AddStack();
+
+ if ( !m_rightop->Execute(pStk2) ) return FALSE; // interrupted here ?
+
+ 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()); // lower
+ break;
+ case ID_HI:
+ result->Hi(pStk1->GetVar(), pStk2->GetVar()); // higher
+ break;
+ case ID_LS:
+ result->Ls(pStk1->GetVar(), pStk2->GetVar()); // lower or equal
+ break;
+ case ID_HS:
+ result->Hs(pStk1->GetVar(), pStk2->GetVar()); // higher of equal
+ break;
+ case ID_EQ:
+ result->Eq(pStk1->GetVar(), pStk2->GetVar()); // equal
+ break;
+ case ID_NE:
+ result->Ne(pStk1->GetVar(), pStk2->GetVar()); // not equal
+ break;
+ }
+ pStk2->SetVar(result); // puts the result on the stack
+
+ pStk1->Return(pStk2); // frees the stack
+ return pStack->Return(pStk1); // transmit the result
}
diff --git a/src/CBot/CBotFunction.cpp b/src/CBot/CBotFunction.cpp
index 756c6cb..1c94c1b 100644
--- a/src/CBot/CBotFunction.cpp
+++ b/src/CBot/CBotFunction.cpp
@@ -25,147 +25,147 @@
// pour libérer tout selon l'arbre établi
CBotFunction::CBotFunction()
{
- m_Param = NULL; // empty parameter list
- m_Block = NULL; // the instruction block
- m_next = NULL; // functions can be chained
- m_bPublic = false; // function not public
- m_bExtern = false; // function not extern
- m_nextpublic = NULL;
- m_prevpublic = NULL;
- m_pProg = NULL;
-// m_nThisIdent = 0;
- m_nFuncIdent = 0;
- m_bSynchro = false;
+ m_Param = NULL; // empty parameter list
+ m_Block = NULL; // the instruction block
+ m_next = NULL; // functions can be chained
+ m_bPublic = false; // function not public
+ m_bExtern = false; // function not extern
+ m_nextpublic = NULL;
+ m_prevpublic = NULL;
+ m_pProg = NULL;
+// m_nThisIdent = 0;
+ m_nFuncIdent = 0;
+ m_bSynchro = false;
}
CBotFunction* CBotFunction::m_listPublic = NULL;
CBotFunction::~CBotFunction()
{
- delete m_Param; // empty parameter list
- delete m_Block; // the instruction block
- delete m_next;
-
- // remove public list if there is
- if ( m_bPublic )
- {
- if ( m_nextpublic != NULL )
- {
- m_nextpublic->m_prevpublic = m_prevpublic;
- }
- if ( m_prevpublic != NULL)
- {
- m_prevpublic->m_nextpublic = m_nextpublic;
- }
- else
- {
- // if prev = next = null may not be in the list!
- if ( m_listPublic == this ) m_listPublic = m_nextpublic;
- }
- }
+ delete m_Param; // empty parameter list
+ delete m_Block; // the instruction block
+ delete m_next;
+
+ // remove public list if there is
+ if ( m_bPublic )
+ {
+ if ( m_nextpublic != NULL )
+ {
+ m_nextpublic->m_prevpublic = m_prevpublic;
+ }
+ if ( m_prevpublic != NULL)
+ {
+ m_prevpublic->m_nextpublic = m_nextpublic;
+ }
+ else
+ {
+ // if prev = next = null may not be in the list!
+ if ( m_listPublic == this ) m_listPublic = m_nextpublic;
+ }
+ }
}
bool CBotFunction::IsPublic()
{
- return m_bPublic;
+ return m_bPublic;
}
bool CBotFunction::IsExtern()
{
- return m_bExtern;
+ return m_bExtern;
}
bool CBotFunction::GetPosition(int& start, int& stop, CBotGet modestart, CBotGet modestop)
{
- start = m_extern.GivStart();
- stop = m_closeblk.GivEnd();
-
- if (modestart == GetPosExtern)
- {
- start = m_extern.GivStart();
- }
- if (modestop == GetPosExtern)
- {
- stop = m_extern.GivEnd();
- }
- if (modestart == GetPosNom)
- {
- start = m_token.GivStart();
- }
- if (modestop == GetPosNom)
- {
- stop = m_token.GivEnd();
- }
- if (modestart == GetPosParam)
- {
- start = m_openpar.GivStart();
- }
- if (modestop == GetPosParam)
- {
- stop = m_closepar.GivEnd();
- }
- if (modestart == GetPosBloc)
- {
- start = m_openblk.GivStart();
- }
- if (modestop == GetPosBloc)
- {
- stop = m_closeblk.GivEnd();
- }
-
- return true;
+ start = m_extern.GivStart();
+ stop = m_closeblk.GivEnd();
+
+ if (modestart == GetPosExtern)
+ {
+ start = m_extern.GivStart();
+ }
+ if (modestop == GetPosExtern)
+ {
+ stop = m_extern.GivEnd();
+ }
+ if (modestart == GetPosNom)
+ {
+ start = m_token.GivStart();
+ }
+ if (modestop == GetPosNom)
+ {
+ stop = m_token.GivEnd();
+ }
+ if (modestart == GetPosParam)
+ {
+ start = m_openpar.GivStart();
+ }
+ if (modestop == GetPosParam)
+ {
+ stop = m_closepar.GivEnd();
+ }
+ if (modestart == GetPosBloc)
+ {
+ start = m_openblk.GivStart();
+ }
+ if (modestop == GetPosBloc)
+ {
+ stop = m_closeblk.GivEnd();
+ }
+
+ return true;
}
-CBotTypResult ArrayType(CBotToken* &p, CBotCStack* pile, CBotTypResult type)
+CBotTypResult ArrayType(CBotToken* &p, CBotCStack* pile, CBotTypResult type)
{
- while ( IsOfType( p, ID_OPBRK ) )
- {
- if ( !IsOfType( p, ID_CLBRK ) )
- {
- pile->SetError(TX_CLBRK, p->GivStart());
- return CBotTypResult( -1 );
- }
- type = CBotTypResult( CBotTypArrayPointer, type );
- }
- return type;
+ while ( IsOfType( p, ID_OPBRK ) )
+ {
+ if ( !IsOfType( p, ID_CLBRK ) )
+ {
+ pile->SetError(TX_CLBRK, p->GivStart());
+ return CBotTypResult( -1 );
+ }
+ type = CBotTypResult( CBotTypArrayPointer, type );
+ }
+ return type;
}
-CBotTypResult TypeParam(CBotToken* &p, CBotCStack* pile)
+CBotTypResult TypeParam(CBotToken* &p, CBotCStack* pile)
{
- CBotClass* pClass = NULL;
-
- switch (p->GivType())
- {
- case ID_INT:
- p = p->GivNext();
- return ArrayType(p, pile, CBotTypResult( CBotTypInt ));
- case ID_FLOAT:
- p = p->GivNext();
- return ArrayType(p, pile, CBotTypResult( CBotTypFloat ));
- case ID_BOOLEAN:
- case ID_BOOL:
- p = p->GivNext();
- return ArrayType(p, pile, CBotTypResult( CBotTypBoolean ));
- case ID_STRING:
- p = p->GivNext();
- return ArrayType(p, pile, CBotTypResult( CBotTypString ));
- case ID_VOID:
- p = p->GivNext();
- return CBotTypResult( 0 );
-
- case TokenTypVar:
- pClass = CBotClass::Find(p);
- if ( pClass != NULL)
- {
- p = p->GivNext();
- return ArrayType(p, pile,
- pClass->IsIntrinsic() ?
- CBotTypResult( CBotTypIntrinsic, pClass ) :
- CBotTypResult( CBotTypPointer, pClass ) );
- }
- }
- return CBotTypResult( -1 );
+ CBotClass* pClass = NULL;
+
+ switch (p->GivType())
+ {
+ case ID_INT:
+ p = p->GivNext();
+ return ArrayType(p, pile, CBotTypResult( CBotTypInt ));
+ case ID_FLOAT:
+ p = p->GivNext();
+ return ArrayType(p, pile, CBotTypResult( CBotTypFloat ));
+ case ID_BOOLEAN:
+ case ID_BOOL:
+ p = p->GivNext();
+ return ArrayType(p, pile, CBotTypResult( CBotTypBoolean ));
+ case ID_STRING:
+ p = p->GivNext();
+ return ArrayType(p, pile, CBotTypResult( CBotTypString ));
+ case ID_VOID:
+ p = p->GivNext();
+ return CBotTypResult( 0 );
+
+ case TokenTypVar:
+ pClass = CBotClass::Find(p);
+ if ( pClass != NULL)
+ {
+ p = p->GivNext();
+ return ArrayType(p, pile,
+ pClass->IsIntrinsic() ?
+ CBotTypResult( CBotTypIntrinsic, pClass ) :
+ CBotTypResult( CBotTypPointer, pClass ) );
+ }
+ }
+ return CBotTypResult( -1 );
}
// compiles a new function
@@ -173,297 +173,297 @@ CBotTypResult TypeParam(CBotToken* &p, CBotCStack* pile)
// as the elements belonging to the class for methods
CBotFunction* CBotFunction::Compile(CBotToken* &p, CBotCStack* pStack, CBotFunction* finput, bool bLocal)
{
- CBotToken* pp;
- CBotFunction* func = finput;
- if ( func == NULL ) func = new CBotFunction();
-
- CBotCStack* pStk = pStack->TokenStack(p, bLocal);
-
-// func->m_nFuncIdent = CBotVar::NextUniqNum();
-
- while (true)
- {
- if ( IsOfType(p, ID_PUBLIC) )
- {
- func->m_bPublic = true;
- continue;
- }
- pp = p;
- if ( IsOfType(p, ID_EXTERN) )
- {
- func->m_extern = pp; // for the position of the word "extern"
- func->m_bExtern = true;
-// func->m_bPublic = true; // therefore also public!
- continue;
- }
- break;
- }
-
- func->m_retToken = *p;
-// CBotClass* pClass;
- func->m_retTyp = TypeParam(p, pStk); // type of the result
-
- if (func->m_retTyp.GivType() >= 0)
- {
- CBotToken* pp = p;
- func->m_token = *p;
-
- if ( IsOfType(p, ID_NOT) )
- {
- CBotToken d("~" + p->GivString());
- func->m_token = d;
- }
-
- // un nom de fonction est-il là ?
- if (IsOfType(p, TokenTypVar))
- {
- if ( IsOfType( p, ID_DBLDOTS ) ) // method for a class
- {
- func->m_MasterClass = pp->GivString();
- CBotClass* pClass = CBotClass::Find(pp);
- if ( pClass == NULL ) goto bad;
-
-// pp = p;
- func->m_token = *p;
- if (!IsOfType(p, TokenTypVar)) goto bad;
-
- }
- func->m_openpar = p;
- func->m_Param = CBotDefParam::Compile( p, pStk );
- func->m_closepar = p->GivPrev();
- if (pStk->IsOk())
- {
- pStk->SetRetType(func->m_retTyp); // for knowledge what type returns
-
- if (!func->m_MasterClass.IsEmpty())
- {
- // return "this" known
- CBotVar* pThis = CBotVar::Create("this", CBotTypResult( CBotTypClass, func->m_MasterClass ));
- pThis->SetInit(2);
-// pThis->SetUniqNum(func->m_nThisIdent = -2); //CBotVar::NextUniqNum() will not
- pThis->SetUniqNum(-2);
- pStk->AddVar(pThis);
-
- // initialize variables acording to This
- // only saves the pointer to the first,
- // the rest is chained
- CBotVar* pv = pThis->GivItemList();
-// int num = 1;
- while (pv != NULL)
- {
- CBotVar* pcopy = CBotVar::Create(pv);
-// pcopy->SetInit(2);
- pcopy->Copy(pv);
- pcopy->SetPrivate(pv->GivPrivate());
-// pcopy->SetUniqNum(pv->GivUniqNum()); //num++);
- pStk->AddVar(pcopy);
- pv = pv->GivNext();
- }
- }
-
- // and compiles the following instruction block
- func->m_openblk = p;
- func->m_Block = CBotBlock::Compile(p, pStk, false);
- func->m_closeblk = p->GivPrev();
- if ( pStk->IsOk() )
- {
- if ( func->m_bPublic ) // public function, return known for all
- {
- CBotFunction::AddPublic(func);
- }
- return pStack->ReturnFunc(func, pStk);
- }
- }
- }
+ CBotToken* pp;
+ CBotFunction* func = finput;
+ if ( func == NULL ) func = new CBotFunction();
+
+ CBotCStack* pStk = pStack->TokenStack(p, bLocal);
+
+// func->m_nFuncIdent = CBotVar::NextUniqNum();
+
+ while (true)
+ {
+ if ( IsOfType(p, ID_PUBLIC) )
+ {
+ func->m_bPublic = true;
+ continue;
+ }
+ pp = p;
+ if ( IsOfType(p, ID_EXTERN) )
+ {
+ func->m_extern = pp; // for the position of the word "extern"
+ func->m_bExtern = true;
+// func->m_bPublic = true; // therefore also public!
+ continue;
+ }
+ break;
+ }
+
+ func->m_retToken = *p;
+// CBotClass* pClass;
+ func->m_retTyp = TypeParam(p, pStk); // type of the result
+
+ if (func->m_retTyp.GivType() >= 0)
+ {
+ CBotToken* pp = p;
+ func->m_token = *p;
+
+ if ( IsOfType(p, ID_NOT) )
+ {
+ CBotToken d("~" + p->GivString());
+ func->m_token = d;
+ }
+
+ // un nom de fonction est-il là ?
+ if (IsOfType(p, TokenTypVar))
+ {
+ if ( IsOfType( p, ID_DBLDOTS ) ) // method for a class
+ {
+ func->m_MasterClass = pp->GivString();
+ CBotClass* pClass = CBotClass::Find(pp);
+ if ( pClass == NULL ) goto bad;
+
+// pp = p;
+ func->m_token = *p;
+ if (!IsOfType(p, TokenTypVar)) goto bad;
+
+ }
+ func->m_openpar = p;
+ func->m_Param = CBotDefParam::Compile( p, pStk );
+ func->m_closepar = p->GivPrev();
+ if (pStk->IsOk())
+ {
+ pStk->SetRetType(func->m_retTyp); // for knowledge what type returns
+
+ if (!func->m_MasterClass.IsEmpty())
+ {
+ // return "this" known
+ CBotVar* pThis = CBotVar::Create("this", CBotTypResult( CBotTypClass, func->m_MasterClass ));
+ pThis->SetInit(2);
+// pThis->SetUniqNum(func->m_nThisIdent = -2); //CBotVar::NextUniqNum() will not
+ pThis->SetUniqNum(-2);
+ pStk->AddVar(pThis);
+
+ // initialize variables acording to This
+ // only saves the pointer to the first,
+ // the rest is chained
+ CBotVar* pv = pThis->GivItemList();
+// int num = 1;
+ while (pv != NULL)
+ {
+ CBotVar* pcopy = CBotVar::Create(pv);
+// pcopy->SetInit(2);
+ pcopy->Copy(pv);
+ pcopy->SetPrivate(pv->GivPrivate());
+// pcopy->SetUniqNum(pv->GivUniqNum()); //num++);
+ pStk->AddVar(pcopy);
+ pv = pv->GivNext();
+ }
+ }
+
+ // and compiles the following instruction block
+ func->m_openblk = p;
+ func->m_Block = CBotBlock::Compile(p, pStk, false);
+ func->m_closeblk = p->GivPrev();
+ if ( pStk->IsOk() )
+ {
+ if ( func->m_bPublic ) // public function, return known for all
+ {
+ CBotFunction::AddPublic(func);
+ }
+ return pStack->ReturnFunc(func, pStk);
+ }
+ }
+ }
bad:
- pStk->SetError(TX_NOFONC, p);
- }
- pStk->SetError(TX_NOTYP, p);
- if ( finput == NULL ) delete func;
- return pStack->ReturnFunc(NULL, pStk);
+ pStk->SetError(TX_NOFONC, p);
+ }
+ pStk->SetError(TX_NOTYP, p);
+ if ( finput == NULL ) delete func;
+ return pStack->ReturnFunc(NULL, pStk);
}
// pre-compile a new function
-CBotFunction* CBotFunction::Compile1(CBotToken* &p, CBotCStack* pStack, CBotClass* pClass)
+CBotFunction* CBotFunction::Compile1(CBotToken* &p, CBotCStack* pStack, CBotClass* pClass)
{
- CBotFunction* func = new CBotFunction();
- func->m_nFuncIdent = CBotVar::NextUniqNum();
-
- CBotCStack* pStk = pStack->TokenStack(p, true);
-
- while (true)
- {
- if ( IsOfType(p, ID_PUBLIC) )
- {
- // func->m_bPublic = true; // will be done in two passes
- continue;
- }
- if ( IsOfType(p, ID_EXTERN) )
- {
- func->m_bExtern = true;
- continue;
- }
- break;
- }
-
- func->m_retToken = *p;
- func->m_retTyp = TypeParam(p, pStack); // type of the result
-
- if (func->m_retTyp.GivType() >= 0)
- {
- CBotToken* pp = p;
- func->m_token = *p;
- // un nom de fonction est-il là ?
- if (IsOfType(p, TokenTypVar))
- {
- if ( IsOfType( p, ID_DBLDOTS ) ) // method for a class
- {
- func->m_MasterClass = pp->GivString();
- CBotClass* pClass = CBotClass::Find(pp);
- if ( pClass == NULL )
- {
- pStk->SetError(TX_NOCLASS, pp);
- goto bad;
- }
-
- pp = p;
- func->m_token = *p;
- if (!IsOfType(p, TokenTypVar)) goto bad;
-
- }
- func->m_Param = CBotDefParam::Compile( p, pStk );
- if (pStk->IsOk())
- {
- // looks if the function exists elsewhere
- if (( pClass != NULL || !pStack->CheckCall(pp, func->m_Param)) &&
- ( pClass == NULL || !pClass->CheckCall(pp, func->m_Param)) )
- {
- if (IsOfType(p, ID_OPBLK))
- {
- int level = 1;
- // and skips the following instruction block
- do
- {
- int type = p->GivType();
- p = p->GivNext();
- if (type == ID_OPBLK) level++;
- if (type == ID_CLBLK) level--;
- }
- while (level > 0 && p != NULL);
-
- return pStack->ReturnFunc(func, pStk);
- }
- pStk->SetError(TX_OPENBLK, p);
- }
- }
- pStk->SetError(TX_REDEF, pp);
- }
+ CBotFunction* func = new CBotFunction();
+ func->m_nFuncIdent = CBotVar::NextUniqNum();
+
+ CBotCStack* pStk = pStack->TokenStack(p, true);
+
+ while (true)
+ {
+ if ( IsOfType(p, ID_PUBLIC) )
+ {
+ // func->m_bPublic = true; // will be done in two passes
+ continue;
+ }
+ if ( IsOfType(p, ID_EXTERN) )
+ {
+ func->m_bExtern = true;
+ continue;
+ }
+ break;
+ }
+
+ func->m_retToken = *p;
+ func->m_retTyp = TypeParam(p, pStack); // type of the result
+
+ if (func->m_retTyp.GivType() >= 0)
+ {
+ CBotToken* pp = p;
+ func->m_token = *p;
+ // un nom de fonction est-il là ?
+ if (IsOfType(p, TokenTypVar))
+ {
+ if ( IsOfType( p, ID_DBLDOTS ) ) // method for a class
+ {
+ func->m_MasterClass = pp->GivString();
+ CBotClass* pClass = CBotClass::Find(pp);
+ if ( pClass == NULL )
+ {
+ pStk->SetError(TX_NOCLASS, pp);
+ goto bad;
+ }
+
+ pp = p;
+ func->m_token = *p;
+ if (!IsOfType(p, TokenTypVar)) goto bad;
+
+ }
+ func->m_Param = CBotDefParam::Compile( p, pStk );
+ if (pStk->IsOk())
+ {
+ // looks if the function exists elsewhere
+ if (( pClass != NULL || !pStack->CheckCall(pp, func->m_Param)) &&
+ ( pClass == NULL || !pClass->CheckCall(pp, func->m_Param)) )
+ {
+ if (IsOfType(p, ID_OPBLK))
+ {
+ int level = 1;
+ // and skips the following instruction block
+ do
+ {
+ int type = p->GivType();
+ p = p->GivNext();
+ if (type == ID_OPBLK) level++;
+ if (type == ID_CLBLK) level--;
+ }
+ while (level > 0 && p != NULL);
+
+ return pStack->ReturnFunc(func, pStk);
+ }
+ pStk->SetError(TX_OPENBLK, p);
+ }
+ }
+ pStk->SetError(TX_REDEF, pp);
+ }
bad:
- pStk->SetError(TX_NOFONC, p);
- }
- pStk->SetError(TX_NOTYP, p);
- delete func;
- return pStack->ReturnFunc(NULL, pStk);
+ pStk->SetError(TX_NOFONC, p);
+ }
+ pStk->SetError(TX_NOTYP, p);
+ delete func;
+ return pStack->ReturnFunc(NULL, pStk);
}
-#ifdef _DEBUG
+#ifdef _DEBUG
static int xx = 0;
#endif
bool CBotFunction::Execute(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInstance)
{
- CBotStack* pile = pj->AddStack(this, 2); // one end of stack local to this function
-// if ( pile == EOX ) return true;
-
- pile->SetBotCall(m_pProg); // bases for routines
-
- if ( pile->GivState() == 0 )
- {
- if ( !m_Param->Execute(ppVars, pile) ) return false; // define parameters
- pile->IncState();
- }
-
- if ( pile->GivState() == 1 && !m_MasterClass.IsEmpty() )
- {
- // makes "this" known
- CBotVar* pThis ;
- if ( pInstance == NULL )
- {
- pThis = CBotVar::Create("this", CBotTypResult( CBotTypClass, m_MasterClass ));
- pThis->SetInit(2);
- }
- else
- {
- pThis = CBotVar::Create("this", CBotTypResult( CBotTypPointer, m_MasterClass ));
- pThis->SetPointer(pInstance);
- pThis->SetInit(2);
- }
-
-// pThis->SetUniqNum(m_nThisIdent);
- pThis->SetUniqNum(-2);
- pile->AddVar(pThis);
-
- pile->IncState();
- }
-
- if ( pile->IfStep() ) return false;
-
- if ( !m_Block->Execute(pile) )
- {
- if ( pile->GivError() < 0 )
- pile->SetError( 0 );
- else
- return false;
- }
-
- return pj->Return(pile);
+ CBotStack* pile = pj->AddStack(this, 2); // one end of stack local to this function
+// if ( pile == EOX ) return true;
+
+ pile->SetBotCall(m_pProg); // bases for routines
+
+ if ( pile->GivState() == 0 )
+ {
+ if ( !m_Param->Execute(ppVars, pile) ) return false; // define parameters
+ pile->IncState();
+ }
+
+ if ( pile->GivState() == 1 && !m_MasterClass.IsEmpty() )
+ {
+ // makes "this" known
+ CBotVar* pThis ;
+ if ( pInstance == NULL )
+ {
+ pThis = CBotVar::Create("this", CBotTypResult( CBotTypClass, m_MasterClass ));
+ pThis->SetInit(2);
+ }
+ else
+ {
+ pThis = CBotVar::Create("this", CBotTypResult( CBotTypPointer, m_MasterClass ));
+ pThis->SetPointer(pInstance);
+ pThis->SetInit(2);
+ }
+
+// pThis->SetUniqNum(m_nThisIdent);
+ pThis->SetUniqNum(-2);
+ pile->AddVar(pThis);
+
+ pile->IncState();
+ }
+
+ if ( pile->IfStep() ) return false;
+
+ if ( !m_Block->Execute(pile) )
+ {
+ if ( pile->GivError() < 0 )
+ pile->SetError( 0 );
+ else
+ return false;
+ }
+
+ return pj->Return(pile);
}
void CBotFunction::RestoreState(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInstance)
{
- CBotStack* pile = pj->RestoreStack(this); // one end of stack local to this function
- if ( pile == NULL ) return;
- CBotStack* pile2 = pile;
-
- pile->SetBotCall(m_pProg); // bases for routines
-
- if ( pile->GivBlock() < 2 )
- {
- CBotStack* pile2 = pile->RestoreStack(NULL); // one end of stack local to this function
- if ( pile2 == NULL ) return;
- pile->SetState(pile->GivState() + pile2->GivState());
- pile2->Delete();
- }
-
- m_Param->RestoreState(pile2, true); // parameters
-
- if ( !m_MasterClass.IsEmpty() )
- {
- CBotVar* pThis = pile->FindVar("this");
- pThis->SetInit(2);
- pThis->SetUniqNum(-2);
- }
-
- m_Block->RestoreState(pile2, true);
+ CBotStack* pile = pj->RestoreStack(this); // one end of stack local to this function
+ if ( pile == NULL ) return;
+ CBotStack* pile2 = pile;
+
+ pile->SetBotCall(m_pProg); // bases for routines
+
+ if ( pile->GivBlock() < 2 )
+ {
+ CBotStack* pile2 = pile->RestoreStack(NULL); // one end of stack local to this function
+ if ( pile2 == NULL ) return;
+ pile->SetState(pile->GivState() + pile2->GivState());
+ pile2->Delete();
+ }
+
+ m_Param->RestoreState(pile2, true); // parameters
+
+ if ( !m_MasterClass.IsEmpty() )
+ {
+ CBotVar* pThis = pile->FindVar("this");
+ pThis->SetInit(2);
+ pThis->SetUniqNum(-2);
+ }
+
+ m_Block->RestoreState(pile2, true);
}
void CBotFunction::AddNext(CBotFunction* p)
{
- CBotFunction* pp = this;
- while (pp->m_next != NULL) pp = pp->m_next;
+ CBotFunction* pp = this;
+ while (pp->m_next != NULL) pp = pp->m_next;
- pp->m_next = p;
+ pp->m_next = p;
}
CBotTypResult CBotFunction::CompileCall(const char* name, CBotVar** ppVars, long& nIdent)
{
- nIdent = 0;
- CBotTypResult type;
+ nIdent = 0;
+ CBotTypResult type;
- CBotFunction* pt = FindLocalOrPublic(nIdent, name, ppVars, type);
- return type;
+ CBotFunction* pt = FindLocalOrPublic(nIdent, name, ppVars, type);
+ return type;
}
@@ -472,154 +472,154 @@ CBotTypResult CBotFunction::CompileCall(const char* name, CBotVar** ppVars, long
CBotFunction* CBotFunction::FindLocalOrPublic(long& nIdent, const char* name, CBotVar** ppVars, CBotTypResult& TypeOrError, bool bPublic)
{
- TypeOrError.SetType(TX_UNDEFCALL); // no routine of the name
- CBotFunction* pt;
-
- if ( nIdent )
- {
- if ( this != NULL ) for ( pt = this ; pt != NULL ; pt = pt->m_next )
- {
- if ( pt->m_nFuncIdent == nIdent )
- {
- TypeOrError = pt->m_retTyp;
- return pt;
- }
- }
-
- // search the list of public functions
-
- for ( pt = m_listPublic ; pt != NULL ; pt = pt->m_nextpublic )
- {
- if ( pt->m_nFuncIdent == nIdent )
- {
- TypeOrError = pt->m_retTyp;
- return pt;
- }
- }
- }
-
- if ( name == NULL ) return NULL;
-
- int delta = 99999; // seeks the lowest signature
- CBotFunction* pFunc = NULL; // the best function found
-
- if ( this != NULL )
- {
- for ( pt = this ; pt != NULL ; pt = pt->m_next )
- {
- if ( pt->m_token.GivString() == name )
- {
- int i = 0;
- int alpha = 0; // signature of parameters
- // parameters are compatible?
- CBotDefParam* pv = pt->m_Param; // expected list of parameters
- CBotVar* pw = ppVars[i++]; // provided list parameter
- while ( pv != NULL && pw != NULL)
- {
- if (!TypesCompatibles(pv->GivTypResult(), pw->GivTypResult()))
- {
- if ( pFunc == NULL ) TypeOrError = TX_BADPARAM;
- break;
- }
- int d = pv->GivType() - pw->GivType(2);
- alpha += d>0 ? d : -10*d; // quality loss, 10 times more expensive!
-
- pv = pv->GivNext();
- pw = ppVars[i++];
- }
- if ( pw != NULL )
- {
- if ( pFunc != NULL ) continue;
- if ( TypeOrError.Eq(TX_LOWPARAM) ) TypeOrError.SetType(TX_NUMPARAM);
- if ( TypeOrError.Eq(TX_UNDEFCALL)) TypeOrError.SetType(TX_OVERPARAM);
- continue; // too many parameters
- }
- if ( pv != NULL )
- {
- if ( pFunc != NULL ) continue;
- if ( TypeOrError.Eq(TX_OVERPARAM) ) TypeOrError.SetType(TX_NUMPARAM);
- if ( TypeOrError.Eq(TX_UNDEFCALL) ) TypeOrError.SetType(TX_LOWPARAM);
- continue; // not enough parameters
- }
-
- if (alpha == 0) // perfect signature
- {
- nIdent = pt->m_nFuncIdent;
- TypeOrError = pt->m_retTyp;
- return pt;
- }
-
- if ( alpha < delta ) // a better signature?
- {
- pFunc = pt;
- delta = alpha;
- }
- }
- }
- }
-
- if ( bPublic )
- {
- for ( pt = m_listPublic ; pt != NULL ; pt = pt->m_nextpublic )
- {
- if ( pt->m_token.GivString() == name )
- {
- int i = 0;
- int alpha = 0; // signature of parameters
- // parameters sont-ils compatibles ?
- CBotDefParam* pv = pt->m_Param; // list of expected parameters
- CBotVar* pw = ppVars[i++]; // list of provided parameters
- while ( pv != NULL && pw != NULL)
- {
- if (!TypesCompatibles(pv->GivTypResult(), pw->GivTypResult()))
- {
- if ( pFunc == NULL ) TypeOrError = TX_BADPARAM;
- break;
- }
- int d = pv->GivType() - pw->GivType(2);
- alpha += d>0 ? d : -10*d; // quality loss, 10 times more expensive!
-
- pv = pv->GivNext();
- pw = ppVars[i++];
- }
- if ( pw != NULL )
- {
- if ( pFunc != NULL ) continue;
- if ( TypeOrError.Eq(TX_LOWPARAM) ) TypeOrError.SetType(TX_NUMPARAM);
- if ( TypeOrError.Eq(TX_UNDEFCALL)) TypeOrError.SetType(TX_OVERPARAM);
- continue; // to many parameters
- }
- if ( pv != NULL )
- {
- if ( pFunc != NULL ) continue;
- if ( TypeOrError.Eq(TX_OVERPARAM) ) TypeOrError.SetType(TX_NUMPARAM);
- if ( TypeOrError.Eq(TX_UNDEFCALL) ) TypeOrError.SetType(TX_LOWPARAM);
- continue; // not enough parameters
- }
-
- if (alpha == 0) // perfect signature
- {
- nIdent = pt->m_nFuncIdent;
- TypeOrError = pt->m_retTyp;
- return pt;
- }
-
- if ( alpha < delta ) // a better signature?
- {
- pFunc = pt;
- delta = alpha;
- }
- }
- }
- }
-
- if ( pFunc != NULL )
- {
- nIdent = pFunc->m_nFuncIdent;
- TypeOrError = pFunc->m_retTyp;
- return pFunc;
- }
- return NULL;
+ TypeOrError.SetType(TX_UNDEFCALL); // no routine of the name
+ CBotFunction* pt;
+
+ if ( nIdent )
+ {
+ if ( this != NULL ) for ( pt = this ; pt != NULL ; pt = pt->m_next )
+ {
+ if ( pt->m_nFuncIdent == nIdent )
+ {
+ TypeOrError = pt->m_retTyp;
+ return pt;
+ }
+ }
+
+ // search the list of public functions
+
+ for ( pt = m_listPublic ; pt != NULL ; pt = pt->m_nextpublic )
+ {
+ if ( pt->m_nFuncIdent == nIdent )
+ {
+ TypeOrError = pt->m_retTyp;
+ return pt;
+ }
+ }
+ }
+
+ if ( name == NULL ) return NULL;
+
+ int delta = 99999; // seeks the lowest signature
+ CBotFunction* pFunc = NULL; // the best function found
+
+ if ( this != NULL )
+ {
+ for ( pt = this ; pt != NULL ; pt = pt->m_next )
+ {
+ if ( pt->m_token.GivString() == name )
+ {
+ int i = 0;
+ int alpha = 0; // signature of parameters
+ // parameters are compatible?
+ CBotDefParam* pv = pt->m_Param; // expected list of parameters
+ CBotVar* pw = ppVars[i++]; // provided list parameter
+ while ( pv != NULL && pw != NULL)
+ {
+ if (!TypesCompatibles(pv->GivTypResult(), pw->GivTypResult()))
+ {
+ if ( pFunc == NULL ) TypeOrError = TX_BADPARAM;
+ break;
+ }
+ int d = pv->GivType() - pw->GivType(2);
+ alpha += d>0 ? d : -10*d; // quality loss, 10 times more expensive!
+
+ pv = pv->GivNext();
+ pw = ppVars[i++];
+ }
+ if ( pw != NULL )
+ {
+ if ( pFunc != NULL ) continue;
+ if ( TypeOrError.Eq(TX_LOWPARAM) ) TypeOrError.SetType(TX_NUMPARAM);
+ if ( TypeOrError.Eq(TX_UNDEFCALL)) TypeOrError.SetType(TX_OVERPARAM);
+ continue; // too many parameters
+ }
+ if ( pv != NULL )
+ {
+ if ( pFunc != NULL ) continue;
+ if ( TypeOrError.Eq(TX_OVERPARAM) ) TypeOrError.SetType(TX_NUMPARAM);
+ if ( TypeOrError.Eq(TX_UNDEFCALL) ) TypeOrError.SetType(TX_LOWPARAM);
+ continue; // not enough parameters
+ }
+
+ if (alpha == 0) // perfect signature
+ {
+ nIdent = pt->m_nFuncIdent;
+ TypeOrError = pt->m_retTyp;
+ return pt;
+ }
+
+ if ( alpha < delta ) // a better signature?
+ {
+ pFunc = pt;
+ delta = alpha;
+ }
+ }
+ }
+ }
+
+ if ( bPublic )
+ {
+ for ( pt = m_listPublic ; pt != NULL ; pt = pt->m_nextpublic )
+ {
+ if ( pt->m_token.GivString() == name )
+ {
+ int i = 0;
+ int alpha = 0; // signature of parameters
+ // parameters sont-ils compatibles ?
+ CBotDefParam* pv = pt->m_Param; // list of expected parameters
+ CBotVar* pw = ppVars[i++]; // list of provided parameters
+ while ( pv != NULL && pw != NULL)
+ {
+ if (!TypesCompatibles(pv->GivTypResult(), pw->GivTypResult()))
+ {
+ if ( pFunc == NULL ) TypeOrError = TX_BADPARAM;
+ break;
+ }
+ int d = pv->GivType() - pw->GivType(2);
+ alpha += d>0 ? d : -10*d; // quality loss, 10 times more expensive!
+
+ pv = pv->GivNext();
+ pw = ppVars[i++];
+ }
+ if ( pw != NULL )
+ {
+ if ( pFunc != NULL ) continue;
+ if ( TypeOrError.Eq(TX_LOWPARAM) ) TypeOrError.SetType(TX_NUMPARAM);
+ if ( TypeOrError.Eq(TX_UNDEFCALL)) TypeOrError.SetType(TX_OVERPARAM);
+ continue; // to many parameters
+ }
+ if ( pv != NULL )
+ {
+ if ( pFunc != NULL ) continue;
+ if ( TypeOrError.Eq(TX_OVERPARAM) ) TypeOrError.SetType(TX_NUMPARAM);
+ if ( TypeOrError.Eq(TX_UNDEFCALL) ) TypeOrError.SetType(TX_LOWPARAM);
+ continue; // not enough parameters
+ }
+
+ if (alpha == 0) // perfect signature
+ {
+ nIdent = pt->m_nFuncIdent;
+ TypeOrError = pt->m_retTyp;
+ return pt;
+ }
+
+ if ( alpha < delta ) // a better signature?
+ {
+ pFunc = pt;
+ delta = alpha;
+ }
+ }
+ }
+ }
+
+ if ( pFunc != NULL )
+ {
+ nIdent = pFunc->m_nFuncIdent;
+ TypeOrError = pFunc->m_retTyp;
+ return pFunc;
+ }
+ return NULL;
}
@@ -627,128 +627,128 @@ CBotFunction* CBotFunction::FindLocalOrPublic(long& nIdent, const char* name, CB
int CBotFunction::DoCall(long& nIdent, const char* name, CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken)
{
- CBotTypResult type;
- CBotFunction* pt = NULL;
-
- pt = FindLocalOrPublic(nIdent, name, ppVars, type);
-
- if ( pt != NULL )
- {
- CBotStack* pStk1 = pStack->AddStack(pt, 2); // to put "this"
-// if ( pStk1 == EOX ) return true;
-
- pStk1->SetBotCall(pt->m_pProg); // it may have changed module
-
- if ( pStk1->IfStep() ) return false;
-
- CBotStack* pStk3 = pStk1->AddStack(NULL, true); // parameters
-
- // preparing parameters on the stack
-
- if ( pStk1->GivState() == 0 )
- {
- if ( !pt->m_MasterClass.IsEmpty() )
- {
- CBotVar* pInstance = m_pProg->m_pInstance;
- // make "this" known
- CBotVar* pThis ;
- if ( pInstance == NULL )
- {
- pThis = CBotVar::Create("this", CBotTypResult( CBotTypClass, pt->m_MasterClass ));
- pThis->SetInit(2);
- }
- else
- {
- pThis = CBotVar::Create("this", CBotTypResult( CBotTypPointer, pt->m_MasterClass ));
- pThis->SetPointer(pInstance);
- pThis->SetInit(2);
- }
-
- pThis->SetUniqNum(-2);
- pStk1->AddVar(pThis);
-
- }
-
- // initializes the variables as parameters
- pt->m_Param->Execute(ppVars, pStk3); // cannot be interrupted
-
- pStk1->IncState();
- }
-
- // finally execution of the found function
-
- if ( !pStk3->GivRetVar( // puts the result on the stack
- pt->m_Block->Execute(pStk3) )) // GivRetVar said if it is interrupted
- {
- if ( !pStk3->IsOk() && pt->m_pProg != m_pProg )
- {
+ CBotTypResult type;
+ CBotFunction* pt = NULL;
+
+ pt = FindLocalOrPublic(nIdent, name, ppVars, type);
+
+ if ( pt != NULL )
+ {
+ CBotStack* pStk1 = pStack->AddStack(pt, 2); // to put "this"
+// if ( pStk1 == EOX ) return true;
+
+ pStk1->SetBotCall(pt->m_pProg); // it may have changed module
+
+ if ( pStk1->IfStep() ) return false;
+
+ CBotStack* pStk3 = pStk1->AddStack(NULL, true); // parameters
+
+ // preparing parameters on the stack
+
+ if ( pStk1->GivState() == 0 )
+ {
+ if ( !pt->m_MasterClass.IsEmpty() )
+ {
+ CBotVar* pInstance = m_pProg->m_pInstance;
+ // make "this" known
+ CBotVar* pThis ;
+ if ( pInstance == NULL )
+ {
+ pThis = CBotVar::Create("this", CBotTypResult( CBotTypClass, pt->m_MasterClass ));
+ pThis->SetInit(2);
+ }
+ else
+ {
+ pThis = CBotVar::Create("this", CBotTypResult( CBotTypPointer, pt->m_MasterClass ));
+ pThis->SetPointer(pInstance);
+ pThis->SetInit(2);
+ }
+
+ pThis->SetUniqNum(-2);
+ pStk1->AddVar(pThis);
+
+ }
+
+ // initializes the variables as parameters
+ pt->m_Param->Execute(ppVars, pStk3); // cannot be interrupted
+
+ pStk1->IncState();
+ }
+
+ // finally execution of the found function
+
+ if ( !pStk3->GivRetVar( // puts the result on the stack
+ pt->m_Block->Execute(pStk3) )) // GivRetVar said if it is interrupted
+ {
+ if ( !pStk3->IsOk() && pt->m_pProg != m_pProg )
+ {
#ifdef _DEBUG
- if ( m_pProg->GivFunctions()->GivName() == "LaCommande" ) return false;
+ if ( m_pProg->GivFunctions()->GivName() == "LaCommande" ) return false;
#endif
- pStk3->SetPosError(pToken); // indicates the error on the procedure call
- }
- return false; // interrupt !
- }
-
- return pStack->Return( pStk3 );
- }
- return -1;
+ pStk3->SetPosError(pToken); // indicates the error on the procedure call
+ }
+ return false; // interrupt !
+ }
+
+ return pStack->Return( pStk3 );
+ }
+ return -1;
}
void CBotFunction::RestoreCall(long& nIdent, const char* name, CBotVar** ppVars, CBotStack* pStack)
{
- CBotTypResult type;
- CBotFunction* pt = NULL;
- CBotStack* pStk1;
- CBotStack* pStk3;
-
- // search function to return the ok identifier
-
- pt = FindLocalOrPublic(nIdent, name, ppVars, type);
-
- if ( pt != NULL )
- {
- pStk1 = pStack->RestoreStack(pt);
- if ( pStk1 == NULL ) return;
-
- pStk1->SetBotCall(pt->m_pProg); // it may have changed module
-
- if ( pStk1->GivBlock() < 2 )
- {
- CBotStack* pStk2 = pStk1->RestoreStack(NULL); // used more
- if ( pStk2 == NULL ) return;
- pStk3 = pStk2->RestoreStack(NULL);
- if ( pStk3 == NULL ) return;
- }
- else
- {
- pStk3 = pStk1->RestoreStack(NULL);
- if ( pStk3 == NULL ) return;
- }
-
- // preparing parameters on the stack
-
- {
- if ( !pt->m_MasterClass.IsEmpty() )
- {
- CBotVar* pInstance = m_pProg->m_pInstance;
- // make "this" known
- CBotVar* pThis = pStk1->FindVar("this");
- pThis->SetInit(2);
- pThis->SetUniqNum(-2);
- }
- }
-
- if ( pStk1->GivState() == 0 )
- {
- pt->m_Param->RestoreState(pStk3, true);
- return;
- }
-
- // initializes the variables as parameters
- pt->m_Param->RestoreState(pStk3, false);
- pt->m_Block->RestoreState(pStk3, true);
- }
+ CBotTypResult type;
+ CBotFunction* pt = NULL;
+ CBotStack* pStk1;
+ CBotStack* pStk3;
+
+ // search function to return the ok identifier
+
+ pt = FindLocalOrPublic(nIdent, name, ppVars, type);
+
+ if ( pt != NULL )
+ {
+ pStk1 = pStack->RestoreStack(pt);
+ if ( pStk1 == NULL ) return;
+
+ pStk1->SetBotCall(pt->m_pProg); // it may have changed module
+
+ if ( pStk1->GivBlock() < 2 )
+ {
+ CBotStack* pStk2 = pStk1->RestoreStack(NULL); // used more
+ if ( pStk2 == NULL ) return;
+ pStk3 = pStk2->RestoreStack(NULL);
+ if ( pStk3 == NULL ) return;
+ }
+ else
+ {
+ pStk3 = pStk1->RestoreStack(NULL);
+ if ( pStk3 == NULL ) return;
+ }
+
+ // preparing parameters on the stack
+
+ {
+ if ( !pt->m_MasterClass.IsEmpty() )
+ {
+ CBotVar* pInstance = m_pProg->m_pInstance;
+ // make "this" known
+ CBotVar* pThis = pStk1->FindVar("this");
+ pThis->SetInit(2);
+ pThis->SetUniqNum(-2);
+ }
+ }
+
+ if ( pStk1->GivState() == 0 )
+ {
+ pt->m_Param->RestoreState(pStk3, true);
+ return;
+ }
+
+ // initializes the variables as parameters
+ pt->m_Param->RestoreState(pStk3, false);
+ pt->m_Block->RestoreState(pStk3, true);
+ }
}
@@ -758,167 +758,167 @@ void CBotFunction::RestoreCall(long& nIdent, const char* name, CBotVar** ppVars,
int CBotFunction::DoCall(long& nIdent, const char* name, CBotVar* pThis, CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken, CBotClass* pClass)
{
- CBotTypResult type;
- CBotProgram* pProgCurrent = pStack->GivBotCall();
-
- CBotFunction* pt = FindLocalOrPublic(nIdent, name, ppVars, type, false);
-
- if ( pt != NULL )
- {
-// DEBUG( "CBotFunction::DoCall" + pt->GivName(), 0, pStack);
-
- CBotStack* pStk = pStack->AddStack(pt, 2);
-// if ( pStk == EOX ) return true;
-
- pStk->SetBotCall(pt->m_pProg); // it may have changed module
- CBotStack* pStk3 = pStk->AddStack(NULL, true); // to set parameters passed
-
- // preparing parameters on the stack
-
- if ( pStk->GivState() == 0 )
- {
- // sets the variable "this" on the stack
- CBotVar* pthis = CBotVar::Create("this", CBotTypNullPointer);
- pthis->Copy(pThis, false);
- pthis->SetUniqNum(-2); // special value
- pStk->AddVar(pthis);
-
- CBotClass* pClass = pThis->GivClass()->GivParent();
- if ( pClass )
- {
- // sets the variable "super" on the stack
- CBotVar* psuper = CBotVar::Create("super", CBotTypNullPointer);
- psuper->Copy(pThis, false); // in fact identical to "this"
- psuper->SetUniqNum(-3); // special value
- pStk->AddVar(psuper);
- }
- // initializes the variables as parameters
- pt->m_Param->Execute(ppVars, pStk3); // cannot be interrupted
- pStk->IncState();
- }
-
- if ( pStk->GivState() == 1 )
- {
- if ( pt->m_bSynchro )
- {
- CBotProgram* pProgBase = pStk->GivBotCall(true);
- if ( !pClass->Lock(pProgBase) ) return false; // expected to power \TODO attend de pouvoir
- }
- pStk->IncState();
- }
- // finally calls the found function
-
- if ( !pStk3->GivRetVar( // puts the result on the stack
- pt->m_Block->Execute(pStk3) )) // GivRetVar said if it is interrupted
- {
- if ( !pStk3->IsOk() )
- {
- if ( pt->m_bSynchro )
- {
- pClass->Unlock(); // release function
- }
-
- if ( pt->m_pProg != pProgCurrent )
- {
- pStk3->SetPosError(pToken); // indicates the error on the procedure call
- }
- }
- return false; // interrupt !
- }
-
- if ( pt->m_bSynchro )
- {
- pClass->Unlock(); // release function
- }
-
- return pStack->Return( pStk3 );
- }
- return -1;
+ CBotTypResult type;
+ CBotProgram* pProgCurrent = pStack->GivBotCall();
+
+ CBotFunction* pt = FindLocalOrPublic(nIdent, name, ppVars, type, false);
+
+ if ( pt != NULL )
+ {
+// DEBUG( "CBotFunction::DoCall" + pt->GivName(), 0, pStack);
+
+ CBotStack* pStk = pStack->AddStack(pt, 2);
+// if ( pStk == EOX ) return true;
+
+ pStk->SetBotCall(pt->m_pProg); // it may have changed module
+ CBotStack* pStk3 = pStk->AddStack(NULL, true); // to set parameters passed
+
+ // preparing parameters on the stack
+
+ if ( pStk->GivState() == 0 )
+ {
+ // sets the variable "this" on the stack
+ CBotVar* pthis = CBotVar::Create("this", CBotTypNullPointer);
+ pthis->Copy(pThis, false);
+ pthis->SetUniqNum(-2); // special value
+ pStk->AddVar(pthis);
+
+ CBotClass* pClass = pThis->GivClass()->GivParent();
+ if ( pClass )
+ {
+ // sets the variable "super" on the stack
+ CBotVar* psuper = CBotVar::Create("super", CBotTypNullPointer);
+ psuper->Copy(pThis, false); // in fact identical to "this"
+ psuper->SetUniqNum(-3); // special value
+ pStk->AddVar(psuper);
+ }
+ // initializes the variables as parameters
+ pt->m_Param->Execute(ppVars, pStk3); // cannot be interrupted
+ pStk->IncState();
+ }
+
+ if ( pStk->GivState() == 1 )
+ {
+ if ( pt->m_bSynchro )
+ {
+ CBotProgram* pProgBase = pStk->GivBotCall(true);
+ if ( !pClass->Lock(pProgBase) ) return false; // expected to power \TODO attend de pouvoir
+ }
+ pStk->IncState();
+ }
+ // finally calls the found function
+
+ if ( !pStk3->GivRetVar( // puts the result on the stack
+ pt->m_Block->Execute(pStk3) )) // GivRetVar said if it is interrupted
+ {
+ if ( !pStk3->IsOk() )
+ {
+ if ( pt->m_bSynchro )
+ {
+ pClass->Unlock(); // release function
+ }
+
+ if ( pt->m_pProg != pProgCurrent )
+ {
+ pStk3->SetPosError(pToken); // indicates the error on the procedure call
+ }
+ }
+ return false; // interrupt !
+ }
+
+ if ( pt->m_bSynchro )
+ {
+ pClass->Unlock(); // release function
+ }
+
+ return pStack->Return( pStk3 );
+ }
+ return -1;
}
void CBotFunction::RestoreCall(long& nIdent, const char* name, CBotVar* pThis, CBotVar** ppVars, CBotStack* pStack, CBotClass* pClass)
{
- CBotTypResult type;
- CBotFunction* pt = FindLocalOrPublic(nIdent, name, ppVars, type);
+ CBotTypResult type;
+ CBotFunction* pt = FindLocalOrPublic(nIdent, name, ppVars, type);
- if ( pt != NULL )
- {
- CBotStack* pStk = pStack->RestoreStack(pt);
- if ( pStk == NULL ) return;
- pStk->SetBotCall(pt->m_pProg); // it may have changed module
+ if ( pt != NULL )
+ {
+ CBotStack* pStk = pStack->RestoreStack(pt);
+ if ( pStk == NULL ) return;
+ pStk->SetBotCall(pt->m_pProg); // it may have changed module
- CBotVar* pthis = pStk->FindVar("this");
- pthis->SetUniqNum(-2);
+ CBotVar* pthis = pStk->FindVar("this");
+ pthis->SetUniqNum(-2);
- CBotStack* pStk3 = pStk->RestoreStack(NULL); // to set parameters passed
- if ( pStk3 == NULL ) return;
+ CBotStack* pStk3 = pStk->RestoreStack(NULL); // to set parameters passed
+ if ( pStk3 == NULL ) return;
- pt->m_Param->RestoreState(pStk3, true); // parameters
+ pt->m_Param->RestoreState(pStk3, true); // parameters
- if ( pStk->GivState() > 1 && // latching is effective?
- pt->m_bSynchro )
- {
- CBotProgram* pProgBase = pStk->GivBotCall(true);
- pClass->Lock(pProgBase); // locks the class
- }
+ if ( pStk->GivState() > 1 && // latching is effective?
+ pt->m_bSynchro )
+ {
+ CBotProgram* pProgBase = pStk->GivBotCall(true);
+ pClass->Lock(pProgBase); // locks the class
+ }
- // finally calls the found function
+ // finally calls the found function
- pt->m_Block->RestoreState(pStk3, true); // interrupt !
- }
+ pt->m_Block->RestoreState(pStk3, true); // interrupt !
+ }
}
// see if the "signature" of parameters is identical
bool CBotFunction::CheckParam(CBotDefParam* pParam)
{
- CBotDefParam* pp = m_Param;
- while ( pp != NULL && pParam != NULL )
- {
- CBotTypResult type1 = pp->GivType();
- CBotTypResult type2 = pParam->GivType();
- if ( !type1.Compare(type2) ) return false;
- pp = pp->GivNext();
- pParam = pParam->GivNext();
- }
- return ( pp == NULL && pParam == NULL );
+ CBotDefParam* pp = m_Param;
+ while ( pp != NULL && pParam != NULL )
+ {
+ CBotTypResult type1 = pp->GivType();
+ CBotTypResult type2 = pParam->GivType();
+ if ( !type1.Compare(type2) ) return false;
+ pp = pp->GivNext();
+ pParam = pParam->GivNext();
+ }
+ return ( pp == NULL && pParam == NULL );
}
CBotString CBotFunction::GivName()
{
- return m_token.GivString();
+ return m_token.GivString();
}
CBotString CBotFunction::GivParams()
{
- if ( m_Param == NULL ) return CBotString("()");
+ if ( m_Param == NULL ) return CBotString("()");
- CBotString params = "( ";
- CBotDefParam* p = m_Param; // list of parameters
+ CBotString params = "( ";
+ CBotDefParam* p = m_Param; // list of parameters
- while (p != NULL)
- {
- params += p->GivParamString();
- p = p->GivNext();
- if ( p != NULL ) params += ", ";
- }
+ while (p != NULL)
+ {
+ params += p->GivParamString();
+ p = p->GivNext();
+ if ( p != NULL ) params += ", ";
+ }
- params += " )";
- return params;
+ params += " )";
+ return params;
}
CBotFunction* CBotFunction::Next()
{
- return m_next;
+ return m_next;
}
void CBotFunction::AddPublic(CBotFunction* func)
{
- if ( m_listPublic != NULL )
- {
- func->m_nextpublic = m_listPublic;
- m_listPublic->m_prevpublic = func;
- }
- m_listPublic = func;
+ if ( m_listPublic != NULL )
+ {
+ func->m_nextpublic = m_listPublic;
+ m_listPublic->m_prevpublic = func;
+ }
+ m_listPublic = func;
}
@@ -929,172 +929,172 @@ void CBotFunction::AddPublic(CBotFunction* func)
CBotDefParam::CBotDefParam()
{
- m_next = NULL;
- m_nIdent = 0;
+ m_next = NULL;
+ m_nIdent = 0;
}
CBotDefParam::~CBotDefParam()
{
- delete m_next;
+ delete m_next;
}
// compiles a list of parameters
CBotDefParam* CBotDefParam::Compile(CBotToken* &p, CBotCStack* pStack)
{
- // mainly not pStack->TokenStack here
- // declared variables must remain visible thereafter
-
- pStack->SetStartError(p->GivStart());
-
- if (IsOfType(p, ID_OPENPAR))
- {
- CBotDefParam* list = NULL;
-
- while (!IsOfType(p, ID_CLOSEPAR))
- {
- CBotDefParam* param = new CBotDefParam();
- if (list == NULL) list = param;
- else list->AddNext(param); // added to the list
-
- CBotClass* pClass = NULL;//= CBotClass::Find(p);
- param->m_typename = p->GivString();
- CBotTypResult type = param->m_type = TypeParam(p, pStack);
-// if ( type == CBotTypPointer ) type = CBotTypClass; // we must create a new object
-
- if (param->m_type.GivType() > 0)
- {
- CBotToken* pp = p;
- param->m_token = *p;
- if (pStack->IsOk() && IsOfType(p, TokenTypVar) )
- {
-
- // variable already declared?
- if (pStack->CheckVarLocal(pp))
- {
- pStack->SetError(TX_REDEFVAR, pp);
- break;
- }
-
- if ( type.Eq(CBotTypArrayPointer) ) type.SetType(CBotTypArrayBody);
- CBotVar* var = CBotVar::Create(pp->GivString(), type); // creates the variable
-// if ( pClass ) var->SetClass(pClass);
- var->SetInit(2); // mark initialized
- param->m_nIdent = CBotVar::NextUniqNum();
- var->SetUniqNum(param->m_nIdent);
- pStack->AddVar(var); // place on the stack
-
- if (IsOfType(p, ID_COMMA) || p->GivType() == ID_CLOSEPAR)
- continue;
- }
- pStack->SetError(TX_CLOSEPAR, p->GivStart());
- }
- pStack->SetError(TX_NOTYP, p);
- delete list;
- return NULL;
- }
- return list;
- }
- pStack->SetError(TX_OPENPAR, p->GivStart());
- return NULL;
+ // mainly not pStack->TokenStack here
+ // declared variables must remain visible thereafter
+
+ pStack->SetStartError(p->GivStart());
+
+ if (IsOfType(p, ID_OPENPAR))
+ {
+ CBotDefParam* list = NULL;
+
+ while (!IsOfType(p, ID_CLOSEPAR))
+ {
+ CBotDefParam* param = new CBotDefParam();
+ if (list == NULL) list = param;
+ else list->AddNext(param); // added to the list
+
+ CBotClass* pClass = NULL;//= CBotClass::Find(p);
+ param->m_typename = p->GivString();
+ CBotTypResult type = param->m_type = TypeParam(p, pStack);
+// if ( type == CBotTypPointer ) type = CBotTypClass; // we must create a new object
+
+ if (param->m_type.GivType() > 0)
+ {
+ CBotToken* pp = p;
+ param->m_token = *p;
+ if (pStack->IsOk() && IsOfType(p, TokenTypVar) )
+ {
+
+ // variable already declared?
+ if (pStack->CheckVarLocal(pp))
+ {
+ pStack->SetError(TX_REDEFVAR, pp);
+ break;
+ }
+
+ if ( type.Eq(CBotTypArrayPointer) ) type.SetType(CBotTypArrayBody);
+ CBotVar* var = CBotVar::Create(pp->GivString(), type); // creates the variable
+// if ( pClass ) var->SetClass(pClass);
+ var->SetInit(2); // mark initialized
+ param->m_nIdent = CBotVar::NextUniqNum();
+ var->SetUniqNum(param->m_nIdent);
+ pStack->AddVar(var); // place on the stack
+
+ if (IsOfType(p, ID_COMMA) || p->GivType() == ID_CLOSEPAR)
+ continue;
+ }
+ pStack->SetError(TX_CLOSEPAR, p->GivStart());
+ }
+ pStack->SetError(TX_NOTYP, p);
+ delete list;
+ return NULL;
+ }
+ return list;
+ }
+ pStack->SetError(TX_OPENPAR, p->GivStart());
+ return NULL;
}
void CBotDefParam::AddNext(CBotDefParam* p)
{
- CBotDefParam* pp = this;
- while (pp->m_next != NULL) pp = pp->m_next;
+ CBotDefParam* pp = this;
+ while (pp->m_next != NULL) pp = pp->m_next;
- pp->m_next = p;
+ pp->m_next = p;
}
bool CBotDefParam::Execute(CBotVar** ppVars, CBotStack* &pj)
{
- int i = 0;
- CBotDefParam* p = this;
-
- while ( p != NULL )
- {
- // creates a local variable on the stack
- CBotVar* newvar = CBotVar::Create(p->m_token.GivString(), p->m_type);
-
- // serves to make the transformation of types:
- if ( ppVars != NULL && ppVars[i] != NULL )
- {
- switch (p->m_type.GivType())
- {
- case CBotTypInt:
- newvar->SetValInt(ppVars[i]->GivValInt());
- break;
- case CBotTypFloat:
- newvar->SetValFloat(ppVars[i]->GivValFloat());
- break;
- case CBotTypString:
- newvar->SetValString(ppVars[i]->GivValString());
- break;
- case CBotTypBoolean:
- newvar->SetValInt(ppVars[i]->GivValInt());
- break;
- case CBotTypIntrinsic:
- ((CBotVarClass*)newvar)->Copy(ppVars[i], false);
- break;
- case CBotTypPointer:
- case CBotTypArrayPointer:
- {
- newvar->SetPointer(ppVars[i]->GivPointer());
- }
- break;
- default:
- ASM_TRAP();
- }
- }
- newvar->SetUniqNum(p->m_nIdent);
- pj->AddVar(newvar); // add a variable
- p = p->m_next;
- i++;
- }
-
- return true;
+ int i = 0;
+ CBotDefParam* p = this;
+
+ while ( p != NULL )
+ {
+ // creates a local variable on the stack
+ CBotVar* newvar = CBotVar::Create(p->m_token.GivString(), p->m_type);
+
+ // serves to make the transformation of types:
+ if ( ppVars != NULL && ppVars[i] != NULL )
+ {
+ switch (p->m_type.GivType())
+ {
+ case CBotTypInt:
+ newvar->SetValInt(ppVars[i]->GivValInt());
+ break;
+ case CBotTypFloat:
+ newvar->SetValFloat(ppVars[i]->GivValFloat());
+ break;
+ case CBotTypString:
+ newvar->SetValString(ppVars[i]->GivValString());
+ break;
+ case CBotTypBoolean:
+ newvar->SetValInt(ppVars[i]->GivValInt());
+ break;
+ case CBotTypIntrinsic:
+ ((CBotVarClass*)newvar)->Copy(ppVars[i], false);
+ break;
+ case CBotTypPointer:
+ case CBotTypArrayPointer:
+ {
+ newvar->SetPointer(ppVars[i]->GivPointer());
+ }
+ break;
+ default:
+ ASM_TRAP();
+ }
+ }
+ newvar->SetUniqNum(p->m_nIdent);
+ pj->AddVar(newvar); // add a variable
+ p = p->m_next;
+ i++;
+ }
+
+ return true;
}
void CBotDefParam::RestoreState(CBotStack* &pj, bool bMain)
{
- int i = 0;
- CBotDefParam* p = this;
-
- while ( p != NULL )
- {
- // creates a local variable on the stack
- CBotVar* var = pj->FindVar(p->m_token.GivString());
- var->SetUniqNum(p->m_nIdent);
- p = p->m_next;
- }
+ int i = 0;
+ CBotDefParam* p = this;
+
+ while ( p != NULL )
+ {
+ // creates a local variable on the stack
+ CBotVar* var = pj->FindVar(p->m_token.GivString());
+ var->SetUniqNum(p->m_nIdent);
+ p = p->m_next;
+ }
}
int CBotDefParam::GivType()
{
- return m_type.GivType();
+ return m_type.GivType();
}
CBotTypResult CBotDefParam::GivTypResult()
{
- return m_type;
+ return m_type;
}
CBotDefParam* CBotDefParam::GivNext()
{
- return m_next;
+ return m_next;
}
CBotString CBotDefParam::GivParamString()
{
- CBotString param;
-
- param = m_typename;
- param += ' ';
+ CBotString param;
+
+ param = m_typename;
+ param += ' ';
- param += m_token.GivString();
- return param;
+ param += m_token.GivString();
+ return param;
}
@@ -1104,80 +1104,80 @@ CBotString CBotDefParam::GivParamString()
CBotReturn::CBotReturn()
{
- m_Instr = NULL;
- name = "CBotReturn"; // debug
+ m_Instr = NULL;
+ name = "CBotReturn"; // debug
}
CBotReturn::~CBotReturn()
{
- delete m_Instr;
+ delete m_Instr;
}
CBotInstr* CBotReturn::Compile(CBotToken* &p, CBotCStack* pStack)
{
- CBotToken* pp = p;
-
- if (!IsOfType(p, ID_RETURN)) return NULL; // should never happen
-
- CBotReturn* inst = new CBotReturn(); // creates the object
- inst->SetToken( pp );
-
- CBotTypResult type = pStack->GivRetType();
-
- if ( type.GivType() == 0 ) // returned void ?
- {
- if ( IsOfType( p, ID_SEP ) ) return inst;
- pStack->SetError( TX_BADTYPE, pp );
- return NULL;
- }
-
- inst->m_Instr = CBotExpression::Compile(p, pStack);
- if ( pStack->IsOk() )
- {
- CBotTypResult retType = pStack->GivTypResult(2);
- if (TypeCompatible(retType, type, ID_ASS))
- {
- if ( IsOfType( p, ID_SEP ) )
- return inst;
-
- pStack->SetError(TX_ENDOF, p->GivStart());
- }
- pStack->SetError(TX_BADTYPE, p->GivStart());
- }
-
- delete inst;
- return NULL; // no object, the error is on the stack
+ CBotToken* pp = p;
+
+ if (!IsOfType(p, ID_RETURN)) return NULL; // should never happen
+
+ CBotReturn* inst = new CBotReturn(); // creates the object
+ inst->SetToken( pp );
+
+ CBotTypResult type = pStack->GivRetType();
+
+ if ( type.GivType() == 0 ) // returned void ?
+ {
+ if ( IsOfType( p, ID_SEP ) ) return inst;
+ pStack->SetError( TX_BADTYPE, pp );
+ return NULL;
+ }
+
+ inst->m_Instr = CBotExpression::Compile(p, pStack);
+ if ( pStack->IsOk() )
+ {
+ CBotTypResult retType = pStack->GivTypResult(2);
+ if (TypeCompatible(retType, type, ID_ASS))
+ {
+ if ( IsOfType( p, ID_SEP ) )
+ return inst;
+
+ pStack->SetError(TX_ENDOF, p->GivStart());
+ }
+ pStack->SetError(TX_BADTYPE, p->GivStart());
+ }
+
+ delete inst;
+ return NULL; // no object, the error is on the stack
}
bool CBotReturn::Execute(CBotStack* &pj)
{
- CBotStack* pile = pj->AddStack(this);
-// if ( pile == EOX ) return true;
+ CBotStack* pile = pj->AddStack(this);
+// if ( pile == EOX ) return true;
- if ( pile->GivState() == 0 )
- {
- if ( m_Instr != NULL && !m_Instr->Execute(pile) ) return false; // evaluate the result
- // the result is on the stack
- pile->IncState();
- }
+ if ( pile->GivState() == 0 )
+ {
+ if ( m_Instr != NULL && !m_Instr->Execute(pile) ) return false; // evaluate the result
+ // the result is on the stack
+ pile->IncState();
+ }
- if ( pile->IfStep() ) return false;
+ if ( pile->IfStep() ) return false;
- pile->SetBreak(3, CBotString());
- return pj->Return(pile);
+ pile->SetBreak(3, CBotString());
+ return pj->Return(pile);
}
void CBotReturn::RestoreState(CBotStack* &pj, bool bMain)
{
- if ( !bMain ) return;
- CBotStack* pile = pj->RestoreStack(this);
- if ( pile == NULL ) return;
-
- if ( pile->GivState() == 0 )
- {
- if ( m_Instr != NULL ) m_Instr->RestoreState(pile, bMain); // evaluate the result
- return;
- }
+ if ( !bMain ) return;
+ CBotStack* pile = pj->RestoreStack(this);
+ if ( pile == NULL ) return;
+
+ if ( pile->GivState() == 0 )
+ {
+ if ( m_Instr != NULL ) m_Instr->RestoreState(pile, bMain); // evaluate the result
+ return;
+ }
}
////////////////////////////////////////////////////////////////////////////////
@@ -1185,172 +1185,172 @@ void CBotReturn::RestoreState(CBotStack* &pj, bool bMain)
CBotInstrCall::CBotInstrCall()
{
- m_Parameters = NULL;
- m_nFuncIdent = 0;
- name = "CBotInstrCall";
+ m_Parameters = NULL;
+ m_nFuncIdent = 0;
+ name = "CBotInstrCall";
}
CBotInstrCall::~CBotInstrCall()
{
- delete m_Parameters;
+ delete m_Parameters;
}
CBotInstr* CBotInstrCall::Compile(CBotToken* &p, CBotCStack* pStack)
{
- CBotVar* ppVars[1000];
-
- int i = 0;
-
- CBotToken* pp = p;
- p = p->GivNext();
-
- pStack->SetStartError(p->GivStart());
- CBotCStack* pile = pStack;
-
- if ( IsOfType(p, ID_OPENPAR) )
- {
- int start, end;
- CBotInstrCall* inst = new CBotInstrCall();
- inst->SetToken(pp);
-
- // compile la list of parameters
- if (!IsOfType(p, ID_CLOSEPAR)) while (true)
- {
- start = p->GivStart();
- pile = pile->TokenStack(); // keeps the results on the stack
-
- CBotInstr* param = CBotExpression::Compile(p, pile);
- end = p->GivStart();
- if ( inst->m_Parameters == NULL ) inst->m_Parameters = param;
- else inst->m_Parameters->AddNext(param); // constructs the list
-
- if ( !pile->IsOk() )
- {
- delete inst;
- return pStack->Return(NULL, pile);
- }
-
- if ( param != NULL )
- {
- if ( pile->GivTypResult().Eq(99) )
- {
- delete pStack->TokenStack();
- pStack->SetError(TX_VOID, p->GivStart());
- delete inst;
- return NULL;
- }
- ppVars[i] = pile->GivVar();
- ppVars[i]->GivToken()->SetPos(start, end);
- i++;
-
- if (IsOfType(p, ID_COMMA)) continue; // skips the comma
- if (IsOfType(p, ID_CLOSEPAR)) break;
- }
-
- pStack->SetError(TX_CLOSEPAR, p->GivStart());
- delete pStack->TokenStack();
- delete inst;
- return NULL;
- }
- ppVars[i] = NULL;
-
- // the routine is known?
-// CBotClass* pClass = NULL;
- inst->m_typRes = pStack->CompileCall(pp, ppVars, inst->m_nFuncIdent);
- if ( inst->m_typRes.GivType() >= 20 )
- {
-// if (pVar2!=NULL) pp = pVar2->RetToken();
- pStack->SetError( inst->m_typRes.GivType(), pp );
- delete pStack->TokenStack();
- delete inst;
- return NULL;
- }
-
- delete pStack->TokenStack();
- if ( inst->m_typRes.GivType() > 0 )
- {
- CBotVar* pRes = CBotVar::Create("", inst->m_typRes);
- pStack->SetVar(pRes); // for knowing the type of the result
- }
- else pStack->SetVar(NULL); // routine returns void
-
- return inst;
- }
- p = pp;
- delete pStack->TokenStack();
- return NULL;
+ CBotVar* ppVars[1000];
+
+ int i = 0;
+
+ CBotToken* pp = p;
+ p = p->GivNext();
+
+ pStack->SetStartError(p->GivStart());
+ CBotCStack* pile = pStack;
+
+ if ( IsOfType(p, ID_OPENPAR) )
+ {
+ int start, end;
+ CBotInstrCall* inst = new CBotInstrCall();
+ inst->SetToken(pp);
+
+ // compile la list of parameters
+ if (!IsOfType(p, ID_CLOSEPAR)) while (true)
+ {
+ start = p->GivStart();
+ pile = pile->TokenStack(); // keeps the results on the stack
+
+ CBotInstr* param = CBotExpression::Compile(p, pile);
+ end = p->GivStart();
+ if ( inst->m_Parameters == NULL ) inst->m_Parameters = param;
+ else inst->m_Parameters->AddNext(param); // constructs the list
+
+ if ( !pile->IsOk() )
+ {
+ delete inst;
+ return pStack->Return(NULL, pile);
+ }
+
+ if ( param != NULL )
+ {
+ if ( pile->GivTypResult().Eq(99) )
+ {
+ delete pStack->TokenStack();
+ pStack->SetError(TX_VOID, p->GivStart());
+ delete inst;
+ return NULL;
+ }
+ ppVars[i] = pile->GivVar();
+ ppVars[i]->GivToken()->SetPos(start, end);
+ i++;
+
+ if (IsOfType(p, ID_COMMA)) continue; // skips the comma
+ if (IsOfType(p, ID_CLOSEPAR)) break;
+ }
+
+ pStack->SetError(TX_CLOSEPAR, p->GivStart());
+ delete pStack->TokenStack();
+ delete inst;
+ return NULL;
+ }
+ ppVars[i] = NULL;
+
+ // the routine is known?
+// CBotClass* pClass = NULL;
+ inst->m_typRes = pStack->CompileCall(pp, ppVars, inst->m_nFuncIdent);
+ if ( inst->m_typRes.GivType() >= 20 )
+ {
+// if (pVar2!=NULL) pp = pVar2->RetToken();
+ pStack->SetError( inst->m_typRes.GivType(), pp );
+ delete pStack->TokenStack();
+ delete inst;
+ return NULL;
+ }
+
+ delete pStack->TokenStack();
+ if ( inst->m_typRes.GivType() > 0 )
+ {
+ CBotVar* pRes = CBotVar::Create("", inst->m_typRes);
+ pStack->SetVar(pRes); // for knowing the type of the result
+ }
+ else pStack->SetVar(NULL); // routine returns void
+
+ return inst;
+ }
+ p = pp;
+ delete pStack->TokenStack();
+ return NULL;
}
bool CBotInstrCall::Execute(CBotStack* &pj)
{
- CBotVar* ppVars[1000];
- CBotStack* pile = pj->AddStack(this);
- if ( pile->StackOver() ) return pj->Return( pile );
-
- CBotStack* pile1 = pile;
-
- int i = 0;
-
- CBotInstr* p = m_Parameters;
- // evaluates parameters
- // and places the values ​​on the stack
- // for allow of interruption at any time
- if ( p != NULL) while ( true )
- {
- pile = pile->AddStack(); // place on the stack for the results
- if ( pile->GivState() == 0 )
- {
- if (!p->Execute(pile)) return false; // interrupted here?
- pile->SetState(1); // mark as special for reknowed parameters \TODO marque spéciale pour reconnaîre parameters
- }
- ppVars[i++] = pile->GivVar();
- p = p->GivNext();
- if ( p == NULL) break;
- }
- ppVars[i] = NULL;
-
- CBotStack* pile2 = pile->AddStack();
- if ( pile2->IfStep() ) return false;
-
- if ( !pile2->ExecuteCall(m_nFuncIdent, GivToken(), ppVars, m_typRes)) return false; // interrupt
-
- return pj->Return(pile2); // release the entire stack
+ CBotVar* ppVars[1000];
+ CBotStack* pile = pj->AddStack(this);
+ if ( pile->StackOver() ) return pj->Return( pile );
+
+ CBotStack* pile1 = pile;
+
+ int i = 0;
+
+ CBotInstr* p = m_Parameters;
+ // evaluates parameters
+ // and places the values ​​on the stack
+ // for allow of interruption at any time
+ if ( p != NULL) while ( true )
+ {
+ pile = pile->AddStack(); // place on the stack for the results
+ if ( pile->GivState() == 0 )
+ {
+ if (!p->Execute(pile)) return false; // interrupted here?
+ pile->SetState(1); // mark as special for reknowed parameters \TODO marque spéciale pour reconnaîre parameters
+ }
+ ppVars[i++] = pile->GivVar();
+ p = p->GivNext();
+ if ( p == NULL) break;
+ }
+ ppVars[i] = NULL;
+
+ CBotStack* pile2 = pile->AddStack();
+ if ( pile2->IfStep() ) return false;
+
+ if ( !pile2->ExecuteCall(m_nFuncIdent, GivToken(), ppVars, m_typRes)) return false; // interrupt
+
+ return pj->Return(pile2); // release the entire stack
}
void CBotInstrCall::RestoreState(CBotStack* &pj, bool bMain)
{
- if ( !bMain ) return;
-
- CBotStack* pile = pj->RestoreStack(this);
- if ( pile == NULL ) return;
-
- CBotStack* pile1 = pile;
-
- int i = 0;
- CBotVar* ppVars[1000];
- CBotInstr* p = m_Parameters;
- // evaluate parameters
- // and place the values on the stack
- // for allow of interruption at any time
- if ( p != NULL) while ( true )
- {
- pile = pile->RestoreStack(); // place on the stack for the results
- if ( pile == NULL ) return;
- if ( pile->GivState() == 0 )
- {
- p->RestoreState(pile, bMain); // interrupt here!
- return;
- }
- ppVars[i++] = pile->GivVar(); // constructs the list of parameters
- p = p->GivNext();
- if ( p == NULL) break;
- }
- ppVars[i] = NULL;
-
- CBotStack* pile2 = pile->RestoreStack();
- if ( pile2 == NULL ) return;
-
- pile2->RestoreCall(m_nFuncIdent, GivToken(), ppVars);
+ if ( !bMain ) return;
+
+ CBotStack* pile = pj->RestoreStack(this);
+ if ( pile == NULL ) return;
+
+ CBotStack* pile1 = pile;
+
+ int i = 0;
+ CBotVar* ppVars[1000];
+ CBotInstr* p = m_Parameters;
+ // evaluate parameters
+ // and place the values on the stack
+ // for allow of interruption at any time
+ if ( p != NULL) while ( true )
+ {
+ pile = pile->RestoreStack(); // place on the stack for the results
+ if ( pile == NULL ) return;
+ if ( pile->GivState() == 0 )
+ {
+ p->RestoreState(pile, bMain); // interrupt here!
+ return;
+ }
+ ppVars[i++] = pile->GivVar(); // constructs the list of parameters
+ p = p->GivNext();
+ if ( p == NULL) break;
+ }
+ ppVars[i] = NULL;
+
+ CBotStack* pile2 = pile->RestoreStack();
+ if ( pile2 == NULL ) return;
+
+ pile2->RestoreCall(m_nFuncIdent, GivToken(), ppVars);
}
//////////////////////////////////////////////////////////////////////////////
@@ -1361,287 +1361,287 @@ void CBotInstrCall::RestoreState(CBotStack* &pj, bool bMain)
CBotClass* CBotClass::Compile1(CBotToken* &p, CBotCStack* pStack)
{
- if ( !IsOfType(p, ID_PUBLIC) )
- {
- pStack->SetError(TX_NOPUBLIC, p);
- return NULL;
- }
-
- if ( !IsOfType(p, ID_CLASS) ) return NULL;
-
- CBotString name = p->GivString();
-
- CBotClass* pOld = CBotClass::Find(name);
- if ( pOld != NULL && pOld->m_IsDef )
- {
- pStack->SetError( TX_REDEFCLASS, p );
- return NULL;
- }
-
- // a name of the class is there?
- if (IsOfType(p, TokenTypVar))
- {
- CBotClass* pPapa = NULL;
- if ( IsOfType( p, ID_EXTENDS ) )
- {
- CBotString name = p->GivString();
- pPapa = CBotClass::Find(name);
-
- if (!IsOfType(p, TokenTypVar) || pPapa == NULL )
- {
- pStack->SetError( TX_NOCLASS, p );
- return NULL;
- }
- }
- CBotClass* classe = (pOld == NULL) ? new CBotClass(name, pPapa) : pOld;
- classe->Purge(); // emptythe old definitions
- classe->m_IsDef = false; // current definition
-
- if ( !IsOfType( p, ID_OPBLK) )
- {
- pStack->SetError(TX_OPENBLK, p);
- return NULL;
- }
-
- while ( pStack->IsOk() && !IsOfType( p, ID_CLBLK ) )
- {
- classe->CompileDefItem(p, pStack, false);
- }
-
- if (pStack->IsOk()) return classe;
- }
- pStack->SetError(TX_ENDOF, p);
- return NULL;
+ if ( !IsOfType(p, ID_PUBLIC) )
+ {
+ pStack->SetError(TX_NOPUBLIC, p);
+ return NULL;
+ }
+
+ if ( !IsOfType(p, ID_CLASS) ) return NULL;
+
+ CBotString name = p->GivString();
+
+ CBotClass* pOld = CBotClass::Find(name);
+ if ( pOld != NULL && pOld->m_IsDef )
+ {
+ pStack->SetError( TX_REDEFCLASS, p );
+ return NULL;
+ }
+
+ // a name of the class is there?
+ if (IsOfType(p, TokenTypVar))
+ {
+ CBotClass* pPapa = NULL;
+ if ( IsOfType( p, ID_EXTENDS ) )
+ {
+ CBotString name = p->GivString();
+ pPapa = CBotClass::Find(name);
+
+ if (!IsOfType(p, TokenTypVar) || pPapa == NULL )
+ {
+ pStack->SetError( TX_NOCLASS, p );
+ return NULL;
+ }
+ }
+ CBotClass* classe = (pOld == NULL) ? new CBotClass(name, pPapa) : pOld;
+ classe->Purge(); // emptythe old definitions
+ classe->m_IsDef = false; // current definition
+
+ if ( !IsOfType( p, ID_OPBLK) )
+ {
+ pStack->SetError(TX_OPENBLK, p);
+ return NULL;
+ }
+
+ while ( pStack->IsOk() && !IsOfType( p, ID_CLBLK ) )
+ {
+ classe->CompileDefItem(p, pStack, false);
+ }
+
+ if (pStack->IsOk()) return classe;
+ }
+ pStack->SetError(TX_ENDOF, p);
+ return NULL;
}
bool CBotClass::CompileDefItem(CBotToken* &p, CBotCStack* pStack, bool bSecond)
{
- bool bStatic = false;
- int mProtect = PR_PUBLIC;
- bool bSynchro = false;
-
- while (IsOfType(p, ID_SEP)) ;
-
- CBotTypResult type( -1 );
-
- if ( IsOfType(p, ID_SYNCHO) ) bSynchro = true;
- CBotToken* pBase = p;
-
- if ( IsOfType(p, ID_STATIC) ) bStatic = true;
- if ( IsOfType(p, ID_PUBLIC) ) mProtect = PR_PUBLIC;
- if ( IsOfType(p, ID_PRIVATE) ) mProtect = PR_PRIVATE;
- if ( IsOfType(p, ID_PROTECTED) ) mProtect = PR_PROTECT;
- if ( IsOfType(p, ID_STATIC) ) bStatic = true;
-
-// CBotClass* pClass = NULL;
- type = TypeParam(p, pStack); // type of the result
-
- if ( type.Eq(-1) )
- {
- pStack->SetError(TX_NOTYP, p);
- return false;
- }
-
- while (pStack->IsOk())
- {
- CBotToken* pp = p;
- IsOfType(p, ID_NOT); // skips ~ eventual (destructor)
-
- if (IsOfType(p, TokenTypVar))
- {
- CBotInstr* limites = NULL;
- while ( IsOfType( p, ID_OPBRK ) ) // a table?
- {
- CBotInstr* i = NULL;
-
- if ( p->GivType() != ID_CLBRK )
- i = CBotExpression::Compile( p, pStack ); // expression for the value
- else
- i = new CBotEmpty(); // special if not a formula
-
- type = CBotTypResult(CBotTypArrayPointer, type);
-
- if (!pStack->IsOk() || !IsOfType( p, ID_CLBRK ) )
- {
- pStack->SetError(TX_CLBRK, p->GivStart());
- return false;
- }
-
-/* CBotVar* pv = pStack->GivVar();
- if ( pv->GivType()>= CBotTypBoolean )
- {
- pStack->SetError(TX_BADTYPE, p->GivStart());
- return false;
- }*/
-
- if (limites == NULL) limites = i;
- else limites->AddNext3(i);
- }
-
- if ( p->GivType() == ID_OPENPAR )
- {
- if ( !bSecond )
- {
- p = pBase;
- CBotFunction* f =
- CBotFunction::Compile1(p, pStack, this);
-
- if ( f == NULL ) return false;
-
- if (m_pMethod == NULL) m_pMethod = f;
- else m_pMethod->AddNext(f);
- }
- else
- {
- // return a method precompiled in pass 1
- CBotFunction* pf = m_pMethod;
- CBotFunction* prev = NULL;
- while ( pf != NULL )
- {
- if (pf->GivName() == pp->GivString()) break;
- prev = pf;
- pf = pf->Next();
- }
-
- bool bConstructor = (pp->GivString() == GivName());
- CBotCStack* pile = pStack->TokenStack(NULL, true);
-
- // make "this" known
- CBotToken TokenThis(CBotString("this"), CBotString());
- CBotVar* pThis = CBotVar::Create(&TokenThis, CBotTypResult( CBotTypClass, this ) );
- pThis->SetUniqNum(-2);
- pile->AddVar(pThis);
-
- if ( m_pParent )
- {
- // makes "super" known
- CBotToken TokenSuper(CBotString("super"), CBotString());
- CBotVar* pThis = CBotVar::Create(&TokenSuper, CBotTypResult( CBotTypClass, m_pParent ) );
- pThis->SetUniqNum(-3);
- pile->AddVar(pThis);
- }
-
-// int num = 1;
- CBotClass* my = this;
- while (my != NULL)
- {
- // places a copy of variables of a class (this) on a stack
- CBotVar* pv = my->m_pVar;
- while (pv != NULL)
- {
- CBotVar* pcopy = CBotVar::Create(pv);
- pcopy->SetInit(!bConstructor || pv->IsStatic());
- pcopy->SetUniqNum(pv->GivUniqNum());
- pile->AddVar(pcopy);
- pv = pv->GivNext();
- }
- my = my->m_pParent;
- }
-
- // compiles a method
- p = pBase;
- CBotFunction* f =
- CBotFunction::Compile(p, pile, NULL/*, false*/);
-
- if ( f != NULL )
- {
- f->m_pProg = pStack->GivBotCall();
- f->m_bSynchro = bSynchro;
- // replaces the element in the chain
- f->m_next = pf->m_next;
- pf->m_next = NULL;
- delete pf;
- if (prev == NULL) m_pMethod = f;
- else prev->m_next = f;
- }
- pStack->Return(NULL, pile);
- }
-
- return pStack->IsOk();
- }
-
- // definition of an element
- if (type.Eq(0))
- {
- pStack->SetError(TX_ENDOF, p);
- return false;
- }
-
- CBotInstr* i = NULL;
- if ( IsOfType(p, ID_ASS ) )
- {
- if ( type.Eq(CBotTypArrayPointer) )
- {
- i = CBotListArray::Compile(p, pStack, type.GivTypElem());
- }
- else
- {
- // it has an assignmet to calculate
- i = CBotTwoOpExpr::Compile(p, pStack);
- }
- if ( !pStack->IsOk() ) return false;
- }
-
-
- if ( !bSecond )
- {
- CBotVar* pv = CBotVar::Create(pp->GivString(), type);
- pv -> SetStatic( bStatic );
- pv -> SetPrivate( mProtect );
-
- AddItem( pv );
-
- pv->m_InitExpr = i;
- pv->m_LimExpr = limites;
-
-
- if ( pv->IsStatic() && pv->m_InitExpr != NULL )
- {
- CBotStack* pile = CBotStack::FirstStack(); // independent stack
- while(pile->IsOk() && !pv->m_InitExpr->Execute(pile)); // evaluates the expression without timer
- pv->SetVal( pile->GivVar() ) ;
- pile->Delete();
- }
- }
- else
- delete i;
-
- if ( IsOfType(p, ID_COMMA) ) continue;
- if ( IsOfType(p, ID_SEP) ) break;
- }
- pStack->SetError(TX_ENDOF, p);
- }
- return pStack->IsOk();
+ bool bStatic = false;
+ int mProtect = PR_PUBLIC;
+ bool bSynchro = false;
+
+ while (IsOfType(p, ID_SEP)) ;
+
+ CBotTypResult type( -1 );
+
+ if ( IsOfType(p, ID_SYNCHO) ) bSynchro = true;
+ CBotToken* pBase = p;
+
+ if ( IsOfType(p, ID_STATIC) ) bStatic = true;
+ if ( IsOfType(p, ID_PUBLIC) ) mProtect = PR_PUBLIC;
+ if ( IsOfType(p, ID_PRIVATE) ) mProtect = PR_PRIVATE;
+ if ( IsOfType(p, ID_PROTECTED) ) mProtect = PR_PROTECT;
+ if ( IsOfType(p, ID_STATIC) ) bStatic = true;
+
+// CBotClass* pClass = NULL;
+ type = TypeParam(p, pStack); // type of the result
+
+ if ( type.Eq(-1) )
+ {
+ pStack->SetError(TX_NOTYP, p);
+ return false;
+ }
+
+ while (pStack->IsOk())
+ {
+ CBotToken* pp = p;
+ IsOfType(p, ID_NOT); // skips ~ eventual (destructor)
+
+ if (IsOfType(p, TokenTypVar))
+ {
+ CBotInstr* limites = NULL;
+ while ( IsOfType( p, ID_OPBRK ) ) // a table?
+ {
+ CBotInstr* i = NULL;
+
+ if ( p->GivType() != ID_CLBRK )
+ i = CBotExpression::Compile( p, pStack ); // expression for the value
+ else
+ i = new CBotEmpty(); // special if not a formula
+
+ type = CBotTypResult(CBotTypArrayPointer, type);
+
+ if (!pStack->IsOk() || !IsOfType( p, ID_CLBRK ) )
+ {
+ pStack->SetError(TX_CLBRK, p->GivStart());
+ return false;
+ }
+
+/* CBotVar* pv = pStack->GivVar();
+ if ( pv->GivType()>= CBotTypBoolean )
+ {
+ pStack->SetError(TX_BADTYPE, p->GivStart());
+ return false;
+ }*/
+
+ if (limites == NULL) limites = i;
+ else limites->AddNext3(i);
+ }
+
+ if ( p->GivType() == ID_OPENPAR )
+ {
+ if ( !bSecond )
+ {
+ p = pBase;
+ CBotFunction* f =
+ CBotFunction::Compile1(p, pStack, this);
+
+ if ( f == NULL ) return false;
+
+ if (m_pMethod == NULL) m_pMethod = f;
+ else m_pMethod->AddNext(f);
+ }
+ else
+ {
+ // return a method precompiled in pass 1
+ CBotFunction* pf = m_pMethod;
+ CBotFunction* prev = NULL;
+ while ( pf != NULL )
+ {
+ if (pf->GivName() == pp->GivString()) break;
+ prev = pf;
+ pf = pf->Next();
+ }
+
+ bool bConstructor = (pp->GivString() == GivName());
+ CBotCStack* pile = pStack->TokenStack(NULL, true);
+
+ // make "this" known
+ CBotToken TokenThis(CBotString("this"), CBotString());
+ CBotVar* pThis = CBotVar::Create(&TokenThis, CBotTypResult( CBotTypClass, this ) );
+ pThis->SetUniqNum(-2);
+ pile->AddVar(pThis);
+
+ if ( m_pParent )
+ {
+ // makes "super" known
+ CBotToken TokenSuper(CBotString("super"), CBotString());
+ CBotVar* pThis = CBotVar::Create(&TokenSuper, CBotTypResult( CBotTypClass, m_pParent ) );
+ pThis->SetUniqNum(-3);
+ pile->AddVar(pThis);
+ }
+
+// int num = 1;
+ CBotClass* my = this;
+ while (my != NULL)
+ {
+ // places a copy of variables of a class (this) on a stack
+ CBotVar* pv = my->m_pVar;
+ while (pv != NULL)
+ {
+ CBotVar* pcopy = CBotVar::Create(pv);
+ pcopy->SetInit(!bConstructor || pv->IsStatic());
+ pcopy->SetUniqNum(pv->GivUniqNum());
+ pile->AddVar(pcopy);
+ pv = pv->GivNext();
+ }
+ my = my->m_pParent;
+ }
+
+ // compiles a method
+ p = pBase;
+ CBotFunction* f =
+ CBotFunction::Compile(p, pile, NULL/*, false*/);
+
+ if ( f != NULL )
+ {
+ f->m_pProg = pStack->GivBotCall();
+ f->m_bSynchro = bSynchro;
+ // replaces the element in the chain
+ f->m_next = pf->m_next;
+ pf->m_next = NULL;
+ delete pf;
+ if (prev == NULL) m_pMethod = f;
+ else prev->m_next = f;
+ }
+ pStack->Return(NULL, pile);
+ }
+
+ return pStack->IsOk();
+ }
+
+ // definition of an element
+ if (type.Eq(0))
+ {
+ pStack->SetError(TX_ENDOF, p);
+ return false;
+ }
+
+ CBotInstr* i = NULL;
+ if ( IsOfType(p, ID_ASS ) )
+ {
+ if ( type.Eq(CBotTypArrayPointer) )
+ {
+ i = CBotListArray::Compile(p, pStack, type.GivTypElem());
+ }
+ else
+ {
+ // it has an assignmet to calculate
+ i = CBotTwoOpExpr::Compile(p, pStack);
+ }
+ if ( !pStack->IsOk() ) return false;
+ }
+
+
+ if ( !bSecond )
+ {
+ CBotVar* pv = CBotVar::Create(pp->GivString(), type);
+ pv -> SetStatic( bStatic );
+ pv -> SetPrivate( mProtect );
+
+ AddItem( pv );
+
+ pv->m_InitExpr = i;
+ pv->m_LimExpr = limites;
+
+
+ if ( pv->IsStatic() && pv->m_InitExpr != NULL )
+ {
+ CBotStack* pile = CBotStack::FirstStack(); // independent stack
+ while(pile->IsOk() && !pv->m_InitExpr->Execute(pile)); // evaluates the expression without timer
+ pv->SetVal( pile->GivVar() ) ;
+ pile->Delete();
+ }
+ }
+ else
+ delete i;
+
+ if ( IsOfType(p, ID_COMMA) ) continue;
+ if ( IsOfType(p, ID_SEP) ) break;
+ }
+ pStack->SetError(TX_ENDOF, p);
+ }
+ return pStack->IsOk();
}
CBotClass* CBotClass::Compile(CBotToken* &p, CBotCStack* pStack)
{
- if ( !IsOfType(p, ID_PUBLIC) ) return NULL;
- if ( !IsOfType(p, ID_CLASS) ) return NULL;
-
- CBotString name = p->GivString();
-
- // a name for the class is there?
- if (IsOfType(p, TokenTypVar))
- {
- // the class was created by Compile1
- CBotClass* pOld = CBotClass::Find(name);
-
- if ( IsOfType( p, ID_EXTENDS ) )
- {
- IsOfType(p, TokenTypVar); // necessarily
- }
- IsOfType( p, ID_OPBLK); // necessarily
-
- while ( pStack->IsOk() && !IsOfType( p, ID_CLBLK ) )
- {
- pOld->CompileDefItem(p, pStack, true);
- }
-
- pOld->m_IsDef = true; // complete definition
- if (pStack->IsOk()) return pOld;
- }
- pStack->SetError(TX_ENDOF, p);
- return NULL;
+ if ( !IsOfType(p, ID_PUBLIC) ) return NULL;
+ if ( !IsOfType(p, ID_CLASS) ) return NULL;
+
+ CBotString name = p->GivString();
+
+ // a name for the class is there?
+ if (IsOfType(p, TokenTypVar))
+ {
+ // the class was created by Compile1
+ CBotClass* pOld = CBotClass::Find(name);
+
+ if ( IsOfType( p, ID_EXTENDS ) )
+ {
+ IsOfType(p, TokenTypVar); // necessarily
+ }
+ IsOfType( p, ID_OPBLK); // necessarily
+
+ while ( pStack->IsOk() && !IsOfType( p, ID_CLBLK ) )
+ {
+ pOld->CompileDefItem(p, pStack, true);
+ }
+
+ pOld->m_IsDef = true; // complete definition
+ if (pStack->IsOk()) return pOld;
+ }
+ pStack->SetError(TX_ENDOF, p);
+ return NULL;
}
diff --git a/src/CBot/CBotIf.cpp b/src/CBot/CBotIf.cpp
index c1dc833..84dbd6a 100644
--- a/src/CBot/CBotIf.cpp
+++ b/src/CBot/CBotIf.cpp
@@ -22,17 +22,17 @@
// various constructors / destructors
CBotIf::CBotIf()
{
- m_Condition =
- m_Block =
- m_BlockElse = NULL; // NULL so that delete is not possible further
- name = "CBotIf"; // debug
+ m_Condition =
+ m_Block =
+ m_BlockElse = NULL; // NULL so that delete is not possible further
+ name = "CBotIf"; // debug
}
CBotIf::~CBotIf()
{
- delete m_Condition; // frees the condition
- delete m_Block; // frees the block of instruction1
- delete m_BlockElse; // frees the block of instruction2
+ delete m_Condition; // frees the condition
+ delete m_Block; // frees the block of instruction1
+ delete m_BlockElse; // frees the block of instruction2
}
// compilation (static routine)
@@ -40,47 +40,47 @@ CBotIf::~CBotIf()
CBotInstr* CBotIf::Compile(CBotToken* &p, CBotCStack* pStack)
{
- CBotToken* pp = p; // preserves at the ^ token (starting instruction)
-
- if (!IsOfType(p, ID_IF)) return NULL; // should never happen
-
- CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
-
- CBotIf* inst = new CBotIf(); // create the object
- inst->SetToken( pp );
-
- if ( NULL != (inst->m_Condition = CBotCondition::Compile( p, pStk )) )
- {
- // the condition does exist
-
- inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
- if ( pStk->IsOk() )
- {
- // the statement block is ok (can be empty)
-
- // see if the next instruction is the token "else"
- if (IsOfType(p, ID_ELSE))
- {
- // if so, compiles the following statement block
- inst->m_BlockElse = CBotBlock::CompileBlkOrInst( p, pStk, true );
- if (!pStk->IsOk())
- {
- // there is no correct block after the else
- // frees the object, and transmits the error that is on the stack
- delete inst;
- return pStack->Return(NULL, pStk);
- }
- }
-
- // return the corrent object to the application
- return pStack->Return(inst, pStk);
- }
- }
-
- // error, frees the object
- delete inst;
- // and transmits the error that is on the stack.
- return pStack->Return(NULL, pStk);
+ CBotToken* pp = p; // preserves at the ^ token (starting instruction)
+
+ if (!IsOfType(p, ID_IF)) return NULL; // should never happen
+
+ CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
+
+ CBotIf* inst = new CBotIf(); // create the object
+ inst->SetToken( pp );
+
+ if ( NULL != (inst->m_Condition = CBotCondition::Compile( p, pStk )) )
+ {
+ // the condition does exist
+
+ inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
+ if ( pStk->IsOk() )
+ {
+ // the statement block is ok (can be empty)
+
+ // see if the next instruction is the token "else"
+ if (IsOfType(p, ID_ELSE))
+ {
+ // if so, compiles the following statement block
+ inst->m_BlockElse = CBotBlock::CompileBlkOrInst( p, pStk, true );
+ if (!pStk->IsOk())
+ {
+ // there is no correct block after the else
+ // frees the object, and transmits the error that is on the stack
+ delete inst;
+ return pStack->Return(NULL, pStk);
+ }
+ }
+
+ // return the corrent object to the application
+ return pStack->Return(inst, pStk);
+ }
+ }
+
+ // error, frees the object
+ delete inst;
+ // and transmits the error that is on the stack.
+ return pStack->Return(NULL, pStk);
}
@@ -88,74 +88,74 @@ CBotInstr* CBotIf::Compile(CBotToken* &p, CBotCStack* pStack)
bool CBotIf :: Execute(CBotStack* &pj)
{
- CBotStack* pile = pj->AddStack(this); // adds an item to the stack
- // or found in case of recovery
-// if ( pile == EOX ) return true;
-
- if ( pile->IfStep() ) return false;
-
- // according to recovery, it may be in one of two states
- if( pile->GivState() == 0 )
- {
- // evaluates the condition
- if ( !m_Condition->Execute(pile) ) return false; // interrupted here?
-
- // terminates if there is an error
- if ( !pile->IsOk() )
- {
- return pj->Return(pile); // returns the results and releases the stack
- }
-
- // passes into the second state
- if (!pile->SetState(1)) return false; // ready for further
- }
-
- // second state, evaluates the associated instructions
- // the result of the condition is on the stack
-
- if ( pile->GivVal() == true ) // condition was true?
- {
- if ( m_Block != NULL && // block may be absent
- !m_Block->Execute(pile) ) return false; // interrupted here?
- }
- else
- {
- if ( m_BlockElse != NULL && // if there is an alternate block
- !m_BlockElse->Execute(pile) ) return false; // interrupted here
- }
-
- // sends the results and releases the stack
- return pj->Return(pile);
+ CBotStack* pile = pj->AddStack(this); // adds an item to the stack
+ // or found in case of recovery
+// if ( pile == EOX ) return true;
+
+ if ( pile->IfStep() ) return false;
+
+ // according to recovery, it may be in one of two states
+ if( pile->GivState() == 0 )
+ {
+ // evaluates the condition
+ if ( !m_Condition->Execute(pile) ) return false; // interrupted here?
+
+ // terminates if there is an error
+ if ( !pile->IsOk() )
+ {
+ return pj->Return(pile); // returns the results and releases the stack
+ }
+
+ // passes into the second state
+ if (!pile->SetState(1)) return false; // ready for further
+ }
+
+ // second state, evaluates the associated instructions
+ // the result of the condition is on the stack
+
+ if ( pile->GivVal() == true ) // condition was true?
+ {
+ if ( m_Block != NULL && // block may be absent
+ !m_Block->Execute(pile) ) return false; // interrupted here?
+ }
+ else
+ {
+ if ( m_BlockElse != NULL && // if there is an alternate block
+ !m_BlockElse->Execute(pile) ) return false; // interrupted here
+ }
+
+ // sends the results and releases the stack
+ return pj->Return(pile);
}
void CBotIf :: RestoreState(CBotStack* &pj, bool bMain)
{
- if ( !bMain ) return;
-
- CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack
- if ( pile == NULL ) return;
-
- // according to recovery, it may be in one of two states
- if( pile->GivState() == 0 )
- {
- // evaluates the condition
- m_Condition->RestoreState(pile, bMain); // interrupted here!
- return;
- }
-
- // second state, evaluates the associated instructions
- // the result of the condition is on the stack
-
- if ( pile->GivVal() == true ) // condition was true?
- {
- if ( m_Block != NULL ) // block may be absent
- m_Block->RestoreState(pile, bMain); // interrupted here!
- }
- else
- {
- if ( m_BlockElse != NULL ) // if there is an alternate block
- m_BlockElse->RestoreState(pile, bMain); // interrupted here!
- }
+ if ( !bMain ) return;
+
+ CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack
+ if ( pile == NULL ) return;
+
+ // according to recovery, it may be in one of two states
+ if( pile->GivState() == 0 )
+ {
+ // evaluates the condition
+ m_Condition->RestoreState(pile, bMain); // interrupted here!
+ return;
+ }
+
+ // second state, evaluates the associated instructions
+ // the result of the condition is on the stack
+
+ if ( pile->GivVal() == true ) // condition was true?
+ {
+ if ( m_Block != NULL ) // block may be absent
+ m_Block->RestoreState(pile, bMain); // interrupted here!
+ }
+ else
+ {
+ if ( m_BlockElse != NULL ) // if there is an alternate block
+ m_BlockElse->RestoreState(pile, bMain); // interrupted here!
+ }
}
diff --git a/src/CBot/CBotProgram.cpp b/src/CBot/CBotProgram.cpp
index 5f1c021..d9be052 100644
--- a/src/CBot/CBotProgram.cpp
+++ b/src/CBot/CBotProgram.cpp
@@ -22,597 +22,597 @@
CBotProgram::CBotProgram()
{
- m_Prog = NULL;
- m_pRun = NULL;
- m_pClass = NULL;
- m_pStack = NULL;
- m_pInstance = NULL;
-
- m_ErrorCode = 0;
- m_Ident = 0;
- m_bDebugDD = 0;
+ m_Prog = NULL;
+ m_pRun = NULL;
+ m_pClass = NULL;
+ m_pStack = NULL;
+ m_pInstance = NULL;
+
+ m_ErrorCode = 0;
+ m_Ident = 0;
+ m_bDebugDD = 0;
}
CBotProgram::CBotProgram(CBotVar* pInstance)
{
- m_Prog = NULL;
- m_pRun = NULL;
- m_pClass = NULL;
- m_pStack = NULL;
- m_pInstance = pInstance;
-
- m_ErrorCode = 0;
- m_Ident = 0;
- m_bDebugDD = 0;
+ m_Prog = NULL;
+ m_pRun = NULL;
+ m_pClass = NULL;
+ m_pStack = NULL;
+ m_pInstance = pInstance;
+
+ m_ErrorCode = 0;
+ m_Ident = 0;
+ m_bDebugDD = 0;
}
CBotProgram::~CBotProgram()
{
-// delete m_pClass;
- m_pClass->Purge();
- m_pClass = NULL;
+// delete m_pClass;
+ m_pClass->Purge();
+ m_pClass = NULL;
- CBotClass::FreeLock(this);
+ CBotClass::FreeLock(this);
- delete m_Prog;
-#if STACKMEM
- m_pStack->Delete();
+ delete m_Prog;
+#if STACKMEM
+ m_pStack->Delete();
#else
- delete m_pStack;
+ delete m_pStack;
#endif
}
bool CBotProgram::Compile( const char* program, CBotStringArray& ListFonctions, void* pUser )
{
- int error = 0;
- Stop();
-
-// delete m_pClass;
- m_pClass->Purge(); // purge the old definitions of classes
- // but without destroying the object
- m_pClass = NULL;
- delete m_Prog; m_Prog= NULL;
-
- ListFonctions.SetSize(0);
- m_ErrorCode = 0;
-
- if (m_pInstance != NULL && m_pInstance->m_pUserPtr != NULL)
- pUser = m_pInstance->m_pUserPtr;
-
- // transforms the program in Tokens
- CBotToken* pBaseToken = CBotToken::CompileTokens(program, error);
- if ( pBaseToken == NULL ) return false;
-
-
- CBotCStack* pStack = new CBotCStack(NULL);
- CBotToken* p = pBaseToken->GivNext(); // skips the first token (separator)
-
- pStack->SetBotCall(this); // defined used routines
- CBotCall::SetPUser(pUser);
-
- // first made a quick pass just to take the headers of routines and classes
- while ( pStack->IsOk() && p != NULL && p->GivType() != 0)
- {
- if ( IsOfType(p, ID_SEP) ) continue; // semicolons lurking
-
- if ( p->GivType() == ID_CLASS ||
- ( p->GivType() == ID_PUBLIC && p->GivNext()->GivType() == ID_CLASS ))
- {
- CBotClass* nxt = CBotClass::Compile1(p, pStack);
- if (m_pClass == NULL ) m_pClass = nxt;
- else m_pClass->AddNext(nxt);
- }
- else
- {
- CBotFunction* next = CBotFunction::Compile1(p, pStack, NULL);
- if (m_Prog == NULL ) m_Prog = next;
- else m_Prog->AddNext(next);
- }
- }
- if ( !pStack->IsOk() )
- {
- m_ErrorCode = pStack->GivError(m_ErrorStart, m_ErrorEnd);
- delete m_Prog;
- m_Prog = NULL;
- delete pBaseToken;
- return false;
- }
-
-// CBotFunction* temp = NULL;
- CBotFunction* next = m_Prog; // rewind the list
-
- p = pBaseToken->GivNext(); // returns to the beginning
-
- while ( pStack->IsOk() && p != NULL && p->GivType() != 0 )
- {
- if ( IsOfType(p, ID_SEP) ) continue; // semicolons lurking
-
- if ( p->GivType() == ID_CLASS ||
- ( p->GivType() == ID_PUBLIC && p->GivNext()->GivType() == ID_CLASS ))
- {
- m_bCompileClass = true;
- CBotClass::Compile(p, pStack); // completes the definition of the class
- }
- else
- {
- m_bCompileClass = false;
- CBotFunction::Compile(p, pStack, next);
- if (next->IsExtern()) ListFonctions.Add(next->GivName()/* + next->GivParams()*/);
- next->m_pProg = this; // keeps pointers to the module
- next = next->Next();
- }
- }
-
-// delete m_Prog; // the list of first pass
-// m_Prog = temp; // list of the second pass
-
- if ( !pStack->IsOk() )
- {
- m_ErrorCode = pStack->GivError(m_ErrorStart, m_ErrorEnd);
- delete m_Prog;
- m_Prog = NULL;
- }
-
- delete pBaseToken;
- delete pStack;
-
- return (m_Prog != NULL);
+ int error = 0;
+ Stop();
+
+// delete m_pClass;
+ m_pClass->Purge(); // purge the old definitions of classes
+ // but without destroying the object
+ m_pClass = NULL;
+ delete m_Prog; m_Prog= NULL;
+
+ ListFonctions.SetSize(0);
+ m_ErrorCode = 0;
+
+ if (m_pInstance != NULL && m_pInstance->m_pUserPtr != NULL)
+ pUser = m_pInstance->m_pUserPtr;
+
+ // transforms the program in Tokens
+ CBotToken* pBaseToken = CBotToken::CompileTokens(program, error);
+ if ( pBaseToken == NULL ) return false;
+
+
+ CBotCStack* pStack = new CBotCStack(NULL);
+ CBotToken* p = pBaseToken->GivNext(); // skips the first token (separator)
+
+ pStack->SetBotCall(this); // defined used routines
+ CBotCall::SetPUser(pUser);
+
+ // first made a quick pass just to take the headers of routines and classes
+ while ( pStack->IsOk() && p != NULL && p->GivType() != 0)
+ {
+ if ( IsOfType(p, ID_SEP) ) continue; // semicolons lurking
+
+ if ( p->GivType() == ID_CLASS ||
+ ( p->GivType() == ID_PUBLIC && p->GivNext()->GivType() == ID_CLASS ))
+ {
+ CBotClass* nxt = CBotClass::Compile1(p, pStack);
+ if (m_pClass == NULL ) m_pClass = nxt;
+ else m_pClass->AddNext(nxt);
+ }
+ else
+ {
+ CBotFunction* next = CBotFunction::Compile1(p, pStack, NULL);
+ if (m_Prog == NULL ) m_Prog = next;
+ else m_Prog->AddNext(next);
+ }
+ }
+ if ( !pStack->IsOk() )
+ {
+ m_ErrorCode = pStack->GivError(m_ErrorStart, m_ErrorEnd);
+ delete m_Prog;
+ m_Prog = NULL;
+ delete pBaseToken;
+ return false;
+ }
+
+// CBotFunction* temp = NULL;
+ CBotFunction* next = m_Prog; // rewind the list
+
+ p = pBaseToken->GivNext(); // returns to the beginning
+
+ while ( pStack->IsOk() && p != NULL && p->GivType() != 0 )
+ {
+ if ( IsOfType(p, ID_SEP) ) continue; // semicolons lurking
+
+ if ( p->GivType() == ID_CLASS ||
+ ( p->GivType() == ID_PUBLIC && p->GivNext()->GivType() == ID_CLASS ))
+ {
+ m_bCompileClass = true;
+ CBotClass::Compile(p, pStack); // completes the definition of the class
+ }
+ else
+ {
+ m_bCompileClass = false;
+ CBotFunction::Compile(p, pStack, next);
+ if (next->IsExtern()) ListFonctions.Add(next->GivName()/* + next->GivParams()*/);
+ next->m_pProg = this; // keeps pointers to the module
+ next = next->Next();
+ }
+ }
+
+// delete m_Prog; // the list of first pass
+// m_Prog = temp; // list of the second pass
+
+ if ( !pStack->IsOk() )
+ {
+ m_ErrorCode = pStack->GivError(m_ErrorStart, m_ErrorEnd);
+ delete m_Prog;
+ m_Prog = NULL;
+ }
+
+ delete pBaseToken;
+ delete pStack;
+
+ return (m_Prog != NULL);
}
bool CBotProgram::Start(const char* name)
{
-#if STACKMEM
- m_pStack->Delete();
+#if STACKMEM
+ m_pStack->Delete();
#else
- delete m_pStack;
+ delete m_pStack;
#endif
- m_pStack = NULL;
-
- m_pRun = m_Prog;
- while (m_pRun != NULL)
- {
- if ( m_pRun->GivName() == name ) break;
- m_pRun = m_pRun->m_next;
- }
-
- if ( m_pRun == NULL )
- {
- m_ErrorCode = TX_NORUN;
- return false;
- }
-
-#if STACKMEM
- m_pStack = CBotStack::FirstStack();
+ m_pStack = NULL;
+
+ m_pRun = m_Prog;
+ while (m_pRun != NULL)
+ {
+ if ( m_pRun->GivName() == name ) break;
+ m_pRun = m_pRun->m_next;
+ }
+
+ if ( m_pRun == NULL )
+ {
+ m_ErrorCode = TX_NORUN;
+ return false;
+ }
+
+#if STACKMEM
+ m_pStack = CBotStack::FirstStack();
#else
- m_pStack = new CBotStack(NULL); // creates an execution stack
+ m_pStack = new CBotStack(NULL); // creates an execution stack
#endif
- m_pStack->SetBotCall(this); // bases for routines
+ m_pStack->SetBotCall(this); // bases for routines
- return true; // we are ready for Run ()
+ return true; // we are ready for Run ()
}
bool CBotProgram::GetPosition(const char* name, int& start, int& stop, CBotGet modestart, CBotGet modestop)
{
- CBotFunction* p = m_Prog;
- while (p != NULL)
- {
- if ( p->GivName() == name ) break;
- p = p->m_next;
- }
+ CBotFunction* p = m_Prog;
+ while (p != NULL)
+ {
+ if ( p->GivName() == name ) break;
+ p = p->m_next;
+ }
- if ( p == NULL ) return false;
+ if ( p == NULL ) return false;
- p->GetPosition(start, stop, modestart, modestop);
- return true;
+ p->GetPosition(start, stop, modestart, modestop);
+ return true;
}
bool CBotProgram::Run(void* pUser, int timer)
{
- bool ok;
-
- if (m_pStack == NULL || m_pRun == NULL) goto error;
-
- m_ErrorCode = 0;
- if (m_pInstance != NULL && m_pInstance->m_pUserPtr != NULL)
- pUser = m_pInstance->m_pUserPtr;
-
- m_pStack->Reset(pUser); // empty the possible previous error, and resets the timer
- if ( timer >= 0 ) m_pStack->SetTimer(timer);
-
- m_pStack->SetBotCall(this); // bases for routines
-
-#if STACKRUN
- // resumes execution on the top of the stack
- ok = m_pStack->Execute();
- if ( ok )
- {
-#ifdef _DEBUG
- CBotVar* ppVar[3];
- ppVar[0] = CBotVar::Create("aa", CBotTypInt);
- ppVar[1] = CBotVar::Create("bb", CBotTypInt);
- ppVar[2] = NULL;
- ok = m_pRun->Execute(ppVar, m_pStack, m_pInstance);
+ bool ok;
+
+ if (m_pStack == NULL || m_pRun == NULL) goto error;
+
+ m_ErrorCode = 0;
+ if (m_pInstance != NULL && m_pInstance->m_pUserPtr != NULL)
+ pUser = m_pInstance->m_pUserPtr;
+
+ m_pStack->Reset(pUser); // empty the possible previous error, and resets the timer
+ if ( timer >= 0 ) m_pStack->SetTimer(timer);
+
+ m_pStack->SetBotCall(this); // bases for routines
+
+#if STACKRUN
+ // resumes execution on the top of the stack
+ ok = m_pStack->Execute();
+ if ( ok )
+ {
+#ifdef _DEBUG
+ CBotVar* ppVar[3];
+ ppVar[0] = CBotVar::Create("aa", CBotTypInt);
+ ppVar[1] = CBotVar::Create("bb", CBotTypInt);
+ ppVar[2] = NULL;
+ ok = m_pRun->Execute(ppVar, m_pStack, m_pInstance);
#else
- // returns to normal execution
- ok = m_pRun->Execute(NULL, m_pStack, m_pInstance);
+ // returns to normal execution
+ ok = m_pRun->Execute(NULL, m_pStack, m_pInstance);
#endif
- }
+ }
#else
- ok = m_pRun->Execute(NULL, m_pStack, m_pInstance);
+ ok = m_pRun->Execute(NULL, m_pStack, m_pInstance);
#endif
- // completed on a mistake?
- if (!ok && !m_pStack->IsOk())
- {
- m_ErrorCode = m_pStack->GivError(m_ErrorStart, m_ErrorEnd);
-#if STACKMEM
- m_pStack->Delete();
+ // completed on a mistake?
+ if (!ok && !m_pStack->IsOk())
+ {
+ m_ErrorCode = m_pStack->GivError(m_ErrorStart, m_ErrorEnd);
+#if STACKMEM
+ m_pStack->Delete();
#else
- delete m_pStack;
+ delete m_pStack;
#endif
- m_pStack = NULL;
- return true; // execution is finished!
- }
+ m_pStack = NULL;
+ return true; // execution is finished!
+ }
- if ( ok ) m_pRun = NULL; // more function in execution
- return ok;
+ if ( ok ) m_pRun = NULL; // more function in execution
+ return ok;
error:
- m_ErrorCode = TX_NORUN;
- return true;
+ m_ErrorCode = TX_NORUN;
+ return true;
}
void CBotProgram::Stop()
{
-#if STACKMEM
- m_pStack->Delete();
+#if STACKMEM
+ m_pStack->Delete();
#else
- delete m_pStack;
+ delete m_pStack;
#endif
- m_pStack = NULL;
- m_pRun = NULL;
+ m_pStack = NULL;
+ m_pRun = NULL;
}
bool CBotProgram::GetRunPos(const char* &FunctionName, int &start, int &end)
{
- FunctionName = NULL;
- start = end = 0;
- if (m_pStack == NULL) return false;
+ FunctionName = NULL;
+ start = end = 0;
+ if (m_pStack == NULL) return false;
- m_pStack->GetRunPos(FunctionName, start, end);
- return true;
+ m_pStack->GetRunPos(FunctionName, start, end);
+ return true;
}
CBotVar* CBotProgram::GivStackVars(const char* &FunctionName, int level)
{
- FunctionName = NULL;
- if (m_pStack == NULL) return NULL;
+ FunctionName = NULL;
+ if (m_pStack == NULL) return NULL;
- return m_pStack->GivStackVars(FunctionName, level);
+ return m_pStack->GivStackVars(FunctionName, level);
}
void CBotProgram::SetTimer(int n)
{
- CBotStack::SetTimer( n );
+ CBotStack::SetTimer( n );
}
int CBotProgram::GivError()
{
- return m_ErrorCode;
+ return m_ErrorCode;
}
void CBotProgram::SetIdent(long n)
{
- m_Ident = n;
+ m_Ident = n;
}
long CBotProgram::GivIdent()
{
- return m_Ident;
+ return m_Ident;
}
bool CBotProgram::GetError(int& code, int& start, int& end)
{
- code = m_ErrorCode;
- start = m_ErrorStart;
- end = m_ErrorEnd;
- return code > 0;
+ code = m_ErrorCode;
+ start = m_ErrorStart;
+ end = m_ErrorEnd;
+ return code > 0;
}
bool CBotProgram::GetError(int& code, int& start, int& end, CBotProgram* &pProg)
{
- code = m_ErrorCode;
- start = m_ErrorStart;
- end = m_ErrorEnd;
- pProg = this;
- return code > 0;
+ code = m_ErrorCode;
+ start = m_ErrorStart;
+ end = m_ErrorEnd;
+ pProg = this;
+ return code > 0;
}
CBotString CBotProgram::GivErrorText(int code)
{
- CBotString TextError;
-
- TextError.LoadString( code );
- if (TextError.IsEmpty())
- {
- char buf[100];
- sprintf(buf, "Exception numéro %d.", code);
- TextError = buf;
- }
- return TextError;
+ CBotString TextError;
+
+ TextError.LoadString( code );
+ if (TextError.IsEmpty())
+ {
+ char buf[100];
+ sprintf(buf, "Exception numéro %d.", code);
+ TextError = buf;
+ }
+ return TextError;
}
CBotFunction* CBotProgram::GivFunctions()
{
- return m_Prog;
+ return m_Prog;
}
bool CBotProgram::AddFunction(const char* name,
- bool rExec (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser),
- CBotTypResult rCompile (CBotVar* &pVar, void* pUser))
+ bool rExec (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser),
+ CBotTypResult rCompile (CBotVar* &pVar, void* pUser))
{
- // stores pointers to the two functions
- return CBotCall::AddFunction(name, rExec, rCompile);
+ // stores pointers to the two functions
+ return CBotCall::AddFunction(name, rExec, rCompile);
}
bool WriteWord(FILE* pf, unsigned short w)
{
- size_t lg;
+ size_t lg;
- lg = fwrite(&w, sizeof( unsigned short ), 1, pf );
+ lg = fwrite(&w, sizeof( unsigned short ), 1, pf );
- return (lg == 1);
+ return (lg == 1);
}
bool ReadWord(FILE* pf, unsigned short& w)
{
- size_t lg;
+ size_t lg;
- lg = fread(&w, sizeof( unsigned short ), 1, pf );
+ lg = fread(&w, sizeof( unsigned short ), 1, pf );
- return (lg == 1);
+ return (lg == 1);
}
bool WriteFloat(FILE* pf, float w)
{
- size_t lg;
+ size_t lg;
- lg = fwrite(&w, sizeof( float ), 1, pf );
+ lg = fwrite(&w, sizeof( float ), 1, pf );
- return (lg == 1);
+ return (lg == 1);
}
bool ReadFloat(FILE* pf, float& w)
{
- size_t lg;
+ size_t lg;
- lg = fread(&w, sizeof( float ), 1, pf );
+ lg = fread(&w, sizeof( float ), 1, pf );
- return (lg == 1);
+ return (lg == 1);
}
bool WriteLong(FILE* pf, long w)
{
- size_t lg;
+ size_t lg;
- lg = fwrite(&w, sizeof( long ), 1, pf );
+ lg = fwrite(&w, sizeof( long ), 1, pf );
- return (lg == 1);
+ return (lg == 1);
}
bool ReadLong(FILE* pf, long& w)
{
- size_t lg;
+ size_t lg;
- lg = fread(&w, sizeof( long ), 1, pf );
+ lg = fread(&w, sizeof( long ), 1, pf );
- return (lg == 1);
+ return (lg == 1);
}
bool WriteString(FILE* pf, CBotString s)
{
- size_t lg1, lg2;
+ size_t lg1, lg2;
- lg1 = s.GivLength();
- if (!WriteWord(pf, lg1)) return false;
+ lg1 = s.GivLength();
+ if (!WriteWord(pf, lg1)) return false;
- lg2 = fwrite(s, 1, lg1, pf );
- return (lg1 == lg2);
+ lg2 = fwrite(s, 1, lg1, pf );
+ return (lg1 == lg2);
}
bool ReadString(FILE* pf, CBotString& s)
{
- unsigned short w;
- char buf[1000];
- size_t lg1, lg2;
+ unsigned short w;
+ char buf[1000];
+ size_t lg1, lg2;
- if (!ReadWord(pf, w)) return false;
- lg1 = w;
- lg2 = fread(buf, 1, lg1, pf );
- buf[lg2] = 0;
+ if (!ReadWord(pf, w)) return false;
+ lg1 = w;
+ lg2 = fread(buf, 1, lg1, pf );
+ buf[lg2] = 0;
- s = buf;
- return (lg1 == lg2);
+ s = buf;
+ return (lg1 == lg2);
}
bool WriteType(FILE* pf, CBotTypResult type)
{
- int typ = type.GivType();
- if ( typ == CBotTypIntrinsic ) typ = CBotTypClass;
- if ( !WriteWord(pf, typ) ) return false;
- if ( typ == CBotTypClass )
- {
- CBotClass* p = type.GivClass();
- if ( !WriteString(pf, p->GivName()) ) return false;
- }
- if ( type.Eq( CBotTypArrayBody ) ||
- type.Eq( CBotTypArrayPointer ) )
- {
- if ( !WriteWord(pf, type.GivLimite()) ) return false;
- if ( !WriteType(pf, type.GivTypElem()) ) return false;
- }
- return true;
+ int typ = type.GivType();
+ if ( typ == CBotTypIntrinsic ) typ = CBotTypClass;
+ if ( !WriteWord(pf, typ) ) return false;
+ if ( typ == CBotTypClass )
+ {
+ CBotClass* p = type.GivClass();
+ if ( !WriteString(pf, p->GivName()) ) return false;
+ }
+ if ( type.Eq( CBotTypArrayBody ) ||
+ type.Eq( CBotTypArrayPointer ) )
+ {
+ if ( !WriteWord(pf, type.GivLimite()) ) return false;
+ if ( !WriteType(pf, type.GivTypElem()) ) return false;
+ }
+ return true;
}
bool ReadType(FILE* pf, CBotTypResult& type)
{
- unsigned short w, ww;
- if ( !ReadWord(pf, w) ) return false;
- type.SetType(w);
-
- if ( type.Eq( CBotTypIntrinsic ) )
- {
- type = CBotTypResult( w, "point" );
- }
-
- if ( type.Eq( CBotTypClass ) )
- {
- CBotString s;
- if ( !ReadString(pf, s) ) return false;
- type = CBotTypResult( w, s );
- }
-
- if ( type.Eq( CBotTypArrayPointer ) ||
- type.Eq( CBotTypArrayBody ) )
- {
- CBotTypResult r;
- if ( !ReadWord(pf, ww) ) return false;
- if ( !ReadType(pf, r) ) return false;
- type = CBotTypResult( w, r );
- type.SetLimite((short)ww);
- }
- return true;
+ unsigned short w, ww;
+ if ( !ReadWord(pf, w) ) return false;
+ type.SetType(w);
+
+ if ( type.Eq( CBotTypIntrinsic ) )
+ {
+ type = CBotTypResult( w, "point" );
+ }
+
+ if ( type.Eq( CBotTypClass ) )
+ {
+ CBotString s;
+ if ( !ReadString(pf, s) ) return false;
+ type = CBotTypResult( w, s );
+ }
+
+ if ( type.Eq( CBotTypArrayPointer ) ||
+ type.Eq( CBotTypArrayBody ) )
+ {
+ CBotTypResult r;
+ if ( !ReadWord(pf, ww) ) return false;
+ if ( !ReadType(pf, r) ) return false;
+ type = CBotTypResult( w, r );
+ type.SetLimite((short)ww);
+ }
+ return true;
}
bool CBotProgram::DefineNum(const char* name, long val)
{
- return CBotToken::DefineNum(name, val);
+ return CBotToken::DefineNum(name, val);
}
bool CBotProgram::SaveState(FILE* pf)
{
- if (!WriteWord( pf, CBOTVERSION)) return false;
-
-
- if ( m_pStack != NULL )
- {
- if (!WriteWord( pf, 1)) return false;
- if (!WriteString( pf, m_pRun->GivName() )) return false;
- if (!m_pStack->SaveState(pf)) return false;
- }
- else
- {
- if (!WriteWord( pf, 0)) return false;
- }
- return true;
+ if (!WriteWord( pf, CBOTVERSION)) return false;
+
+
+ if ( m_pStack != NULL )
+ {
+ if (!WriteWord( pf, 1)) return false;
+ if (!WriteString( pf, m_pRun->GivName() )) return false;
+ if (!m_pStack->SaveState(pf)) return false;
+ }
+ else
+ {
+ if (!WriteWord( pf, 0)) return false;
+ }
+ return true;
}
bool CBotProgram::RestoreState(FILE* pf)
{
- unsigned short w;
- CBotString s;
+ unsigned short w;
+ CBotString s;
- Stop();
+ Stop();
- if (!ReadWord( pf, w )) return false;
- if ( w != CBOTVERSION ) return false;
+ if (!ReadWord( pf, w )) return false;
+ if ( w != CBOTVERSION ) return false;
- if (!ReadWord( pf, w )) return false;
- if ( w == 0 ) return true;
+ if (!ReadWord( pf, w )) return false;
+ if ( w == 0 ) return true;
- if (!ReadString( pf, s )) return false;
- Start(s); // point de reprise
+ if (!ReadString( pf, s )) return false;
+ Start(s); // point de reprise
-#if STACKMEM
- m_pStack->Delete();
+#if STACKMEM
+ m_pStack->Delete();
#else
- delete m_pStack;
+ delete m_pStack;
#endif
- m_pStack = NULL;
+ m_pStack = NULL;
- // retrieves the stack from the memory
- // uses a NULL pointer (m_pStack) but it's ok like that
- if (!m_pStack->RestoreState(pf, m_pStack)) return false;
- m_pStack->SetBotCall(this); // bases for routines
+ // retrieves the stack from the memory
+ // uses a NULL pointer (m_pStack) but it's ok like that
+ if (!m_pStack->RestoreState(pf, m_pStack)) return false;
+ m_pStack->SetBotCall(this); // bases for routines
- // restored some states in the stack according to the structure
- m_pRun->RestoreState(NULL, m_pStack, m_pInstance);
- return true;
+ // restored some states in the stack according to the structure
+ m_pRun->RestoreState(NULL, m_pStack, m_pInstance);
+ return true;
}
int CBotProgram::GivVersion()
{
- return CBOTVERSION;
+ return CBOTVERSION;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
CBotCall* CBotCall::m_ListCalls = NULL;
-
+
CBotCall::CBotCall(const char* name,
- bool rExec (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser),
- CBotTypResult rCompile (CBotVar* &pVar, void* pUser))
+ bool rExec (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser),
+ CBotTypResult rCompile (CBotVar* &pVar, void* pUser))
{
- m_name = name;
- m_rExec = rExec;
- m_rComp = rCompile;
- m_next = NULL;
- m_nFuncIdent = CBotVar::NextUniqNum();
+ m_name = name;
+ m_rExec = rExec;
+ m_rComp = rCompile;
+ m_next = NULL;
+ m_nFuncIdent = CBotVar::NextUniqNum();
}
CBotCall::~CBotCall()
{
- if (m_next) delete m_next;
- m_next = NULL;
+ if (m_next) delete m_next;
+ m_next = NULL;
}
void CBotCall::Free()
{
- delete CBotCall::m_ListCalls;
+ delete CBotCall::m_ListCalls;
}
bool CBotCall::AddFunction(const char* name,
- bool rExec (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser),
- CBotTypResult rCompile (CBotVar* &pVar, void* pUser))
+ bool rExec (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser),
+ CBotTypResult rCompile (CBotVar* &pVar, void* pUser))
{
- CBotCall* p = m_ListCalls;
- CBotCall* pp = NULL;
-
- if ( p != NULL ) while ( p->m_next != NULL )
- {
- if ( p->GivName() == name )
- {
- // frees redefined function
- if ( pp ) pp->m_next = p->m_next;
- else m_ListCalls = p->m_next;
- pp = p;
- p = p->m_next;
- pp->m_next = NULL; // not to destroy the following list
- delete pp;
- continue;
- }
- pp = p; // previous pointer
- p = p->m_next;
- }
-
- pp = new CBotCall(name, rExec, rCompile);
-
- if (p) p->m_next = pp;
- else m_ListCalls = pp;
-
- return true;
+ CBotCall* p = m_ListCalls;
+ CBotCall* pp = NULL;
+
+ if ( p != NULL ) while ( p->m_next != NULL )
+ {
+ if ( p->GivName() == name )
+ {
+ // frees redefined function
+ if ( pp ) pp->m_next = p->m_next;
+ else m_ListCalls = p->m_next;
+ pp = p;
+ p = p->m_next;
+ pp->m_next = NULL; // not to destroy the following list
+ delete pp;
+ continue;
+ }
+ pp = p; // previous pointer
+ p = p->m_next;
+ }
+
+ pp = new CBotCall(name, rExec, rCompile);
+
+ if (p) p->m_next = pp;
+ else m_ListCalls = pp;
+
+ return true;
}
@@ -620,25 +620,25 @@ bool CBotCall::AddFunction(const char* name,
// in a chained list of variables
CBotVar* MakeListVars(CBotVar** ppVars, bool bSetVal=false)
{
- int i = 0;
- CBotVar* pVar = NULL;
-
- while( true )
- {
- ppVars[i];
- if ( ppVars[i] == NULL ) break;
-
- CBotVar* pp = CBotVar::Create(ppVars[i]);
- if (bSetVal) pp->Copy(ppVars[i]);
- else
- if ( ppVars[i]->GivType() == CBotTypPointer )
- pp->SetClass( ppVars[i]->GivClass());
+ int i = 0;
+ CBotVar* pVar = NULL;
+
+ while( true )
+ {
+ ppVars[i];
+ if ( ppVars[i] == NULL ) break;
+
+ CBotVar* pp = CBotVar::Create(ppVars[i]);
+ if (bSetVal) pp->Copy(ppVars[i]);
+ else
+ if ( ppVars[i]->GivType() == CBotTypPointer )
+ pp->SetClass( ppVars[i]->GivClass());
// copy the pointer according to indirections
- if (pVar == NULL) pVar = pp;
- else pVar->AddNext(pp);
- i++;
- }
- return pVar;
+ if (pVar == NULL) pVar = pp;
+ else pVar->AddNext(pp);
+ i++;
+ }
+ return pVar;
}
// is acceptable by a call procedure name
@@ -646,212 +646,212 @@ CBotVar* MakeListVars(CBotVar** ppVars, bool bSetVal=false)
CBotTypResult CBotCall::CompileCall(CBotToken* &p, CBotVar** ppVar, CBotCStack* pStack, long& nIdent)
{
- nIdent = 0;
- CBotCall* pt = m_ListCalls;
- CBotString name = p->GivString();
-
- while ( pt != NULL )
- {
- if ( pt->m_name == name )
- {
- CBotVar* pVar = MakeListVars(ppVar);
- CBotVar* pVar2 = pVar;
- CBotTypResult r = pt->m_rComp(pVar2, m_pUser);
- int ret = r.GivType();
-
- // if a class is returned, it is actually a pointer
- if ( ret == CBotTypClass ) r.SetType( ret = CBotTypPointer );
-
- if ( ret > 20 )
- {
- if (pVar2) pStack->SetError(ret, p /*pVar2->GivToken()*/ );
- }
- delete pVar;
- nIdent = pt->m_nFuncIdent;
- return r;
- }
- pt = pt->m_next;
- }
- return -1;
+ nIdent = 0;
+ CBotCall* pt = m_ListCalls;
+ CBotString name = p->GivString();
+
+ while ( pt != NULL )
+ {
+ if ( pt->m_name == name )
+ {
+ CBotVar* pVar = MakeListVars(ppVar);
+ CBotVar* pVar2 = pVar;
+ CBotTypResult r = pt->m_rComp(pVar2, m_pUser);
+ int ret = r.GivType();
+
+ // if a class is returned, it is actually a pointer
+ if ( ret == CBotTypClass ) r.SetType( ret = CBotTypPointer );
+
+ if ( ret > 20 )
+ {
+ if (pVar2) pStack->SetError(ret, p /*pVar2->GivToken()*/ );
+ }
+ delete pVar;
+ nIdent = pt->m_nFuncIdent;
+ return r;
+ }
+ pt = pt->m_next;
+ }
+ return -1;
}
void* CBotCall::m_pUser = NULL;
void CBotCall::SetPUser(void* pUser)
{
- m_pUser = pUser;
+ m_pUser = pUser;
}
bool CBotCall::CheckCall(const char* name)
{
- CBotCall* p = m_ListCalls;
-
- while ( p != NULL )
- {
- if ( name == p->GivName() ) return true;
- p = p->m_next;
- }
- return false;
+ CBotCall* p = m_ListCalls;
+
+ while ( p != NULL )
+ {
+ if ( name == p->GivName() ) return true;
+ p = p->m_next;
+ }
+ return false;
}
CBotString CBotCall::GivName()
{
- return m_name;
+ return m_name;
}
CBotCall* CBotCall::Next()
{
- return m_next;
+ return m_next;
}
int CBotCall::DoCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBotStack* pStack, CBotTypResult& rettype)
{
- CBotCall* pt = m_ListCalls;
-
- if ( nIdent ) while ( pt != NULL )
- {
- if ( pt->m_nFuncIdent == nIdent )
- {
- goto fund;
- }
- pt = pt->m_next;
- }
-
- pt = m_ListCalls;
-
- if ( token != NULL )
- {
- CBotString name = token->GivString();
- while ( pt != NULL )
- {
- if ( pt->m_name == name )
- {
- nIdent = pt->m_nFuncIdent;
- goto fund;
- }
- pt = pt->m_next;
- }
- }
-
- return -1;
+ CBotCall* pt = m_ListCalls;
+
+ if ( nIdent ) while ( pt != NULL )
+ {
+ if ( pt->m_nFuncIdent == nIdent )
+ {
+ goto fund;
+ }
+ pt = pt->m_next;
+ }
+
+ pt = m_ListCalls;
+
+ if ( token != NULL )
+ {
+ CBotString name = token->GivString();
+ while ( pt != NULL )
+ {
+ if ( pt->m_name == name )
+ {
+ nIdent = pt->m_nFuncIdent;
+ goto fund;
+ }
+ pt = pt->m_next;
+ }
+ }
+
+ return -1;
fund:
#if !STACKRUN
- // lists the parameters depending on the contents of the stack (pStackVar)
-
- CBotVar* pVar = MakeListVars(ppVar, true);
- CBotVar* pVarToDelete = pVar;
-
- // creates a variable to the result
- CBotVar* pResult = rettype.Eq(0) ? NULL : CBotVar::Create("", rettype);
-
- CBotVar* pRes = pResult;
- int Exception = 0;
- int res = pt->m_rExec(pVar, pResult, Exception, pStack->GivPUser());
-
- if ( pResult != pRes ) delete pRes; // different result if made
- delete pVarToDelete;
-
- if (res == false)
- {
- if (Exception!=0)
- {
- pStack->SetError(Exception, token);
- }
- delete pResult;
- return false;
- }
- pStack->SetVar(pResult);
-
- if ( rettype.GivType() > 0 && pResult == NULL )
- {
- pStack->SetError(TX_NORETVAL, token);
- }
- nIdent = pt->m_nFuncIdent;
- return true;
+ // lists the parameters depending on the contents of the stack (pStackVar)
+
+ CBotVar* pVar = MakeListVars(ppVar, true);
+ CBotVar* pVarToDelete = pVar;
+
+ // creates a variable to the result
+ CBotVar* pResult = rettype.Eq(0) ? NULL : CBotVar::Create("", rettype);
+
+ CBotVar* pRes = pResult;
+ int Exception = 0;
+ int res = pt->m_rExec(pVar, pResult, Exception, pStack->GivPUser());
+
+ if ( pResult != pRes ) delete pRes; // different result if made
+ delete pVarToDelete;
+
+ if (res == false)
+ {
+ if (Exception!=0)
+ {
+ pStack->SetError(Exception, token);
+ }
+ delete pResult;
+ return false;
+ }
+ pStack->SetVar(pResult);
+
+ if ( rettype.GivType() > 0 && pResult == NULL )
+ {
+ pStack->SetError(TX_NORETVAL, token);
+ }
+ nIdent = pt->m_nFuncIdent;
+ return true;
#else
- CBotStack* pile = pStack->AddStackEOX(pt);
- if ( pile == EOX ) return true;
+ CBotStack* pile = pStack->AddStackEOX(pt);
+ if ( pile == EOX ) return true;
- // lists the parameters depending on the contents of the stack (pStackVar)
+ // lists the parameters depending on the contents of the stack (pStackVar)
- CBotVar* pVar = MakeListVars(ppVar, true);
- CBotVar* pVarToDelete = pVar;
+ CBotVar* pVar = MakeListVars(ppVar, true);
+ CBotVar* pVarToDelete = pVar;
- // creates a variable to the result
- CBotVar* pResult = rettype.Eq(0) ? NULL : CBotVar::Create("", rettype);
+ // creates a variable to the result
+ CBotVar* pResult = rettype.Eq(0) ? NULL : CBotVar::Create("", rettype);
- pile->SetVar( pVar );
+ pile->SetVar( pVar );
- CBotStack* pile2 = pile->AddStack();
- pile2->SetVar( pResult );
+ CBotStack* pile2 = pile->AddStack();
+ pile2->SetVar( pResult );
- pile->SetError(0, token); // for the position on error + away
- return pt->Run( pStack );
+ pile->SetError(0, token); // for the position on error + away
+ return pt->Run( pStack );
#endif
}
-#if STACKRUN
+#if STACKRUN
bool CBotCall::RestoreCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBotStack* pStack)
{
- CBotCall* pt = m_ListCalls;
-
- {
- CBotString name = token->GivString();
- while ( pt != NULL )
- {
- if ( pt->m_name == name )
- {
- nIdent = pt->m_nFuncIdent;
-
- CBotStack* pile = pStack->RestoreStackEOX(pt);
- if ( pile == NULL ) return true;
-
- CBotStack* pile2 = pile->RestoreStack();
- return true;
- }
- pt = pt->m_next;
- }
- }
-
- return false;
+ CBotCall* pt = m_ListCalls;
+
+ {
+ CBotString name = token->GivString();
+ while ( pt != NULL )
+ {
+ if ( pt->m_name == name )
+ {
+ nIdent = pt->m_nFuncIdent;
+
+ CBotStack* pile = pStack->RestoreStackEOX(pt);
+ if ( pile == NULL ) return true;
+
+ CBotStack* pile2 = pile->RestoreStack();
+ return true;
+ }
+ pt = pt->m_next;
+ }
+ }
+
+ return false;
}
bool CBotCall::Run(CBotStack* pStack)
{
- CBotStack* pile = pStack->AddStackEOX(this);
- if ( pile == EOX ) return true;
- CBotVar* pVar = pile->GivVar();
-
- CBotStack* pile2 = pile->AddStack();
- CBotVar* pResult = pile2->GivVar();
- CBotVar* pRes = pResult;
-
- int Exception = 0;
- int res = m_rExec(pVar, pResult, Exception, pStack->GivPUser());
-
- if (res == false)
- {
- if (Exception!=0)
- {
- pStack->SetError(Exception);
- }
- if ( pResult != pRes ) delete pResult; // different result if made
- return false;
- }
-
- if ( pResult != NULL ) pStack->SetCopyVar( pResult );
- if ( pResult != pRes ) delete pResult; // different result if made
-
- return true;
+ CBotStack* pile = pStack->AddStackEOX(this);
+ if ( pile == EOX ) return true;
+ CBotVar* pVar = pile->GivVar();
+
+ CBotStack* pile2 = pile->AddStack();
+ CBotVar* pResult = pile2->GivVar();
+ CBotVar* pRes = pResult;
+
+ int Exception = 0;
+ int res = m_rExec(pVar, pResult, Exception, pStack->GivPUser());
+
+ if (res == false)
+ {
+ if (Exception!=0)
+ {
+ pStack->SetError(Exception);
+ }
+ if ( pResult != pRes ) delete pResult; // different result if made
+ return false;
+ }
+
+ if ( pResult != NULL ) pStack->SetCopyVar( pResult );
+ if ( pResult != pRes ) delete pResult; // different result if made
+
+ return true;
}
#endif
@@ -859,168 +859,168 @@ bool CBotCall::Run(CBotStack* pStack)
///////////////////////////////////////////////////////////////////////////////////////
CBotCallMethode::CBotCallMethode(const char* name,
- bool rExec (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception),
- CBotTypResult rCompile (CBotVar* pThis, CBotVar* &pVar))
+ bool rExec (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception),
+ CBotTypResult rCompile (CBotVar* pThis, CBotVar* &pVar))
{
- m_name = name;
- m_rExec = rExec;
- m_rComp = rCompile;
- m_next = NULL;
- m_nFuncIdent = CBotVar::NextUniqNum();
+ m_name = name;
+ m_rExec = rExec;
+ m_rComp = rCompile;
+ m_next = NULL;
+ m_nFuncIdent = CBotVar::NextUniqNum();
}
CBotCallMethode::~CBotCallMethode()
{
- delete m_next;
- m_next = NULL;
+ delete m_next;
+ m_next = NULL;
}
// is acceptable by a call procedure name
// and given parameters
CBotTypResult CBotCallMethode::CompileCall(const char* name, CBotVar* pThis,
- CBotVar** ppVar, CBotCStack* pStack,
- long& nIdent)
+ CBotVar** ppVar, CBotCStack* pStack,
+ long& nIdent)
{
- CBotCallMethode* pt = this;
- nIdent = 0;
-
- while ( pt != NULL )
- {
- if ( pt->m_name == name )
- {
- CBotVar* pVar = MakeListVars(ppVar, true);
- CBotVar* pVar2 = pVar;
- CBotTypResult r = pt->m_rComp(pThis, pVar2);
- int ret = r.GivType();
- if ( ret > 20 )
- {
- if (pVar2) pStack->SetError(ret, pVar2->GivToken());
- }
- delete pVar;
- nIdent = pt->m_nFuncIdent;
- return r;
- }
- pt = pt->m_next;
- }
- return CBotTypResult(-1);
+ CBotCallMethode* pt = this;
+ nIdent = 0;
+
+ while ( pt != NULL )
+ {
+ if ( pt->m_name == name )
+ {
+ CBotVar* pVar = MakeListVars(ppVar, true);
+ CBotVar* pVar2 = pVar;
+ CBotTypResult r = pt->m_rComp(pThis, pVar2);
+ int ret = r.GivType();
+ if ( ret > 20 )
+ {
+ if (pVar2) pStack->SetError(ret, pVar2->GivToken());
+ }
+ delete pVar;
+ nIdent = pt->m_nFuncIdent;
+ return r;
+ }
+ pt = pt->m_next;
+ }
+ return CBotTypResult(-1);
}
CBotString CBotCallMethode::GivName()
{
- return m_name;
+ return m_name;
}
CBotCallMethode* CBotCallMethode::Next()
{
- return m_next;
+ return m_next;
}
void CBotCallMethode::AddNext(CBotCallMethode* pt)
{
- CBotCallMethode* p = this;
- while ( p->m_next != NULL ) p = p->m_next;
+ CBotCallMethode* p = this;
+ while ( p->m_next != NULL ) p = p->m_next;
- p->m_next = pt;
+ p->m_next = pt;
}
int CBotCallMethode::DoCall(long& nIdent, const char* name, CBotVar* pThis, CBotVar** ppVars, CBotVar* &pResult, CBotStack* pStack, CBotToken* pToken)
{
- CBotCallMethode* pt = this;
-
- // search by the identifier
-
- if ( nIdent ) while ( pt != NULL )
- {
- if ( pt->m_nFuncIdent == nIdent )
- {
- // lists the parameters depending on the contents of the stack (pStackVar)
-
- CBotVar* pVar = MakeListVars(ppVars, true);
- CBotVar* pVarToDelete = pVar;
-
- // then calls the routine external to the module
-
- int Exception = 0;
- int res = pt->m_rExec(pThis, pVar, pResult, Exception);
- pStack->SetVar(pResult);
-
- if (res == false)
- {
- if (Exception!=0)
- {
-// pStack->SetError(Exception, pVar->GivToken());
- pStack->SetError(Exception, pToken);
- }
- delete pVarToDelete;
- return false;
- }
- delete pVarToDelete;
- return true;
- }
- pt = pt->m_next;
- }
-
- // search by name
-
- while ( pt != NULL )
- {
- if ( pt->m_name == name )
- {
- // lists the parameters depending on the contents of the stack (pStackVar)
-
- CBotVar* pVar = MakeListVars(ppVars, true);
- CBotVar* pVarToDelete = pVar;
-
- int Exception = 0;
- int res = pt->m_rExec(pThis, pVar, pResult, Exception);
- pStack->SetVar(pResult);
-
- if (res == false)
- {
- if (Exception!=0)
- {
-// pStack->SetError(Exception, pVar->GivToken());
- pStack->SetError(Exception, pToken);
- }
- delete pVarToDelete;
- return false;
- }
- delete pVarToDelete;
- nIdent = pt->m_nFuncIdent;
- return true;
- }
- pt = pt->m_next;
- }
-
- return -1;
+ CBotCallMethode* pt = this;
+
+ // search by the identifier
+
+ if ( nIdent ) while ( pt != NULL )
+ {
+ if ( pt->m_nFuncIdent == nIdent )
+ {
+ // lists the parameters depending on the contents of the stack (pStackVar)
+
+ CBotVar* pVar = MakeListVars(ppVars, true);
+ CBotVar* pVarToDelete = pVar;
+
+ // then calls the routine external to the module
+
+ int Exception = 0;
+ int res = pt->m_rExec(pThis, pVar, pResult, Exception);
+ pStack->SetVar(pResult);
+
+ if (res == false)
+ {
+ if (Exception!=0)
+ {
+// pStack->SetError(Exception, pVar->GivToken());
+ pStack->SetError(Exception, pToken);
+ }
+ delete pVarToDelete;
+ return false;
+ }
+ delete pVarToDelete;
+ return true;
+ }
+ pt = pt->m_next;
+ }
+
+ // search by name
+
+ while ( pt != NULL )
+ {
+ if ( pt->m_name == name )
+ {
+ // lists the parameters depending on the contents of the stack (pStackVar)
+
+ CBotVar* pVar = MakeListVars(ppVars, true);
+ CBotVar* pVarToDelete = pVar;
+
+ int Exception = 0;
+ int res = pt->m_rExec(pThis, pVar, pResult, Exception);
+ pStack->SetVar(pResult);
+
+ if (res == false)
+ {
+ if (Exception!=0)
+ {
+// pStack->SetError(Exception, pVar->GivToken());
+ pStack->SetError(Exception, pToken);
+ }
+ delete pVarToDelete;
+ return false;
+ }
+ delete pVarToDelete;
+ nIdent = pt->m_nFuncIdent;
+ return true;
+ }
+ pt = pt->m_next;
+ }
+
+ return -1;
}
bool rSizeOf( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
- if ( pVar == NULL ) return TX_LOWPARAM;
+ if ( pVar == NULL ) return TX_LOWPARAM;
- int i = 0;
- pVar = pVar->GivItemList();
+ int i = 0;
+ pVar = pVar->GivItemList();
- while ( pVar != NULL )
- {
- i++;
- pVar = pVar->GivNext();
- }
+ while ( pVar != NULL )
+ {
+ i++;
+ pVar = pVar->GivNext();
+ }
- pResult->SetValInt(i);
- return true;
+ pResult->SetValInt(i);
+ return true;
}
CBotTypResult cSizeOf( CBotVar* &pVar, void* pUser )
{
- if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
- if ( pVar->GivType() != CBotTypArrayPointer )
- return CBotTypResult( TX_BADPARAM );
- return CBotTypResult( CBotTypInt );
+ if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
+ if ( pVar->GivType() != CBotTypArrayPointer )
+ return CBotTypResult( TX_BADPARAM );
+ return CBotTypResult( CBotTypInt );
}
@@ -1028,18 +1028,18 @@ CBotString CBotProgram::m_DebugVarStr = "";
bool rCBotDebug( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
- pResult->SetValString( CBotProgram::m_DebugVarStr );
+ pResult->SetValString( CBotProgram::m_DebugVarStr );
- return true;
+ return true;
}
CBotTypResult cCBotDebug( CBotVar* &pVar, void* pUser )
{
- // no parameter
- if ( pVar != NULL ) return CBotTypResult( TX_OVERPARAM );
+ // no parameter
+ if ( pVar != NULL ) return CBotTypResult( TX_OVERPARAM );
- // function returns a result "string"
- return CBotTypResult( CBotTypString );
+ // function returns a result "string"
+ return CBotTypResult( CBotTypString );
}
@@ -1047,58 +1047,58 @@ CBotTypResult cCBotDebug( CBotVar* &pVar, void* pUser )
void CBotProgram::Init()
{
- CBotToken::DefineNum( "CBotErrOpenPar", 5000) ; // missing the opening parenthesis
- CBotToken::DefineNum( "CBotErrClosePar", 5001) ; // missing the closing parenthesis
- CBotToken::DefineNum( "CBotErrNotBoolean", 5002) ; // expression must be a boolean
- CBotToken::DefineNum( "CBotErrUndefVar", 5003) ; // undeclared variable
- CBotToken::DefineNum( "CBotErrBadLeft", 5004) ; // impossible assignment (5 = ...)
- CBotToken::DefineNum( "CBotErrNoTerminator", 5005) ;// semicolon expected
- CBotToken::DefineNum( "CBotErrCaseOut", 5006) ; // case outside a switch
- CBotToken::DefineNum( "CBotErrCloseBlock", 5008) ; // missing " } "
- CBotToken::DefineNum( "CBotErrElseWhitoutIf", 5009) ;// else without matching if
- CBotToken::DefineNum( "CBotErrOpenBlock", 5010) ; // missing " { "
- CBotToken::DefineNum( "CBotErrBadType1", 5011) ; // wrong type for the assignment
- CBotToken::DefineNum( "CBotErrRedefVar", 5012) ; // redefinition of the variable
- CBotToken::DefineNum( "CBotErrBadType2", 5013) ; // two operands are incompatible
- CBotToken::DefineNum( "CBotErrUndefCall", 5014) ; // routine unknown
- CBotToken::DefineNum( "CBotErrNoDoubleDots", 5015) ;// " : " expected
- CBotToken::DefineNum( "CBotErrBreakOutside", 5017) ;// break outside of a loop
- CBotToken::DefineNum( "CBotErrUndefLabel", 5019) ; // unknown label
- CBotToken::DefineNum( "CBotErrLabel", 5018) ; // label can not get here
- CBotToken::DefineNum( "CBotErrNoCase", 5020) ; // missing " case "
- CBotToken::DefineNum( "CBotErrBadNum", 5021) ; // expected number
- CBotToken::DefineNum( "CBotErrVoid", 5022) ; // " void " not possble here
- CBotToken::DefineNum( "CBotErrNoType", 5023) ; // type declaration expected
- CBotToken::DefineNum( "CBotErrNoVar", 5024) ; // variable name expected
- CBotToken::DefineNum( "CBotErrNoFunc", 5025) ; // expected function name
- CBotToken::DefineNum( "CBotErrOverParam", 5026) ; // too many parameters
- CBotToken::DefineNum( "CBotErrRedefFunc", 5027) ; // this function already exists
- CBotToken::DefineNum( "CBotErrLowParam", 5028) ; // not enough parameters
- CBotToken::DefineNum( "CBotErrBadParam", 5029) ; // mauvais types de paramètres
- CBotToken::DefineNum( "CBotErrNbParam", 5030) ; // wrong number of parameters
- CBotToken::DefineNum( "CBotErrUndefItem", 5031) ; // element does not exist in the class
- CBotToken::DefineNum( "CBotErrUndefClass", 5032) ; // variable is not a class
- CBotToken::DefineNum( "CBotErrNoConstruct", 5033) ; // no appropriate constructor
- CBotToken::DefineNum( "CBotErrRedefClass", 5034) ; // Class already exists
- CBotToken::DefineNum( "CBotErrCloseIndex", 5035) ; // " ] " expected
- CBotToken::DefineNum( "CBotErrReserved", 5036) ; // reserved word (for a DefineNum)
+ CBotToken::DefineNum( "CBotErrOpenPar", 5000) ; // missing the opening parenthesis
+ CBotToken::DefineNum( "CBotErrClosePar", 5001) ; // missing the closing parenthesis
+ CBotToken::DefineNum( "CBotErrNotBoolean", 5002) ; // expression must be a boolean
+ CBotToken::DefineNum( "CBotErrUndefVar", 5003) ; // undeclared variable
+ CBotToken::DefineNum( "CBotErrBadLeft", 5004) ; // impossible assignment (5 = ...)
+ CBotToken::DefineNum( "CBotErrNoTerminator", 5005) ;// semicolon expected
+ CBotToken::DefineNum( "CBotErrCaseOut", 5006) ; // case outside a switch
+ CBotToken::DefineNum( "CBotErrCloseBlock", 5008) ; // missing " } "
+ CBotToken::DefineNum( "CBotErrElseWhitoutIf", 5009) ;// else without matching if
+ CBotToken::DefineNum( "CBotErrOpenBlock", 5010) ; // missing " { "
+ CBotToken::DefineNum( "CBotErrBadType1", 5011) ; // wrong type for the assignment
+ CBotToken::DefineNum( "CBotErrRedefVar", 5012) ; // redefinition of the variable
+ CBotToken::DefineNum( "CBotErrBadType2", 5013) ; // two operands are incompatible
+ CBotToken::DefineNum( "CBotErrUndefCall", 5014) ; // routine unknown
+ CBotToken::DefineNum( "CBotErrNoDoubleDots", 5015) ;// " : " expected
+ CBotToken::DefineNum( "CBotErrBreakOutside", 5017) ;// break outside of a loop
+ CBotToken::DefineNum( "CBotErrUndefLabel", 5019) ; // unknown label
+ CBotToken::DefineNum( "CBotErrLabel", 5018) ; // label can not get here
+ CBotToken::DefineNum( "CBotErrNoCase", 5020) ; // missing " case "
+ CBotToken::DefineNum( "CBotErrBadNum", 5021) ; // expected number
+ CBotToken::DefineNum( "CBotErrVoid", 5022) ; // " void " not possble here
+ CBotToken::DefineNum( "CBotErrNoType", 5023) ; // type declaration expected
+ CBotToken::DefineNum( "CBotErrNoVar", 5024) ; // variable name expected
+ CBotToken::DefineNum( "CBotErrNoFunc", 5025) ; // expected function name
+ CBotToken::DefineNum( "CBotErrOverParam", 5026) ; // too many parameters
+ CBotToken::DefineNum( "CBotErrRedefFunc", 5027) ; // this function already exists
+ CBotToken::DefineNum( "CBotErrLowParam", 5028) ; // not enough parameters
+ CBotToken::DefineNum( "CBotErrBadParam", 5029) ; // mauvais types de paramètres
+ CBotToken::DefineNum( "CBotErrNbParam", 5030) ; // wrong number of parameters
+ CBotToken::DefineNum( "CBotErrUndefItem", 5031) ; // element does not exist in the class
+ CBotToken::DefineNum( "CBotErrUndefClass", 5032) ; // variable is not a class
+ CBotToken::DefineNum( "CBotErrNoConstruct", 5033) ; // no appropriate constructor
+ CBotToken::DefineNum( "CBotErrRedefClass", 5034) ; // Class already exists
+ CBotToken::DefineNum( "CBotErrCloseIndex", 5035) ; // " ] " expected
+ CBotToken::DefineNum( "CBotErrReserved", 5036) ; // reserved word (for a DefineNum)
// Here are the list of errors that can be returned by the module
// for the execution
- CBotToken::DefineNum( "CBotErrZeroDiv", 6000) ; // division by zero
- CBotToken::DefineNum( "CBotErrNotInit", 6001) ; // uninitialized variable
- CBotToken::DefineNum( "CBotErrBadThrow", 6002) ; // throw a negative value
- CBotToken::DefineNum( "CBotErrNoRetVal", 6003) ; // function did not return results
- CBotToken::DefineNum( "CBotErrNoRun", 6004) ; // active Run () without a function
- CBotToken::DefineNum( "CBotErrUndefFunc", 6005) ; // Calling a function that no longer exists
+ CBotToken::DefineNum( "CBotErrZeroDiv", 6000) ; // division by zero
+ CBotToken::DefineNum( "CBotErrNotInit", 6001) ; // uninitialized variable
+ CBotToken::DefineNum( "CBotErrBadThrow", 6002) ; // throw a negative value
+ CBotToken::DefineNum( "CBotErrNoRetVal", 6003) ; // function did not return results
+ CBotToken::DefineNum( "CBotErrNoRun", 6004) ; // active Run () without a function
+ CBotToken::DefineNum( "CBotErrUndefFunc", 6005) ; // Calling a function that no longer exists
- CBotProgram::AddFunction("sizeof", rSizeOf, cSizeOf );
+ CBotProgram::AddFunction("sizeof", rSizeOf, cSizeOf );
- InitStringFunctions();
+ InitStringFunctions();
- // just a function for various debug
- CBotProgram::AddFunction("CBOTDEBUGDD", rCBotDebug, cCBotDebug);
+ // just a function for various debug
+ CBotProgram::AddFunction("CBOTDEBUGDD", rCBotDebug, cCBotDebug);
//TODO implement this deletion
// DeleteFile("CbotDebug.txt");
@@ -1106,8 +1106,8 @@ void CBotProgram::Init()
void CBotProgram::Free()
{
- CBotToken::Free() ;
- CBotCall ::Free() ;
- CBotClass::Free() ;
+ CBotToken::Free() ;
+ CBotCall ::Free() ;
+ CBotClass::Free() ;
}
diff --git a/src/CBot/CBotString.cpp b/src/CBot/CBotString.cpp
index 6acd96e..1b42c23 100644
--- a/src/CBot/CBotString.cpp
+++ b/src/CBot/CBotString.cpp
@@ -1,692 +1,692 @@
-// * 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
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-/////////////////////////////////////////////////////
-
-//strings management
-
-#include "CBot.h"
-
-#include <cstdlib>
-#include <cstring>
-#include <algorithm>
-
-//Map is filled with id-string pars that are needed for CBot language parsing
-const std::map<EID, char *> CBotString::s_keywordString =
-{
- {ID_IF, "if"},
- {ID_ELSE, "else"},
- {ID_WHILE, "while"},
- {ID_DO, "do"},
- {ID_FOR, "for"},
- {ID_BREAK, "break"},
- {ID_CONTINUE, "continue"},
- {ID_SWITCH, "switch"},
- {ID_CASE, "case"},
- {ID_DEFAULT, "default"},
- {ID_TRY, "try"},
- {ID_THROW, "throw"},
- {ID_CATCH, "catch"},
- {ID_FINALLY, "finally"},
- {ID_TXT_AND, "and"},
- {ID_TXT_OR, "or"},
- {ID_TXT_NOT, "not"},
- {ID_RETURN, "return"},
- {ID_CLASS, "class"},
- {ID_EXTENDS, "extends"},
- {ID_SYNCHO, "synchronized"},
- {ID_NEW, "new"},
- {ID_PUBLIC, "public"},
- {ID_EXTERN, "extern"},
- {ID_FINAL, "final"},
- {ID_STATIC, "static"},
- {ID_PROTECTED, "protected"},
- {ID_PRIVATE, "private"},
- {ID_REPEAT, "repeat"},
- {ID_DEBUGDD, "STARTDEBUGDD"},
- {ID_INT, "int"},
- {ID_FLOAT, "float"},
- {ID_BOOLEAN, "boolean"},
- {ID_STRING, "string"},
- {ID_VOID, "void"},
- {ID_BOOL, "bool"},
- {ID_TRUE, "true"},
- {ID_FALSE, "false"},
- {ID_NULL, "null"},
- {ID_NAN, "nan"},
- {ID_OPENPAR, "("},
- {ID_CLOSEPAR, ")"},
- {ID_OPBLK, "{"},
- {ID_CLBLK, "}"},
- {ID_SEP, "},"},
- {ID_COMMA, ","},
- {ID_DOTS, ":"},
- {ID_DOT, "."},
- {ID_OPBRK, "["},
- {ID_CLBRK, "]"},
- {ID_DBLDOTS, "::"},
- {ID_LOGIC, "?"},
- {ID_ADD, "+"},
- {ID_SUB, "-"},
- {ID_MUL, "*"},
- {ID_DIV, "/"},
- {ID_ASS, "="},
- {ID_ASSADD, "+="},
- {ID_ASSSUB, "-="},
- {ID_ASSMUL, "*="},
- {ID_ASSDIV, "/="},
- {ID_ASSOR, "|="},
- {ID_ASSAND, "&="},
- {ID_ASSXOR, "^="},
- {ID_ASSSL, "<<="},
- {ID_ASSSR, ">>>="},
- {ID_ASSASR, ">>="},
- {ID_SL, "<<"},
- {ID_SR, ">>"},
- {ID_ASR, ">>"},
- {ID_INC, "++"},
- {ID_DEC, "--"},
- {ID_LO, "<"},
- {ID_HI, ">"},
- {ID_LS, "<<"},
- {ID_HS, ">="},
- {ID_EQ, "=="},
- {ID_NE, "!="},
- {ID_AND, "&"},
- {ID_XOR, "^"},
- {ID_OR, "|"},
- {ID_LOG_AND, "&&"},
- {ID_LOG_OR, "||"},
- {ID_LOG_NOT, "!"},
- {ID_NOT, "~"},
- {ID_MODULO, "%"},
- {ID_POWER, "**"},
- {ID_ASSMODULO, "%="},
- {ID_SUPER, "super"},
- {TX_UNDEF, "undefined"},
- {TX_NAN, "not a number"}
-};
-
-CBotString::CBotString()
-{
- m_ptr = NULL;
- m_lg = 0;
-}
-
-CBotString::~CBotString()
-{
- free(m_ptr); //we can call free on null pointer as it's save
-}
-
-
-CBotString::CBotString(const char* p)
-{
- m_lg = strlen(p);
-
- m_ptr = NULL;
- if (m_lg>0)
- {
- m_ptr = (char*)malloc(m_lg+1);
- strcpy(m_ptr, p);
- }
-}
-
-CBotString::CBotString(const CBotString& srcString)
-{
- m_lg = srcString.m_lg;
-
- m_ptr = NULL;
- if (m_lg>0)
- {
- m_ptr = (char*)malloc(m_lg+1);
- strcpy(m_ptr, srcString.m_ptr);
- }
-}
-
-
-
-
-int CBotString::GivLength()
-{
- if (m_ptr == NULL) return 0;
- return strlen( m_ptr );
-}
-
-
-
-CBotString CBotString::Left(int nCount) const
-{
- char chain[2000];
-
- size_t i;
- for (i = 0; i < m_lg && i < nCount && i < 1999; ++i)
- {
- chain[i] = m_ptr[i];
- }
- chain[i] = 0 ;
-
- return CBotString(chain);
-}
-
-CBotString CBotString::Right(int nCount) const
-{
- char chain[2000];
-
- int i = m_lg - nCount;
- if ( i < 0 ) i = 0;
-
- size_t j;
- for (size_t j = 0 ; i < m_lg && i < 1999; ++i)
- {
- chain[j++] = m_ptr[i];
- }
- chain[j] = 0 ;
-
- return CBotString(chain);
-}
-
-CBotString CBotString::Mid(int nFirst, int nCount) const
-{
- char chain[2000];
-
- size_t i;
- for (i = nFirst; i < m_lg && i < 1999 && i <= nFirst + nCount; ++i)
- {
- chain[i] = m_ptr[i];
- }
- chain[i] = 0 ;
-
- return CBotString(chain);
-}
-
-CBotString CBotString::Mid(int nFirst) const
-{
- char chain[2000];
-
- size_t i;
- for (i = nFirst; i < m_lg && i < 1999 ; ++i)
- {
- chain[i] = m_ptr[i];
- }
- chain[i] = 0 ;
-
- return CBotString(chain);
-}
-
-
-int CBotString::Find(const char c)
-{
- for (size_t i = 0; i < m_lg; ++i)
- {
- if (m_ptr[i] == c) return i;
- }
- return -1;
-}
-
-int CBotString::Find(const char * lpsz)
-{
- int l = strlen(lpsz);
-
- for (size_t i = 0; i <= m_lg-l; ++i)
- {
- for (size_t j = 0; j < l; ++j)
- {
- if (m_ptr[i+j] != lpsz[j]) goto bad;
- }
- return i;
-bad:;
- }
- return -1;
-}
-
-int CBotString::ReverseFind(const char c)
-{
- int i;
- for (i = m_lg-1; i >= 0; --i)
- {
- if (m_ptr[i] == c) return i;
- }
- return -1;
-}
-
-int CBotString::ReverseFind(const char * lpsz)
-{
- int i, j;
- int l = strlen(lpsz);
-
- for (i = m_lg-l; i >= 0; --i)
- {
- for (j = 0; j < l; ++j)
- {
- if (m_ptr[i+j] != lpsz[j]) goto bad;
- }
- return i;
-bad:;
- }
- return -1;
-}
-
-CBotString CBotString::Mid(int start, int lg)
-{
- CBotString res;
- if (start >= m_lg) return res;
-
- if ( lg < 0 ) lg = m_lg - start;
-
- char* p = (char*)malloc(m_lg+1);
- strcpy(p, m_ptr+start);
- p[lg] = 0;
-
- res = p;
- free(p);
- return res;
-}
-
-void CBotString::MakeUpper()
-{
- for (size_t i = 0; i < m_lg && i < 1999 ; ++i)
- {
- char c = m_ptr[i];
- if ( c >= 'a' && c <= 'z' ) m_ptr[i] = c - 'a' + 'A';
- }
-}
-
-void CBotString::MakeLower()
-{
- for (size_t i = 0; i < m_lg && i < 1999 ; ++i)
- {
- char c = m_ptr[i];
- if ( c >= 'A' && c <= 'Z' ) m_ptr[i] = c - 'A' + 'a';
- }
-}
-
-bool CBotString::LoadString(unsigned int id)
-{
- const char * str = NULL;
- str = MapIdToString((EID)id);
- if (m_ptr != NULL) free(m_ptr);
-
- m_lg = strlen(str);
- m_ptr = NULL;
- if (m_lg > 0)
- {
- m_ptr = (char*)malloc(m_lg+1);
- strcpy(m_ptr, str);
- return true;
- }
- return false;
-}
-
-
-const CBotString& CBotString::operator=(const CBotString& stringSrc)
-{
- free(m_ptr);
- m_ptr = NULL;
-
- m_lg = stringSrc.m_lg;
-
- if (m_lg > 0)
- {
- m_ptr = (char*)malloc(m_lg+1);
- strcpy(m_ptr, stringSrc.m_ptr);
- }
-
- return *this;
-}
-
-CBotString operator+(const CBotString& string, const char * lpsz)
-{
- CBotString s(string);
- s += lpsz;
- return s;
-}
-
-const CBotString& CBotString::operator+(const CBotString& stringSrc)
-{
- char* p = (char*)malloc(m_lg+stringSrc.m_lg+1);
-
- strcpy(p, m_ptr);
- char* pp = p + m_lg;
- strcpy(pp, stringSrc.m_ptr);
-
- free(m_ptr);
- m_ptr = p;
- m_lg += stringSrc.m_lg;
-
- return *this;
-}
-
-const CBotString& CBotString::operator=(const char ch)
-{
- free(m_ptr);
-
- m_lg = 1;
-
- m_ptr = (char*)malloc(2);
- m_ptr[0] = ch;
- m_ptr[1] = 0;
-
- return *this;
-}
-
-const CBotString& CBotString::operator=(const char* pString)
-{
- free(m_ptr);
- m_ptr = NULL;
-
- if (pString != NULL)
- {
- m_lg = strlen(pString);
-
- if (m_lg != 0)
- {
- m_ptr = (char*)malloc(m_lg+1);
- strcpy(m_ptr, pString);
- }
- }
-
- return *this;
-}
-
-
-const CBotString& CBotString::operator+=(const char ch)
-{
- char* p = (char*)malloc(m_lg+2);
-
- if (m_ptr!=NULL) strcpy(p, m_ptr);
- p[m_lg++] = ch;
- p[m_lg] = 0;
-
- free(m_ptr);
-
- m_ptr = p;
-
- return *this;
-}
-
-const CBotString& CBotString::operator+=(const CBotString& str)
-{
- char* p = (char*)malloc(m_lg+str.m_lg+1);
-
- strcpy(p, m_ptr);
- char* pp = p + m_lg;
- strcpy(pp, str.m_ptr);
-
- m_lg = m_lg + str.m_lg;
-
- free(m_ptr);
-
- m_ptr = p;
-
- return *this;
-}
-
-bool CBotString::operator==(const CBotString& str)
-{
- return Compare(str) == 0;
-}
-
-bool CBotString::operator==(const char* p)
-{
- return Compare(p) == 0;
-}
-
-bool CBotString::operator!=(const CBotString& str)
-{
- return Compare(str) != 0;
-}
-
-bool CBotString::operator!=(const char* p)
-{
- return Compare(p) != 0;
-}
-
-bool CBotString::operator>(const CBotString& str)
-{
- return Compare(str) > 0;
-}
-
-bool CBotString::operator>(const char* p)
-{
- return Compare(p) > 0;
-}
-
-bool CBotString::operator>=(const CBotString& str)
-{
- return Compare(str) >= 0;
-}
-
-bool CBotString::operator>=(const char* p)
-{
- return Compare(p) >= 0;
-}
-
-bool CBotString::operator<(const CBotString& str)
-{
- return Compare(str) < 0;
-}
-
-bool CBotString::operator<(const char* p)
-{
- return Compare(p) < 0;
-}
-
-bool CBotString::operator<=(const CBotString& str)
-{
- return Compare(str) <= 0;
-}
-
-bool CBotString::operator<=(const char* p)
-{
- return Compare(p) <= 0;
-}
-
-bool CBotString::IsEmpty() const
-{
- return (m_lg == 0);
-}
-
-void CBotString::Empty()
-{
- free(m_ptr);
- m_ptr = NULL;
- m_lg = 0;
-}
-
-static char emptyString[] = {0};
-
-CBotString::operator const char * () const
-{
- if (this == NULL || m_ptr == NULL) return emptyString;
- return m_ptr;
-}
-
-
-int CBotString::Compare(const char * lpsz) const
-{
- char* p = m_ptr;
- if (lpsz == NULL) lpsz = emptyString;
- if (m_ptr == NULL) p = emptyString;
- return strcmp(p, lpsz); // wcscmp
-}
-
-const char * CBotString::MapIdToString(EID id)
-{
- if (s_keywordString.find(id) != s_keywordString.end())
- {
- return s_keywordString.at(id);
- }
- else
- {
- return emptyString;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////
-// arrays of strings
-
-CBotStringArray::CBotStringArray()
-{
- m_pData = NULL;
- m_nSize = m_nMaxSize = 0;
-}
-
-CBotStringArray::~CBotStringArray()
-{
- SetSize(0); // destroys data !
-}
-
-
-int CBotStringArray::GivSize()
-{
- return m_nSize;
-}
-
-void CBotStringArray::Add(const CBotString& str)
-{
- SetSize(m_nSize+1);
-
- m_pData[m_nSize-1] = str;
-}
-
-///////////////////////////////////////////////////////////////////////
-// utility routines
-
-static inline void ConstructElement(CBotString* pNewData)
-{
- memset(pNewData, 0, sizeof(CBotString));
-}
-
-static inline void DestructElement(CBotString* pOldData)
-{
- pOldData->~CBotString();
-}
-
-static inline void CopyElement(CBotString* pSrc, CBotString* pDest)
-{
- *pSrc = *pDest;
-}
-
-static void ConstructElements(CBotString* pNewData, int nCount)
-{
- while (nCount--)
- {
- ConstructElement(pNewData);
- pNewData++;
- }
-}
-
-static void DestructElements(CBotString* pOldData, int nCount)
-{
- while (nCount--)
- {
- DestructElement(pOldData);
- pOldData++;
- }
-}
-
-static void CopyElements(CBotString* pDest, CBotString* pSrc, int nCount)
-{
- while (nCount--)
- {
- *pDest = *pSrc;
- ++pDest;
- ++pSrc;
- }
-}
-
-
-
-// set the array size
-
-void CBotStringArray::SetSize(int nNewSize)
-{
- if (nNewSize == 0)
- {
- // shrink to nothing
-
- DestructElements(m_pData, m_nSize);
- delete[] (unsigned char *)m_pData;
- m_pData = NULL;
- m_nSize = m_nMaxSize = 0;
- }
- else if (m_pData == NULL)
- {
- // create one with exact size
- m_pData = (CBotString*) new unsigned char[nNewSize * sizeof(CBotString)];
-
- ConstructElements(m_pData, nNewSize);
-
- m_nSize = m_nMaxSize = nNewSize;
- }
- else if (nNewSize <= m_nMaxSize)
- {
- // it fits
- if (nNewSize > m_nSize)
- {
- // initialize the new elements
-
- ConstructElements(&m_pData[m_nSize], nNewSize-m_nSize);
-
- }
-
- else if (m_nSize > nNewSize) // destroy the old elements
- DestructElements(&m_pData[nNewSize], m_nSize-nNewSize);
-
- m_nSize = nNewSize;
- }
- else
- {
- // otherwise, grow array
- int nGrowBy;
- {
- // heuristically determine growth when nGrowBy == 0
- // (this avoids heap fragmentation in many situations)
- nGrowBy = std::min(1024, std::max(4, m_nSize / 8));
- }
- int nNewMax;
- if (nNewSize < m_nMaxSize + nGrowBy)
- nNewMax = m_nMaxSize + nGrowBy; // granularity
- else
- nNewMax = nNewSize; // no slush
-
- CBotString* pNewData = (CBotString*) new unsigned char[nNewMax * sizeof(CBotString)];
-
- // copy new data from old
- memcpy(pNewData, m_pData, m_nSize * sizeof(CBotString));
-
- // construct remaining elements
- ConstructElements(&pNewData[m_nSize], nNewSize-m_nSize);
-
-
- // Get rid of old stuff (note: no destructors called)
- delete[] (unsigned char *)m_pData;
- m_pData = pNewData;
- m_nSize = nNewSize;
- m_nMaxSize = nNewMax;
- }
-}
-
-
-CBotString& CBotStringArray::operator[](int nIndex)
-{
- return ElementAt(nIndex);
-}
-
-CBotString& CBotStringArray::ElementAt(int nIndex)
-{
- return m_pData[nIndex];
-}
-
+// * 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
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+/////////////////////////////////////////////////////
+
+//strings management
+
+#include "CBot.h"
+
+#include <cstdlib>
+#include <cstring>
+#include <algorithm>
+
+//Map is filled with id-string pars that are needed for CBot language parsing
+const std::map<EID, char *> CBotString::s_keywordString =
+{
+ {ID_IF, "if"},
+ {ID_ELSE, "else"},
+ {ID_WHILE, "while"},
+ {ID_DO, "do"},
+ {ID_FOR, "for"},
+ {ID_BREAK, "break"},
+ {ID_CONTINUE, "continue"},
+ {ID_SWITCH, "switch"},
+ {ID_CASE, "case"},
+ {ID_DEFAULT, "default"},
+ {ID_TRY, "try"},
+ {ID_THROW, "throw"},
+ {ID_CATCH, "catch"},
+ {ID_FINALLY, "finally"},
+ {ID_TXT_AND, "and"},
+ {ID_TXT_OR, "or"},
+ {ID_TXT_NOT, "not"},
+ {ID_RETURN, "return"},
+ {ID_CLASS, "class"},
+ {ID_EXTENDS, "extends"},
+ {ID_SYNCHO, "synchronized"},
+ {ID_NEW, "new"},
+ {ID_PUBLIC, "public"},
+ {ID_EXTERN, "extern"},
+ {ID_FINAL, "final"},
+ {ID_STATIC, "static"},
+ {ID_PROTECTED, "protected"},
+ {ID_PRIVATE, "private"},
+ {ID_REPEAT, "repeat"},
+ {ID_DEBUGDD, "STARTDEBUGDD"},
+ {ID_INT, "int"},
+ {ID_FLOAT, "float"},
+ {ID_BOOLEAN, "boolean"},
+ {ID_STRING, "string"},
+ {ID_VOID, "void"},
+ {ID_BOOL, "bool"},
+ {ID_TRUE, "true"},
+ {ID_FALSE, "false"},
+ {ID_NULL, "null"},
+ {ID_NAN, "nan"},
+ {ID_OPENPAR, "("},
+ {ID_CLOSEPAR, ")"},
+ {ID_OPBLK, "{"},
+ {ID_CLBLK, "}"},
+ {ID_SEP, "},"},
+ {ID_COMMA, ","},
+ {ID_DOTS, ":"},
+ {ID_DOT, "."},
+ {ID_OPBRK, "["},
+ {ID_CLBRK, "]"},
+ {ID_DBLDOTS, "::"},
+ {ID_LOGIC, "?"},
+ {ID_ADD, "+"},
+ {ID_SUB, "-"},
+ {ID_MUL, "*"},
+ {ID_DIV, "/"},
+ {ID_ASS, "="},
+ {ID_ASSADD, "+="},
+ {ID_ASSSUB, "-="},
+ {ID_ASSMUL, "*="},
+ {ID_ASSDIV, "/="},
+ {ID_ASSOR, "|="},
+ {ID_ASSAND, "&="},
+ {ID_ASSXOR, "^="},
+ {ID_ASSSL, "<<="},
+ {ID_ASSSR, ">>>="},
+ {ID_ASSASR, ">>="},
+ {ID_SL, "<<"},
+ {ID_SR, ">>"},
+ {ID_ASR, ">>"},
+ {ID_INC, "++"},
+ {ID_DEC, "--"},
+ {ID_LO, "<"},
+ {ID_HI, ">"},
+ {ID_LS, "<<"},
+ {ID_HS, ">="},
+ {ID_EQ, "=="},
+ {ID_NE, "!="},
+ {ID_AND, "&"},
+ {ID_XOR, "^"},
+ {ID_OR, "|"},
+ {ID_LOG_AND, "&&"},
+ {ID_LOG_OR, "||"},
+ {ID_LOG_NOT, "!"},
+ {ID_NOT, "~"},
+ {ID_MODULO, "%"},
+ {ID_POWER, "**"},
+ {ID_ASSMODULO, "%="},
+ {ID_SUPER, "super"},
+ {TX_UNDEF, "undefined"},
+ {TX_NAN, "not a number"}
+};
+
+CBotString::CBotString()
+{
+ m_ptr = NULL;
+ m_lg = 0;
+}
+
+CBotString::~CBotString()
+{
+ free(m_ptr); //we can call free on null pointer as it's save
+}
+
+
+CBotString::CBotString(const char* p)
+{
+ m_lg = strlen(p);
+
+ m_ptr = NULL;
+ if (m_lg>0)
+ {
+ m_ptr = (char*)malloc(m_lg+1);
+ strcpy(m_ptr, p);
+ }
+}
+
+CBotString::CBotString(const CBotString& srcString)
+{
+ m_lg = srcString.m_lg;
+
+ m_ptr = NULL;
+ if (m_lg>0)
+ {
+ m_ptr = (char*)malloc(m_lg+1);
+ strcpy(m_ptr, srcString.m_ptr);
+ }
+}
+
+
+
+
+int CBotString::GivLength()
+{
+ if (m_ptr == NULL) return 0;
+ return strlen( m_ptr );
+}
+
+
+
+CBotString CBotString::Left(int nCount) const
+{
+ char chain[2000];
+
+ size_t i;
+ for (i = 0; i < m_lg && i < nCount && i < 1999; ++i)
+ {
+ chain[i] = m_ptr[i];
+ }
+ chain[i] = 0 ;
+
+ return CBotString(chain);
+}
+
+CBotString CBotString::Right(int nCount) const
+{
+ char chain[2000];
+
+ int i = m_lg - nCount;
+ if ( i < 0 ) i = 0;
+
+ size_t j;
+ for (size_t j = 0 ; i < m_lg && i < 1999; ++i)
+ {
+ chain[j++] = m_ptr[i];
+ }
+ chain[j] = 0 ;
+
+ return CBotString(chain);
+}
+
+CBotString CBotString::Mid(int nFirst, int nCount) const
+{
+ char chain[2000];
+
+ size_t i;
+ for (i = nFirst; i < m_lg && i < 1999 && i <= nFirst + nCount; ++i)
+ {
+ chain[i] = m_ptr[i];
+ }
+ chain[i] = 0 ;
+
+ return CBotString(chain);
+}
+
+CBotString CBotString::Mid(int nFirst) const
+{
+ char chain[2000];
+
+ size_t i;
+ for (i = nFirst; i < m_lg && i < 1999 ; ++i)
+ {
+ chain[i] = m_ptr[i];
+ }
+ chain[i] = 0 ;
+
+ return CBotString(chain);
+}
+
+
+int CBotString::Find(const char c)
+{
+ for (size_t i = 0; i < m_lg; ++i)
+ {
+ if (m_ptr[i] == c) return i;
+ }
+ return -1;
+}
+
+int CBotString::Find(const char * lpsz)
+{
+ int l = strlen(lpsz);
+
+ for (size_t i = 0; i <= m_lg-l; ++i)
+ {
+ for (size_t j = 0; j < l; ++j)
+ {
+ if (m_ptr[i+j] != lpsz[j]) goto bad;
+ }
+ return i;
+bad:;
+ }
+ return -1;
+}
+
+int CBotString::ReverseFind(const char c)
+{
+ int i;
+ for (i = m_lg-1; i >= 0; --i)
+ {
+ if (m_ptr[i] == c) return i;
+ }
+ return -1;
+}
+
+int CBotString::ReverseFind(const char * lpsz)
+{
+ int i, j;
+ int l = strlen(lpsz);
+
+ for (i = m_lg-l; i >= 0; --i)
+ {
+ for (j = 0; j < l; ++j)
+ {
+ if (m_ptr[i+j] != lpsz[j]) goto bad;
+ }
+ return i;
+bad:;
+ }
+ return -1;
+}
+
+CBotString CBotString::Mid(int start, int lg)
+{
+ CBotString res;
+ if (start >= m_lg) return res;
+
+ if ( lg < 0 ) lg = m_lg - start;
+
+ char* p = (char*)malloc(m_lg+1);
+ strcpy(p, m_ptr+start);
+ p[lg] = 0;
+
+ res = p;
+ free(p);
+ return res;
+}
+
+void CBotString::MakeUpper()
+{
+ for (size_t i = 0; i < m_lg && i < 1999 ; ++i)
+ {
+ char c = m_ptr[i];
+ if ( c >= 'a' && c <= 'z' ) m_ptr[i] = c - 'a' + 'A';
+ }
+}
+
+void CBotString::MakeLower()
+{
+ for (size_t i = 0; i < m_lg && i < 1999 ; ++i)
+ {
+ char c = m_ptr[i];
+ if ( c >= 'A' && c <= 'Z' ) m_ptr[i] = c - 'A' + 'a';
+ }
+}
+
+bool CBotString::LoadString(unsigned int id)
+{
+ const char * str = NULL;
+ str = MapIdToString((EID)id);
+ if (m_ptr != NULL) free(m_ptr);
+
+ m_lg = strlen(str);
+ m_ptr = NULL;
+ if (m_lg > 0)
+ {
+ m_ptr = (char*)malloc(m_lg+1);
+ strcpy(m_ptr, str);
+ return true;
+ }
+ return false;
+}
+
+
+const CBotString& CBotString::operator=(const CBotString& stringSrc)
+{
+ free(m_ptr);
+ m_ptr = NULL;
+
+ m_lg = stringSrc.m_lg;
+
+ if (m_lg > 0)
+ {
+ m_ptr = (char*)malloc(m_lg+1);
+ strcpy(m_ptr, stringSrc.m_ptr);
+ }
+
+ return *this;
+}
+
+CBotString operator+(const CBotString& string, const char * lpsz)
+{
+ CBotString s(string);
+ s += lpsz;
+ return s;
+}
+
+const CBotString& CBotString::operator+(const CBotString& stringSrc)
+{
+ char* p = (char*)malloc(m_lg+stringSrc.m_lg+1);
+
+ strcpy(p, m_ptr);
+ char* pp = p + m_lg;
+ strcpy(pp, stringSrc.m_ptr);
+
+ free(m_ptr);
+ m_ptr = p;
+ m_lg += stringSrc.m_lg;
+
+ return *this;
+}
+
+const CBotString& CBotString::operator=(const char ch)
+{
+ free(m_ptr);
+
+ m_lg = 1;
+
+ m_ptr = (char*)malloc(2);
+ m_ptr[0] = ch;
+ m_ptr[1] = 0;
+
+ return *this;
+}
+
+const CBotString& CBotString::operator=(const char* pString)
+{
+ free(m_ptr);
+ m_ptr = NULL;
+
+ if (pString != NULL)
+ {
+ m_lg = strlen(pString);
+
+ if (m_lg != 0)
+ {
+ m_ptr = (char*)malloc(m_lg+1);
+ strcpy(m_ptr, pString);
+ }
+ }
+
+ return *this;
+}
+
+
+const CBotString& CBotString::operator+=(const char ch)
+{
+ char* p = (char*)malloc(m_lg+2);
+
+ if (m_ptr!=NULL) strcpy(p, m_ptr);
+ p[m_lg++] = ch;
+ p[m_lg] = 0;
+
+ free(m_ptr);
+
+ m_ptr = p;
+
+ return *this;
+}
+
+const CBotString& CBotString::operator+=(const CBotString& str)
+{
+ char* p = (char*)malloc(m_lg+str.m_lg+1);
+
+ strcpy(p, m_ptr);
+ char* pp = p + m_lg;
+ strcpy(pp, str.m_ptr);
+
+ m_lg = m_lg + str.m_lg;
+
+ free(m_ptr);
+
+ m_ptr = p;
+
+ return *this;
+}
+
+bool CBotString::operator==(const CBotString& str)
+{
+ return Compare(str) == 0;
+}
+
+bool CBotString::operator==(const char* p)
+{
+ return Compare(p) == 0;
+}
+
+bool CBotString::operator!=(const CBotString& str)
+{
+ return Compare(str) != 0;
+}
+
+bool CBotString::operator!=(const char* p)
+{
+ return Compare(p) != 0;
+}
+
+bool CBotString::operator>(const CBotString& str)
+{
+ return Compare(str) > 0;
+}
+
+bool CBotString::operator>(const char* p)
+{
+ return Compare(p) > 0;
+}
+
+bool CBotString::operator>=(const CBotString& str)
+{
+ return Compare(str) >= 0;
+}
+
+bool CBotString::operator>=(const char* p)
+{
+ return Compare(p) >= 0;
+}
+
+bool CBotString::operator<(const CBotString& str)
+{
+ return Compare(str) < 0;
+}
+
+bool CBotString::operator<(const char* p)
+{
+ return Compare(p) < 0;
+}
+
+bool CBotString::operator<=(const CBotString& str)
+{
+ return Compare(str) <= 0;
+}
+
+bool CBotString::operator<=(const char* p)
+{
+ return Compare(p) <= 0;
+}
+
+bool CBotString::IsEmpty() const
+{
+ return (m_lg == 0);
+}
+
+void CBotString::Empty()
+{
+ free(m_ptr);
+ m_ptr = NULL;
+ m_lg = 0;
+}
+
+static char emptyString[] = {0};
+
+CBotString::operator const char * () const
+{
+ if (this == NULL || m_ptr == NULL) return emptyString;
+ return m_ptr;
+}
+
+
+int CBotString::Compare(const char * lpsz) const
+{
+ char* p = m_ptr;
+ if (lpsz == NULL) lpsz = emptyString;
+ if (m_ptr == NULL) p = emptyString;
+ return strcmp(p, lpsz); // wcscmp
+}
+
+const char * CBotString::MapIdToString(EID id)
+{
+ if (s_keywordString.find(id) != s_keywordString.end())
+ {
+ return s_keywordString.at(id);
+ }
+ else
+ {
+ return emptyString;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+// arrays of strings
+
+CBotStringArray::CBotStringArray()
+{
+ m_pData = NULL;
+ m_nSize = m_nMaxSize = 0;
+}
+
+CBotStringArray::~CBotStringArray()
+{
+ SetSize(0); // destroys data !
+}
+
+
+int CBotStringArray::GivSize()
+{
+ return m_nSize;
+}
+
+void CBotStringArray::Add(const CBotString& str)
+{
+ SetSize(m_nSize+1);
+
+ m_pData[m_nSize-1] = str;
+}
+
+///////////////////////////////////////////////////////////////////////
+// utility routines
+
+static inline void ConstructElement(CBotString* pNewData)
+{
+ memset(pNewData, 0, sizeof(CBotString));
+}
+
+static inline void DestructElement(CBotString* pOldData)
+{
+ pOldData->~CBotString();
+}
+
+static inline void CopyElement(CBotString* pSrc, CBotString* pDest)
+{
+ *pSrc = *pDest;
+}
+
+static void ConstructElements(CBotString* pNewData, int nCount)
+{
+ while (nCount--)
+ {
+ ConstructElement(pNewData);
+ pNewData++;
+ }
+}
+
+static void DestructElements(CBotString* pOldData, int nCount)
+{
+ while (nCount--)
+ {
+ DestructElement(pOldData);
+ pOldData++;
+ }
+}
+
+static void CopyElements(CBotString* pDest, CBotString* pSrc, int nCount)
+{
+ while (nCount--)
+ {
+ *pDest = *pSrc;
+ ++pDest;
+ ++pSrc;
+ }
+}
+
+
+
+// set the array size
+
+void CBotStringArray::SetSize(int nNewSize)
+{
+ if (nNewSize == 0)
+ {
+ // shrink to nothing
+
+ DestructElements(m_pData, m_nSize);
+ delete[] (unsigned char *)m_pData;
+ m_pData = NULL;
+ m_nSize = m_nMaxSize = 0;
+ }
+ else if (m_pData == NULL)
+ {
+ // create one with exact size
+ m_pData = (CBotString*) new unsigned char[nNewSize * sizeof(CBotString)];
+
+ ConstructElements(m_pData, nNewSize);
+
+ m_nSize = m_nMaxSize = nNewSize;
+ }
+ else if (nNewSize <= m_nMaxSize)
+ {
+ // it fits
+ if (nNewSize > m_nSize)
+ {
+ // initialize the new elements
+
+ ConstructElements(&m_pData[m_nSize], nNewSize-m_nSize);
+
+ }
+
+ else if (m_nSize > nNewSize) // destroy the old elements
+ DestructElements(&m_pData[nNewSize], m_nSize-nNewSize);
+
+ m_nSize = nNewSize;
+ }
+ else
+ {
+ // otherwise, grow array
+ int nGrowBy;
+ {
+ // heuristically determine growth when nGrowBy == 0
+ // (this avoids heap fragmentation in many situations)
+ nGrowBy = std::min(1024, std::max(4, m_nSize / 8));
+ }
+ int nNewMax;
+ if (nNewSize < m_nMaxSize + nGrowBy)
+ nNewMax = m_nMaxSize + nGrowBy; // granularity
+ else
+ nNewMax = nNewSize; // no slush
+
+ CBotString* pNewData = (CBotString*) new unsigned char[nNewMax * sizeof(CBotString)];
+
+ // copy new data from old
+ memcpy(pNewData, m_pData, m_nSize * sizeof(CBotString));
+
+ // construct remaining elements
+ ConstructElements(&pNewData[m_nSize], nNewSize-m_nSize);
+
+
+ // Get rid of old stuff (note: no destructors called)
+ delete[] (unsigned char *)m_pData;
+ m_pData = pNewData;
+ m_nSize = nNewSize;
+ m_nMaxSize = nNewMax;
+ }
+}
+
+
+CBotString& CBotStringArray::operator[](int nIndex)
+{
+ return ElementAt(nIndex);
+}
+
+CBotString& CBotStringArray::ElementAt(int nIndex)
+{
+ return m_pData[nIndex];
+}
+
diff --git a/src/CBot/CBotToken.cpp b/src/CBot/CBotToken.cpp
index c76df7f..2c0bfae 100644
--- a/src/CBot/CBotToken.cpp
+++ b/src/CBot/CBotToken.cpp
@@ -1,562 +1,562 @@
-// * 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
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-
-//CBotToken.cpp
-
-//////////////////////////////////////////////////////////////////
-// Managing Tokens
-// the text of a program is first transformed
-// into a sequence of tokens for easy interpretation
-// it will only treat the case as an error
-// where there is an illegal character in a string
-
-
-#include "CBot.h"
-#include <cstdarg>
-
-CBotStringArray CBotToken::m_ListKeyWords;
-int CBotToken::m_ListIdKeyWords[200];
-CBotStringArray CBotToken::m_ListKeyDefine;
-long CBotToken::m_ListKeyNums[MAXDEFNUM];
-
-//! contructors
-CBotToken::CBotToken()
-{
- m_next = NULL;
- m_prev = NULL;
- m_type = TokenTypVar; // at the beginning a default variable type
- m_IdKeyWord = -1;
-}
-
-CBotToken::CBotToken(const CBotToken* pSrc)
-{
- m_next = NULL;
- m_prev = NULL;
-
- m_Text.Empty();
- m_Sep.Empty();
-
- m_type = 0;
- m_IdKeyWord = 0;
-
- m_start = 0;
- m_end = 0;
-
- if ( pSrc != NULL )
- {
-
- m_type = pSrc->m_type;
- m_IdKeyWord = pSrc->m_IdKeyWord;
-
- m_Text = pSrc->m_Text;
- m_Sep = pSrc->m_Sep;
-
- m_start = pSrc->m_start;
- m_end = pSrc->m_end;
- }
-}
-
-CBotToken::CBotToken(const CBotString& mot, const CBotString& sep, int start, int end)
-{
- m_Text = mot; // word (mot) found as token
- m_Sep = sep; // separator
- m_next = NULL;
- m_prev = NULL;
- m_start = start;
- m_end = end;
-
- m_type = TokenTypVar; // at the beginning a default variable type
- m_IdKeyWord = -1;
-}
-
-CBotToken::CBotToken(const char* mot, const char* sep)
-{
- m_Text = mot;
- if ( sep != NULL ) m_Sep = sep;
- m_next = NULL;
- m_prev = NULL;
-
- m_type = TokenTypVar; // at the beginning a default variable type
- m_IdKeyWord = -1;
-}
-
-CBotToken::~CBotToken()
-{
- delete m_next; // recursive
- m_next = NULL;
-}
-
-void CBotToken::Free()
-{
- m_ListKeyDefine.SetSize(0);
-}
-
-const CBotToken& CBotToken::operator=(const CBotToken& src)
-{
- if (m_next != NULL) delete(m_next);
- m_next = NULL;
- m_prev = NULL;
-
- m_Text = src.m_Text;
- m_Sep = src.m_Sep;
-
- m_type = src.m_type;
- m_IdKeyWord = src.m_IdKeyWord;
-
- m_start = src.m_start;
- m_end = src.m_end;
- return *this;
-}
-
-
-int CBotToken::GivType()
-{
- if (this == NULL) return 0;
- if (m_type == TokenTypKeyWord) return m_IdKeyWord;
- return m_type;
-}
-
-long CBotToken::GivIdKey()
-{
- return m_IdKeyWord;
-}
-
-CBotToken* CBotToken::GivNext()
-{
- if (this == NULL) return NULL;
- return m_next;
-}
-
-CBotToken* CBotToken::GivPrev()
-{
- if (this == NULL) return NULL;
- return m_prev;
-}
-
-void CBotToken::AddNext(CBotToken* p)
-{
- CBotToken* n = new CBotToken(p);
- CBotToken* pt = this;
-
- while ( pt->m_next != NULL ) pt = pt->m_next;
-
- pt->m_next = n;
- n->m_prev = pt;
-}
-
-
-CBotString& CBotToken::GivString()
-{
- return m_Text;
-}
-
-CBotString& CBotToken::GivSep()
-{
- return m_Sep;
-}
-
-void CBotToken::SetString(const char* name)
-{
- m_Text = name;
-}
-
-
-int CBotToken::GivStart()
-{
- if (this == NULL) return -1;
- return m_start;
-}
-
-int CBotToken::GivEnd()
-{
- if (this == NULL) return -1;
- return m_end;
-}
-
-void CBotToken::SetPos(int start, int end)
-{
- m_start = start;
- m_end = end;
-}
-
-bool CharInList(const char c, const char* list)
-{
- int i = 0;
-
- while (true)
- {
- if (c == list[i++]) return true;
- if (list[i] == 0) return false;
- }
-}
-
-bool Char2InList(const char c, const char cc, const char* list)
-{
- int i = 0;
-
- while (true)
- {
- if (c == list[i++] &&
- cc == list[i++]) return true;
-
- if (list[i] == 0) return false;
- }
-}
-
-static char* sep1 = " \r\n\t,:()[]{}-+*/=;><!~^|&%.";
-static char* sep2 = " \r\n\t"; // only separators
-static char* sep3 = ",:()[]{}-+*/=;<>!~^|&%."; // operational separators
-static char* num = "0123456789"; // point (single) is tested separately
-static char* hexnum = "0123456789ABCDEFabcdef";
-static char* nch = "\"\r\n\t"; // forbidden in chains
-
-//static char* duo = "+=-=*=/===!=<=>=++--///**/||&&"; // double operators
-
-// looking for the next token in a sentence
-// do not start with separators
-// which are made in the previous token
-CBotToken* CBotToken::NextToken(char* &program, int& error, bool first)
-{
- CBotString mot; // the word which is found
- CBotString sep; // separators that are after
- char c;
- bool stop = first;
-
- if (*program == 0) return NULL;
-
- c = *(program++); // next character
-
- if (!first)
- {
- mot = c; // built the word
- c = *(program++); // next character
-
- // special case for strings
- if ( mot[0] == '\"' )
- {
- while (c != 0 && !CharInList(c, nch))
- {
- mot += c;
- c = *(program++); // next character
- if ( c == '\\' )
- {
- c = *(program++); // next character
- if ( c == 'n' ) c = '\n';
- if ( c == 'r' ) c = '\r';
- if ( c == 't' ) c = '\t';
- mot += c;
- c = *(program++); // next character
- }
- }
- if ( c == '\"' )
- {
- mot += c; // string is complete
- c = *(program++); // next character
- }
- stop = true;
- }
-
- // special case for numbers
- if ( CharInList(mot[0], num ))
- {
- bool bdot = false; // found a point?
- bool bexp = false; // found an exponent?
-
- char* liste = num;
- if (mot[0] == '0' && c == 'x') // hexadecimal value?
- {
- mot += c;
- c = *(program++); // next character
- liste = hexnum;
- }
-cw:
- while (c != 0 && CharInList(c, liste))
- {
-cc: mot += c;
- c = *(program++); // next character
- }
- if ( liste == num ) // not for hexadecimal
- {
- if ( !bdot && c == '.' ) { bdot = true; goto cc; }
- if ( !bexp && ( c == 'e' || c == 'E' ) )
- {
- bexp = true;
- mot += c;
- c = *(program++); // next character
- if ( c == '-' ||
- c == '+' ) goto cc;
- goto cw;
- }
-
- }
- stop = true;
- }
-
- if (CharInList(mot[0], sep3)) // an operational separator?
- {
- CBotString motc = mot;
- while (motc += c, c != 0 && GivKeyWords(motc)>0) // operand seeks the longest possible
- {
- mot += c; // build the word
- c = *(program++); // next character
- }
-
- stop = true;
- }
- }
-
-
-
- while (true)
- {
- if (stop || c == 0 || CharInList(c, sep1))
- {
- if (!first && mot.IsEmpty()) return NULL; // end of the analysis
-bis:
- while (CharInList(c, sep2))
- {
- sep += c; // after all the separators
- c = *(program++);
- }
- if (c == '/' && *program == '/') // comment on the heap?
- {
- while( c != '\n' && c != 0 )
- {
- sep += c;
- c = *(program++); // next character
- }
- goto bis;
- }
-
- if (c == '/' && *program == '*') // comment on the heap?
- {
- while( c != 0 && (c != '*' || *program != '/'))
- {
- sep += c;
- c = *(program++); // next character
- }
- if ( c != 0 )
- {
- sep += c;
- c = *(program++); // next character
- sep += c;
- c = *(program++); // next character
- }
- goto bis;
- }
-
- program--;
-
- CBotToken* token = new CBotToken(mot, sep);
-
- if (CharInList( mot[0], num )) token->m_type = TokenTypNum;
- if (mot[0] == '\"') token->m_type = TokenTypString;
- if (first) token->m_type = 0;
-
- token->m_IdKeyWord = GivKeyWords(mot);
- if (token->m_IdKeyWord > 0) token->m_type = TokenTypKeyWord;
- else GivKeyDefNum(mot, token) ; // treats DefineNum
-
- return token;
- }
-
- mot += c; // built the word
- c = *(program++); // next character
- }
-}
-
-CBotToken* CBotToken::CompileTokens(const char* program, int& error)
-{
- CBotToken *nxt, *prv, *tokenbase;
- char* p = (char*) program;
- int pos = 0;
-
- error = 0;
- prv = tokenbase = NextToken(p, error, true);
-
- if (tokenbase == NULL) return NULL;
-
- tokenbase->m_start = pos;
- pos += tokenbase->m_Text.GivLength();
- tokenbase->m_end = pos;
- pos += tokenbase->m_Sep.GivLength();
-
- char* pp = p;
- while (NULL != (nxt = NextToken(p, error)))
- {
- prv->m_next = nxt; // added after
- nxt->m_prev = prv;
- prv = nxt; // advance
-
- nxt->m_start = pos;
-/* pos += nxt->m_Text.GivLength(); // chain may be shorter (BOA deleted)
- nxt->m_end = pos;
- pos += nxt->m_Sep.GivLength();*/
- pos += (p - pp); // total size
- nxt->m_end = pos - nxt->m_Sep.GivLength();
- pp = p;
- }
-
- // adds a token as a terminator
- // ( useful for the previous )
- nxt = new CBotToken();
- nxt->m_type = 0;
- prv->m_next = nxt; // added after
- nxt->m_prev = prv;
-
- return tokenbase;
-}
-
-void CBotToken::Delete(CBotToken* pToken)
-{
- delete pToken;
-}
-
-
-// search if a word is part of the keywords
-
-int CBotToken::GivKeyWords(const char* w)
-{
- int i;
- int l = m_ListKeyWords.GivSize();
-
- if (l == 0)
- {
- LoadKeyWords(); // takes the list for the first time
- l = m_ListKeyWords.GivSize();
- }
-
- for (i = 0; i < l; i++)
- {
- if (m_ListKeyWords[i] == w) return m_ListIdKeyWords[ i ];
- }
-
- return -1;
-}
-
-bool CBotToken::GivKeyDefNum(const char* w, CBotToken* &token)
-{
- int i;
- int l = m_ListKeyDefine.GivSize();
-
- for (i = 0; i < l; i++)
- {
- if (m_ListKeyDefine[i] == w)
- {
- token->m_IdKeyWord = m_ListKeyNums[i];
- token->m_type = TokenTypDef;
- return true;
- }
- }
-
- return false;
-}
-
-
-/// \todo Fixme Figure out how this should work.
-
-// recreates the list of keywords and its IDs basing on some resources
-// defines of TokenKey.. are in CBotDll.h
-
-void CBotToken::LoadKeyWords()
-{
- CBotString s;
- int i, n = 0;
-
- i = TokenKeyWord; //start with keywords of the language
- while (s.LoadString(i))
- {
- m_ListKeyWords.Add(s);
- m_ListIdKeyWords[n++] = i++;
- }
-
- i = TokenKeyDeclare; //keywords of declarations
- while (s.LoadString(i))
- {
- m_ListKeyWords.Add(s);
- m_ListIdKeyWords[n++] = i++;
- }
-
-
- i = TokenKeyVal; //keywords of values
- while (s.LoadString(i))
- {
- m_ListKeyWords.Add(s);
- m_ListIdKeyWords[n++] = i++;
- }
-
- i = TokenKeyOp; //operators
- while (s.LoadString(i))
- {
- m_ListKeyWords.Add(s);
- m_ListIdKeyWords[n++] = i++;
- }
-}
-
-bool CBotToken::DefineNum(const char* name, long val)
-{
- int i;
- int l = m_ListKeyDefine.GivSize();
-
- for (i = 0; i < l; i++)
- {
- if (m_ListKeyDefine[i] == name) return false;
- }
- if ( i == MAXDEFNUM ) return false;
-
- m_ListKeyDefine.Add( name );
- m_ListKeyNums[i] = val;
- return true;
-}
-
-bool IsOfType(CBotToken* &p, int type1, int type2)
-{
- if (p->GivType() == type1 ||
- p->GivType() == type2 )
- {
- p = p->GivNext();
- return true;
- }
- return false;
-}
-// Same with any number of arguments
-// There must be a zero as the last argument
-bool IsOfTypeList(CBotToken* &p, int type1, ...)
-{
- int i = type1;
- int max = 20;
- int type = p->GivType();
-
- va_list marker;
- va_start( marker, type1 ); /* Initialize variable arguments. */
-
- while (true)
- {
- if (type == i)
- {
- p = p->GivNext();
- va_end( marker ); /* Reset variable arguments. */
- return true;
- }
- if (--max == 0 || 0 == (i = va_arg( marker, int)))
- {
- va_end( marker ); /* Reset variable arguments. */
- return false;
- }
- }
-}
-
+// * 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
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+
+
+//CBotToken.cpp
+
+//////////////////////////////////////////////////////////////////
+// Managing Tokens
+// the text of a program is first transformed
+// into a sequence of tokens for easy interpretation
+// it will only treat the case as an error
+// where there is an illegal character in a string
+
+
+#include "CBot.h"
+#include <cstdarg>
+
+CBotStringArray CBotToken::m_ListKeyWords;
+int CBotToken::m_ListIdKeyWords[200];
+CBotStringArray CBotToken::m_ListKeyDefine;
+long CBotToken::m_ListKeyNums[MAXDEFNUM];
+
+//! contructors
+CBotToken::CBotToken()
+{
+ m_next = NULL;
+ m_prev = NULL;
+ m_type = TokenTypVar; // at the beginning a default variable type
+ m_IdKeyWord = -1;
+}
+
+CBotToken::CBotToken(const CBotToken* pSrc)
+{
+ m_next = NULL;
+ m_prev = NULL;
+
+ m_Text.Empty();
+ m_Sep.Empty();
+
+ m_type = 0;
+ m_IdKeyWord = 0;
+
+ m_start = 0;
+ m_end = 0;
+
+ if ( pSrc != NULL )
+ {
+
+ m_type = pSrc->m_type;
+ m_IdKeyWord = pSrc->m_IdKeyWord;
+
+ m_Text = pSrc->m_Text;
+ m_Sep = pSrc->m_Sep;
+
+ m_start = pSrc->m_start;
+ m_end = pSrc->m_end;
+ }
+}
+
+CBotToken::CBotToken(const CBotString& mot, const CBotString& sep, int start, int end)
+{
+ m_Text = mot; // word (mot) found as token
+ m_Sep = sep; // separator
+ m_next = NULL;
+ m_prev = NULL;
+ m_start = start;
+ m_end = end;
+
+ m_type = TokenTypVar; // at the beginning a default variable type
+ m_IdKeyWord = -1;
+}
+
+CBotToken::CBotToken(const char* mot, const char* sep)
+{
+ m_Text = mot;
+ if ( sep != NULL ) m_Sep = sep;
+ m_next = NULL;
+ m_prev = NULL;
+
+ m_type = TokenTypVar; // at the beginning a default variable type
+ m_IdKeyWord = -1;
+}
+
+CBotToken::~CBotToken()
+{
+ delete m_next; // recursive
+ m_next = NULL;
+}
+
+void CBotToken::Free()
+{
+ m_ListKeyDefine.SetSize(0);
+}
+
+const CBotToken& CBotToken::operator=(const CBotToken& src)
+{
+ if (m_next != NULL) delete(m_next);
+ m_next = NULL;
+ m_prev = NULL;
+
+ m_Text = src.m_Text;
+ m_Sep = src.m_Sep;
+
+ m_type = src.m_type;
+ m_IdKeyWord = src.m_IdKeyWord;
+
+ m_start = src.m_start;
+ m_end = src.m_end;
+ return *this;
+}
+
+
+int CBotToken::GivType()
+{
+ if (this == NULL) return 0;
+ if (m_type == TokenTypKeyWord) return m_IdKeyWord;
+ return m_type;
+}
+
+long CBotToken::GivIdKey()
+{
+ return m_IdKeyWord;
+}
+
+CBotToken* CBotToken::GivNext()
+{
+ if (this == NULL) return NULL;
+ return m_next;
+}
+
+CBotToken* CBotToken::GivPrev()
+{
+ if (this == NULL) return NULL;
+ return m_prev;
+}
+
+void CBotToken::AddNext(CBotToken* p)
+{
+ CBotToken* n = new CBotToken(p);
+ CBotToken* pt = this;
+
+ while ( pt->m_next != NULL ) pt = pt->m_next;
+
+ pt->m_next = n;
+ n->m_prev = pt;
+}
+
+
+CBotString& CBotToken::GivString()
+{
+ return m_Text;
+}
+
+CBotString& CBotToken::GivSep()
+{
+ return m_Sep;
+}
+
+void CBotToken::SetString(const char* name)
+{
+ m_Text = name;
+}
+
+
+int CBotToken::GivStart()
+{
+ if (this == NULL) return -1;
+ return m_start;
+}
+
+int CBotToken::GivEnd()
+{
+ if (this == NULL) return -1;
+ return m_end;
+}
+
+void CBotToken::SetPos(int start, int end)
+{
+ m_start = start;
+ m_end = end;
+}
+
+bool CharInList(const char c, const char* list)
+{
+ int i = 0;
+
+ while (true)
+ {
+ if (c == list[i++]) return true;
+ if (list[i] == 0) return false;
+ }
+}
+
+bool Char2InList(const char c, const char cc, const char* list)
+{
+ int i = 0;
+
+ while (true)
+ {
+ if (c == list[i++] &&
+ cc == list[i++]) return true;
+
+ if (list[i] == 0) return false;
+ }
+}
+
+static char* sep1 = " \r\n\t,:()[]{}-+*/=;><!~^|&%.";
+static char* sep2 = " \r\n\t"; // only separators
+static char* sep3 = ",:()[]{}-+*/=;<>!~^|&%."; // operational separators
+static char* num = "0123456789"; // point (single) is tested separately
+static char* hexnum = "0123456789ABCDEFabcdef";
+static char* nch = "\"\r\n\t"; // forbidden in chains
+
+//static char* duo = "+=-=*=/===!=<=>=++--///**/||&&"; // double operators
+
+// looking for the next token in a sentence
+// do not start with separators
+// which are made in the previous token
+CBotToken* CBotToken::NextToken(char* &program, int& error, bool first)
+{
+ CBotString mot; // the word which is found
+ CBotString sep; // separators that are after
+ char c;
+ bool stop = first;
+
+ if (*program == 0) return NULL;
+
+ c = *(program++); // next character
+
+ if (!first)
+ {
+ mot = c; // built the word
+ c = *(program++); // next character
+
+ // special case for strings
+ if ( mot[0] == '\"' )
+ {
+ while (c != 0 && !CharInList(c, nch))
+ {
+ mot += c;
+ c = *(program++); // next character
+ if ( c == '\\' )
+ {
+ c = *(program++); // next character
+ if ( c == 'n' ) c = '\n';
+ if ( c == 'r' ) c = '\r';
+ if ( c == 't' ) c = '\t';
+ mot += c;
+ c = *(program++); // next character
+ }
+ }
+ if ( c == '\"' )
+ {
+ mot += c; // string is complete
+ c = *(program++); // next character
+ }
+ stop = true;
+ }
+
+ // special case for numbers
+ if ( CharInList(mot[0], num ))
+ {
+ bool bdot = false; // found a point?
+ bool bexp = false; // found an exponent?
+
+ char* liste = num;
+ if (mot[0] == '0' && c == 'x') // hexadecimal value?
+ {
+ mot += c;
+ c = *(program++); // next character
+ liste = hexnum;
+ }
+cw:
+ while (c != 0 && CharInList(c, liste))
+ {
+cc: mot += c;
+ c = *(program++); // next character
+ }
+ if ( liste == num ) // not for hexadecimal
+ {
+ if ( !bdot && c == '.' ) { bdot = true; goto cc; }
+ if ( !bexp && ( c == 'e' || c == 'E' ) )
+ {
+ bexp = true;
+ mot += c;
+ c = *(program++); // next character
+ if ( c == '-' ||
+ c == '+' ) goto cc;
+ goto cw;
+ }
+
+ }
+ stop = true;
+ }
+
+ if (CharInList(mot[0], sep3)) // an operational separator?
+ {
+ CBotString motc = mot;
+ while (motc += c, c != 0 && GivKeyWords(motc)>0) // operand seeks the longest possible
+ {
+ mot += c; // build the word
+ c = *(program++); // next character
+ }
+
+ stop = true;
+ }
+ }
+
+
+
+ while (true)
+ {
+ if (stop || c == 0 || CharInList(c, sep1))
+ {
+ if (!first && mot.IsEmpty()) return NULL; // end of the analysis
+bis:
+ while (CharInList(c, sep2))
+ {
+ sep += c; // after all the separators
+ c = *(program++);
+ }
+ if (c == '/' && *program == '/') // comment on the heap?
+ {
+ while( c != '\n' && c != 0 )
+ {
+ sep += c;
+ c = *(program++); // next character
+ }
+ goto bis;
+ }
+
+ if (c == '/' && *program == '*') // comment on the heap?
+ {
+ while( c != 0 && (c != '*' || *program != '/'))
+ {
+ sep += c;
+ c = *(program++); // next character
+ }
+ if ( c != 0 )
+ {
+ sep += c;
+ c = *(program++); // next character
+ sep += c;
+ c = *(program++); // next character
+ }
+ goto bis;
+ }
+
+ program--;
+
+ CBotToken* token = new CBotToken(mot, sep);
+
+ if (CharInList( mot[0], num )) token->m_type = TokenTypNum;
+ if (mot[0] == '\"') token->m_type = TokenTypString;
+ if (first) token->m_type = 0;
+
+ token->m_IdKeyWord = GivKeyWords(mot);
+ if (token->m_IdKeyWord > 0) token->m_type = TokenTypKeyWord;
+ else GivKeyDefNum(mot, token) ; // treats DefineNum
+
+ return token;
+ }
+
+ mot += c; // built the word
+ c = *(program++); // next character
+ }
+}
+
+CBotToken* CBotToken::CompileTokens(const char* program, int& error)
+{
+ CBotToken *nxt, *prv, *tokenbase;
+ char* p = (char*) program;
+ int pos = 0;
+
+ error = 0;
+ prv = tokenbase = NextToken(p, error, true);
+
+ if (tokenbase == NULL) return NULL;
+
+ tokenbase->m_start = pos;
+ pos += tokenbase->m_Text.GivLength();
+ tokenbase->m_end = pos;
+ pos += tokenbase->m_Sep.GivLength();
+
+ char* pp = p;
+ while (NULL != (nxt = NextToken(p, error)))
+ {
+ prv->m_next = nxt; // added after
+ nxt->m_prev = prv;
+ prv = nxt; // advance
+
+ nxt->m_start = pos;
+/* pos += nxt->m_Text.GivLength(); // chain may be shorter (BOA deleted)
+ nxt->m_end = pos;
+ pos += nxt->m_Sep.GivLength();*/
+ pos += (p - pp); // total size
+ nxt->m_end = pos - nxt->m_Sep.GivLength();
+ pp = p;
+ }
+
+ // adds a token as a terminator
+ // ( useful for the previous )
+ nxt = new CBotToken();
+ nxt->m_type = 0;
+ prv->m_next = nxt; // added after
+ nxt->m_prev = prv;
+
+ return tokenbase;
+}
+
+void CBotToken::Delete(CBotToken* pToken)
+{
+ delete pToken;
+}
+
+
+// search if a word is part of the keywords
+
+int CBotToken::GivKeyWords(const char* w)
+{
+ int i;
+ int l = m_ListKeyWords.GivSize();
+
+ if (l == 0)
+ {
+ LoadKeyWords(); // takes the list for the first time
+ l = m_ListKeyWords.GivSize();
+ }
+
+ for (i = 0; i < l; i++)
+ {
+ if (m_ListKeyWords[i] == w) return m_ListIdKeyWords[ i ];
+ }
+
+ return -1;
+}
+
+bool CBotToken::GivKeyDefNum(const char* w, CBotToken* &token)
+{
+ int i;
+ int l = m_ListKeyDefine.GivSize();
+
+ for (i = 0; i < l; i++)
+ {
+ if (m_ListKeyDefine[i] == w)
+ {
+ token->m_IdKeyWord = m_ListKeyNums[i];
+ token->m_type = TokenTypDef;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/// \todo Fixme Figure out how this should work.
+
+// recreates the list of keywords and its IDs basing on some resources
+// defines of TokenKey.. are in CBotDll.h
+
+void CBotToken::LoadKeyWords()
+{
+ CBotString s;
+ int i, n = 0;
+
+ i = TokenKeyWord; //start with keywords of the language
+ while (s.LoadString(i))
+ {
+ m_ListKeyWords.Add(s);
+ m_ListIdKeyWords[n++] = i++;
+ }
+
+ i = TokenKeyDeclare; //keywords of declarations
+ while (s.LoadString(i))
+ {
+ m_ListKeyWords.Add(s);
+ m_ListIdKeyWords[n++] = i++;
+ }
+
+
+ i = TokenKeyVal; //keywords of values
+ while (s.LoadString(i))
+ {
+ m_ListKeyWords.Add(s);
+ m_ListIdKeyWords[n++] = i++;
+ }
+
+ i = TokenKeyOp; //operators
+ while (s.LoadString(i))
+ {
+ m_ListKeyWords.Add(s);
+ m_ListIdKeyWords[n++] = i++;
+ }
+}
+
+bool CBotToken::DefineNum(const char* name, long val)
+{
+ int i;
+ int l = m_ListKeyDefine.GivSize();
+
+ for (i = 0; i < l; i++)
+ {
+ if (m_ListKeyDefine[i] == name) return false;
+ }
+ if ( i == MAXDEFNUM ) return false;
+
+ m_ListKeyDefine.Add( name );
+ m_ListKeyNums[i] = val;
+ return true;
+}
+
+bool IsOfType(CBotToken* &p, int type1, int type2)
+{
+ if (p->GivType() == type1 ||
+ p->GivType() == type2 )
+ {
+ p = p->GivNext();
+ return true;
+ }
+ return false;
+}
+// Same with any number of arguments
+// There must be a zero as the last argument
+bool IsOfTypeList(CBotToken* &p, int type1, ...)
+{
+ int i = type1;
+ int max = 20;
+ int type = p->GivType();
+
+ va_list marker;
+ va_start( marker, type1 ); /* Initialize variable arguments. */
+
+ while (true)
+ {
+ if (type == i)
+ {
+ p = p->GivNext();
+ va_end( marker ); /* Reset variable arguments. */
+ return true;
+ }
+ if (--max == 0 || 0 == (i = va_arg( marker, int)))
+ {
+ va_end( marker ); /* Reset variable arguments. */
+ return false;
+ }
+ }
+}
+
diff --git a/src/CBot/CBotToken.h b/src/CBot/CBotToken.h
index 8e9d1e3..6f11bb2 100644
--- a/src/CBot/CBotToken.h
+++ b/src/CBot/CBotToken.h
@@ -1,38 +1,38 @@
-// * 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
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-
-// interpreter of the lanuage CBot for game COLOBOT
-// writing a program is first transformed into a list of tokens
-// before tackling the compiler itself
-// for example
-// int var = 3 * ( pos.y + x )
-// is decomposed into (each line is a token)
-// int
-// var
-// =
-// 3
-// *
-// (
-// pos.y
-// +
-// x
-// )
-
-#pragma once
-
-extern bool IsOfType(CBotToken* &p, int type1, int type2 = -1);
-extern bool IsOfTypeList(CBotToken* &p, int type1, ...);
+// * 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
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+
+
+// interpreter of the lanuage CBot for game COLOBOT
+// writing a program is first transformed into a list of tokens
+// before tackling the compiler itself
+// for example
+// int var = 3 * ( pos.y + x )
+// is decomposed into (each line is a token)
+// int
+// var
+// =
+// 3
+// *
+// (
+// pos.y
+// +
+// x
+// )
+
+#pragma once
+
+extern bool IsOfType(CBotToken* &p, int type1, int type2 = -1);
+extern bool IsOfTypeList(CBotToken* &p, int type1, ...);
diff --git a/src/CBot/CBotTwoOpExpr.cpp b/src/CBot/CBotTwoOpExpr.cpp
index 49cfcc8..62290da 100644
--- a/src/CBot/CBotTwoOpExpr.cpp
+++ b/src/CBot/CBotTwoOpExpr.cpp
@@ -16,7 +16,7 @@
///////////////////////////////////////////////////
// expression of type Opérande1 + Opérande2
-// Opérande1 > Opérande2
+// Opérande1 > Opérande2
#include "CBot.h"
@@ -24,271 +24,271 @@
CBotTwoOpExpr::CBotTwoOpExpr()
{
- m_leftop =
- m_rightop = NULL; // NULL to be able to delete without other
- name = "CBotTwoOpExpr"; // debug
+ m_leftop =
+ m_rightop = NULL; // NULL to be able to delete without other
+ name = "CBotTwoOpExpr"; // debug
}
CBotTwoOpExpr::~CBotTwoOpExpr()
{
- delete m_leftop;
- delete m_rightop;
+ delete m_leftop;
+ delete m_rightop;
}
CBotLogicExpr::CBotLogicExpr()
{
- m_condition =
- m_op1 =
- m_op2 = NULL; // NULL to be able to delete without other
- name = "CBotLogicExpr"; // debug
+ m_condition =
+ m_op1 =
+ m_op2 = NULL; // NULL to be able to delete without other
+ name = "CBotLogicExpr"; // debug
}
CBotLogicExpr::~CBotLogicExpr()
{
- delete m_condition;
- delete m_op1;
- delete m_op2;
+ delete m_condition;
+ delete m_op1;
+ delete m_op2;
}
// type of operands accepted by operations
-#define ENTIER ((1<<CBotTypByte)|(1<<CBotTypShort)|(1<<CBotTypChar)|(1<<CBotTypInt)|(1<<CBotTypLong))
-#define FLOTANT ((1<<CBotTypFloat)|(1<<CBotTypDouble))
-#define BOOLEEN (1<<CBotTypBoolean)
-#define CHAINE (1<<CBotTypString)
-#define POINTER (1<<CBotTypPointer)
-#define INSTANCE (1<<CBotTypClass)
+#define ENTIER ((1<<CBotTypByte)|(1<<CBotTypShort)|(1<<CBotTypChar)|(1<<CBotTypInt)|(1<<CBotTypLong))
+#define FLOTANT ((1<<CBotTypFloat)|(1<<CBotTypDouble))
+#define BOOLEEN (1<<CBotTypBoolean)
+#define CHAINE (1<<CBotTypString)
+#define POINTER (1<<CBotTypPointer)
+#define INSTANCE (1<<CBotTypClass)
// list of operations (précéance)
-// acceptable type, operand
-// zero ends level \TODO précéance
+// acceptable type, operand
+// zero ends level \TODO précéance
-static int ListOp[] =
+static int ListOp[] =
{
- BOOLEEN, ID_LOGIC, 0,
- BOOLEEN, ID_TXT_OR,
- BOOLEEN, ID_LOG_OR, 0,
- BOOLEEN, ID_TXT_AND,
- BOOLEEN, ID_LOG_AND, 0,
- BOOLEEN|ENTIER, ID_OR, 0,
- BOOLEEN|ENTIER, ID_XOR, 0,
- BOOLEEN|ENTIER, ID_AND, 0,
- BOOLEEN|ENTIER|FLOTANT
- |CHAINE
- |POINTER
- |INSTANCE,ID_EQ,
- BOOLEEN|ENTIER|FLOTANT
- |CHAINE
- |POINTER
- |INSTANCE,ID_NE, 0,
- ENTIER|FLOTANT|CHAINE, ID_HI,
- ENTIER|FLOTANT|CHAINE, ID_LO,
- ENTIER|FLOTANT|CHAINE, ID_HS,
- ENTIER|FLOTANT|CHAINE, ID_LS, 0,
- ENTIER, ID_SR,
- ENTIER, ID_SL,
- ENTIER, ID_ASR, 0,
- ENTIER|FLOTANT|CHAINE, ID_ADD,
- ENTIER|FLOTANT, ID_SUB, 0,
- ENTIER|FLOTANT, ID_MUL,
- ENTIER|FLOTANT, ID_DIV,
- ENTIER|FLOTANT, ID_MODULO, 0,
- ENTIER|FLOTANT, ID_POWER, 0,
- 0,
+ BOOLEEN, ID_LOGIC, 0,
+ BOOLEEN, ID_TXT_OR,
+ BOOLEEN, ID_LOG_OR, 0,
+ BOOLEEN, ID_TXT_AND,
+ BOOLEEN, ID_LOG_AND, 0,
+ BOOLEEN|ENTIER, ID_OR, 0,
+ BOOLEEN|ENTIER, ID_XOR, 0,
+ BOOLEEN|ENTIER, ID_AND, 0,
+ BOOLEEN|ENTIER|FLOTANT
+ |CHAINE
+ |POINTER
+ |INSTANCE,ID_EQ,
+ BOOLEEN|ENTIER|FLOTANT
+ |CHAINE
+ |POINTER
+ |INSTANCE,ID_NE, 0,
+ ENTIER|FLOTANT|CHAINE, ID_HI,
+ ENTIER|FLOTANT|CHAINE, ID_LO,
+ ENTIER|FLOTANT|CHAINE, ID_HS,
+ ENTIER|FLOTANT|CHAINE, ID_LS, 0,
+ ENTIER, ID_SR,
+ ENTIER, ID_SL,
+ ENTIER, ID_ASR, 0,
+ ENTIER|FLOTANT|CHAINE, ID_ADD,
+ ENTIER|FLOTANT, ID_SUB, 0,
+ ENTIER|FLOTANT, ID_MUL,
+ ENTIER|FLOTANT, ID_DIV,
+ ENTIER|FLOTANT, ID_MODULO, 0,
+ ENTIER|FLOTANT, ID_POWER, 0,
+ 0,
};
bool IsInList( int val, int* list, int& typemasque )
{
- while (true)
- {
- if ( *list == 0 ) return false;
- typemasque = *list++;
- if ( *list++ == val ) return true;
- }
+ while (true)
+ {
+ if ( *list == 0 ) return false;
+ typemasque = *list++;
+ if ( *list++ == val ) return true;
+ }
}
bool TypeOk( int type, int test )
{
- while (true)
- {
- if ( type == 0 ) return (test & 1);
- type--; test /= 2;
- }
+ while (true)
+ {
+ if ( type == 0 ) return (test & 1);
+ type--; test /= 2;
+ }
}
// compiles a instruction of type A op B
CBotInstr* CBotTwoOpExpr::Compile(CBotToken* &p, CBotCStack* pStack, int* pOperations)
{
- int typemasque;
-
- if ( pOperations == NULL ) pOperations = ListOp;
- int* pOp = pOperations;
- while ( *pOp++ != 0 ); // follows the table
-
- CBotCStack* pStk = pStack->TokenStack(); // one end of stack please
-
- // search the intructions that may be suitable to the left of the operation
- CBotInstr* left = (*pOp == 0) ?
- CBotParExpr::Compile( p, pStk ) : // expression (...) left
- CBotTwoOpExpr::Compile( p, pStk, pOp ); // expression A * B left
-
- if (left == NULL) return pStack->Return(NULL, pStk); // if error, transmit
-
- // did we expected the operand?
- int TypeOp = p->GivType();
- if ( IsInList( TypeOp, pOperations, typemasque ) )
- {
- CBotTypResult type1, type2;
- type1 = pStk->GivTypResult(); // what kind of the first operand?
-
- if ( TypeOp == ID_LOGIC ) // special case provided for: ? op1: op2;
- {
- if ( !type1.Eq(CBotTypBoolean) )
- {
- pStk->SetError( TX_BADTYPE, p);
- return pStack->Return(NULL, pStk);
- }
- CBotLogicExpr* inst = new CBotLogicExpr();
- inst->m_condition = left;
-
- p = p->GivNext(); // skip the token of the operation
- inst->m_op1 = CBotExpression::Compile(p, pStk);
- CBotToken* pp = p;
- if ( inst->m_op1 == NULL || !IsOfType( p, ID_DOTS ) )
- {
- pStk->SetError( TX_MISDOTS, p->GivStart());
- delete inst;
- return pStack->Return(NULL, pStk);
- }
- type1 = pStk->GivTypResult();
-
- inst->m_op2 = CBotExpression::Compile(p, pStk);
- if ( inst->m_op2 == NULL )
- {
- pStk->SetError( TX_ENDOF, p->GivStart() );
- delete inst;
- return pStack->Return(NULL, pStk);
- }
- type2 = pStk->GivTypResult();
- if (!TypeCompatible(type1, type2))
- {
- pStk->SetError( TX_BAD2TYPE, pp );
- delete inst;
- return pStack->Return(NULL, pStk);
- }
-
- pStk->SetType(type1); // the greatest of 2 types
-
- return pStack->Return(inst, pStk);
- }
-
- CBotTwoOpExpr* inst = new CBotTwoOpExpr(); // element for operation
- inst->SetToken(p); // stores the operation
-
-
- p = p->GivNext(); // skip the token of the operation
-
- // looking statements that may be suitable for right
-
- if ( NULL != (inst->m_rightop = CBotTwoOpExpr::Compile( p, pStk, pOp )) )
- // expression (...) right
- {
- // there is an second operand acceptable
-
- type2 = pStk->GivTypResult(); // what kind of results?
-
- // what kind of result?
- int TypeRes = MAX( type1.GivType(3), type2.GivType(3) );
- if ( TypeOp == ID_ADD && type1.Eq(CBotTypString) )
- {
- TypeRes = CBotTypString;
- type2 = type1; // any type convertible chain
- }
- else if ( TypeOp == ID_ADD && type2.Eq(CBotTypString) )
- {
- TypeRes = CBotTypString;
- type1 = type2; // any type convertible chain
- }
- else if (!TypeOk( TypeRes, typemasque )) type1.SetType(99);// error of type
-
- switch ( TypeOp )
- {
- case ID_LOG_OR:
- case ID_LOG_AND:
- case ID_TXT_OR:
- case ID_TXT_AND:
- case ID_EQ:
- case ID_NE:
- case ID_HI:
- case ID_LO:
- case ID_HS:
- case ID_LS:
- TypeRes = CBotTypBoolean;
- }
- if ( TypeCompatible (type1, type2, TypeOp ) ) // the results are compatible
- {
- // ok so, saves the operand in the object
- inst->m_leftop = left;
-
- // special for evaluation of the operations of the same level from left to right
- while ( IsInList( p->GivType(), pOperations, typemasque ) ) // same operation(s) follows?
- {
- TypeOp = p->GivType();
- CBotTwoOpExpr* i = new CBotTwoOpExpr(); // element for operation
- i->SetToken(p); // stores the operation
- i->m_leftop = inst; // left operand
- type1 = TypeRes;
-
- p = p->GivNext(); // advance after
- i->m_rightop = CBotTwoOpExpr::Compile( p, pStk, pOp );
- type2 = pStk->GivTypResult();
-
- if ( !TypeCompatible (type1, type2, TypeOp) ) // the results are compatible
- {
- pStk->SetError(TX_BAD2TYPE, &i->m_token);
- delete i;
- return pStack->Return(NULL, pStk);
- }
-
- if ( TypeRes != CBotTypString )
- TypeRes = MAX(type1.GivType(), type2.GivType());
- inst = i;
- }
-
- CBotTypResult t(type1);
- t.SetType(TypeRes);
- // is a variable on the stack for the type of result
- pStk->SetVar(CBotVar::Create((CBotToken*)NULL, t));
-
- // and returns the requested object
- return pStack->Return(inst, pStk);
- }
- pStk->SetError(TX_BAD2TYPE, &inst->m_token);
- }
-
- // in case of error, releases the elements
- delete left;
- delete inst;
- // and transmits the error to the stack
- return pStack->Return(NULL, pStk);
- }
-
- // if we are not dealing with an operation + or -
- // goes to that requested, the operand (left) found
- // instead of the object "addition"
- return pStack->Return(left, pStk);
+ int typemasque;
+
+ if ( pOperations == NULL ) pOperations = ListOp;
+ int* pOp = pOperations;
+ while ( *pOp++ != 0 ); // follows the table
+
+ CBotCStack* pStk = pStack->TokenStack(); // one end of stack please
+
+ // search the intructions that may be suitable to the left of the operation
+ CBotInstr* left = (*pOp == 0) ?
+ CBotParExpr::Compile( p, pStk ) : // expression (...) left
+ CBotTwoOpExpr::Compile( p, pStk, pOp ); // expression A * B left
+
+ if (left == NULL) return pStack->Return(NULL, pStk); // if error, transmit
+
+ // did we expected the operand?
+ int TypeOp = p->GivType();
+ if ( IsInList( TypeOp, pOperations, typemasque ) )
+ {
+ CBotTypResult type1, type2;
+ type1 = pStk->GivTypResult(); // what kind of the first operand?
+
+ if ( TypeOp == ID_LOGIC ) // special case provided for: ? op1: op2;
+ {
+ if ( !type1.Eq(CBotTypBoolean) )
+ {
+ pStk->SetError( TX_BADTYPE, p);
+ return pStack->Return(NULL, pStk);
+ }
+ CBotLogicExpr* inst = new CBotLogicExpr();
+ inst->m_condition = left;
+
+ p = p->GivNext(); // skip the token of the operation
+ inst->m_op1 = CBotExpression::Compile(p, pStk);
+ CBotToken* pp = p;
+ if ( inst->m_op1 == NULL || !IsOfType( p, ID_DOTS ) )
+ {
+ pStk->SetError( TX_MISDOTS, p->GivStart());
+ delete inst;
+ return pStack->Return(NULL, pStk);
+ }
+ type1 = pStk->GivTypResult();
+
+ inst->m_op2 = CBotExpression::Compile(p, pStk);
+ if ( inst->m_op2 == NULL )
+ {
+ pStk->SetError( TX_ENDOF, p->GivStart() );
+ delete inst;
+ return pStack->Return(NULL, pStk);
+ }
+ type2 = pStk->GivTypResult();
+ if (!TypeCompatible(type1, type2))
+ {
+ pStk->SetError( TX_BAD2TYPE, pp );
+ delete inst;
+ return pStack->Return(NULL, pStk);
+ }
+
+ pStk->SetType(type1); // the greatest of 2 types
+
+ return pStack->Return(inst, pStk);
+ }
+
+ CBotTwoOpExpr* inst = new CBotTwoOpExpr(); // element for operation
+ inst->SetToken(p); // stores the operation
+
+
+ p = p->GivNext(); // skip the token of the operation
+
+ // looking statements that may be suitable for right
+
+ if ( NULL != (inst->m_rightop = CBotTwoOpExpr::Compile( p, pStk, pOp )) )
+ // expression (...) right
+ {
+ // there is an second operand acceptable
+
+ type2 = pStk->GivTypResult(); // what kind of results?
+
+ // what kind of result?
+ int TypeRes = MAX( type1.GivType(3), type2.GivType(3) );
+ if ( TypeOp == ID_ADD && type1.Eq(CBotTypString) )
+ {
+ TypeRes = CBotTypString;
+ type2 = type1; // any type convertible chain
+ }
+ else if ( TypeOp == ID_ADD && type2.Eq(CBotTypString) )
+ {
+ TypeRes = CBotTypString;
+ type1 = type2; // any type convertible chain
+ }
+ else if (!TypeOk( TypeRes, typemasque )) type1.SetType(99);// error of type
+
+ switch ( TypeOp )
+ {
+ case ID_LOG_OR:
+ case ID_LOG_AND:
+ case ID_TXT_OR:
+ case ID_TXT_AND:
+ case ID_EQ:
+ case ID_NE:
+ case ID_HI:
+ case ID_LO:
+ case ID_HS:
+ case ID_LS:
+ TypeRes = CBotTypBoolean;
+ }
+ if ( TypeCompatible (type1, type2, TypeOp ) ) // the results are compatible
+ {
+ // ok so, saves the operand in the object
+ inst->m_leftop = left;
+
+ // special for evaluation of the operations of the same level from left to right
+ while ( IsInList( p->GivType(), pOperations, typemasque ) ) // same operation(s) follows?
+ {
+ TypeOp = p->GivType();
+ CBotTwoOpExpr* i = new CBotTwoOpExpr(); // element for operation
+ i->SetToken(p); // stores the operation
+ i->m_leftop = inst; // left operand
+ type1 = TypeRes;
+
+ p = p->GivNext(); // advance after
+ i->m_rightop = CBotTwoOpExpr::Compile( p, pStk, pOp );
+ type2 = pStk->GivTypResult();
+
+ if ( !TypeCompatible (type1, type2, TypeOp) ) // the results are compatible
+ {
+ pStk->SetError(TX_BAD2TYPE, &i->m_token);
+ delete i;
+ return pStack->Return(NULL, pStk);
+ }
+
+ if ( TypeRes != CBotTypString )
+ TypeRes = MAX(type1.GivType(), type2.GivType());
+ inst = i;
+ }
+
+ CBotTypResult t(type1);
+ t.SetType(TypeRes);
+ // is a variable on the stack for the type of result
+ pStk->SetVar(CBotVar::Create((CBotToken*)NULL, t));
+
+ // and returns the requested object
+ return pStack->Return(inst, pStk);
+ }
+ pStk->SetError(TX_BAD2TYPE, &inst->m_token);
+ }
+
+ // in case of error, releases the elements
+ delete left;
+ delete inst;
+ // and transmits the error to the stack
+ return pStack->Return(NULL, pStk);
+ }
+
+ // if we are not dealing with an operation + or -
+ // goes to that requested, the operand (left) found
+ // instead of the object "addition"
+ return pStack->Return(left, pStk);
}
bool IsNan(CBotVar* left, CBotVar* right, int* err = NULL)
{
- if ( left ->GivInit() > IS_DEF || right->GivInit() > IS_DEF )
- {
- if ( err != NULL ) *err = TX_OPNAN ;
- return true;
- }
- return false;
+ if ( left ->GivInit() > IS_DEF || right->GivInit() > IS_DEF )
+ {
+ if ( err != NULL ) *err = TX_OPNAN ;
+ return true;
+ }
+ return false;
}
@@ -296,273 +296,273 @@ bool IsNan(CBotVar* left, CBotVar* right, int* err = NULL)
bool CBotTwoOpExpr::Execute(CBotStack* &pStack)
{
- CBotStack* pStk1 = pStack->AddStack(this); // adds an item to the stack
- // or return in case of recovery
-// if ( pStk1 == EOX ) return true;
-
- // according to recovery, it may be in one of two states
-
- if ( pStk1->GivState() == 0 ) // first state, evaluates the left operand
- {
- if (!m_leftop->Execute(pStk1) ) return false; // interrupted here?
-
- // for OR and AND logic does not evaluate the second expression if not necessary
- if ( (GivTokenType() == ID_LOG_AND || GivTokenType() == ID_TXT_AND ) && pStk1->GivVal() == false )
- {
- CBotVar* res = CBotVar::Create( (CBotToken*)NULL, CBotTypBoolean);
- res->SetValInt(false);
- pStk1->SetVar(res);
- return pStack->Return(pStk1); // transmits the result
- }
- if ( (GivTokenType() == ID_LOG_OR||GivTokenType() == ID_TXT_OR) && pStk1->GivVal() == true )
- {
- CBotVar* res = CBotVar::Create( (CBotToken*)NULL, CBotTypBoolean);
- res->SetValInt(true);
- pStk1->SetVar(res);
- return pStack->Return(pStk1); // transmits the result
- }
-
- // passes to the next step
- pStk1->SetState(1); // ready for further
- }
+ CBotStack* pStk1 = pStack->AddStack(this); // adds an item to the stack
+ // or return in case of recovery
+// if ( pStk1 == EOX ) return true;
+
+ // according to recovery, it may be in one of two states
+
+ if ( pStk1->GivState() == 0 ) // first state, evaluates the left operand
+ {
+ if (!m_leftop->Execute(pStk1) ) return false; // interrupted here?
+
+ // for OR and AND logic does not evaluate the second expression if not necessary
+ if ( (GivTokenType() == ID_LOG_AND || GivTokenType() == ID_TXT_AND ) && pStk1->GivVal() == false )
+ {
+ CBotVar* res = CBotVar::Create( (CBotToken*)NULL, CBotTypBoolean);
+ res->SetValInt(false);
+ pStk1->SetVar(res);
+ return pStack->Return(pStk1); // transmits the result
+ }
+ if ( (GivTokenType() == ID_LOG_OR||GivTokenType() == ID_TXT_OR) && pStk1->GivVal() == true )
+ {
+ CBotVar* res = CBotVar::Create( (CBotToken*)NULL, CBotTypBoolean);
+ res->SetValInt(true);
+ pStk1->SetVar(res);
+ return pStack->Return(pStk1); // transmits the result
+ }
+
+ // passes to the next step
+ pStk1->SetState(1); // ready for further
+ }
// requires a little more stack to avoid touching the result
// of which is left on the stack, precisely
- CBotStack* pStk2 = pStk1->AddStack(); // adds an item to the stack
- // or return in case of recovery
-
- // 2e état, évalue l'opérande de droite
- if ( pStk2->GivState() == 0 )
- {
- if ( !m_rightop->Execute(pStk2) ) return false; // interrupted here?
- pStk2->IncState();
- }
-
- CBotTypResult type1 = pStk1->GivTypResult(); // what kind of results?
- CBotTypResult type2 = pStk2->GivTypResult();
-
- CBotStack* pStk3 = pStk2->AddStack(this); // adds an item to the stack
- if ( pStk3->IfStep() ) return false; // shows the operation if step by step
-
- // creates a temporary variable to put the result
- // what kind of result?
- int TypeRes = MAX(type1.GivType(), type2.GivType());
-
- if ( GivTokenType() == ID_ADD && type1.Eq(CBotTypString) )
- {
- TypeRes = CBotTypString;
- }
-
- switch ( GivTokenType() )
- {
- case ID_LOG_OR:
- case ID_LOG_AND:
- case ID_TXT_OR:
- case ID_TXT_AND:
- case ID_EQ:
- case ID_NE:
- case ID_HI:
- case ID_LO:
- case ID_HS:
- case ID_LS:
- TypeRes = CBotTypBoolean;
- break;
- case ID_DIV:
- TypeRes = MAX(TypeRes, CBotTypFloat);
- }
-
- // creates a variable for the result
- CBotVar* result = CBotVar::Create( (CBotToken*)NULL, TypeRes);
-
- // creates a variable to perform the calculation in the appropriate type
- TypeRes = MAX(type1.GivType(), type2.GivType());
-
- if ( GivTokenType() == ID_ADD && type1.Eq(CBotTypString) )
- {
- TypeRes = CBotTypString;
- }
-
- CBotVar* temp;
-
- if ( TypeRes == CBotTypPointer ) TypeRes = CBotTypNullPointer;
- if ( TypeRes == CBotTypClass ) temp = CBotVar::Create( (CBotToken*)NULL, CBotTypResult(CBotTypIntrinsic, type1.GivClass() ) );
- else temp = CBotVar::Create( (CBotToken*)NULL, TypeRes );
-
- int err = 0;
- // is a operation according to request
- CBotVar* left = pStk1->GivVar();
- CBotVar* right = pStk2->GivVar();
-
- switch (GivTokenType())
- {
- case ID_ADD:
- if ( !IsNan(left, right, &err) ) result->Add(left , right); // addition
- break;
- case ID_SUB:
- if ( !IsNan(left, right, &err) ) result->Sub(left , right); // substraction
- break;
- case ID_MUL:
- if ( !IsNan(left, right, &err) ) result->Mul(left , right); // multiplies
- break;
- case ID_POWER:
- if ( !IsNan(left, right, &err) ) result->Power(left , right); // power
- break;
- case ID_DIV:
- if ( !IsNan(left, right, &err) ) err = result->Div(left , right);// division
- break;
- case ID_MODULO:
- if ( !IsNan(left, right, &err) ) err = result->Modulo(left , right);// remainder of division
- break;
- case ID_LO:
- if ( !IsNan(left, right, &err) )
- result->SetValInt(temp->Lo(left , right)); // lower
- break;
- case ID_HI:
- if ( !IsNan(left, right, &err) )
- result->SetValInt(temp->Hi(left , right)); // top
- break;
- case ID_LS:
- if ( !IsNan(left, right, &err) )
- result->SetValInt(temp->Ls(left , right)); // less than or equal
- break;
- case ID_HS:
- if ( !IsNan(left, right, &err) )
- result->SetValInt(temp->Hs(left , right)); // greater than or equal
- break;
- case ID_EQ:
- if ( IsNan(left, right) )
- result->SetValInt(left->GivInit() == right->GivInit()) ;
- else
- result->SetValInt(temp->Eq(left , right)); // equal
- break;
- case ID_NE:
- if ( IsNan(left, right) )
- result->SetValInt(left ->GivInit() != right->GivInit()) ;
- else
- result->SetValInt(temp->Ne(left , right)); // different
- break;
- case ID_TXT_AND:
- case ID_LOG_AND:
- case ID_AND:
- if ( !IsNan(left, right, &err) ) result->And(left , right); // AND
- break;
- case ID_TXT_OR:
- case ID_LOG_OR:
- case ID_OR:
- if ( !IsNan(left, right, &err) ) result->Or(left , right); // OR
- break;
- case ID_XOR:
- if ( !IsNan(left, right, &err) ) result->XOr(left , right); // exclusive OR
- break;
- case ID_ASR:
- if ( !IsNan(left, right, &err) ) result->ASR(left , right);
- break;
- case ID_SR:
- if ( !IsNan(left, right, &err) ) result->SR(left , right);
- break;
- case ID_SL:
- if ( !IsNan(left, right, &err) ) result->SL(left , right);
- break;
- default:
- ASM_TRAP();
- }
- delete temp;
-
- pStk2->SetVar(result); // puts the result on the stack
- if ( err ) pStk2->SetError(err, &m_token); // and the possible error (division by zero)
-
-// pStk1->Return(pStk2); // releases the stack
- return pStack->Return(pStk2); // transmits the result
+ CBotStack* pStk2 = pStk1->AddStack(); // adds an item to the stack
+ // or return in case of recovery
+
+ // 2e état, évalue l'opérande de droite
+ if ( pStk2->GivState() == 0 )
+ {
+ if ( !m_rightop->Execute(pStk2) ) return false; // interrupted here?
+ pStk2->IncState();
+ }
+
+ CBotTypResult type1 = pStk1->GivTypResult(); // what kind of results?
+ CBotTypResult type2 = pStk2->GivTypResult();
+
+ CBotStack* pStk3 = pStk2->AddStack(this); // adds an item to the stack
+ if ( pStk3->IfStep() ) return false; // shows the operation if step by step
+
+ // creates a temporary variable to put the result
+ // what kind of result?
+ int TypeRes = MAX(type1.GivType(), type2.GivType());
+
+ if ( GivTokenType() == ID_ADD && type1.Eq(CBotTypString) )
+ {
+ TypeRes = CBotTypString;
+ }
+
+ switch ( GivTokenType() )
+ {
+ case ID_LOG_OR:
+ case ID_LOG_AND:
+ case ID_TXT_OR:
+ case ID_TXT_AND:
+ case ID_EQ:
+ case ID_NE:
+ case ID_HI:
+ case ID_LO:
+ case ID_HS:
+ case ID_LS:
+ TypeRes = CBotTypBoolean;
+ break;
+ case ID_DIV:
+ TypeRes = MAX(TypeRes, CBotTypFloat);
+ }
+
+ // creates a variable for the result
+ CBotVar* result = CBotVar::Create( (CBotToken*)NULL, TypeRes);
+
+ // creates a variable to perform the calculation in the appropriate type
+ TypeRes = MAX(type1.GivType(), type2.GivType());
+
+ if ( GivTokenType() == ID_ADD && type1.Eq(CBotTypString) )
+ {
+ TypeRes = CBotTypString;
+ }
+
+ CBotVar* temp;
+
+ if ( TypeRes == CBotTypPointer ) TypeRes = CBotTypNullPointer;
+ if ( TypeRes == CBotTypClass ) temp = CBotVar::Create( (CBotToken*)NULL, CBotTypResult(CBotTypIntrinsic, type1.GivClass() ) );
+ else temp = CBotVar::Create( (CBotToken*)NULL, TypeRes );
+
+ int err = 0;
+ // is a operation according to request
+ CBotVar* left = pStk1->GivVar();
+ CBotVar* right = pStk2->GivVar();
+
+ switch (GivTokenType())
+ {
+ case ID_ADD:
+ if ( !IsNan(left, right, &err) ) result->Add(left , right); // addition
+ break;
+ case ID_SUB:
+ if ( !IsNan(left, right, &err) ) result->Sub(left , right); // substraction
+ break;
+ case ID_MUL:
+ if ( !IsNan(left, right, &err) ) result->Mul(left , right); // multiplies
+ break;
+ case ID_POWER:
+ if ( !IsNan(left, right, &err) ) result->Power(left , right); // power
+ break;
+ case ID_DIV:
+ if ( !IsNan(left, right, &err) ) err = result->Div(left , right);// division
+ break;
+ case ID_MODULO:
+ if ( !IsNan(left, right, &err) ) err = result->Modulo(left , right);// remainder of division
+ break;
+ case ID_LO:
+ if ( !IsNan(left, right, &err) )
+ result->SetValInt(temp->Lo(left , right)); // lower
+ break;
+ case ID_HI:
+ if ( !IsNan(left, right, &err) )
+ result->SetValInt(temp->Hi(left , right)); // top
+ break;
+ case ID_LS:
+ if ( !IsNan(left, right, &err) )
+ result->SetValInt(temp->Ls(left , right)); // less than or equal
+ break;
+ case ID_HS:
+ if ( !IsNan(left, right, &err) )
+ result->SetValInt(temp->Hs(left , right)); // greater than or equal
+ break;
+ case ID_EQ:
+ if ( IsNan(left, right) )
+ result->SetValInt(left->GivInit() == right->GivInit()) ;
+ else
+ result->SetValInt(temp->Eq(left , right)); // equal
+ break;
+ case ID_NE:
+ if ( IsNan(left, right) )
+ result->SetValInt(left ->GivInit() != right->GivInit()) ;
+ else
+ result->SetValInt(temp->Ne(left , right)); // different
+ break;
+ case ID_TXT_AND:
+ case ID_LOG_AND:
+ case ID_AND:
+ if ( !IsNan(left, right, &err) ) result->And(left , right); // AND
+ break;
+ case ID_TXT_OR:
+ case ID_LOG_OR:
+ case ID_OR:
+ if ( !IsNan(left, right, &err) ) result->Or(left , right); // OR
+ break;
+ case ID_XOR:
+ if ( !IsNan(left, right, &err) ) result->XOr(left , right); // exclusive OR
+ break;
+ case ID_ASR:
+ if ( !IsNan(left, right, &err) ) result->ASR(left , right);
+ break;
+ case ID_SR:
+ if ( !IsNan(left, right, &err) ) result->SR(left , right);
+ break;
+ case ID_SL:
+ if ( !IsNan(left, right, &err) ) result->SL(left , right);
+ break;
+ default:
+ ASM_TRAP();
+ }
+ delete temp;
+
+ pStk2->SetVar(result); // puts the result on the stack
+ if ( err ) pStk2->SetError(err, &m_token); // and the possible error (division by zero)
+
+// pStk1->Return(pStk2); // releases the stack
+ return pStack->Return(pStk2); // transmits the result
}
void CBotTwoOpExpr::RestoreState(CBotStack* &pStack, bool bMain)
{
- if ( !bMain ) return;
- CBotStack* pStk1 = pStack->RestoreStack(this); // adds an item to the stack
- if ( pStk1 == NULL ) return;
-
- // according to recovery, it may be in one of two states
-
- if ( pStk1->GivState() == 0 ) // first state, evaluates the left operand
- {
- m_leftop->RestoreState(pStk1, bMain); // interrupted here!
- return;
- }
-
- CBotStack* pStk2 = pStk1->RestoreStack(); // adds an item to the stack
- if ( pStk2 == NULL ) return;
-
- // second state, evaluates the right operand
- if ( pStk2->GivState() == 0 )
- {
- m_rightop->RestoreState(pStk2, bMain); // interrupted here!
- return;
- }
+ if ( !bMain ) return;
+ CBotStack* pStk1 = pStack->RestoreStack(this); // adds an item to the stack
+ if ( pStk1 == NULL ) return;
+
+ // according to recovery, it may be in one of two states
+
+ if ( pStk1->GivState() == 0 ) // first state, evaluates the left operand
+ {
+ m_leftop->RestoreState(pStk1, bMain); // interrupted here!
+ return;
+ }
+
+ CBotStack* pStk2 = pStk1->RestoreStack(); // adds an item to the stack
+ if ( pStk2 == NULL ) return;
+
+ // second state, evaluates the right operand
+ if ( pStk2->GivState() == 0 )
+ {
+ m_rightop->RestoreState(pStk2, bMain); // interrupted here!
+ return;
+ }
}
bool CBotLogicExpr::Execute(CBotStack* &pStack)
{
- CBotStack* pStk1 = pStack->AddStack(this); // adds an item to the stack
- // or return in case of recovery
-// if ( pStk1 == EOX ) return true;
-
- if ( pStk1->GivState() == 0 )
- {
- if ( !m_condition->Execute(pStk1) ) return false;
- if (!pStk1->SetState(1)) return false;
- }
-
- if ( pStk1->GivVal() == true )
- {
- if ( !m_op1->Execute(pStk1) ) return false;
- }
- else
- {
- if ( !m_op2->Execute(pStk1) ) return false;
- }
-
- return pStack->Return(pStk1); // transmits the result
+ CBotStack* pStk1 = pStack->AddStack(this); // adds an item to the stack
+ // or return in case of recovery
+// if ( pStk1 == EOX ) return true;
+
+ if ( pStk1->GivState() == 0 )
+ {
+ if ( !m_condition->Execute(pStk1) ) return false;
+ if (!pStk1->SetState(1)) return false;
+ }
+
+ if ( pStk1->GivVal() == true )
+ {
+ if ( !m_op1->Execute(pStk1) ) return false;
+ }
+ else
+ {
+ if ( !m_op2->Execute(pStk1) ) return false;
+ }
+
+ return pStack->Return(pStk1); // transmits the result
}
void CBotLogicExpr::RestoreState(CBotStack* &pStack, bool bMain)
{
- if ( !bMain ) return;
-
- CBotStack* pStk1 = pStack->RestoreStack(this); // adds an item to the stack
- if ( pStk1 == NULL ) return;
-
- if ( pStk1->GivState() == 0 )
- {
- m_condition->RestoreState(pStk1, bMain);
- return;
- }
-
- if ( pStk1->GivVal() == true )
- {
- m_op1->RestoreState(pStk1, bMain);
- }
- else
- {
- m_op2->RestoreState(pStk1, bMain);
- }
+ if ( !bMain ) return;
+
+ CBotStack* pStk1 = pStack->RestoreStack(this); // adds an item to the stack
+ if ( pStk1 == NULL ) return;
+
+ if ( pStk1->GivState() == 0 )
+ {
+ m_condition->RestoreState(pStk1, bMain);
+ return;
+ }
+
+ if ( pStk1->GivVal() == true )
+ {
+ m_op1->RestoreState(pStk1, bMain);
+ }
+ else
+ {
+ m_op2->RestoreState(pStk1, bMain);
+ }
}
#if 0
void t()
{
- int x,y;
- 1>0 ? x = 0 : y = 0;
+ int x,y;
+ 1>0 ? x = 0 : y = 0;
}
#endif
#if 01
void t(bool t)
{
- int x;
- x = 1 + t ? 1 : 3 + 4 * 2 ;
- t ? 0 : "test";
+ int x;
+ x = 1 + t ? 1 : 3 + 4 * 2 ;
+ t ? 0 : "test";
}
#endif
diff --git a/src/CBot/CBotWhile.cpp b/src/CBot/CBotWhile.cpp
index 36923ae..51310a9 100644
--- a/src/CBot/CBotWhile.cpp
+++ b/src/CBot/CBotWhile.cpp
@@ -16,15 +16,15 @@
///////////////////////////////////////////////////////////////////////
// This file defined the following statements:
-// CBotWhile "while (condition) {instructions}"
-// CBotDo "do {instructions} while (condition)"
-// CBotFor "for (init, condition, incr) {instructions}"
-// CBotSwitch "switch (val) {instructions}"
-// CBotCase "case val:"
-// CBotBreak "break", "break label", "continu", "continu label"
-// CBotTry "try {instructions}"
-// CBotCatch "catch (condition) {instructions}" or "finally"
-// CBotThrow "throw execption"
+// CBotWhile "while (condition) {instructions}"
+// CBotDo "do {instructions} while (condition)"
+// CBotFor "for (init, condition, incr) {instructions}"
+// CBotSwitch "switch (val) {instructions}"
+// CBotCase "case val:"
+// CBotBreak "break", "break label", "continu", "continu label"
+// CBotTry "try {instructions}"
+// CBotCatch "catch (condition) {instructions}" or "finally"
+// CBotThrow "throw execption"
#include "CBot.h"
@@ -36,122 +36,122 @@
CBotWhile::CBotWhile()
{
- m_Condition =
- m_Block = NULL; // NULL so that delete is not possible further
- name = "CBotWhile"; // debug
+ m_Condition =
+ m_Block = NULL; // NULL so that delete is not possible further
+ name = "CBotWhile"; // debug
}
CBotWhile::~CBotWhile()
{
- delete m_Condition; // frees the condition
- delete m_Block; // releases the block instruction
+ delete m_Condition; // frees the condition
+ delete m_Block; // releases the block instruction
}
CBotInstr* CBotWhile::Compile(CBotToken* &p, CBotCStack* pStack)
{
- CBotWhile* inst = new CBotWhile(); // creates the object
- CBotToken* pp = p; // preserves at the ^ token (starting position)
+ CBotWhile* inst = new CBotWhile(); // creates the object
+ CBotToken* pp = p; // preserves at the ^ token (starting position)
- if ( IsOfType( p, TokenTypVar ) &&
- IsOfType( p, ID_DOTS ) )
- {
- inst->m_label = pp->GivString(); // records the name of the label
- }
+ if ( IsOfType( p, TokenTypVar ) &&
+ IsOfType( p, ID_DOTS ) )
+ {
+ inst->m_label = pp->GivString(); // records the name of the label
+ }
- inst->SetToken(p);
- if (!IsOfType(p, ID_WHILE)) return NULL; // should never happen
+ inst->SetToken(p);
+ if (!IsOfType(p, ID_WHILE)) return NULL; // should never happen
- CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
+ CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
// a bit of battery please (??)
- if ( NULL != (inst->m_Condition = CBotCondition::Compile( p, pStk )) )
- {
- // the condition exists
+ if ( NULL != (inst->m_Condition = CBotCondition::Compile( p, pStk )) )
+ {
+ // the condition exists
- IncLvl(inst->m_label);
- inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
- DecLvl();
+ IncLvl(inst->m_label);
+ inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
+ DecLvl();
- if ( pStk->IsOk() )
- {
- // the statement block is ok (it may be empty!
+ if ( pStk->IsOk() )
+ {
+ // the statement block is ok (it may be empty!
- return pStack->Return(inst, pStk); // return an object to the application
+ return pStack->Return(inst, pStk); // return an object to the application
// makes the object to which the application
- }
- }
+ }
+ }
- delete inst; // error, frees the place
- return pStack->Return(NULL, pStk); // no object, the error is on the stack
+ delete inst; // error, frees the place
+ return pStack->Return(NULL, pStk); // no object, the error is on the stack
}
// executes a "while" instruction
bool CBotWhile :: Execute(CBotStack* &pj)
{
- CBotStack* pile = pj->AddStack(this); // adds an item to the stack
- // or find in case of recovery
-// if ( pile == EOX ) return true;
+ CBotStack* pile = pj->AddStack(this); // adds an item to the stack
+ // or find in case of recovery
+// if ( pile == EOX ) return true;
- if ( pile->IfStep() ) return false;
+ if ( pile->IfStep() ) return false;
- while( true ) switch( pile->GivState() ) // executes the loop
- { // there are two possible states (depending on recovery)
- case 0:
- // evaluates the condition
- if ( !m_Condition->Execute(pile) ) return false; // interrupted here?
+ while( true ) switch( pile->GivState() ) // executes the loop
+ { // there are two possible states (depending on recovery)
+ case 0:
+ // evaluates the condition
+ if ( !m_Condition->Execute(pile) ) return false; // interrupted here?
- // the result of the condition is on the stack
+ // the result of the condition is on the stack
- // terminates if an error or if the condition is false
- if ( !pile->IsOk() || pile->GivVal() != true )
- {
- return pj->Return(pile); // sends the results and releases the stack
- }
+ // terminates if an error or if the condition is false
+ if ( !pile->IsOk() || pile->GivVal() != true )
+ {
+ return pj->Return(pile); // sends the results and releases the stack
+ }
- // the condition is true, pass in the second mode
+ // the condition is true, pass in the second mode
- if (!pile->SetState(1)) return false; // ready for further
+ if (!pile->SetState(1)) return false; // ready for further
- case 1:
- // evaluates the associated statement block
- if ( m_Block != NULL &&
- !m_Block->Execute(pile) )
- {
- if (pile->IfContinue(0, m_label)) continue; // if continued, will return to test
- return pj->BreakReturn(pile, m_label); // sends the results and releases the stack
- }
+ case 1:
+ // evaluates the associated statement block
+ if ( m_Block != NULL &&
+ !m_Block->Execute(pile) )
+ {
+ if (pile->IfContinue(0, m_label)) continue; // if continued, will return to test
+ return pj->BreakReturn(pile, m_label); // sends the results and releases the stack
+ }
- // terminates if there is an error
- if ( !pile->IsOk() )
- {
- return pj->Return(pile); // sends the results and releases the stack
- }
-
- // returns to the test again
- if (!pile->SetState(0, 0)) return false;
- continue;
- }
+ // terminates if there is an error
+ if ( !pile->IsOk() )
+ {
+ return pj->Return(pile); // sends the results and releases the stack
+ }
+
+ // returns to the test again
+ if (!pile->SetState(0, 0)) return false;
+ continue;
+ }
}
void CBotWhile :: RestoreState(CBotStack* &pj, bool bMain)
{
- if ( !bMain ) return;
- CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack
- if ( pile == NULL ) return;
-
- switch( pile->GivState() )
- { // there are two possible states (depending on recovery)
- case 0:
- // evaluates the condition
- m_Condition->RestoreState(pile, bMain);
- return;
+ if ( !bMain ) return;
+ CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack
+ if ( pile == NULL ) return;
+
+ switch( pile->GivState() )
+ { // there are two possible states (depending on recovery)
+ case 0:
+ // evaluates the condition
+ m_Condition->RestoreState(pile, bMain);
+ return;
- case 1:
- // evaluates the associated statement block
- if ( m_Block != NULL ) m_Block->RestoreState(pile, bMain);
- return;
- }
+ case 1:
+ // evaluates the associated statement block
+ if ( m_Block != NULL ) m_Block->RestoreState(pile, bMain);
+ return;
+ }
}
@@ -162,140 +162,140 @@ void CBotWhile :: RestoreState(CBotStack* &pj, bool bMain)
CBotRepeat::CBotRepeat()
{
- m_NbIter =
- m_Block = NULL; // NULL so that delete is not possible further
- name = "CBotRepeat"; // debug
+ m_NbIter =
+ m_Block = NULL; // NULL so that delete is not possible further
+ name = "CBotRepeat"; // debug
}
CBotRepeat::~CBotRepeat()
{
- delete m_NbIter; // frees the condition
- delete m_Block; // frees the instruction block
+ delete m_NbIter; // frees the condition
+ delete m_Block; // frees the instruction block
}
CBotInstr* CBotRepeat::Compile(CBotToken* &p, CBotCStack* pStack)
{
- CBotRepeat* inst = new CBotRepeat(); // creates the object
- CBotToken* pp = p; // preserves at the ^ token (starting position)
-
- if ( IsOfType( p, TokenTypVar ) &&
- IsOfType( p, ID_DOTS ) )
- {
- inst->m_label = pp->GivString(); // register the name of label
- }
-
- inst->SetToken(p);
- if (!IsOfType(p, ID_REPEAT)) return NULL; // should never happen
-
- CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
-
- if ( IsOfType(p, ID_OPENPAR ) )
- {
- CBotToken* ppp = p; // preserves the ^ token (starting position)
- if ( NULL != (inst->m_NbIter = CBotExpression::Compile( p, pStk )) )
- {
- if ( pStk->GivType() < CBotTypLong )
- {
- if ( IsOfType(p, ID_CLOSEPAR ) )
- {
-
- IncLvl(inst->m_label);
- inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
- DecLvl();
-
- if ( pStk->IsOk() )
- {
- // the statement block is ok (it may be empty!
-
- return pStack->Return(inst, pStk); // return an object to the application
- }
- }
- pStack->SetError(TX_CLOSEPAR, p->GivStart());
- }
- pStk->SetStartError(ppp->GivStart());
- pStk->SetError( TX_BADTYPE, p->GivStart() );
- }
- pStack->SetError(TX_ENDOF, p);
- }
- pStack->SetError(TX_OPENPAR, p->GivStart()); // missing parenthesis
-
- delete inst; // error, frees up
- return pStack->Return(NULL, pStk); // no object, the error is on the stack
+ CBotRepeat* inst = new CBotRepeat(); // creates the object
+ CBotToken* pp = p; // preserves at the ^ token (starting position)
+
+ if ( IsOfType( p, TokenTypVar ) &&
+ IsOfType( p, ID_DOTS ) )
+ {
+ inst->m_label = pp->GivString(); // register the name of label
+ }
+
+ inst->SetToken(p);
+ if (!IsOfType(p, ID_REPEAT)) return NULL; // should never happen
+
+ CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
+
+ if ( IsOfType(p, ID_OPENPAR ) )
+ {
+ CBotToken* ppp = p; // preserves the ^ token (starting position)
+ if ( NULL != (inst->m_NbIter = CBotExpression::Compile( p, pStk )) )
+ {
+ if ( pStk->GivType() < CBotTypLong )
+ {
+ if ( IsOfType(p, ID_CLOSEPAR ) )
+ {
+
+ IncLvl(inst->m_label);
+ inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
+ DecLvl();
+
+ if ( pStk->IsOk() )
+ {
+ // the statement block is ok (it may be empty!
+
+ return pStack->Return(inst, pStk); // return an object to the application
+ }
+ }
+ pStack->SetError(TX_CLOSEPAR, p->GivStart());
+ }
+ pStk->SetStartError(ppp->GivStart());
+ pStk->SetError( TX_BADTYPE, p->GivStart() );
+ }
+ pStack->SetError(TX_ENDOF, p);
+ }
+ pStack->SetError(TX_OPENPAR, p->GivStart()); // missing parenthesis
+
+ delete inst; // error, frees up
+ return pStack->Return(NULL, pStk); // no object, the error is on the stack
}
// execution of intruction "repeat"
bool CBotRepeat :: Execute(CBotStack* &pj)
{
- CBotStack* pile = pj->AddStack(this); // adds an item to the stack
- // or find in case of recovery
-// if ( pile == EOX ) return true;
+ CBotStack* pile = pj->AddStack(this); // adds an item to the stack
+ // or find in case of recovery
+// if ( pile == EOX ) return true;
- if ( pile->IfStep() ) return false;
+ if ( pile->IfStep() ) return false;
- while( true ) switch( pile->GivState() ) // executes the loop
- { // there are two possible states (depending on recovery)
- case 0:
- // evaluates the number of iterations
- if ( !m_NbIter->Execute(pile) ) return false; // interrupted here ?
+ while( true ) switch( pile->GivState() ) // executes the loop
+ { // there are two possible states (depending on recovery)
+ case 0:
+ // evaluates the number of iterations
+ if ( !m_NbIter->Execute(pile) ) return false; // interrupted here ?
- // the result of the condition is on the stack
+ // the result of the condition is on the stack
- // terminates if an error or if the condition is false
- int n;
- if ( !pile->IsOk() || ( n = pile->GivVal() ) < 1 )
- {
- return pj->Return(pile); // sends the results and releases the stack
- }
+ // terminates if an error or if the condition is false
+ int n;
+ if ( !pile->IsOk() || ( n = pile->GivVal() ) < 1 )
+ {
+ return pj->Return(pile); // sends the results and releases the stack
+ }
- // puts the number of iterations +1 to the "state"
+ // puts the number of iterations +1 to the "state"
- if (!pile->SetState(n+1)) return false; // ready for further
- continue; // continue as a result
+ if (!pile->SetState(n+1)) return false; // ready for further
+ continue; // continue as a result
- case 1:
- // normal end of the loop
- return pj->Return(pile); // sends the results and releases the stack
+ case 1:
+ // normal end of the loop
+ return pj->Return(pile); // sends the results and releases the stack
- default:
- // evaluates the associated statement block
- if ( m_Block != NULL &&
- !m_Block->Execute(pile) )
- {
- if (pile->IfContinue(pile->GivState()-1, m_label)) continue; // if continued, will return to test
- return pj->BreakReturn(pile, m_label); // sends the results and releases the stack
- }
+ default:
+ // evaluates the associated statement block
+ if ( m_Block != NULL &&
+ !m_Block->Execute(pile) )
+ {
+ if (pile->IfContinue(pile->GivState()-1, m_label)) continue; // if continued, will return to test
+ return pj->BreakReturn(pile, m_label); // sends the results and releases the stack
+ }
- // terminates if there is an error
- if ( !pile->IsOk() )
- {
- return pj->Return(pile); // sends the results and releases the stack
- }
-
- // returns to the test again
- if (!pile->SetState(pile->GivState()-1, 0)) return false;
- continue;
- }
+ // terminates if there is an error
+ if ( !pile->IsOk() )
+ {
+ return pj->Return(pile); // sends the results and releases the stack
+ }
+
+ // returns to the test again
+ if (!pile->SetState(pile->GivState()-1, 0)) return false;
+ continue;
+ }
}
void CBotRepeat :: RestoreState(CBotStack* &pj, bool bMain)
{
- if ( !bMain ) return;
- CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack
- if ( pile == NULL ) return;
-
- switch( pile->GivState() )
- { // there are two possible states (depending on recovery)
- case 0:
- // evaluates the condition
- m_NbIter->RestoreState(pile, bMain);
- return;
+ if ( !bMain ) return;
+ CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack
+ if ( pile == NULL ) return;
+
+ switch( pile->GivState() )
+ { // there are two possible states (depending on recovery)
+ case 0:
+ // evaluates the condition
+ m_NbIter->RestoreState(pile, bMain);
+ return;
- case 1:
- // evaluates the associated statement block
- if ( m_Block != NULL ) m_Block->RestoreState(pile, bMain);
- return;
- }
+ case 1:
+ // evaluates the associated statement block
+ if ( m_Block != NULL ) m_Block->RestoreState(pile, bMain);
+ return;
+ }
}
///////////////////////////////////////////////////////////////////////////
@@ -305,127 +305,127 @@ void CBotRepeat :: RestoreState(CBotStack* &pj, bool bMain)
CBotDo::CBotDo()
{
- m_Condition =
- m_Block = NULL; // NULL so that delete is not possible further
- name = "CBotDo"; // debug
+ m_Condition =
+ m_Block = NULL; // NULL so that delete is not possible further
+ name = "CBotDo"; // debug
}
CBotDo::~CBotDo()
{
- delete m_Condition; // frees the condition
- delete m_Block; // frees the instruction block
+ delete m_Condition; // frees the condition
+ delete m_Block; // frees the instruction block
}
CBotInstr* CBotDo::Compile(CBotToken* &p, CBotCStack* pStack)
{
- CBotDo* inst = new CBotDo(); // creates the object
-
- CBotToken* pp = p; // preserves at the ^ token (starting position)
-
- if ( IsOfType( p, TokenTypVar ) &&
- IsOfType( p, ID_DOTS ) )
- {
- inst->m_label = pp->GivString(); // register the name of label
- }
-
- inst->SetToken(p);
- if (!IsOfType(p, ID_DO)) return NULL; // should never happen
-
- CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
-
-
- // looking for a statement block after the do
- IncLvl(inst->m_label);
- inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
- DecLvl();
-
- if ( pStk->IsOk() )
- {
- if (IsOfType(p, ID_WHILE))
- {
- if ( NULL != (inst->m_Condition = CBotCondition::Compile( p, pStk )) )
- {
- // the condition exists
- if (IsOfType(p, ID_SEP))
- {
- return pStack->Return(inst, pStk); // return an object to the application
- }
- pStk->SetError(TX_ENDOF, p->GivStart());
- }
- }
- pStk->SetError(TX_WHILE, p->GivStart());
- }
-
- delete inst; // error, frees up
- return pStack->Return(NULL, pStk); // no object, the error is on the stack
+ CBotDo* inst = new CBotDo(); // creates the object
+
+ CBotToken* pp = p; // preserves at the ^ token (starting position)
+
+ if ( IsOfType( p, TokenTypVar ) &&
+ IsOfType( p, ID_DOTS ) )
+ {
+ inst->m_label = pp->GivString(); // register the name of label
+ }
+
+ inst->SetToken(p);
+ if (!IsOfType(p, ID_DO)) return NULL; // should never happen
+
+ CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
+
+
+ // looking for a statement block after the do
+ IncLvl(inst->m_label);
+ inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
+ DecLvl();
+
+ if ( pStk->IsOk() )
+ {
+ if (IsOfType(p, ID_WHILE))
+ {
+ if ( NULL != (inst->m_Condition = CBotCondition::Compile( p, pStk )) )
+ {
+ // the condition exists
+ if (IsOfType(p, ID_SEP))
+ {
+ return pStack->Return(inst, pStk); // return an object to the application
+ }
+ pStk->SetError(TX_ENDOF, p->GivStart());
+ }
+ }
+ pStk->SetError(TX_WHILE, p->GivStart());
+ }
+
+ delete inst; // error, frees up
+ return pStack->Return(NULL, pStk); // no object, the error is on the stack
}
// executes instruction "do"
bool CBotDo :: Execute(CBotStack* &pj)
{
- CBotStack* pile = pj->AddStack(this); // adds an item to the stack
- // or find in case of recovery
-// if ( pile == EOX ) return true;
-
- if ( pile->IfStep() ) return false;
-
- while( true ) switch( pile->GivState() ) // executes the loop
- { // there are two possible states (depending on recovery)
- case 0:
- // evaluates the associated statement block
- if ( m_Block != NULL &&
- !m_Block->Execute(pile) )
- {
- if (pile->IfContinue(1, m_label)) continue; // if continued, will return to test
- return pj->BreakReturn(pile, m_label); // sends the results and releases the stack
- }
+ CBotStack* pile = pj->AddStack(this); // adds an item to the stack
+ // or find in case of recovery
+// if ( pile == EOX ) return true;
+
+ if ( pile->IfStep() ) return false;
+
+ while( true ) switch( pile->GivState() ) // executes the loop
+ { // there are two possible states (depending on recovery)
+ case 0:
+ // evaluates the associated statement block
+ if ( m_Block != NULL &&
+ !m_Block->Execute(pile) )
+ {
+ if (pile->IfContinue(1, m_label)) continue; // if continued, will return to test
+ return pj->BreakReturn(pile, m_label); // sends the results and releases the stack
+ }
- // terminates if there is an error
- if ( !pile->IsOk() )
- {
- return pj->Return(pile); // sends the results and releases the stack
- }
+ // terminates if there is an error
+ if ( !pile->IsOk() )
+ {
+ return pj->Return(pile); // sends the results and releases the stack
+ }
- if (!pile->SetState(1)) return false; // ready for further
+ if (!pile->SetState(1)) return false; // ready for further
- case 1:
- // evaluates the condition
- if ( !m_Condition->Execute(pile) ) return false; // interrupted here ?
-
- // the result of the condition is on the stack
-
- // terminates if an error or if the condition is false
- if ( !pile->IsOk() || pile->GivVal() != true )
- {
- return pj->Return(pile); // sends the results and releases the stack
- }
-
- // returns to instruction block to start
- if (!pile->SetState(0, 0)) return false;
- continue;
- }
+ case 1:
+ // evaluates the condition
+ if ( !m_Condition->Execute(pile) ) return false; // interrupted here ?
+
+ // the result of the condition is on the stack
+
+ // terminates if an error or if the condition is false
+ if ( !pile->IsOk() || pile->GivVal() != true )
+ {
+ return pj->Return(pile); // sends the results and releases the stack
+ }
+
+ // returns to instruction block to start
+ if (!pile->SetState(0, 0)) return false;
+ continue;
+ }
}
void CBotDo :: RestoreState(CBotStack* &pj, bool bMain)
{
- if ( !bMain ) return;
-
- CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack
- if ( pile == NULL ) return;
-
- switch( pile->GivState() )
- { // there are two possible states (depending on recovery)
- case 0:
- // restores the assosiated statement's block
- if ( m_Block != NULL ) m_Block->RestoreState(pile, bMain);
- return;
-
- case 1:
- // restores the condition
- m_Condition->RestoreState(pile, bMain);
- return;
- }
+ if ( !bMain ) return;
+
+ CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack
+ if ( pile == NULL ) return;
+
+ switch( pile->GivState() )
+ { // there are two possible states (depending on recovery)
+ case 0:
+ // restores the assosiated statement's block
+ if ( m_Block != NULL ) m_Block->RestoreState(pile, bMain);
+ return;
+
+ case 1:
+ // restores the condition
+ m_Condition->RestoreState(pile, bMain);
+ return;
+ }
}
@@ -436,181 +436,181 @@ void CBotDo :: RestoreState(CBotStack* &pj, bool bMain)
CBotFor::CBotFor()
{
- m_Init =
- m_Test =
- m_Incr =
- m_Block = NULL; // NULL so that delete is not possible further
- name = "CBotFor"; // debug
+ m_Init =
+ m_Test =
+ m_Incr =
+ m_Block = NULL; // NULL so that delete is not possible further
+ name = "CBotFor"; // debug
}
CBotFor::~CBotFor()
{
- delete m_Init;
- delete m_Test;
- delete m_Incr;
- delete m_Block; // frees the instruction block
+ delete m_Init;
+ delete m_Test;
+ delete m_Incr;
+ delete m_Block; // frees the instruction block
}
CBotInstr* CBotFor::Compile(CBotToken* &p, CBotCStack* pStack)
{
- CBotFor* inst = new CBotFor(); // creates the object
- CBotToken* pp = p; // preserves at the ^ token (starting position)
-
- if ( IsOfType( p, TokenTypVar ) &&
- IsOfType( p, ID_DOTS ) )
- {
- inst->m_label = pp->GivString(); // register the name of label
- }
-
- inst->SetToken(p);
- if (!IsOfType(p, ID_FOR)) return NULL; // should never happen
-
- if ( !IsOfType(p, ID_OPENPAR)) // missing parenthesis ?
- {
- pStack->SetError(TX_OPENPAR, p->GivStart());
- return NULL;
- }
-
- CBotCStack* pStk = pStack->TokenStack(pp, true); // un petit bout de pile svp
-
- // compiles instructions for initialization
- inst->m_Init = CBotListExpression::Compile( p, pStk );
- if ( pStk->IsOk() )
- {
- if ( !IsOfType(p, ID_SEP)) // lack the semicolon?
- {
- pStack->SetError(TX_OPENPAR, p->GivStart());
- delete inst;
- return pStack->Return(NULL, pStk); // no object, the error is on the stack
- }
- inst->m_Test = CBotBoolExpr::Compile( p, pStk );
- if ( pStk->IsOk() )
- {
- if ( !IsOfType(p, ID_SEP)) // lack the semicolon?
- {
- pStack->SetError(TX_OPENPAR, p->GivStart());
- delete inst;
- return pStack->Return(NULL, pStk); // no object, the error is on the stack
- }
- inst->m_Incr = CBotListExpression::Compile( p, pStk );
- if ( pStk->IsOk() )
- {
- if ( IsOfType(p, ID_CLOSEPAR)) // missing parenthesis ?
- {
- IncLvl(inst->m_label);
- inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
- DecLvl();
- if ( pStk->IsOk() )
- return pStack->Return(inst, pStk);;
- }
- pStack->SetError(TX_CLOSEPAR, p->GivStart());
- }
- }
- }
-
- delete inst; // error, frees up
- return pStack->Return(NULL, pStk); // no object, the error is on the stack
+ CBotFor* inst = new CBotFor(); // creates the object
+ CBotToken* pp = p; // preserves at the ^ token (starting position)
+
+ if ( IsOfType( p, TokenTypVar ) &&
+ IsOfType( p, ID_DOTS ) )
+ {
+ inst->m_label = pp->GivString(); // register the name of label
+ }
+
+ inst->SetToken(p);
+ if (!IsOfType(p, ID_FOR)) return NULL; // should never happen
+
+ if ( !IsOfType(p, ID_OPENPAR)) // missing parenthesis ?
+ {
+ pStack->SetError(TX_OPENPAR, p->GivStart());
+ return NULL;
+ }
+
+ CBotCStack* pStk = pStack->TokenStack(pp, true); // un petit bout de pile svp
+
+ // compiles instructions for initialization
+ inst->m_Init = CBotListExpression::Compile( p, pStk );
+ if ( pStk->IsOk() )
+ {
+ if ( !IsOfType(p, ID_SEP)) // lack the semicolon?
+ {
+ pStack->SetError(TX_OPENPAR, p->GivStart());
+ delete inst;
+ return pStack->Return(NULL, pStk); // no object, the error is on the stack
+ }
+ inst->m_Test = CBotBoolExpr::Compile( p, pStk );
+ if ( pStk->IsOk() )
+ {
+ if ( !IsOfType(p, ID_SEP)) // lack the semicolon?
+ {
+ pStack->SetError(TX_OPENPAR, p->GivStart());
+ delete inst;
+ return pStack->Return(NULL, pStk); // no object, the error is on the stack
+ }
+ inst->m_Incr = CBotListExpression::Compile( p, pStk );
+ if ( pStk->IsOk() )
+ {
+ if ( IsOfType(p, ID_CLOSEPAR)) // missing parenthesis ?
+ {
+ IncLvl(inst->m_label);
+ inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
+ DecLvl();
+ if ( pStk->IsOk() )
+ return pStack->Return(inst, pStk);;
+ }
+ pStack->SetError(TX_CLOSEPAR, p->GivStart());
+ }
+ }
+ }
+
+ delete inst; // error, frees up
+ return pStack->Return(NULL, pStk); // no object, the error is on the stack
}
// execution of instruction "for"
bool CBotFor :: Execute(CBotStack* &pj)
{
- CBotStack* pile = pj->AddStack(this, true); // adds an item to the stack (variables locales)
- // or find in case of recovery
-// if ( pile == EOX ) return true;
-
- if ( pile->IfStep() ) return false;
-
- while( true ) switch( pile->GivState() ) // executes the loop
- { // there are four possible states (depending on recovery)
- case 0:
- // initialize
- if ( m_Init != NULL &&
- !m_Init->Execute(pile) ) return false; // interrupted here ?
- if (!pile->SetState(1)) return false; // ready for further
+ CBotStack* pile = pj->AddStack(this, true); // adds an item to the stack (variables locales)
+ // or find in case of recovery
+// if ( pile == EOX ) return true;
+
+ if ( pile->IfStep() ) return false;
+
+ while( true ) switch( pile->GivState() ) // executes the loop
+ { // there are four possible states (depending on recovery)
+ case 0:
+ // initialize
+ if ( m_Init != NULL &&
+ !m_Init->Execute(pile) ) return false; // interrupted here ?
+ if (!pile->SetState(1)) return false; // ready for further
- case 1:
- // evaluates the condition
- if ( m_Test != NULL ) // no strings attached? -> True!
- {
- if (!m_Test->Execute(pile) ) return false; // interrupted here ?
-
- // the result of the condition is on the stack
-
- // terminates if an error or if the condition is false
- if ( !pile->IsOk() || pile->GivVal() != true )
- {
- return pj->Return(pile); // sends the results and releases the stack
- }
- }
-
- // la condition est vrai, passe à la suite
- if (!pile->SetState(2)) return false; // ready for further
-
- case 2:
- // evaluates the associated statement block
- if ( m_Block != NULL &&
- !m_Block->Execute(pile) )
- {
- if (pile->IfContinue(3, m_label)) continue; // if continued, going on to incrementation
- return pj->BreakReturn(pile, m_label); // sends the results and releases the stack
- }
-
- // terminates if there is an error
- if ( !pile->IsOk() )
- {
- return pj->Return(pile); // sends the results and releases the stack
- }
-
- if (!pile->SetState(3)) return false; // ready for further
-
- case 3:
- // evalutate the incrementation
- if ( m_Incr != NULL &&
- !m_Incr->Execute(pile) ) return false; // interrupted here ?
-
- // returns to the test again
- if (!pile->SetState(1, 0)) return false; // returns to the test
- continue;
- }
+ case 1:
+ // evaluates the condition
+ if ( m_Test != NULL ) // no strings attached? -> True!
+ {
+ if (!m_Test->Execute(pile) ) return false; // interrupted here ?
+
+ // the result of the condition is on the stack
+
+ // terminates if an error or if the condition is false
+ if ( !pile->IsOk() || pile->GivVal() != true )
+ {
+ return pj->Return(pile); // sends the results and releases the stack
+ }
+ }
+
+ // la condition est vrai, passe à la suite
+ if (!pile->SetState(2)) return false; // ready for further
+
+ case 2:
+ // evaluates the associated statement block
+ if ( m_Block != NULL &&
+ !m_Block->Execute(pile) )
+ {
+ if (pile->IfContinue(3, m_label)) continue; // if continued, going on to incrementation
+ return pj->BreakReturn(pile, m_label); // sends the results and releases the stack
+ }
+
+ // terminates if there is an error
+ if ( !pile->IsOk() )
+ {
+ return pj->Return(pile); // sends the results and releases the stack
+ }
+
+ if (!pile->SetState(3)) return false; // ready for further
+
+ case 3:
+ // evalutate the incrementation
+ if ( m_Incr != NULL &&
+ !m_Incr->Execute(pile) ) return false; // interrupted here ?
+
+ // returns to the test again
+ if (!pile->SetState(1, 0)) return false; // returns to the test
+ continue;
+ }
}
void CBotFor :: RestoreState(CBotStack* &pj, bool bMain)
{
- if ( !bMain ) return;
-
- CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack (variables locales)
- if ( pile == NULL ) return;
-
- switch( pile->GivState() )
- { // there are four possible states (depending on recovery)
- case 0:
- // initialize
- if ( m_Init != NULL ) m_Init->RestoreState(pile, true); // interrupted here !
- return;
-
- case 1:
- if ( m_Init != NULL ) m_Init->RestoreState(pile, false); // variables definitions
-
- // evaluates the condition
- if ( m_Test != NULL ) m_Test->RestoreState(pile, true); // interrupted here !
- return;
-
- case 2:
- if ( m_Init != NULL ) m_Init->RestoreState(pile, false); // variable definitions
-
- // evaluates the associated statement block
- if ( m_Block != NULL ) m_Block->RestoreState(pile, true);
- return;
-
- case 3:
- if ( m_Init != NULL ) m_Init->RestoreState(pile, false); // variable definitions
-
- // evaluate the incrementation
- if ( m_Incr != NULL ) m_Incr->RestoreState(pile, true); // interrupted here !
- return;
- }
+ if ( !bMain ) return;
+
+ CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack (variables locales)
+ if ( pile == NULL ) return;
+
+ switch( pile->GivState() )
+ { // there are four possible states (depending on recovery)
+ case 0:
+ // initialize
+ if ( m_Init != NULL ) m_Init->RestoreState(pile, true); // interrupted here !
+ return;
+
+ case 1:
+ if ( m_Init != NULL ) m_Init->RestoreState(pile, false); // variables definitions
+
+ // evaluates the condition
+ if ( m_Test != NULL ) m_Test->RestoreState(pile, true); // interrupted here !
+ return;
+
+ case 2:
+ if ( m_Init != NULL ) m_Init->RestoreState(pile, false); // variable definitions
+
+ // evaluates the associated statement block
+ if ( m_Block != NULL ) m_Block->RestoreState(pile, true);
+ return;
+
+ case 3:
+ if ( m_Init != NULL ) m_Init->RestoreState(pile, false); // variable definitions
+
+ // evaluate the incrementation
+ if ( m_Incr != NULL ) m_Incr->RestoreState(pile, true); // interrupted here !
+ return;
+ }
}
//////////////////////////////////////////////////////////////////////////////////////
@@ -620,92 +620,92 @@ void CBotFor :: RestoreState(CBotStack* &pj, bool bMain)
CBotListExpression::CBotListExpression()
{
- m_Expr = NULL;
- name = "CBotListExpression";
+ m_Expr = NULL;
+ name = "CBotListExpression";
}
CBotListExpression::~CBotListExpression()
{
- delete m_Expr;
+ delete m_Expr;
}
// seeks a declaration of variable or expression
static CBotInstr* CompileInstrOrDefVar(CBotToken* &p, CBotCStack* pStack)
{
- CBotInstr* i = CBotInt::Compile( p, pStack, false, true ); // Is this a declaration of an integer?
- if ( i== NULL ) i = CBotFloat::Compile( p, pStack, false, true ); // or a real number?
- if ( i== NULL ) i = CBotBoolean::Compile( p, pStack, false, true ); // or a boolean?
- if ( i== NULL ) i = CBotIString::Compile( p, pStack, false, true ); // ar a string?
- if ( i== NULL ) i = CBotExpression::Compile( p, pStack ); // compiles an expression
- return i;
+ CBotInstr* i = CBotInt::Compile( p, pStack, false, true ); // Is this a declaration of an integer?
+ if ( i== NULL ) i = CBotFloat::Compile( p, pStack, false, true ); // or a real number?
+ if ( i== NULL ) i = CBotBoolean::Compile( p, pStack, false, true ); // or a boolean?
+ if ( i== NULL ) i = CBotIString::Compile( p, pStack, false, true ); // ar a string?
+ if ( i== NULL ) i = CBotExpression::Compile( p, pStack ); // compiles an expression
+ return i;
}
CBotInstr* CBotListExpression::Compile(CBotToken* &p, CBotCStack* pStack)
{
- CBotListExpression* inst = new CBotListExpression();
-
- inst->m_Expr = CompileInstrOrDefVar( p, pStack ); // compile the first expression in a list
- if (pStack->IsOk())
- {
- while ( IsOfType(p, ID_COMMA) ) // more instructions?
- {
- CBotInstr* i = CompileInstrOrDefVar( p, pStack ); // Is this a declaration of an integer?
- inst->m_Expr->AddNext(i); // added after
- if ( !pStack->IsOk() )
- {
- delete inst;
- return NULL; // no object, the error is on the stack
- }
- }
- return inst;
- }
- delete inst;
- return NULL;
+ CBotListExpression* inst = new CBotListExpression();
+
+ inst->m_Expr = CompileInstrOrDefVar( p, pStack ); // compile the first expression in a list
+ if (pStack->IsOk())
+ {
+ while ( IsOfType(p, ID_COMMA) ) // more instructions?
+ {
+ CBotInstr* i = CompileInstrOrDefVar( p, pStack ); // Is this a declaration of an integer?
+ inst->m_Expr->AddNext(i); // added after
+ if ( !pStack->IsOk() )
+ {
+ delete inst;
+ return NULL; // no object, the error is on the stack
+ }
+ }
+ return inst;
+ }
+ delete inst;
+ return NULL;
}
bool CBotListExpression::Execute(CBotStack* &pj)
{
- CBotStack* pile = pj->AddStack(); // essential
- CBotInstr* p = m_Expr; // the first expression
-
- int state = pile->GivState();
- while (state-->0) p = p->GivNext(); // returns to the interrupted operation
-
- if ( p != NULL ) while (true)
- {
- if ( !p->Execute(pile) ) return false;
- p = p->GivNext();
- if ( p == NULL ) break;
- if (!pile->IncState()) return false; // ready for next
- }
- return pj->Return(pile);
+ CBotStack* pile = pj->AddStack(); // essential
+ CBotInstr* p = m_Expr; // the first expression
+
+ int state = pile->GivState();
+ while (state-->0) p = p->GivNext(); // returns to the interrupted operation
+
+ if ( p != NULL ) while (true)
+ {
+ if ( !p->Execute(pile) ) return false;
+ p = p->GivNext();
+ if ( p == NULL ) break;
+ if (!pile->IncState()) return false; // ready for next
+ }
+ return pj->Return(pile);
}
void CBotListExpression::RestoreState(CBotStack* &pj, bool bMain)
{
- CBotStack* pile = pj;
- int state = 0x7000;
-
- if ( bMain )
- {
- pile = pj->RestoreStack();
- if ( pile == NULL ) return;
- state = pile->GivState();
- }
-
- CBotInstr* p = m_Expr; // the first expression
-
- while (p != NULL && state-->0)
- {
- p->RestoreState(pile, false);
- p = p->GivNext(); // returns to the interrupted operation
- }
-
- if ( p != NULL )
- {
- p->RestoreState(pile, bMain);
- }
+ CBotStack* pile = pj;
+ int state = 0x7000;
+
+ if ( bMain )
+ {
+ pile = pj->RestoreStack();
+ if ( pile == NULL ) return;
+ state = pile->GivState();
+ }
+
+ CBotInstr* p = m_Expr; // the first expression
+
+ while (p != NULL && state-->0)
+ {
+ p->RestoreState(pile, false);
+ p = p->GivNext(); // returns to the interrupted operation
+ }
+
+ if ( p != NULL )
+ {
+ p->RestoreState(pile, bMain);
+ }
}
///////////////////////////////////////////////////////////////////////////
@@ -715,186 +715,186 @@ void CBotListExpression::RestoreState(CBotStack* &pj, bool bMain)
CBotSwitch::CBotSwitch()
{
- m_Value =
- m_Block = NULL; // NULL so that delete is not possible further
- name = "CBotSwitch"; // debug
+ m_Value =
+ m_Block = NULL; // NULL so that delete is not possible further
+ name = "CBotSwitch"; // debug
}
CBotSwitch::~CBotSwitch()
{
- delete m_Value; // frees the value
- delete m_Block; // frees the instruction block
+ delete m_Value; // frees the value
+ delete m_Block; // frees the instruction block
}
CBotInstr* CBotSwitch::Compile(CBotToken* &p, CBotCStack* pStack)
{
- CBotSwitch* inst = new CBotSwitch(); // creates the object
- CBotToken* pp = p; // preserves at the ^ token (starting position)
-
- inst->SetToken(p);
- if (!IsOfType(p, ID_SWITCH)) return NULL; // should never happen
-
- CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
-
- if ( IsOfType(p, ID_OPENPAR ) )
- {
- if ( NULL != (inst->m_Value = CBotExpression::Compile( p, pStk )) )
- {
- if ( pStk->GivType() < CBotTypLong )
- {
- if ( IsOfType(p, ID_CLOSEPAR ) )
- {
- if ( IsOfType(p, ID_OPBLK ) )
- {
- IncLvl();
-
- while( !IsOfType( p, ID_CLBLK ) )
- {
- if ( p->GivType() == ID_CASE || p->GivType() == ID_DEFAULT)
- {
- CBotCStack* pStk2 = pStk->TokenStack(p); // un petit bout de pile svp
-
- CBotInstr* i = CBotCase::Compile( p, pStk2 );
- if (i == NULL)
- {
- delete inst;
- return pStack->Return(NULL, pStk2);
- }
- delete pStk2;
- if ( inst->m_Block == NULL ) inst->m_Block = i;
- else inst->m_Block->AddNext(i);
- continue;
- }
-
- if ( inst->m_Block == NULL )
- {
- pStk->SetError(TX_NOCASE, p->GivStart());
- delete inst;
- return pStack->Return(NULL, pStk);
- }
-
- CBotInstr* i = CBotBlock::CompileBlkOrInst( p, pStk, true );
- if ( !pStk->IsOk() )
- {
- delete inst;
- return pStack->Return(NULL, pStk);
- }
- inst->m_Block->AddNext(i);
-
- if ( p == NULL )
- {
- pStk->SetError(TX_CLOSEBLK, -1);
- delete inst;
- return pStack->Return(NULL, pStk);
- }
- }
- DecLvl();
-
- if ( inst->m_Block == NULL )
- {
- pStk->SetError(TX_NOCASE, p->GivStart());
- delete inst;
- return pStack->Return(NULL, pStk);
- }
- // the statement block is ok
- return pStack->Return(inst, pStk); // return an object to the application
- }
- pStk->SetError( TX_OPENBLK, p->GivStart() );
- }
- pStk->SetError( TX_CLOSEPAR, p->GivStart() );
- }
- pStk->SetError( TX_BADTYPE, p->GivStart() );
- }
- }
- pStk->SetError( TX_OPENPAR, p->GivStart());
-
- delete inst; // error, frees up
- return pStack->Return(NULL, pStk); // no object, the error is on the stack
+ CBotSwitch* inst = new CBotSwitch(); // creates the object
+ CBotToken* pp = p; // preserves at the ^ token (starting position)
+
+ inst->SetToken(p);
+ if (!IsOfType(p, ID_SWITCH)) return NULL; // should never happen
+
+ CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
+
+ if ( IsOfType(p, ID_OPENPAR ) )
+ {
+ if ( NULL != (inst->m_Value = CBotExpression::Compile( p, pStk )) )
+ {
+ if ( pStk->GivType() < CBotTypLong )
+ {
+ if ( IsOfType(p, ID_CLOSEPAR ) )
+ {
+ if ( IsOfType(p, ID_OPBLK ) )
+ {
+ IncLvl();
+
+ while( !IsOfType( p, ID_CLBLK ) )
+ {
+ if ( p->GivType() == ID_CASE || p->GivType() == ID_DEFAULT)
+ {
+ CBotCStack* pStk2 = pStk->TokenStack(p); // un petit bout de pile svp
+
+ CBotInstr* i = CBotCase::Compile( p, pStk2 );
+ if (i == NULL)
+ {
+ delete inst;
+ return pStack->Return(NULL, pStk2);
+ }
+ delete pStk2;
+ if ( inst->m_Block == NULL ) inst->m_Block = i;
+ else inst->m_Block->AddNext(i);
+ continue;
+ }
+
+ if ( inst->m_Block == NULL )
+ {
+ pStk->SetError(TX_NOCASE, p->GivStart());
+ delete inst;
+ return pStack->Return(NULL, pStk);
+ }
+
+ CBotInstr* i = CBotBlock::CompileBlkOrInst( p, pStk, true );
+ if ( !pStk->IsOk() )
+ {
+ delete inst;
+ return pStack->Return(NULL, pStk);
+ }
+ inst->m_Block->AddNext(i);
+
+ if ( p == NULL )
+ {
+ pStk->SetError(TX_CLOSEBLK, -1);
+ delete inst;
+ return pStack->Return(NULL, pStk);
+ }
+ }
+ DecLvl();
+
+ if ( inst->m_Block == NULL )
+ {
+ pStk->SetError(TX_NOCASE, p->GivStart());
+ delete inst;
+ return pStack->Return(NULL, pStk);
+ }
+ // the statement block is ok
+ return pStack->Return(inst, pStk); // return an object to the application
+ }
+ pStk->SetError( TX_OPENBLK, p->GivStart() );
+ }
+ pStk->SetError( TX_CLOSEPAR, p->GivStart() );
+ }
+ pStk->SetError( TX_BADTYPE, p->GivStart() );
+ }
+ }
+ pStk->SetError( TX_OPENPAR, p->GivStart());
+
+ delete inst; // error, frees up
+ return pStack->Return(NULL, pStk); // no object, the error is on the stack
}
// executes instruction "switch"
bool CBotSwitch :: Execute(CBotStack* &pj)
{
- CBotStack* pile1 = pj->AddStack(this); // adds an item to the stack
-// if ( pile1 == EOX ) return true;
-
- CBotInstr* p = m_Block; // first expression
-
- int state = pile1->GivState();
- if (state == 0)
- {
- if ( !m_Value->Execute(pile1) ) return false;
- pile1->SetState(state = -1);
- }
-
- if ( pile1->IfStep() ) return false;
-
- if ( state == -1 )
- {
- state = 0;
- int val = pile1->GivVal(); // result of the value
-
- CBotStack* pile2 = pile1->AddStack();
- while ( p != NULL ) // search for the corresponding case in a list
- {
- state++;
- if ( p->CompCase( pile2, val ) ) break; // found the case
- p = p->GivNext();
- }
- pile2->Delete();
-
- if ( p == NULL ) return pj->Return(pile1); // completed if nothing
-
- if ( !pile1->SetState(state) ) return false;
- }
-
- p = m_Block; // returns to the beginning
- while (state-->0) p = p->GivNext(); // advance in the list
-
- while( p != NULL )
- {
- if ( !p->Execute(pile1) ) return pj->BreakReturn(pile1);
- if ( !pile1->IncState() ) return false;
- p = p->GivNext();
- }
- return pj->Return(pile1);
+ CBotStack* pile1 = pj->AddStack(this); // adds an item to the stack
+// if ( pile1 == EOX ) return true;
+
+ CBotInstr* p = m_Block; // first expression
+
+ int state = pile1->GivState();
+ if (state == 0)
+ {
+ if ( !m_Value->Execute(pile1) ) return false;
+ pile1->SetState(state = -1);
+ }
+
+ if ( pile1->IfStep() ) return false;
+
+ if ( state == -1 )
+ {
+ state = 0;
+ int val = pile1->GivVal(); // result of the value
+
+ CBotStack* pile2 = pile1->AddStack();
+ while ( p != NULL ) // search for the corresponding case in a list
+ {
+ state++;
+ if ( p->CompCase( pile2, val ) ) break; // found the case
+ p = p->GivNext();
+ }
+ pile2->Delete();
+
+ if ( p == NULL ) return pj->Return(pile1); // completed if nothing
+
+ if ( !pile1->SetState(state) ) return false;
+ }
+
+ p = m_Block; // returns to the beginning
+ while (state-->0) p = p->GivNext(); // advance in the list
+
+ while( p != NULL )
+ {
+ if ( !p->Execute(pile1) ) return pj->BreakReturn(pile1);
+ if ( !pile1->IncState() ) return false;
+ p = p->GivNext();
+ }
+ return pj->Return(pile1);
}
void CBotSwitch :: RestoreState(CBotStack* &pj, bool bMain)
{
- if ( !bMain ) return;
-
- CBotStack* pile1 = pj->RestoreStack(this); // adds an item to the stack
- if ( pile1 == NULL ) return;
-
- CBotInstr* p = m_Block; // first expression
-
- int state = pile1->GivState();
- if (state == 0)
- {
- m_Value->RestoreState(pile1, bMain);
- return;
- }
-
- if ( state == -1 )
- {
- return;
- }
-
-// p = m_Block; // returns to the beginning
- while ( p != NULL && state-- > 0 )
- {
- p->RestoreState(pile1, false);
- p = p->GivNext(); // advance in the list
- }
-
- if( p != NULL )
- {
- p->RestoreState(pile1, true);
- return;
- }
+ if ( !bMain ) return;
+
+ CBotStack* pile1 = pj->RestoreStack(this); // adds an item to the stack
+ if ( pile1 == NULL ) return;
+
+ CBotInstr* p = m_Block; // first expression
+
+ int state = pile1->GivState();
+ if (state == 0)
+ {
+ m_Value->RestoreState(pile1, bMain);
+ return;
+ }
+
+ if ( state == -1 )
+ {
+ return;
+ }
+
+// p = m_Block; // returns to the beginning
+ while ( p != NULL && state-- > 0 )
+ {
+ p->RestoreState(pile1, false);
+ p = p->GivNext(); // advance in the list
+ }
+
+ if( p != NULL )
+ {
+ p->RestoreState(pile1, true);
+ return;
+ }
}
///////////////////////////////////////////////////////////////////////////
@@ -905,50 +905,50 @@ void CBotSwitch :: RestoreState(CBotStack* &pj, bool bMain)
CBotCase::CBotCase()
{
- m_Value = NULL; // NULL so that delete is not possible further
- name = "CBotCase"; // debug
+ m_Value = NULL; // NULL so that delete is not possible further
+ name = "CBotCase"; // debug
}
CBotCase::~CBotCase()
{
- delete m_Value; // frees the value
+ delete m_Value; // frees the value
}
CBotInstr* CBotCase::Compile(CBotToken* &p, CBotCStack* pStack)
{
- CBotCase* inst = new CBotCase(); // creates the object
- CBotToken* pp = p; // preserves at the ^ token (starting position)
-
- inst->SetToken(p);
- if (!IsOfType(p, ID_CASE, ID_DEFAULT)) return NULL; // should never happen
-
- if ( pp->GivType() == ID_CASE )
- {
- pp = p;
- inst->m_Value = CBotExprNum::Compile(p, pStack);
- if ( inst->m_Value == NULL )
- {
- pStack->SetError( TX_BADNUM, pp );
- delete inst;
- return NULL;
- }
- }
- if ( !IsOfType( p, ID_DOTS ))
- {
- pStack->SetError( TX_MISDOTS, p->GivStart() );
- delete inst;
- return NULL;
- }
-
- return inst;
+ CBotCase* inst = new CBotCase(); // creates the object
+ CBotToken* pp = p; // preserves at the ^ token (starting position)
+
+ inst->SetToken(p);
+ if (!IsOfType(p, ID_CASE, ID_DEFAULT)) return NULL; // should never happen
+
+ if ( pp->GivType() == ID_CASE )
+ {
+ pp = p;
+ inst->m_Value = CBotExprNum::Compile(p, pStack);
+ if ( inst->m_Value == NULL )
+ {
+ pStack->SetError( TX_BADNUM, pp );
+ delete inst;
+ return NULL;
+ }
+ }
+ if ( !IsOfType( p, ID_DOTS ))
+ {
+ pStack->SetError( TX_MISDOTS, p->GivStart() );
+ delete inst;
+ return NULL;
+ }
+
+ return inst;
}
// execution of instruction "case"
bool CBotCase::Execute(CBotStack* &pj)
{
- return true; // the "case" statement does nothing!
+ return true; // the "case" statement does nothing!
}
void CBotCase::RestoreState(CBotStack* &pj, bool bMain)
@@ -960,10 +960,10 @@ void CBotCase::RestoreState(CBotStack* &pj, bool bMain)
bool CBotCase::CompCase(CBotStack* &pile, int val)
{
- if ( m_Value == NULL ) return true; // "default" case
+ if ( m_Value == NULL ) return true; // "default" case
- while (!m_Value->Execute(pile)); // puts the value on the correspondent stack (without interruption)
- return (pile->GivVal() == val); // compared with the given value
+ while (!m_Value->Execute(pile)); // puts the value on the correspondent stack (without interruption)
+ return (pile->GivVal() == val); // compared with the given value
}
///////////////////////////////////////////////////////////////////////////
@@ -973,7 +973,7 @@ bool CBotCase::CompCase(CBotStack* &pile, int val)
CBotBreak::CBotBreak()
{
- name = "CBotBreak"; // debug
+ name = "CBotBreak"; // debug
}
CBotBreak::~CBotBreak()
@@ -982,58 +982,58 @@ CBotBreak::~CBotBreak()
CBotInstr* CBotBreak::Compile(CBotToken* &p, CBotCStack* pStack)
{
- CBotToken* pp = p; // preserves at the ^ token (starting position)
- int type = p->GivType();
-
- if (!IsOfType(p, ID_BREAK, ID_CONTINUE)) return NULL; // should never happen
-
- if ( !ChkLvl(CBotString(), type ) )
- {
- pStack->SetError(TX_BREAK, pp);
- return NULL; // no object, the error is on the stack
- }
-
- CBotBreak* inst = new CBotBreak(); // creates the object
- inst->SetToken(pp); // keeps the operation
-
- pp = p;
- if ( IsOfType( p, TokenTypVar ) )
- {
- inst->m_label = pp->GivString(); // register the name of label
- if ( !ChkLvl(inst->m_label, type ) )
- {
- delete inst;
- pStack->SetError(TX_NOLABEL, pp);
- return NULL; // no object, the error is on the stack
- }
- }
-
- if (IsOfType(p, ID_SEP))
- {
- return inst; // return what it wants
- }
- delete inst;
-
- pStack->SetError(TX_ENDOF, p->GivStart());
- return NULL; // no object, the error is on the stack
+ CBotToken* pp = p; // preserves at the ^ token (starting position)
+ int type = p->GivType();
+
+ if (!IsOfType(p, ID_BREAK, ID_CONTINUE)) return NULL; // should never happen
+
+ if ( !ChkLvl(CBotString(), type ) )
+ {
+ pStack->SetError(TX_BREAK, pp);
+ return NULL; // no object, the error is on the stack
+ }
+
+ CBotBreak* inst = new CBotBreak(); // creates the object
+ inst->SetToken(pp); // keeps the operation
+
+ pp = p;
+ if ( IsOfType( p, TokenTypVar ) )
+ {
+ inst->m_label = pp->GivString(); // register the name of label
+ if ( !ChkLvl(inst->m_label, type ) )
+ {
+ delete inst;
+ pStack->SetError(TX_NOLABEL, pp);
+ return NULL; // no object, the error is on the stack
+ }
+ }
+
+ if (IsOfType(p, ID_SEP))
+ {
+ return inst; // return what it wants
+ }
+ delete inst;
+
+ pStack->SetError(TX_ENDOF, p->GivStart());
+ return NULL; // no object, the error is on the stack
}
// execution of statement "break" or "continu"
bool CBotBreak :: Execute(CBotStack* &pj)
{
- CBotStack* pile = pj->AddStack(this);
-// if ( pile == EOX ) return true;
+ CBotStack* pile = pj->AddStack(this);
+// if ( pile == EOX ) return true;
- if ( pile->IfStep() ) return false;
+ if ( pile->IfStep() ) return false;
- pile->SetBreak(m_token.GivType()==ID_BREAK ? 1 : 2, m_label);
- return pj->Return(pile);
+ pile->SetBreak(m_token.GivType()==ID_BREAK ? 1 : 2, m_label);
+ return pj->Return(pile);
}
void CBotBreak :: RestoreState(CBotStack* &pj, bool bMain)
{
- if ( bMain ) pj->RestoreStack(this);
+ if ( bMain ) pj->RestoreStack(this);
}
@@ -1044,51 +1044,51 @@ void CBotBreak :: RestoreState(CBotStack* &pj, bool bMain)
CBotTry::CBotTry()
{
- m_ListCatch = NULL;
- m_FinalInst =
- m_Block = NULL; // NULL so that delete is not possible further
- name = "CBotTry"; // debug
+ m_ListCatch = NULL;
+ m_FinalInst =
+ m_Block = NULL; // NULL so that delete is not possible further
+ name = "CBotTry"; // debug
}
CBotTry::~CBotTry()
{
- delete m_ListCatch; // frees the list
- delete m_Block; // frees the instruction block
- delete m_FinalInst;
-}
+ delete m_ListCatch; // frees the list
+ delete m_Block; // frees the instruction block
+ delete m_FinalInst;
+}
CBotInstr* CBotTry::Compile(CBotToken* &p, CBotCStack* pStack)
{
- CBotTry* inst = new CBotTry(); // creates the object
- CBotToken* pp = p; // preserves at the ^ token (starting position)
-
- inst->SetToken(p);
- if (!IsOfType(p, ID_TRY)) return NULL; // should never happen
-
- CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
-
- inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk );
- CBotCatch** pn = &inst->m_ListCatch;
-
- while (pStk->IsOk() && p->GivType() == ID_CATCH)
- {
- CBotCatch* i = CBotCatch::Compile(p, pStk);
- *pn = i;
- pn = &i->m_next;
- }
-
- if (pStk->IsOk() && IsOfType( p, ID_FINALLY) )
- {
- inst->m_FinalInst = CBotBlock::CompileBlkOrInst( p, pStk );
- }
-
- if (pStk->IsOk())
- {
- return pStack->Return(inst, pStk); // return an object to the application
- }
-
- delete inst; // error, frees up
- return pStack->Return(NULL, pStk); // no object, the error is on the stack
+ CBotTry* inst = new CBotTry(); // creates the object
+ CBotToken* pp = p; // preserves at the ^ token (starting position)
+
+ inst->SetToken(p);
+ if (!IsOfType(p, ID_TRY)) return NULL; // should never happen
+
+ CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
+
+ inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk );
+ CBotCatch** pn = &inst->m_ListCatch;
+
+ while (pStk->IsOk() && p->GivType() == ID_CATCH)
+ {
+ CBotCatch* i = CBotCatch::Compile(p, pStk);
+ *pn = i;
+ pn = &i->m_next;
+ }
+
+ if (pStk->IsOk() && IsOfType( p, ID_FINALLY) )
+ {
+ inst->m_FinalInst = CBotBlock::CompileBlkOrInst( p, pStk );
+ }
+
+ if (pStk->IsOk())
+ {
+ return pStack->Return(inst, pStk); // return an object to the application
+ }
+
+ delete inst; // error, frees up
+ return pStack->Return(NULL, pStk); // no object, the error is on the stack
}
// execution of instruction Try
@@ -1098,145 +1098,145 @@ CBotInstr* CBotTry::Compile(CBotToken* &p, CBotCStack* pStack)
bool CBotTry :: Execute(CBotStack* &pj)
{
- int val;
-
- CBotStack* pile1 = pj->AddStack(this); // adds an item to the stack
-// if ( pile1 == EOX ) return true;
-
- if ( pile1->IfStep() ) return false;
- // or find in case of recovery
- CBotStack* pile0 = pj->AddStack2(); // adds an element to the secondary stack
- CBotStack* pile2 = pile0->AddStack();
-
- if ( pile1->GivState() == 0 )
- {
- if ( m_Block->Execute(pile1) )
- {
- if ( m_FinalInst == NULL ) return pj->Return(pile1);
- pile1->SetState(-2); // passes final
- }
-
- val = pile1->GivError();
- if ( val == 0 && CBotStack::m_initimer == 0 ) // mode step?
- return false; // does not make the catch
-
- pile1->IncState();
- pile2->SetState(val); // stores the error number
- pile1->SetError(0); // for now there is are more errors!
-
- if ( val == 0 && CBotStack::m_initimer < 0 ) // mode step?
- return false; // does not make the catch
- }
-
- // there was an interruption
- // see what it returns
-
- CBotCatch* pc = m_ListCatch;
- int state = (short)pile1->GivState(); // where were we?
- val = pile2->GivState(); // what error?
- pile0->SetState(1); // marking the GetRunPos
-
- if ( val >= 0 && state > 0 ) while ( pc != NULL )
- {
- if ( --state <= 0 )
- {
+ int val;
+
+ CBotStack* pile1 = pj->AddStack(this); // adds an item to the stack
+// if ( pile1 == EOX ) return true;
+
+ if ( pile1->IfStep() ) return false;
+ // or find in case of recovery
+ CBotStack* pile0 = pj->AddStack2(); // adds an element to the secondary stack
+ CBotStack* pile2 = pile0->AddStack();
+
+ if ( pile1->GivState() == 0 )
+ {
+ if ( m_Block->Execute(pile1) )
+ {
+ if ( m_FinalInst == NULL ) return pj->Return(pile1);
+ pile1->SetState(-2); // passes final
+ }
+
+ val = pile1->GivError();
+ if ( val == 0 && CBotStack::m_initimer == 0 ) // mode step?
+ return false; // does not make the catch
+
+ pile1->IncState();
+ pile2->SetState(val); // stores the error number
+ pile1->SetError(0); // for now there is are more errors!
+
+ if ( val == 0 && CBotStack::m_initimer < 0 ) // mode step?
+ return false; // does not make the catch
+ }
+
+ // there was an interruption
+ // see what it returns
+
+ CBotCatch* pc = m_ListCatch;
+ int state = (short)pile1->GivState(); // where were we?
+ val = pile2->GivState(); // what error?
+ pile0->SetState(1); // marking the GetRunPos
+
+ if ( val >= 0 && state > 0 ) while ( pc != NULL )
+ {
+ if ( --state <= 0 )
+ {
// request to the catch block if they feel concerned
- // demande au bloc catch s'il se sent concerné
- if ( !pc->TestCatch(pile2, val) ) return false; // suspend !
- pile1->IncState();
- }
- if ( --state <= 0 )
- {
- if ( pile2->GivVal() == true )
- {
-// pile0->SetState(1);
-
- if ( !pc->Execute(pile2) ) return false; // performs the operation
- if ( m_FinalInst == NULL )
- return pj->Return(pile2); // ends the try
-
- pile1->SetState(-2); // passes final
- break;
- }
- pile1->IncState();
- }
- pc = pc->m_next;
- }
- if ( m_FinalInst != NULL &&
- pile1->GivState() > 0 && val != 0 ) pile1->SetState(-1);// if stop then made the final
-
- if (pile1->GivState() <= -1)
- {
-// pile0->SetState(1);
-
- if (!m_FinalInst->Execute(pile2) && pile2->IsOk()) return false;
- if (!pile2->IsOk()) return pj->Return(pile2); // keep this exception
- pile2->SetError(pile1->GivState()==-1 ? val : 0); // gives the initial error
- return pj->Return(pile2);
- }
-
- pile1->SetState(0); // returns to the evaluation
- pile0->SetState(0); // returns to the evaluation
- if ( val != 0 && m_ListCatch == NULL && m_FinalInst == NULL )
- return pj->Return(pile2); // ends the try without exception
-
- pile1->SetError(val); // gives the error
- return false; // it's not for us
+ // demande au bloc catch s'il se sent concerné
+ if ( !pc->TestCatch(pile2, val) ) return false; // suspend !
+ pile1->IncState();
+ }
+ if ( --state <= 0 )
+ {
+ if ( pile2->GivVal() == true )
+ {
+// pile0->SetState(1);
+
+ if ( !pc->Execute(pile2) ) return false; // performs the operation
+ if ( m_FinalInst == NULL )
+ return pj->Return(pile2); // ends the try
+
+ pile1->SetState(-2); // passes final
+ break;
+ }
+ pile1->IncState();
+ }
+ pc = pc->m_next;
+ }
+ if ( m_FinalInst != NULL &&
+ pile1->GivState() > 0 && val != 0 ) pile1->SetState(-1);// if stop then made the final
+
+ if (pile1->GivState() <= -1)
+ {
+// pile0->SetState(1);
+
+ if (!m_FinalInst->Execute(pile2) && pile2->IsOk()) return false;
+ if (!pile2->IsOk()) return pj->Return(pile2); // keep this exception
+ pile2->SetError(pile1->GivState()==-1 ? val : 0); // gives the initial error
+ return pj->Return(pile2);
+ }
+
+ pile1->SetState(0); // returns to the evaluation
+ pile0->SetState(0); // returns to the evaluation
+ if ( val != 0 && m_ListCatch == NULL && m_FinalInst == NULL )
+ return pj->Return(pile2); // ends the try without exception
+
+ pile1->SetError(val); // gives the error
+ return false; // it's not for us
}
void CBotTry :: RestoreState(CBotStack* &pj, bool bMain)
{
- if ( !bMain ) return;
-
- int val;
- CBotStack* pile1 = pj->RestoreStack(this); // adds an item to the stack
- if ( pile1 == NULL ) return;
- // or find in case of recovery
- CBotStack* pile0 = pj->AddStack2(); // adds an item to the secondary stack
- if ( pile0 == NULL ) return;
-
- CBotStack* pile2 = pile0->RestoreStack();
- if ( pile2 == NULL ) return;
-
- m_Block->RestoreState(pile1, bMain);
- if ( pile0->GivState() == 0 )
- {
- return;
- }
-
- // there was an interruption
- // see what it returns
-
- CBotCatch* pc = m_ListCatch;
- int state = pile1->GivState(); // where were we ?
- val = pile2->GivState(); // what error ?
-
- if ( val >= 0 && state > 0 ) while ( pc != NULL )
- {
- if ( --state <= 0 )
- {
+ if ( !bMain ) return;
+
+ int val;
+ CBotStack* pile1 = pj->RestoreStack(this); // adds an item to the stack
+ if ( pile1 == NULL ) return;
+ // or find in case of recovery
+ CBotStack* pile0 = pj->AddStack2(); // adds an item to the secondary stack
+ if ( pile0 == NULL ) return;
+
+ CBotStack* pile2 = pile0->RestoreStack();
+ if ( pile2 == NULL ) return;
+
+ m_Block->RestoreState(pile1, bMain);
+ if ( pile0->GivState() == 0 )
+ {
+ return;
+ }
+
+ // there was an interruption
+ // see what it returns
+
+ CBotCatch* pc = m_ListCatch;
+ int state = pile1->GivState(); // where were we ?
+ val = pile2->GivState(); // what error ?
+
+ if ( val >= 0 && state > 0 ) while ( pc != NULL )
+ {
+ if ( --state <= 0 )
+ {
// request to the catch block if they feel concerned
- // demande au bloc catch s'il se sent concerné
- pc->RestoreCondState(pile2, bMain); // suspend !
- return;
- }
- if ( --state <= 0 )
- {
- if ( pile2->GivVal() == true )
- {
- pc->RestoreState(pile2, bMain); // execute the operation
- return;
- }
- }
- pc = pc->m_next;
- }
-
- if (pile1->GivState() <= -1)
- {
- m_FinalInst->RestoreState(pile2, bMain);
- return;
- }
+ // demande au bloc catch s'il se sent concerné
+ pc->RestoreCondState(pile2, bMain); // suspend !
+ return;
+ }
+ if ( --state <= 0 )
+ {
+ if ( pile2->GivVal() == true )
+ {
+ pc->RestoreState(pile2, bMain); // execute the operation
+ return;
+ }
+ }
+ pc = pc->m_next;
+ }
+
+ if (pile1->GivState() <= -1)
+ {
+ m_FinalInst->RestoreState(pile2, bMain);
+ return;
+ }
}
///////////////////////////////////////////////////////////////////////////
@@ -1246,81 +1246,81 @@ void CBotTry :: RestoreState(CBotStack* &pj, bool bMain)
CBotCatch::CBotCatch()
{
- m_Cond =
- m_Block = NULL; // NULL so that delete is not possible further
- m_next = NULL;
+ m_Cond =
+ m_Block = NULL; // NULL so that delete is not possible further
+ m_next = NULL;
- name = "CBotCatch"; // debug
+ name = "CBotCatch"; // debug
}
CBotCatch::~CBotCatch()
{
- delete m_Cond; // frees the list
- delete m_Block; // frees the instruction block
- delete m_next; // and subsequent
+ 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->GivStart());
-
- inst->SetToken(p);
- if (!IsOfType(p, ID_CATCH)) return NULL; // should never happen
-
- if (IsOfType(p, ID_OPENPAR))
- {
- inst->m_Cond = CBotExpression::Compile(p, pStack);
- if (( pStack->GivType() < CBotTypLong ||
- pStack->GivTypResult().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->GivStart());
- }
- pStack->SetError(TX_BADTYPE, p->GivStart());
- }
- pStack->SetError(TX_OPENPAR, p->GivStart());
- delete inst; // error, frees up
- return NULL; // no object, the error is on the stack
+ CBotCatch* inst = new CBotCatch(); // creates the object
+ pStack->SetStartError(p->GivStart());
+
+ inst->SetToken(p);
+ if (!IsOfType(p, ID_CATCH)) return NULL; // should never happen
+
+ if (IsOfType(p, ID_OPENPAR))
+ {
+ inst->m_Cond = CBotExpression::Compile(p, pStack);
+ if (( pStack->GivType() < CBotTypLong ||
+ pStack->GivTypResult().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->GivStart());
+ }
+ pStack->SetError(TX_BADTYPE, p->GivStart());
+ }
+ pStack->SetError(TX_OPENPAR, p->GivStart());
+ delete inst; // error, frees up
+ return NULL; // no object, the error is on the stack
}
// execution of "catch"
bool CBotCatch :: Execute(CBotStack* &pj)
{
- if ( m_Block == NULL ) return true;
- return m_Block->Execute(pj); // executes the associated block
+ if ( m_Block == NULL ) return true;
+ return m_Block->Execute(pj); // executes the associated block
}
void CBotCatch :: RestoreState(CBotStack* &pj, bool bMain)
{
- if ( bMain && m_Block != NULL ) m_Block->RestoreState(pj, bMain);
+ if ( bMain && m_Block != NULL ) m_Block->RestoreState(pj, bMain);
}
void CBotCatch :: RestoreCondState(CBotStack* &pj, bool bMain)
{
- m_Cond->RestoreState(pj, 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->GivType() != CBotTypBoolean )
- {
- CBotVar* var = CBotVar::Create((CBotToken*)NULL, CBotTypBoolean);
- var->SetValInt( pile->GivVal() == val );
- pile->SetVar(var); // calls on the stack
- }
-
- return true;
+ if ( !m_Cond->Execute(pile) ) return false;
+
+ if ( val > 0 || pile->GivType() != CBotTypBoolean )
+ {
+ CBotVar* var = CBotVar::Create((CBotToken*)NULL, CBotTypBoolean);
+ var->SetValInt( pile->GivVal() == val );
+ pile->SetVar(var); // calls on the stack
+ }
+
+ return true;
}
///////////////////////////////////////////////////////////////////////////
@@ -1330,72 +1330,72 @@ bool CBotCatch :: TestCatch(CBotStack* &pile, int val)
CBotThrow::CBotThrow()
{
- m_Value = NULL; // NULL so that delete is not possible further
+ m_Value = NULL; // NULL so that delete is not possible further
- name = "CBotThrow"; // debug
+ name = "CBotThrow"; // debug
}
CBotThrow::~CBotThrow()
{
- delete m_Value;
+ delete m_Value;
}
CBotInstr* CBotThrow::Compile(CBotToken* &p, CBotCStack* pStack)
{
- pStack->SetStartError(p->GivStart());
+ pStack->SetStartError(p->GivStart());
- CBotThrow* inst = new CBotThrow(); // creates the object
- inst->SetToken(p);
+ CBotThrow* inst = new CBotThrow(); // creates the object
+ inst->SetToken(p);
- CBotToken* pp = p; // preserves at the ^ token (starting position)
+ CBotToken* pp = p; // preserves at the ^ token (starting position)
- if (!IsOfType(p, ID_THROW)) return NULL; // should never happen
+ if (!IsOfType(p, ID_THROW)) return NULL; // should never happen
- inst->m_Value = CBotExpression::Compile( p, pStack );
+ inst->m_Value = CBotExpression::Compile( p, pStack );
- if (pStack->GivType() < CBotTypLong && pStack->IsOk())
- {
- return inst; // return an object to the application
- }
- pStack->SetError(TX_BADTYPE, pp);
+ if (pStack->GivType() < CBotTypLong && pStack->IsOk())
+ {
+ return inst; // return an object to the application
+ }
+ pStack->SetError(TX_BADTYPE, pp);
- delete inst; // error, frees up
- return NULL; // no object, the error is on the stack
+ delete inst; // error, frees up
+ return NULL; // no object, the error is on the stack
}
// execution of instruction "throw"
bool CBotThrow :: Execute(CBotStack* &pj)
{
- CBotStack* pile = pj->AddStack(this);
-// if ( pile == EOX ) return true;
+ CBotStack* pile = pj->AddStack(this);
+// if ( pile == EOX ) return true;
- if ( pile->GivState() == 0 )
- {
- if ( !m_Value->Execute(pile) ) return false;
- pile->IncState();
- }
+ if ( pile->GivState() == 0 )
+ {
+ if ( !m_Value->Execute(pile) ) return false;
+ pile->IncState();
+ }
- if ( pile->IfStep() ) return false;
+ if ( pile->IfStep() ) return false;
- int val = pile->GivVal();
- if ( val < 0 ) val = TX_BADTHROW;
- pile->SetError( val, &m_token );
- return pj->Return( pile );
+ int val = pile->GivVal();
+ if ( val < 0 ) val = TX_BADTHROW;
+ pile->SetError( val, &m_token );
+ return pj->Return( pile );
}
void CBotThrow :: RestoreState(CBotStack* &pj, bool bMain)
{
- if ( !bMain ) return;
+ if ( !bMain ) return;
- CBotStack* pile = pj->RestoreStack(this);
- if ( pile == NULL ) return;
+ CBotStack* pile = pj->RestoreStack(this);
+ if ( pile == NULL ) return;
- if ( pile->GivState() == 0 )
- {
- m_Value->RestoreState(pile, bMain);
- return;
- }
+ if ( pile->GivState() == 0 )
+ {
+ m_Value->RestoreState(pile, bMain);
+ return;
+ }
}
@@ -1405,7 +1405,7 @@ void CBotThrow :: RestoreState(CBotStack* &pj, bool bMain)
CBotStartDebugDD::CBotStartDebugDD()
{
- name = "CBotStartDebugDD"; // debug
+ name = "CBotStartDebugDD"; // debug
}
CBotStartDebugDD::~CBotStartDebugDD()
@@ -1415,9 +1415,9 @@ CBotStartDebugDD::~CBotStartDebugDD()
CBotInstr* CBotStartDebugDD::Compile(CBotToken* &p, CBotCStack* pStack)
{
- if (!IsOfType(p, ID_DEBUGDD)) return NULL; // should never happen
+ if (!IsOfType(p, ID_DEBUGDD)) return NULL; // should never happen
- return new CBotStartDebugDD(); // creates the object
+ return new CBotStartDebugDD(); // creates the object
}
@@ -1425,9 +1425,9 @@ CBotInstr* CBotStartDebugDD::Compile(CBotToken* &p, CBotCStack* pStack)
bool CBotStartDebugDD :: Execute(CBotStack* &pj)
{
- CBotProgram* p = pj->GivBotCall();
- p->m_bDebugDD = true;
+ CBotProgram* p = pj->GivBotCall();
+ p->m_bDebugDD = true;
- return true;
+ return true;
}
diff --git a/src/CBot/ClassFILE.cpp b/src/CBot/ClassFILE.cpp
index 418ddb3..f73a1ac 100644
--- a/src/CBot/ClassFILE.cpp
+++ b/src/CBot/ClassFILE.cpp
@@ -1,428 +1,428 @@
-// * 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
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// ClassFile.cpp
-//
-// definition of methods for class FILE
-
-
-
-// Static variables
-
-static CBotClass* m_pClassFILE;
-static CBotProgram* m_pFuncFile;
-static int m_CompteurFileOpen = 0;
-
-
-
-// Prepares a file name.
-
-void PrepareFilename(CBotString &filename) //DD!
-{
- int pos;
-
- pos = filename.ReverseFind('\\');
- if ( pos > 0 )
- {
- filename = filename.Mid(pos+1); // remove the records (files)??
- }
-
- pos = filename.ReverseFind('/');
- if ( pos > 0 )
- {
- filename = filename.Mid(pos+1); // also those with /
- }
-
- pos = filename.ReverseFind(':');
- if ( pos > 0 )
- {
- filename = filename.Mid(pos+1); // also removes the drive letter C:
- }
-
- filename = CBotString("files\\") + filename;
-}
-
-
-// constructor of the class
-// gets the filename as a parameter
-
-// execution
-bool rfconstruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception)
-{
- CBotString mode;
-
- // accepts no parameters
- if ( pVar == NULL ) return true;
-
- // must be a string
- if ( pVar->GivType() != CBotTypString ) { Exception = CBotErrBadString; return false; }
-
- CBotString filename = pVar->GivValString();
- PrepareFilename(filename); //DR
-
- // there may be a second parameter
- pVar = pVar->GivNext();
- if ( pVar != NULL )
- {
- // recovers the mode
- mode = pVar->GivValString();
- if ( mode != "r" && mode != "w" ) { Exception = CBotErrBadParam; return false; }
-
- // no third parameter, only two or one possible
- if ( pVar->GivNext() != NULL ) { Exception = CBotErrOverParam; return false; }
- }
-
- // save the file name
- pVar = pThis->GivItem("filename");
- pVar->SetValString(filename);
-
- if ( ! mode.IsEmpty() )
- {
- // open the called file
- FILE* pFile = fopen( filename, mode );
- if ( pFile == NULL ) { Exception = CBotErrFileOpen; return false; }
-
- m_CompteurFileOpen ++;
-
- // save the handle of file
- pVar = pThis->GivItem("handle");
- pVar->SetValInt((long)pFile);
- }
-
- return true;
-}
-
-// compilation
-CBotTypResult cfconstruct (CBotVar* pThis, CBotVar* &pVar)
-{
- // accepts no parameters
- if ( pVar == NULL ) return CBotTypResult( 0 );
-
- // must be a string
- if ( pVar->GivType() != CBotTypString )
- return CBotTypResult( CBotErrBadString );
-
- // there may be a second parameter
- pVar = pVar->GivNext();
- if ( pVar != NULL )
- {
- // must be a string
- if ( pVar->GivType() != CBotTypString )
- return CBotTypResult( CBotErrBadString );
- // no third parameter
- if ( pVar->GivNext() != NULL ) return CBotTypResult( CBotErrOverParam );
- }
-
- // le r�sultat est de type void (constructeur)
- return CBotTypResult( 0 );
-}
-
-
-// destructor of the class
-
-// execution
-bool rfdestruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception)
-{
- // retrieves the element "handle"
- pVar = pThis->GivItem("handle");
-
- // not open? no problem
- if ( pVar->GivInit() != IS_DEF) return true;
-
- FILE* pFile= (FILE*)pVar->GivValInt();
- fclose(pFile);
- m_CompteurFileOpen --;
-
- pVar->SetInit(IS_NAN);
-
- return true;
-}
-
-
-// FILE :: open method
-// get the r / w mode as a parameter
-
-// execution
-bool rfopen (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception)
-{
- // there must be a parameter
- if ( pVar == NULL ) { Exception = CBotErrLowParam; return false; }
-
- // must be a string
- if ( pVar->GivType() != CBotTypString ) { Exception = CBotErrBadString; return false; }
-
- // there may be a second parameter
- if ( pVar->GivNext() != NULL )
- {
- // in this case the first parameter is the file name
- CBotString filename = pVar->GivValString();
- PrepareFilename(filename); //DR
-
- // saves the file name
- CBotVar* pVar2 = pThis->GivItem("filename");
- pVar2->SetValString(filename);
-
- // next parameter is the mode
- pVar = pVar -> GivNext();
- }
-
- CBotString mode = pVar->GivValString();
- if ( mode != "r" && mode != "w" ) { Exception = CBotErrBadParam; return false; }
-
- // No third parameter
- if ( pVar->GivNext() != NULL ) { Exception = CBotErrOverParam; return false; }
-
- // retrieves the element "handle"
- pVar = pThis->GivItem("handle");
-
- // which must not be initialized
- if ( pVar->GivInit() == IS_DEF) { Exception = CBotErrFileOpen; return false; }
-
- // contains filename
- pVar = pThis->GivItem("filename");
- CBotString filename = pVar->GivValString();
-
- PrepareFilename(filename); //DD! (if the name was assigned by h.filename = "...";
-
- // open requsted file
- FILE* pFile = fopen( filename, mode );
- if ( pFile == NULL ) //DR
- {
- pResult->SetValInt(false); //DR
- return true; //DR
- }
-
- m_CompteurFileOpen ++;
-
- // saves the handle of file
- pVar = pThis->GivItem("handle");
- pVar->SetValInt((long)pFile);
-
- pResult->SetValInt(true); //DR
- return true;
-}
-
-// compilation
-CBotTypResult cfopen (CBotVar* pThis, CBotVar* &pVar)
-{
- // there must be a parameter
- if ( pVar == NULL ) return CBotTypResult( CBotErrLowParam );
-
- // must be a string
- if ( pVar->GivType() != CBotTypString )
- return CBotTypResult( CBotErrBadString );
-
- // there may be a second parameter
- pVar = pVar->GivNext();
- if ( pVar != NULL )
- {
- // must be a string
- if ( pVar->GivType() != CBotTypString )
- return CBotTypResult( CBotErrBadString );
-
- // no third parameter
- if ( pVar->GivNext() != NULL ) return CBotTypResult( CBotErrOverParam );
- }
-
- // the result is of type bool
- return CBotTypResult(CBotTypBoolean); //DR
-}
-
-
-// FILE :: close method
-
-// execution
-bool rfclose (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception)
-{
- // it should not be any parameter
- if ( pVar != NULL ) return CBotErrOverParam;
-
- // retrieves the element "handle"
- pVar = pThis->GivItem("handle");
-
- if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; }
-
- FILE* pFile= (FILE*)pVar->GivValInt();
- fclose(pFile);
- m_CompteurFileOpen --;
-
- pVar->SetInit(IS_NAN);
-
- return true;
-}
-
-// compilation
-CBotTypResult cfclose (CBotVar* pThis, CBotVar* &pVar)
-{
- // it should not be any parameter
- if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam );
-
- // function returns a result "void"
- return CBotTypResult( 0 );
-}
-
-// FILE :: writeln method
-
-// execution
-bool rfwrite (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception)
-{
- // there must be a parameter
- if ( pVar == NULL ) { Exception = CBotErrLowParam; return false; }
-
- // must be a string
- if ( pVar->GivType() != CBotTypString ) { Exception = CBotErrBadString; return false; }
-
- CBotString param = pVar->GivValString();
-
- //retrieves the element "handle"
- pVar = pThis->GivItem("handle");
-
- if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; }
-
- FILE* pFile= (FILE*)pVar->GivValInt();
-
- int res = fputs(param+CBotString("\n"), pFile);
-
- // on error throws an exception
- if ( res < 0 ) { Exception = CBotErrWrite; return false; }
-
- return true;
-}
-
-// compilation
-CBotTypResult cfwrite (CBotVar* pThis, CBotVar* &pVar)
-{
- // there must be a parameter
- if ( pVar == NULL ) return CBotTypResult( CBotErrLowParam );
-
- // must be a string
- if ( pVar->GivType() != CBotTypString ) return CBotTypResult( CBotErrBadString );
-
- // no other parameter
- if ( pVar->GivNext() != NULL ) return CBotTypResult( CBotErrOverParam );
-
- // function returns "void" result
- return CBotTypResult( 0 );
-}
-
-// FILE :: readln method
-
-// execution
-bool rfread (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception)
-{
- // there shouldn't be any parameter
- if ( pVar != NULL ) { Exception = CBotErrOverParam; return false; }
-
- //retrieves the element "handle"
- pVar = pThis->GivItem("handle");
-
- if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; }
-
- FILE* pFile= (FILE*)pVar->GivValInt();
-
- char chaine[2000];
- int i;
- for ( i = 0 ; i < 2000 ; i++ ) chaine[i] = 0;
-
- fgets(chaine, 1999, pFile);
-
- for ( i = 0 ; i < 2000 ; i++ ) if (chaine[i] == '\n') chaine[i] = 0;
-
- // on error throws an exception
- if ( ferror(pFile) ) { Exception = CBotErrRead; return false; }
-
- pResult->SetValString( chaine );
-
- return true;
-}
-
-// compilation
-CBotTypResult cfread (CBotVar* pThis, CBotVar* &pVar)
-{
- // there shouldn't be any parameter
- if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam );
-
- // function return "string" result
- return CBotTypResult( CBotTypString );
-}
-// FILE :: readln method
-
-
-// execution
-bool rfeof (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception)
-{
- // there shouldn't be any parameter
- if ( pVar != NULL ) { Exception = CBotErrOverParam; return false; }
-
- // retrieves the element "handle"
- pVar = pThis->GivItem("handle");
-
- if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; }
-
- FILE* pFile= (FILE*)pVar->GivValInt();
-
- pResult->SetValInt( feof( pFile ) );
-
- return true;
-}
-
-// compilation
-CBotTypResult cfeof (CBotVar* pThis, CBotVar* &pVar)
-{
- // there shouldn't be any parameter
- if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam );
-
- // function return boolean result
- return CBotTypResult( CBotTypBoolean );
-}
-
-
-
-
-
-void InitClassFILE()
-{
-// creates a class for file management
-// the usage is as follows:
-// file canal( "NomFichier.txt" )
-// canal.open( "r" ); // open reading
-// s = canal.readln( ); // reads a line
-// canal.close(); // closes the file
-
- // create class FILE
- m_pClassFILE = new CBotClass("file", NULL);
- // add the component ".filename"
- m_pClassFILE->AddItem("filename", CBotTypString);
- // add the component ".handle"
- m_pClassFILE->AddItem("handle", CBotTypInt, PR_PRIVATE);
-
- // define a constructor and destructor
- m_pClassFILE->AddFunction("file", rfconstruct, cfconstruct );
- m_pClassFILE->AddFunction("~file", rfdestruct, NULL );
-
- // defined associated methods
- m_pClassFILE->AddFunction("open", rfopen, cfopen );
- m_pClassFILE->AddFunction("close", rfclose, cfclose );
- m_pClassFILE->AddFunction("writeln", rfwrite, cfwrite );
- m_pClassFILE->AddFunction("readln", rfread, cfread );
- m_pClassFILE->AddFunction("eof", rfeof, cfeof );
-
- m_pFuncFile = new CBotProgram( );
- CBotStringArray ListFonctions;
- m_pFuncFile->Compile( "public file openfile(string name, string mode) {return new file(name, mode);}", ListFonctions);
- m_pFuncFile->SetIdent(-2); // restoreState as a special identifier for this function
-}
-
+// * 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
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+
+// ClassFile.cpp
+//
+// definition of methods for class FILE
+
+
+
+// Static variables
+
+static CBotClass* m_pClassFILE;
+static CBotProgram* m_pFuncFile;
+static int m_CompteurFileOpen = 0;
+
+
+
+// Prepares a file name.
+
+void PrepareFilename(CBotString &filename) //DD!
+{
+ int pos;
+
+ pos = filename.ReverseFind('\\');
+ if ( pos > 0 )
+ {
+ filename = filename.Mid(pos+1); // remove the records (files)??
+ }
+
+ pos = filename.ReverseFind('/');
+ if ( pos > 0 )
+ {
+ filename = filename.Mid(pos+1); // also those with /
+ }
+
+ pos = filename.ReverseFind(':');
+ if ( pos > 0 )
+ {
+ filename = filename.Mid(pos+1); // also removes the drive letter C:
+ }
+
+ filename = CBotString("files\\") + filename;
+}
+
+
+// constructor of the class
+// gets the filename as a parameter
+
+// execution
+bool rfconstruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception)
+{
+ CBotString mode;
+
+ // accepts no parameters
+ if ( pVar == NULL ) return true;
+
+ // must be a string
+ if ( pVar->GivType() != CBotTypString ) { Exception = CBotErrBadString; return false; }
+
+ CBotString filename = pVar->GivValString();
+ PrepareFilename(filename); //DR
+
+ // there may be a second parameter
+ pVar = pVar->GivNext();
+ if ( pVar != NULL )
+ {
+ // recovers the mode
+ mode = pVar->GivValString();
+ if ( mode != "r" && mode != "w" ) { Exception = CBotErrBadParam; return false; }
+
+ // no third parameter, only two or one possible
+ if ( pVar->GivNext() != NULL ) { Exception = CBotErrOverParam; return false; }
+ }
+
+ // save the file name
+ pVar = pThis->GivItem("filename");
+ pVar->SetValString(filename);
+
+ if ( ! mode.IsEmpty() )
+ {
+ // open the called file
+ FILE* pFile = fopen( filename, mode );
+ if ( pFile == NULL ) { Exception = CBotErrFileOpen; return false; }
+
+ m_CompteurFileOpen ++;
+
+ // save the handle of file
+ pVar = pThis->GivItem("handle");
+ pVar->SetValInt((long)pFile);
+ }
+
+ return true;
+}
+
+// compilation
+CBotTypResult cfconstruct (CBotVar* pThis, CBotVar* &pVar)
+{
+ // accepts no parameters
+ if ( pVar == NULL ) return CBotTypResult( 0 );
+
+ // must be a string
+ if ( pVar->GivType() != CBotTypString )
+ return CBotTypResult( CBotErrBadString );
+
+ // there may be a second parameter
+ pVar = pVar->GivNext();
+ if ( pVar != NULL )
+ {
+ // must be a string
+ if ( pVar->GivType() != CBotTypString )
+ return CBotTypResult( CBotErrBadString );
+ // no third parameter
+ if ( pVar->GivNext() != NULL ) return CBotTypResult( CBotErrOverParam );
+ }
+
+ // le r�sultat est de type void (constructeur)
+ return CBotTypResult( 0 );
+}
+
+
+// destructor of the class
+
+// execution
+bool rfdestruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception)
+{
+ // retrieves the element "handle"
+ pVar = pThis->GivItem("handle");
+
+ // not open? no problem
+ if ( pVar->GivInit() != IS_DEF) return true;
+
+ FILE* pFile= (FILE*)pVar->GivValInt();
+ fclose(pFile);
+ m_CompteurFileOpen --;
+
+ pVar->SetInit(IS_NAN);
+
+ return true;
+}
+
+
+// FILE :: open method
+// get the r / w mode as a parameter
+
+// execution
+bool rfopen (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception)
+{
+ // there must be a parameter
+ if ( pVar == NULL ) { Exception = CBotErrLowParam; return false; }
+
+ // must be a string
+ if ( pVar->GivType() != CBotTypString ) { Exception = CBotErrBadString; return false; }
+
+ // there may be a second parameter
+ if ( pVar->GivNext() != NULL )
+ {
+ // in this case the first parameter is the file name
+ CBotString filename = pVar->GivValString();
+ PrepareFilename(filename); //DR
+
+ // saves the file name
+ CBotVar* pVar2 = pThis->GivItem("filename");
+ pVar2->SetValString(filename);
+
+ // next parameter is the mode
+ pVar = pVar -> GivNext();
+ }
+
+ CBotString mode = pVar->GivValString();
+ if ( mode != "r" && mode != "w" ) { Exception = CBotErrBadParam; return false; }
+
+ // No third parameter
+ if ( pVar->GivNext() != NULL ) { Exception = CBotErrOverParam; return false; }
+
+ // retrieves the element "handle"
+ pVar = pThis->GivItem("handle");
+
+ // which must not be initialized
+ if ( pVar->GivInit() == IS_DEF) { Exception = CBotErrFileOpen; return false; }
+
+ // contains filename
+ pVar = pThis->GivItem("filename");
+ CBotString filename = pVar->GivValString();
+
+ PrepareFilename(filename); //DD! (if the name was assigned by h.filename = "...";
+
+ // open requsted file
+ FILE* pFile = fopen( filename, mode );
+ if ( pFile == NULL ) //DR
+ {
+ pResult->SetValInt(false); //DR
+ return true; //DR
+ }
+
+ m_CompteurFileOpen ++;
+
+ // saves the handle of file
+ pVar = pThis->GivItem("handle");
+ pVar->SetValInt((long)pFile);
+
+ pResult->SetValInt(true); //DR
+ return true;
+}
+
+// compilation
+CBotTypResult cfopen (CBotVar* pThis, CBotVar* &pVar)
+{
+ // there must be a parameter
+ if ( pVar == NULL ) return CBotTypResult( CBotErrLowParam );
+
+ // must be a string
+ if ( pVar->GivType() != CBotTypString )
+ return CBotTypResult( CBotErrBadString );
+
+ // there may be a second parameter
+ pVar = pVar->GivNext();
+ if ( pVar != NULL )
+ {
+ // must be a string
+ if ( pVar->GivType() != CBotTypString )
+ return CBotTypResult( CBotErrBadString );
+
+ // no third parameter
+ if ( pVar->GivNext() != NULL ) return CBotTypResult( CBotErrOverParam );
+ }
+
+ // the result is of type bool
+ return CBotTypResult(CBotTypBoolean); //DR
+}
+
+
+// FILE :: close method
+
+// execution
+bool rfclose (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception)
+{
+ // it should not be any parameter
+ if ( pVar != NULL ) return CBotErrOverParam;
+
+ // retrieves the element "handle"
+ pVar = pThis->GivItem("handle");
+
+ if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; }
+
+ FILE* pFile= (FILE*)pVar->GivValInt();
+ fclose(pFile);
+ m_CompteurFileOpen --;
+
+ pVar->SetInit(IS_NAN);
+
+ return true;
+}
+
+// compilation
+CBotTypResult cfclose (CBotVar* pThis, CBotVar* &pVar)
+{
+ // it should not be any parameter
+ if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam );
+
+ // function returns a result "void"
+ return CBotTypResult( 0 );
+}
+
+// FILE :: writeln method
+
+// execution
+bool rfwrite (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception)
+{
+ // there must be a parameter
+ if ( pVar == NULL ) { Exception = CBotErrLowParam; return false; }
+
+ // must be a string
+ if ( pVar->GivType() != CBotTypString ) { Exception = CBotErrBadString; return false; }
+
+ CBotString param = pVar->GivValString();
+
+ //retrieves the element "handle"
+ pVar = pThis->GivItem("handle");
+
+ if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; }
+
+ FILE* pFile= (FILE*)pVar->GivValInt();
+
+ int res = fputs(param+CBotString("\n"), pFile);
+
+ // on error throws an exception
+ if ( res < 0 ) { Exception = CBotErrWrite; return false; }
+
+ return true;
+}
+
+// compilation
+CBotTypResult cfwrite (CBotVar* pThis, CBotVar* &pVar)
+{
+ // there must be a parameter
+ if ( pVar == NULL ) return CBotTypResult( CBotErrLowParam );
+
+ // must be a string
+ if ( pVar->GivType() != CBotTypString ) return CBotTypResult( CBotErrBadString );
+
+ // no other parameter
+ if ( pVar->GivNext() != NULL ) return CBotTypResult( CBotErrOverParam );
+
+ // function returns "void" result
+ return CBotTypResult( 0 );
+}
+
+// FILE :: readln method
+
+// execution
+bool rfread (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception)
+{
+ // there shouldn't be any parameter
+ if ( pVar != NULL ) { Exception = CBotErrOverParam; return false; }
+
+ //retrieves the element "handle"
+ pVar = pThis->GivItem("handle");
+
+ if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; }
+
+ FILE* pFile= (FILE*)pVar->GivValInt();
+
+ char chaine[2000];
+ int i;
+ for ( i = 0 ; i < 2000 ; i++ ) chaine[i] = 0;
+
+ fgets(chaine, 1999, pFile);
+
+ for ( i = 0 ; i < 2000 ; i++ ) if (chaine[i] == '\n') chaine[i] = 0;
+
+ // on error throws an exception
+ if ( ferror(pFile) ) { Exception = CBotErrRead; return false; }
+
+ pResult->SetValString( chaine );
+
+ return true;
+}
+
+// compilation
+CBotTypResult cfread (CBotVar* pThis, CBotVar* &pVar)
+{
+ // there shouldn't be any parameter
+ if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam );
+
+ // function return "string" result
+ return CBotTypResult( CBotTypString );
+}
+// FILE :: readln method
+
+
+// execution
+bool rfeof (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception)
+{
+ // there shouldn't be any parameter
+ if ( pVar != NULL ) { Exception = CBotErrOverParam; return false; }
+
+ // retrieves the element "handle"
+ pVar = pThis->GivItem("handle");
+
+ if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; }
+
+ FILE* pFile= (FILE*)pVar->GivValInt();
+
+ pResult->SetValInt( feof( pFile ) );
+
+ return true;
+}
+
+// compilation
+CBotTypResult cfeof (CBotVar* pThis, CBotVar* &pVar)
+{
+ // there shouldn't be any parameter
+ if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam );
+
+ // function return boolean result
+ return CBotTypResult( CBotTypBoolean );
+}
+
+
+
+
+
+void InitClassFILE()
+{
+// creates a class for file management
+// the usage is as follows:
+// file canal( "NomFichier.txt" )
+// canal.open( "r" ); // open reading
+// s = canal.readln( ); // reads a line
+// canal.close(); // closes the file
+
+ // create class FILE
+ m_pClassFILE = new CBotClass("file", NULL);
+ // add the component ".filename"
+ m_pClassFILE->AddItem("filename", CBotTypString);
+ // add the component ".handle"
+ m_pClassFILE->AddItem("handle", CBotTypInt, PR_PRIVATE);
+
+ // define a constructor and destructor
+ m_pClassFILE->AddFunction("file", rfconstruct, cfconstruct );
+ m_pClassFILE->AddFunction("~file", rfdestruct, NULL );
+
+ // defined associated methods
+ m_pClassFILE->AddFunction("open", rfopen, cfopen );
+ m_pClassFILE->AddFunction("close", rfclose, cfclose );
+ m_pClassFILE->AddFunction("writeln", rfwrite, cfwrite );
+ m_pClassFILE->AddFunction("readln", rfread, cfread );
+ m_pClassFILE->AddFunction("eof", rfeof, cfeof );
+
+ m_pFuncFile = new CBotProgram( );
+ CBotStringArray ListFonctions;
+ m_pFuncFile->Compile( "public file openfile(string name, string mode) {return new file(name, mode);}", ListFonctions);
+ m_pFuncFile->SetIdent(-2); // restoreState as a special identifier for this function
+}
+
diff --git a/src/CBot/StringFunctions.cpp b/src/CBot/StringFunctions.cpp
index 213b956..39bafca 100644
--- a/src/CBot/StringFunctions.cpp
+++ b/src/CBot/StringFunctions.cpp
@@ -22,21 +22,21 @@
bool rStrLen( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
- // it takes a parameter
- if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
+ // it takes a parameter
+ if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
- // to be a string
- if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
+ // to be a string
+ if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
- // no second parameter
- if ( pVar->GivNext() != NULL ) { ex = TX_OVERPARAM ; return true; }
+ // no second parameter
+ if ( pVar->GivNext() != NULL ) { ex = TX_OVERPARAM ; return true; }
- // get the contents of the string
- CBotString s = pVar->GivValString();
+ // get the contents of the string
+ CBotString s = pVar->GivValString();
- // puts the length of the stack
- pResult->SetValInt( s.GivLength() );
- return true;
+ // puts the length of the stack
+ pResult->SetValInt( s.GivLength() );
+ return true;
}
// int xxx ( string )
@@ -44,18 +44,18 @@ bool rStrLen( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
CBotTypResult cIntStr( CBotVar* &pVar, void* pUser )
{
- // it takes a parameter
- if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
+ // it takes a parameter
+ if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
- // to be a string
- if ( pVar->GivType() != CBotTypString )
- return CBotTypResult( TX_BADPARAM );
+ // to be a string
+ if ( pVar->GivType() != CBotTypString )
+ return CBotTypResult( TX_BADPARAM );
- // no second parameter
- if ( pVar->GivNext() != NULL ) return CBotTypResult( TX_OVERPARAM );
+ // no second parameter
+ if ( pVar->GivNext() != NULL ) return CBotTypResult( TX_OVERPARAM );
- // the end result is an integer
- return CBotTypResult( CBotTypInt );
+ // the end result is an integer
+ return CBotTypResult( CBotTypInt );
}
@@ -64,34 +64,34 @@ CBotTypResult cIntStr( CBotVar* &pVar, void* pUser )
bool rStrLeft( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
- // it takes a parameter
- if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
+ // it takes a parameter
+ if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
- // to be a string
- if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
+ // to be a string
+ if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
- // get the contents of the string
- CBotString s = pVar->GivValString();
+ // get the contents of the string
+ CBotString s = pVar->GivValString();
- // it takes a second parameter
- pVar = pVar->GivNext();
- if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
+ // it takes a second parameter
+ pVar = pVar->GivNext();
+ if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
- // which must be a number
- if ( pVar->GivType() > CBotTypDouble ) { ex = TX_BADNUM ; return true; }
+ // which must be a number
+ if ( pVar->GivType() > CBotTypDouble ) { ex = TX_BADNUM ; return true; }
- // retrieves this number
- int n = pVar->GivValInt();
+ // retrieves this number
+ int n = pVar->GivValInt();
- // no third parameter
- if ( pVar->GivNext() != NULL ) { ex = TX_OVERPARAM ; return true; }
+ // no third parameter
+ if ( pVar->GivNext() != NULL ) { ex = TX_OVERPARAM ; return true; }
- // takes the interesting part
- s = s.Left( n );
+ // takes the interesting part
+ s = s.Left( n );
- // puts on the stack
- pResult->SetValString( s );
- return true;
+ // puts on the stack
+ pResult->SetValString( s );
+ return true;
}
// string xxx ( string, int )
@@ -99,26 +99,26 @@ bool rStrLeft( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
CBotTypResult cStrStrInt( CBotVar* &pVar, void* pUser )
{
- // it takes a parameter
- if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
+ // it takes a parameter
+ if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
- // to be a string
- if ( pVar->GivType() != CBotTypString )
- return CBotTypResult( TX_BADSTRING );
+ // to be a string
+ if ( pVar->GivType() != CBotTypString )
+ return CBotTypResult( TX_BADSTRING );
- // it takes a second parameter
- pVar = pVar->GivNext();
- if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
+ // it takes a second parameter
+ pVar = pVar->GivNext();
+ if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
- // which must be a number
- if ( pVar->GivType() > CBotTypDouble )
- return CBotTypResult( TX_BADNUM );
+ // which must be a number
+ if ( pVar->GivType() > CBotTypDouble )
+ return CBotTypResult( TX_BADNUM );
- // no third parameter
- if ( pVar->GivNext() != NULL ) return CBotTypResult( TX_OVERPARAM );
+ // no third parameter
+ if ( pVar->GivNext() != NULL ) return CBotTypResult( TX_OVERPARAM );
- // the end result is a string
- return CBotTypResult( CBotTypString );
+ // the end result is a string
+ return CBotTypResult( CBotTypString );
}
// gives the right of a string
@@ -126,34 +126,34 @@ CBotTypResult cStrStrInt( CBotVar* &pVar, void* pUser )
bool rStrRight( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
- // it takes a parameter
- if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
+ // it takes a parameter
+ if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
- // to be a string
- if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
+ // to be a string
+ if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
- // get the contents of the string
- CBotString s = pVar->GivValString();
+ // get the contents of the string
+ CBotString s = pVar->GivValString();
- // it takes a second parameter
- pVar = pVar->GivNext();
- if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
+ // it takes a second parameter
+ pVar = pVar->GivNext();
+ if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
- // which must be a number
- if ( pVar->GivType() > CBotTypDouble ) { ex = TX_BADNUM ; return true; }
+ // which must be a number
+ if ( pVar->GivType() > CBotTypDouble ) { ex = TX_BADNUM ; return true; }
- // retrieves this number
- int n = pVar->GivValInt();
+ // retrieves this number
+ int n = pVar->GivValInt();
- // no third parameter
- if ( pVar->GivNext() != NULL ) { ex = TX_OVERPARAM ; return true; }
+ // no third parameter
+ if ( pVar->GivNext() != NULL ) { ex = TX_OVERPARAM ; return true; }
- // takes the interesting part
- s = s.Right( n );
+ // takes the interesting part
+ s = s.Right( n );
- // puts on the stack
- pResult->SetValString( s );
- return true;
+ // puts on the stack
+ pResult->SetValString( s );
+ return true;
}
// gives the central part of a chain
@@ -161,51 +161,51 @@ bool rStrRight( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
bool rStrMid( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
- // it takes a parameter
- if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
-
- // to be a string
- if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
-
- // get the contents of the string
- CBotString s = pVar->GivValString();
-
- // it takes a second parameter
- pVar = pVar->GivNext();
- if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
-
- // which must be a number
- if ( pVar->GivType() > CBotTypDouble ) { ex = TX_BADNUM ; return true; }
-
- // retrieves this number
- int n = pVar->GivValInt();
-
- // third parameter optional
- if ( pVar->GivNext() != NULL )
- {
- pVar = pVar->GivNext();
-
- // which must be a number
- if ( pVar->GivType() > CBotTypDouble ) { ex = TX_BADNUM ; return true; }
-
- // retrieves this number
- int l = pVar->GivValInt();
-
- // but no fourth parameter
- if ( pVar->GivNext() != NULL ){ ex = TX_OVERPARAM ; return true; }
-
- // takes the interesting part
- s = s.Mid( n, l );
- }
- else
- {
- // takes the interesting part
- s = s.Mid( n );
- }
-
- // puts on the stack
- pResult->SetValString( s );
- return true;
+ // it takes a parameter
+ if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
+
+ // to be a string
+ if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
+
+ // get the contents of the string
+ CBotString s = pVar->GivValString();
+
+ // it takes a second parameter
+ pVar = pVar->GivNext();
+ if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
+
+ // which must be a number
+ if ( pVar->GivType() > CBotTypDouble ) { ex = TX_BADNUM ; return true; }
+
+ // retrieves this number
+ int n = pVar->GivValInt();
+
+ // third parameter optional
+ if ( pVar->GivNext() != NULL )
+ {
+ pVar = pVar->GivNext();
+
+ // which must be a number
+ if ( pVar->GivType() > CBotTypDouble ) { ex = TX_BADNUM ; return true; }
+
+ // retrieves this number
+ int l = pVar->GivValInt();
+
+ // but no fourth parameter
+ if ( pVar->GivNext() != NULL ){ ex = TX_OVERPARAM ; return true; }
+
+ // takes the interesting part
+ s = s.Mid( n, l );
+ }
+ else
+ {
+ // takes the interesting part
+ s = s.Mid( n );
+ }
+
+ // puts on the stack
+ pResult->SetValString( s );
+ return true;
}
// gives the central part of a chain
@@ -213,36 +213,36 @@ bool rStrMid( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
CBotTypResult cStrStrIntInt( CBotVar* &pVar, void* pUser )
{
- // it takes a parameter
- if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
-
- // to be a string
- if ( pVar->GivType() != CBotTypString )
- return CBotTypResult( TX_BADSTRING );
-
- // it takes a second parameter
- pVar = pVar->GivNext();
- if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
-
- // which must be a number
- if ( pVar->GivType() > CBotTypDouble )
- return CBotTypResult( TX_BADNUM );
-
- // third parameter optional
- if ( pVar->GivNext() != NULL )
- {
-
- pVar = pVar->GivNext();
- // which must be a number
- if ( pVar->GivType() > CBotTypDouble )
- return CBotTypResult( TX_BADNUM );
-
- // no fourth parameter
- if ( pVar->GivNext() != NULL ) return CBotTypResult( TX_OVERPARAM );
- }
-
- // the end result is a string
- return CBotTypResult( CBotTypString );
+ // it takes a parameter
+ if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
+
+ // to be a string
+ if ( pVar->GivType() != CBotTypString )
+ return CBotTypResult( TX_BADSTRING );
+
+ // it takes a second parameter
+ pVar = pVar->GivNext();
+ if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
+
+ // which must be a number
+ if ( pVar->GivType() > CBotTypDouble )
+ return CBotTypResult( TX_BADNUM );
+
+ // third parameter optional
+ if ( pVar->GivNext() != NULL )
+ {
+
+ pVar = pVar->GivNext();
+ // which must be a number
+ if ( pVar->GivType() > CBotTypDouble )
+ return CBotTypResult( TX_BADNUM );
+
+ // no fourth parameter
+ if ( pVar->GivNext() != NULL ) return CBotTypResult( TX_OVERPARAM );
+ }
+
+ // the end result is a string
+ return CBotTypResult( CBotTypString );
}
@@ -251,23 +251,23 @@ CBotTypResult cStrStrIntInt( CBotVar* &pVar, void* pUser )
bool rStrVal( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
- // it takes a parameter
- if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
+ // it takes a parameter
+ if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
- // to be a string
- if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
+ // to be a string
+ if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
- // get the contents of the string
- CBotString s = pVar->GivValString();
+ // get the contents of the string
+ CBotString s = pVar->GivValString();
- // but no second parameter
- if ( pVar->GivNext() != NULL ){ ex = TX_OVERPARAM ; return true; }
+ // but no second parameter
+ if ( pVar->GivNext() != NULL ){ ex = TX_OVERPARAM ; return true; }
- float val = GivNumFloat(s);
+ float val = GivNumFloat(s);
- // puts the value on the stack
- pResult->SetValFloat( val );
- return true;
+ // puts the value on the stack
+ pResult->SetValFloat( val );
+ return true;
}
// float xxx ( string )
@@ -275,18 +275,18 @@ bool rStrVal( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
CBotTypResult cFloatStr( CBotVar* &pVar, void* pUser )
{
- // it takes a parameter
- if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
+ // it takes a parameter
+ if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
- // to be a string
- if ( pVar->GivType() != CBotTypString )
- return CBotTypResult( TX_BADSTRING );
+ // to be a string
+ if ( pVar->GivType() != CBotTypString )
+ return CBotTypResult( TX_BADSTRING );
- // no second parameter
- if ( pVar->GivNext() != NULL ) return CBotTypResult( TX_OVERPARAM );
+ // no second parameter
+ if ( pVar->GivNext() != NULL ) return CBotTypResult( TX_OVERPARAM );
- // the end result is a number
- return CBotTypResult( CBotTypFloat );
+ // the end result is a number
+ return CBotTypResult( CBotTypFloat );
}
@@ -295,33 +295,33 @@ CBotTypResult cFloatStr( CBotVar* &pVar, void* pUser )
bool rStrFind( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
- // it takes a parameter
- if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
+ // it takes a parameter
+ if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
- // to be a string
- if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
+ // to be a string
+ if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
- // get the contents of the string
- CBotString s = pVar->GivValString();
+ // get the contents of the string
+ CBotString s = pVar->GivValString();
- // it takes a second parameter
- pVar = pVar->GivNext();
- if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
+ // it takes a second parameter
+ pVar = pVar->GivNext();
+ if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
- // to be a string
- if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
+ // to be a string
+ if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
- // retrieves this number
- CBotString s2 = pVar->GivValString();
+ // retrieves this number
+ CBotString s2 = pVar->GivValString();
- // no third parameter
- if ( pVar->GivNext() != NULL ) { ex = TX_OVERPARAM ; return true; }
+ // no third parameter
+ if ( pVar->GivNext() != NULL ) { ex = TX_OVERPARAM ; return true; }
- // puts the result on the stack
- int res = s.Find(s2);
- pResult->SetValInt( res );
- if ( res < 0 ) pResult->SetInit( IS_NAN );
- return true;
+ // puts the result on the stack
+ int res = s.Find(s2);
+ pResult->SetValInt( res );
+ if ( res < 0 ) pResult->SetInit( IS_NAN );
+ return true;
}
// int xxx ( string, string )
@@ -329,26 +329,26 @@ bool rStrFind( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
CBotTypResult cIntStrStr( CBotVar* &pVar, void* pUser )
{
- // it takes a parameter
- if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
+ // it takes a parameter
+ if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
- // to be a string
- if ( pVar->GivType() != CBotTypString )
- return CBotTypResult( TX_BADSTRING );
+ // to be a string
+ if ( pVar->GivType() != CBotTypString )
+ return CBotTypResult( TX_BADSTRING );
- // it takes a second parameter
- pVar = pVar->GivNext();
- if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
+ // it takes a second parameter
+ pVar = pVar->GivNext();
+ if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
- // to be a string
- if ( pVar->GivType() != CBotTypString )
- return CBotTypResult( TX_BADSTRING );
+ // to be a string
+ if ( pVar->GivType() != CBotTypString )
+ return CBotTypResult( TX_BADSTRING );
- // no third parameter
- if ( pVar->GivNext() != NULL ) return CBotTypResult( TX_OVERPARAM );
+ // no third parameter
+ if ( pVar->GivNext() != NULL ) return CBotTypResult( TX_OVERPARAM );
- // the end result is a number
- return CBotTypResult( CBotTypInt );
+ // the end result is a number
+ return CBotTypResult( CBotTypInt );
}
// gives a string to uppercase
@@ -356,24 +356,24 @@ CBotTypResult cIntStrStr( CBotVar* &pVar, void* pUser )
bool rStrUpper( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
- // it takes a parameter
- if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
+ // it takes a parameter
+ if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
- // to be a string
- if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
+ // to be a string
+ if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
- // get the contents of the string
- CBotString s = pVar->GivValString();
+ // get the contents of the string
+ CBotString s = pVar->GivValString();
- // but no second parameter
- if ( pVar->GivNext() != NULL ){ ex = TX_OVERPARAM ; return true; }
+ // but no second parameter
+ if ( pVar->GivNext() != NULL ){ ex = TX_OVERPARAM ; return true; }
- s.MakeUpper();
+ s.MakeUpper();
- // puts the value on the stack
- pResult->SetValString( s );
- return true;
+ // puts the value on the stack
+ pResult->SetValString( s );
+ return true;
}
// gives a string to lowercase
@@ -381,24 +381,24 @@ bool rStrUpper( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
bool rStrLower( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
- // it takes a parameter
- if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
+ // it takes a parameter
+ if ( pVar == NULL ) { ex = TX_LOWPARAM ; return true; }
- // to be a string
- if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
+ // to be a string
+ if ( pVar->GivType() != CBotTypString ) { ex = TX_BADSTRING ; return true; }
- // get the contents of the string
- CBotString s = pVar->GivValString();
+ // get the contents of the string
+ CBotString s = pVar->GivValString();
- // but no second parameter
- if ( pVar->GivNext() != NULL ){ ex = TX_OVERPARAM ; return true; }
+ // but no second parameter
+ if ( pVar->GivNext() != NULL ){ ex = TX_OVERPARAM ; return true; }
- s.MakeLower();
+ s.MakeLower();
- // puts the value on the stack
- pResult->SetValString( s );
- return true;
+ // puts the value on the stack
+ pResult->SetValString( s );
+ return true;
}
// string xxx ( string )
@@ -406,31 +406,31 @@ bool rStrLower( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
CBotTypResult cStrStr( CBotVar* &pVar, void* pUser )
{
- // it takes a parameter
- if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
+ // it takes a parameter
+ if ( pVar == NULL ) return CBotTypResult( TX_LOWPARAM );
- // to be a string
- if ( pVar->GivType() != CBotTypString )
- return CBotTypResult( TX_BADSTRING );
+ // to be a string
+ if ( pVar->GivType() != CBotTypString )
+ return CBotTypResult( TX_BADSTRING );
- // no second parameter
- if ( pVar->GivNext() != NULL ) return CBotTypResult( TX_OVERPARAM );
+ // no second parameter
+ if ( pVar->GivNext() != NULL ) return CBotTypResult( TX_OVERPARAM );
- // the end result is a string
- return CBotTypResult( CBotTypString );
+ // the end result is a string
+ return CBotTypResult( CBotTypString );
}
void InitStringFunctions()
{
- CBotProgram::AddFunction("strlen", rStrLen, cIntStr );
- CBotProgram::AddFunction("strleft", rStrLeft, cStrStrInt );
- CBotProgram::AddFunction("strright", rStrRight, cStrStrInt );
- CBotProgram::AddFunction("strmid", rStrMid, cStrStrIntInt );
+ CBotProgram::AddFunction("strlen", rStrLen, cIntStr );
+ CBotProgram::AddFunction("strleft", rStrLeft, cStrStrInt );
+ CBotProgram::AddFunction("strright", rStrRight, cStrStrInt );
+ CBotProgram::AddFunction("strmid", rStrMid, cStrStrIntInt );
- CBotProgram::AddFunction("strval", rStrVal, cFloatStr );
- CBotProgram::AddFunction("strfind", rStrFind, cIntStrStr );
+ CBotProgram::AddFunction("strval", rStrVal, cFloatStr );
+ CBotProgram::AddFunction("strfind", rStrFind, cIntStrStr );
- CBotProgram::AddFunction("strupper", rStrUpper, cStrStr );
- CBotProgram::AddFunction("strlower", rStrLower, cStrStr );
+ CBotProgram::AddFunction("strupper", rStrUpper, cStrStr );
+ CBotProgram::AddFunction("strlower", rStrLower, cStrStr );
}
diff --git a/src/CBot/resource.h b/src/CBot/resource.h
index da1ad23..96a01ba 100644
--- a/src/CBot/resource.h
+++ b/src/CBot/resource.h
@@ -1,177 +1,177 @@
-// * 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
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-#pragma once
-#ifndef _RESOURCE_H_
-#define _RESOURCE_H_
-
-enum EID
-{
- ID_IF = 2000,
- ID_ELSE,
- ID_WHILE,
- ID_DO,
- ID_FOR,
- ID_BREAK,
- ID_CONTINUE,
- ID_SWITCH,
- ID_CASE,
- ID_DEFAULT,
- ID_TRY,
- ID_THROW,
- ID_CATCH,
- ID_FINALLY,
- ID_TXT_AND,
- ID_TXT_OR,
- ID_TXT_NOT,
- ID_RETURN,
- ID_CLASS,
- ID_EXTENDS,
- ID_SYNCHO,
- ID_NEW,
- ID_PUBLIC,
- ID_EXTERN,
- ID_FINAL,
- ID_STATIC,
- ID_PROTECTED,
- ID_PRIVATE,
- ID_REPEAT,
- ID_DEBUGDD,
- ID_INT,
- ID_FLOAT,
- ID_BOOLEAN,
- ID_STRING,
- ID_VOID,
- ID_BOOL,
-
- ID_TRUE = 2200,
- ID_FALSE,
- ID_NULL,
- ID_NAN,
-
- ID_OPENPAR = 2300,
- ID_CLOSEPAR,
- ID_OPBLK,
- ID_CLBLK,
- ID_SEP,
- ID_COMMA,
- ID_DOTS,
- ID_DOT,
- ID_OPBRK,
- ID_CLBRK,
- ID_DBLDOTS,
- ID_LOGIC,
- ID_ADD,
- ID_SUB,
- ID_MUL,
- ID_DIV,
- ID_ASS,
- ID_ASSADD,
- ID_ASSSUB,
- ID_ASSMUL,
- ID_ASSDIV,
- ID_ASSOR,
- ID_ASSAND,
- ID_ASSXOR,
- ID_ASSSL,
- ID_ASSSR,
- ID_ASSASR,
- ID_SL,
- ID_SR,
- ID_ASR,
- ID_INC,
- ID_DEC,
- ID_LO,
- ID_HI,
- ID_LS,
- ID_HS,
- ID_EQ,
- ID_NE,
- ID_AND,
- ID_XOR,
- ID_OR,
- ID_LOG_AND,
- ID_LOG_OR,
- ID_LOG_NOT,
- ID_NOT,
- ID_MODULO,
- ID_POWER,
- ID_ASSMODULO,
- TX_UNDEF = 4000,
- TX_NAN,
- ID_SUPER = 6000
-};
-#define TX_OPENPAR 5000
-#define TX_CLOSEPAR 5001
-#define TX_NOTBOOL 5002
-#define TX_UNDEFVAR 5003
-#define TX_BADLEFT 5004
-#define TX_ENDOF 5005
-#define TX_OUTCASE 5006
-#define TX_NOTERM 5007
-#define TX_CLOSEBLK 5008
-#define TX_ELSEWITHOUTIF 5009
-#define TX_OPENBLK 5010
-#define TX_BADTYPE 5011
-#define TX_REDEFVAR 5012
-#define TX_BAD2TYPE 5013
-#define TX_UNDEFCALL 5014
-#define TX_MISDOTS 5015
-#define TX_WHILE 5016
-#define TX_BREAK 5017
-#define TX_LABEL 5018
-#define TX_NOLABEL 5019
-#define TX_NOCASE 5020
-#define TX_BADNUM 5021
-#define TX_VOID 5022
-#define TX_NOTYP 5023
-#define TX_NOVAR 5024
-#define TX_NOFONC 5025
-#define TX_OVERPARAM 5026
-#define TX_REDEF 5027
-#define TX_LOWPARAM 5028
-#define TX_BADPARAM 5029
-#define TX_NUMPARAM 5030
-#define TX_NOITEM 5031
-#define TX_DOT 5032
-#define TX_NOCONST 5033
-#define TX_REDEFCLASS 5034
-#define TX_CLBRK 5035
-#define TX_RESERVED 5036
-#define TX_BADNEW 5037
-#define TX_OPBRK 5038
-#define TX_BADSTRING 5039
-#define TX_BADINDEX 5040
-#define TX_PRIVATE 5041
-#define TX_NOPUBLIC 5042
-#define TX_DIVZERO 6000
-#define TX_NOTINIT 6001
-#define TX_BADTHROW 6002
-#define TX_NORETVAL 6003
-#define TX_NORUN 6004
-#define TX_NOCALL 6005
-#define TX_NOCLASS 6006
-#define TX_NULLPT 6007
-#define TX_OPNAN 6008
-#define TX_OUTARRAY 6009
-#define TX_STACKOVER 6010
-#define TX_DELETEDPT 6011
-#define TX_FILEOPEN 6012
-#define TX_NOTOPEN 6013
-#define TX_ERRREAD 6014
-#define TX_ERRWRITE 6015
-
-#endif //_RESOURCE_H_
+// * 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
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+
+#pragma once
+#ifndef _RESOURCE_H_
+#define _RESOURCE_H_
+
+enum EID
+{
+ ID_IF = 2000,
+ ID_ELSE,
+ ID_WHILE,
+ ID_DO,
+ ID_FOR,
+ ID_BREAK,
+ ID_CONTINUE,
+ ID_SWITCH,
+ ID_CASE,
+ ID_DEFAULT,
+ ID_TRY,
+ ID_THROW,
+ ID_CATCH,
+ ID_FINALLY,
+ ID_TXT_AND,
+ ID_TXT_OR,
+ ID_TXT_NOT,
+ ID_RETURN,
+ ID_CLASS,
+ ID_EXTENDS,
+ ID_SYNCHO,
+ ID_NEW,
+ ID_PUBLIC,
+ ID_EXTERN,
+ ID_FINAL,
+ ID_STATIC,
+ ID_PROTECTED,
+ ID_PRIVATE,
+ ID_REPEAT,
+ ID_DEBUGDD,
+ ID_INT,
+ ID_FLOAT,
+ ID_BOOLEAN,
+ ID_STRING,
+ ID_VOID,
+ ID_BOOL,
+
+ ID_TRUE = 2200,
+ ID_FALSE,
+ ID_NULL,
+ ID_NAN,
+
+ ID_OPENPAR = 2300,
+ ID_CLOSEPAR,
+ ID_OPBLK,
+ ID_CLBLK,
+ ID_SEP,
+ ID_COMMA,
+ ID_DOTS,
+ ID_DOT,
+ ID_OPBRK,
+ ID_CLBRK,
+ ID_DBLDOTS,
+ ID_LOGIC,
+ ID_ADD,
+ ID_SUB,
+ ID_MUL,
+ ID_DIV,
+ ID_ASS,
+ ID_ASSADD,
+ ID_ASSSUB,
+ ID_ASSMUL,
+ ID_ASSDIV,
+ ID_ASSOR,
+ ID_ASSAND,
+ ID_ASSXOR,
+ ID_ASSSL,
+ ID_ASSSR,
+ ID_ASSASR,
+ ID_SL,
+ ID_SR,
+ ID_ASR,
+ ID_INC,
+ ID_DEC,
+ ID_LO,
+ ID_HI,
+ ID_LS,
+ ID_HS,
+ ID_EQ,
+ ID_NE,
+ ID_AND,
+ ID_XOR,
+ ID_OR,
+ ID_LOG_AND,
+ ID_LOG_OR,
+ ID_LOG_NOT,
+ ID_NOT,
+ ID_MODULO,
+ ID_POWER,
+ ID_ASSMODULO,
+ TX_UNDEF = 4000,
+ TX_NAN,
+ ID_SUPER = 6000
+};
+#define TX_OPENPAR 5000
+#define TX_CLOSEPAR 5001
+#define TX_NOTBOOL 5002
+#define TX_UNDEFVAR 5003
+#define TX_BADLEFT 5004
+#define TX_ENDOF 5005
+#define TX_OUTCASE 5006
+#define TX_NOTERM 5007
+#define TX_CLOSEBLK 5008
+#define TX_ELSEWITHOUTIF 5009
+#define TX_OPENBLK 5010
+#define TX_BADTYPE 5011
+#define TX_REDEFVAR 5012
+#define TX_BAD2TYPE 5013
+#define TX_UNDEFCALL 5014
+#define TX_MISDOTS 5015
+#define TX_WHILE 5016
+#define TX_BREAK 5017
+#define TX_LABEL 5018
+#define TX_NOLABEL 5019
+#define TX_NOCASE 5020
+#define TX_BADNUM 5021
+#define TX_VOID 5022
+#define TX_NOTYP 5023
+#define TX_NOVAR 5024
+#define TX_NOFONC 5025
+#define TX_OVERPARAM 5026
+#define TX_REDEF 5027
+#define TX_LOWPARAM 5028
+#define TX_BADPARAM 5029
+#define TX_NUMPARAM 5030
+#define TX_NOITEM 5031
+#define TX_DOT 5032
+#define TX_NOCONST 5033
+#define TX_REDEFCLASS 5034
+#define TX_CLBRK 5035
+#define TX_RESERVED 5036
+#define TX_BADNEW 5037
+#define TX_OPBRK 5038
+#define TX_BADSTRING 5039
+#define TX_BADINDEX 5040
+#define TX_PRIVATE 5041
+#define TX_NOPUBLIC 5042
+#define TX_DIVZERO 6000
+#define TX_NOTINIT 6001
+#define TX_BADTHROW 6002
+#define TX_NORETVAL 6003
+#define TX_NORUN 6004
+#define TX_NOCALL 6005
+#define TX_NOCLASS 6006
+#define TX_NULLPT 6007
+#define TX_OPNAN 6008
+#define TX_OUTARRAY 6009
+#define TX_STACKOVER 6010
+#define TX_DELETEDPT 6011
+#define TX_FILEOPEN 6012
+#define TX_NOTOPEN 6013
+#define TX_ERRREAD 6014
+#define TX_ERRWRITE 6015
+
+#endif //_RESOURCE_H_