diff options
author | Piotr Dziwinski <piotrdz@gmail.com> | 2012-08-08 22:35:17 +0200 |
---|---|---|
committer | Piotr Dziwinski <piotrdz@gmail.com> | 2012-08-08 22:35:17 +0200 |
commit | bc24b9f9e516e657fcc0034808e010287fc2e393 (patch) | |
tree | e9c7c57316dc8b49efec1d8038de71381be61085 /src/CBot | |
parent | beca66071c6a2d82da63fb238cdc86e68ff96bdb (diff) | |
download | colobot-bc24b9f9e516e657fcc0034808e010287fc2e393.tar.gz colobot-bc24b9f9e516e657fcc0034808e010287fc2e393.tar.bz2 colobot-bc24b9f9e516e657fcc0034808e010287fc2e393.zip |
Whitespace fix
Diffstat (limited to 'src/CBot')
-rw-r--r-- | src/CBot/CBotAddExpr.cpp | 144 | ||||
-rw-r--r-- | src/CBot/CBotClass.cpp | 1236 | ||||
-rw-r--r-- | src/CBot/CBotCompExpr.cpp | 172 | ||||
-rw-r--r-- | src/CBot/CBotFunction.cpp | 2744 | ||||
-rw-r--r-- | src/CBot/CBotIf.cpp | 224 | ||||
-rw-r--r-- | src/CBot/CBotProgram.cpp | 1462 | ||||
-rw-r--r-- | src/CBot/CBotString.cpp | 1384 | ||||
-rw-r--r-- | src/CBot/CBotToken.cpp | 1124 | ||||
-rw-r--r-- | src/CBot/CBotToken.h | 76 | ||||
-rw-r--r-- | src/CBot/CBotTwoOpExpr.cpp | 932 | ||||
-rw-r--r-- | src/CBot/CBotWhile.cpp | 2012 | ||||
-rw-r--r-- | src/CBot/ClassFILE.cpp | 856 | ||||
-rw-r--r-- | src/CBot/StringFunctions.cpp | 494 | ||||
-rw-r--r-- | src/CBot/resource.h | 354 |
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_ |