2012-03-19 11:44:39 +00:00
|
|
|
|
// * This file is part of the COLOBOT source code
|
2012-03-09 16:08:05 +00:00
|
|
|
|
// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
|
|
|
|
|
// *
|
|
|
|
|
// * This program is free software: you can redistribute it and/or modify
|
|
|
|
|
// * it under the terms of the GNU General Public License as published by
|
|
|
|
|
// * the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
// * (at your option) any later version.
|
|
|
|
|
// *
|
|
|
|
|
// * This program is distributed in the hope that it will be useful,
|
|
|
|
|
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// * GNU General Public License for more details.
|
|
|
|
|
// *
|
|
|
|
|
// * You should have received a copy of the GNU General Public License
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// * along with this program. If not, see http://www.gnu.org/licenses/.///////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Gestion des variables de type classe
|
|
|
|
|
//
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
#include "CBot.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CBotClass* CBotClass::m_ExClass = NULL;
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
CBotClass::CBotClass(const char* name, CBotClass* pPapa, bool bIntrinsic)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
m_pParent = pPapa;
|
|
|
|
|
m_name = name;
|
|
|
|
|
m_pVar = NULL;
|
|
|
|
|
m_next = NULL;
|
|
|
|
|
m_pCalls = NULL;
|
|
|
|
|
m_pMethod = NULL;
|
|
|
|
|
m_rMaj = NULL;
|
2012-07-04 20:14:28 +00:00
|
|
|
|
m_IsDef = true;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// se place tout seul dans la liste
|
|
|
|
|
if (m_ExClass) m_ExClass->m_ExPrev = this;
|
|
|
|
|
m_ExNext = m_ExClass;
|
|
|
|
|
m_ExPrev = NULL;
|
|
|
|
|
m_ExClass = this;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CBotClass::~CBotClass()
|
|
|
|
|
{
|
|
|
|
|
// retire la classe de la liste
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
delete m_pVar;
|
|
|
|
|
delete m_pCalls;
|
|
|
|
|
delete m_pMethod;
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
delete m_next; // lib<69>re toutes celle de ce niveau
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CBotClass::Free()
|
|
|
|
|
{
|
|
|
|
|
while ( m_ExClass != NULL )
|
|
|
|
|
{
|
|
|
|
|
delete m_ExClass;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CBotClass::Purge()
|
|
|
|
|
{
|
|
|
|
|
if ( this == NULL ) return;
|
|
|
|
|
|
|
|
|
|
delete m_pVar;
|
|
|
|
|
m_pVar = NULL;
|
|
|
|
|
delete m_pCalls;
|
|
|
|
|
m_pCalls = NULL;
|
|
|
|
|
delete m_pMethod;
|
|
|
|
|
m_pMethod = NULL;
|
2012-07-04 20:14:28 +00:00
|
|
|
|
m_IsDef = false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
m_nbVar = m_pParent == NULL ? 0 : m_pParent->m_nbVar;
|
|
|
|
|
|
|
|
|
|
m_next->Purge();
|
2012-03-19 11:44:39 +00:00
|
|
|
|
m_next = NULL; // n'appartient plus <20> cette cha<68>ne
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool CBotClass::Lock(CBotProgram* p)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
int i = m_cptLock++;
|
|
|
|
|
|
|
|
|
|
if ( i == 0 )
|
|
|
|
|
{
|
|
|
|
|
m_cptOne = 1;
|
|
|
|
|
m_ProgInLock[0] = p;
|
2012-07-04 20:14:28 +00:00
|
|
|
|
return true;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
if ( p == m_ProgInLock[0] )
|
|
|
|
|
{
|
|
|
|
|
m_cptOne++;
|
2012-03-19 11:44:39 +00:00
|
|
|
|
m_cptLock--; // a d<>j<EFBFBD> <20>t<EFBFBD> compt<70>
|
2012-07-04 20:14:28 +00:00
|
|
|
|
return true;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for ( int j = 1 ; j <= i ; j++)
|
|
|
|
|
{
|
|
|
|
|
if ( p == m_ProgInLock[j] )
|
|
|
|
|
{
|
|
|
|
|
m_cptLock--;
|
2012-07-04 20:14:28 +00:00
|
|
|
|
return false; // d<>j<EFBFBD> en attente
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( i < 5 ) // maxi 5 en attente
|
|
|
|
|
{
|
|
|
|
|
m_ProgInLock[i] = p; // se place dans la queue
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
m_cptLock--;
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CBotClass::Unlock()
|
|
|
|
|
{
|
|
|
|
|
if ( --m_cptOne > 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CBotClass::FreeLock(CBotProgram* p)
|
|
|
|
|
{
|
|
|
|
|
CBotClass* pClass = m_ExClass;
|
|
|
|
|
|
|
|
|
|
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--;
|
|
|
|
|
|
|
|
|
|
pClass = pClass->m_ExNext;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool CBotClass::AddItem(CBotString name, CBotTypResult type, int mPrivate)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
CBotToken token(name, CBotString());
|
|
|
|
|
CBotClass* pClass = type.GivClass();
|
|
|
|
|
|
|
|
|
|
CBotVar* pVar = CBotVar::Create( name, type );
|
|
|
|
|
/// pVar->SetUniqNum(CBotVar::NextUniqNum());
|
|
|
|
|
pVar->SetPrivate( mPrivate );
|
|
|
|
|
|
|
|
|
|
if ( pClass != NULL )
|
|
|
|
|
{
|
|
|
|
|
// pVar->SetClass(pClass);
|
|
|
|
|
if ( type.Eq(CBotTypClass) )
|
|
|
|
|
{
|
|
|
|
|
// ajoute une instruction new pour initialiser l'object
|
|
|
|
|
pVar->m_InitExpr = new CBotNew() ;
|
|
|
|
|
CBotToken nom( pClass->GivName() );
|
|
|
|
|
pVar->m_InitExpr->SetToken(&nom);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return AddItem( pVar );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool CBotClass::AddItem(CBotVar* pVar)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
pVar->SetUniqNum(++m_nbVar);
|
|
|
|
|
|
|
|
|
|
if ( m_pVar == NULL ) m_pVar = pVar;
|
|
|
|
|
else m_pVar->AddNext(pVar);
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
return true;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CBotClass::AddNext(CBotClass* pClass)
|
|
|
|
|
{
|
|
|
|
|
CBotClass* p = this;
|
|
|
|
|
while (p->m_next != NULL) p = p->m_next;
|
|
|
|
|
|
|
|
|
|
p->m_next = pClass;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CBotString CBotClass::GivName()
|
|
|
|
|
{
|
|
|
|
|
return m_name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CBotClass* CBotClass::GivParent()
|
|
|
|
|
{
|
|
|
|
|
if ( this == NULL ) return NULL;
|
|
|
|
|
return m_pParent;
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool CBotClass::IsChildOf(CBotClass* pClass)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
CBotClass* p = this;
|
|
|
|
|
while ( p != NULL )
|
|
|
|
|
{
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if ( p == pClass ) return true;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
p = p->m_pParent;
|
|
|
|
|
}
|
2012-07-04 20:14:28 +00:00
|
|
|
|
return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CBotVar* CBotClass::GivVar()
|
|
|
|
|
{
|
|
|
|
|
return m_pVar;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CBotVar* CBotClass::GivItem(const char* name)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CBotVar* CBotClass::GivItemRef(int nIdent)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool CBotClass::IsIntrinsic()
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
return m_bIntrinsic;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CBotClass* CBotClass::Find(CBotToken* &pToken)
|
|
|
|
|
{
|
|
|
|
|
return Find(pToken->GivString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CBotClass* CBotClass::Find(const char* name)
|
|
|
|
|
{
|
|
|
|
|
CBotClass* p = m_ExClass;
|
|
|
|
|
|
|
|
|
|
while ( p != NULL )
|
|
|
|
|
{
|
|
|
|
|
if ( p->GivName() == name ) return p;
|
|
|
|
|
p = p->m_ExNext;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool CBotClass::AddFunction(const char* name,
|
|
|
|
|
bool rExec (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception),
|
2012-03-08 18:32:05 +00:00
|
|
|
|
CBotTypResult rCompile (CBotVar* pThis, CBotVar* &pVar))
|
|
|
|
|
{
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// m<>morise les pointeurs aux deux fonctions
|
2012-03-08 18:32:05 +00:00
|
|
|
|
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;
|
2012-03-19 11:44:39 +00:00
|
|
|
|
else m_pCalls->AddNext(p); // ajoute <20> la liste
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
return true;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool CBotClass::AddUpdateFunc( void rMaj ( CBotVar* pThis, void* pUser ) )
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
m_rMaj = rMaj;
|
2012-07-04 20:14:28 +00:00
|
|
|
|
return true;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// compile une m<>thode associ<63>e <20> une instance de classe
|
|
|
|
|
// la m<>thode peut <20>tre d<>clar<61>e par AddFunction ou par l'utilisateur
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
CBotTypResult CBotClass::CompileMethode(const char* name,
|
|
|
|
|
CBotVar* pThis, CBotVar** ppParams,
|
|
|
|
|
CBotCStack* pStack, long& nIdent)
|
|
|
|
|
{
|
2012-03-19 11:44:39 +00:00
|
|
|
|
nIdent = 0; // oublie le pr<70>c<EFBFBD>dent s'il y a lieu
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// recherche dans les m<>thodes d<>clar<61>es par AddFunction
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
CBotTypResult r = m_pCalls->CompileCall(name, pThis, ppParams, pStack, nIdent);
|
|
|
|
|
if ( r.GivType() >= 0) return r;
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// recherche dans les m<>thodes d<>clar<61>es par l'utilisateur
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// ex<65>cute une m<>thode
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool CBotClass::ExecuteMethode(long& nIdent, const char* name,
|
2012-03-08 18:32:05 +00:00
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
ret = m_pMethod->DoCall(nIdent, name, pThis, ppParams, pStack, pToken, this);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// r<>tabli la pile d'ex<65>cution
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
void CBotClass::RestoreMethode(long& nIdent, const char* name, CBotVar* pThis,
|
|
|
|
|
CBotVar** ppParams, CBotStack* &pStack)
|
|
|
|
|
{
|
|
|
|
|
m_pMethod->RestoreCall(nIdent, name, pThis, ppParams, pStack, this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool CBotClass::SaveStaticState(FILE* pf)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if (!WriteWord( pf, CBOTVERSION*2)) return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// sauve l'<27>tat des variables statiques dans les classes
|
2012-03-08 18:32:05 +00:00
|
|
|
|
CBotClass* p = m_ExClass;
|
|
|
|
|
|
|
|
|
|
while ( p != NULL )
|
|
|
|
|
{
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if (!WriteWord( pf, 1)) return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
// enregistre le nom de la classe
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if (!WriteString( pf, p->GivName() )) return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
CBotVar* pv = p->GivVar();
|
|
|
|
|
while( pv != NULL )
|
|
|
|
|
{
|
|
|
|
|
if ( pv->IsStatic() )
|
|
|
|
|
{
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if (!WriteWord( pf, 1)) return false;
|
|
|
|
|
if (!WriteString( pf, pv->GivName() )) return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if ( !pv->Save0State(pf)) return false; // ent<6E>te commune
|
|
|
|
|
if ( !pv->Save1State(pf) ) return false; // sauve selon la classe fille
|
|
|
|
|
if ( !WriteWord( pf, 0)) return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
pv = pv->GivNext();
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if (!WriteWord( pf, 0)) return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
p = p->m_ExNext;
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if (!WriteWord( pf, 0)) return false;
|
|
|
|
|
return true;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool CBotClass::RestoreStaticState(FILE* pf)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
CBotString ClassName, VarName;
|
|
|
|
|
CBotClass* pClass;
|
2012-07-04 20:14:28 +00:00
|
|
|
|
unsigned short w;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if (!ReadWord( pf, w )) return false;
|
|
|
|
|
if ( w != CBOTVERSION*2 ) return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
while (true)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if (!ReadWord( pf, w )) return false;
|
|
|
|
|
if ( w == 0 ) return true;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if (!ReadString( pf, ClassName )) return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
pClass = Find(ClassName);
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
while (true)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if (!ReadWord( pf, w )) return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
if ( w == 0 ) break;
|
|
|
|
|
|
|
|
|
|
CBotVar* pVar = NULL;
|
|
|
|
|
CBotVar* pv = NULL;
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if (!ReadString( pf, VarName )) return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
if ( pClass != NULL ) pVar = pClass->GivItem(VarName);
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if (!CBotVar::RestoreState(pf, pv)) return false; // la variable temp
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
if ( pVar != NULL ) pVar->Copy(pv);
|
|
|
|
|
delete pv;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-07-04 20:14:28 +00:00
|
|
|
|
return true;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
CBotClassInst::CBotClassInst()
|
|
|
|
|
{
|
|
|
|
|
m_next = NULL;
|
|
|
|
|
m_var = NULL;
|
|
|
|
|
m_Parameters = NULL;
|
|
|
|
|
m_expr = NULL;
|
2012-07-04 20:14:28 +00:00
|
|
|
|
m_hasParams = false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
m_nMethodeIdent = 0;
|
|
|
|
|
name = "CBotClassInst";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CBotClassInst::~CBotClassInst()
|
|
|
|
|
{
|
|
|
|
|
delete m_var;
|
|
|
|
|
// delete m_next; // fait par le destructeur de la classe de base ~CBotInstr()
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// d<>finition de pointeur(s) <20> un objet
|
2012-03-08 18:32:05 +00:00
|
|
|
|
// du style
|
|
|
|
|
// CPoint A, B ;
|
|
|
|
|
|
|
|
|
|
CBotInstr* CBotClassInst::Compile(CBotToken* &p, CBotCStack* pStack, CBotClass* pClass)
|
|
|
|
|
{
|
|
|
|
|
// cherche la classe correspondante
|
|
|
|
|
if ( pClass == NULL )
|
|
|
|
|
{
|
|
|
|
|
pStack->SetStartError(p->GivStart());
|
|
|
|
|
pClass = CBotClass::Find(p);
|
|
|
|
|
if ( pClass == NULL )
|
|
|
|
|
{
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// pas trouv<75> ? c'est bizare
|
2012-03-08 18:32:05 +00:00
|
|
|
|
pStack->SetError(TX_NOCLASS, p);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
p = p->GivNext();
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool bIntrinsic = pClass->IsIntrinsic();
|
|
|
|
|
CBotTypResult type = CBotTypResult( bIntrinsic ? CBotTypIntrinsic : CBotTypPointer, pClass );
|
2012-03-08 18:32:05 +00:00
|
|
|
|
CBotClassInst* inst = (CBotClassInst*)CompileArray(p, pStack, type);
|
|
|
|
|
if ( inst != NULL || !pStack->IsOk() ) return inst;
|
|
|
|
|
|
|
|
|
|
CBotCStack* pStk = pStack->TokenStack();
|
|
|
|
|
|
|
|
|
|
inst = new CBotClassInst();
|
2012-07-04 20:14:28 +00:00
|
|
|
|
/// \TODO Need to be revised and fixed after adding unit tests
|
|
|
|
|
CBotToken token(pClass->GivName(), CBotString(), p->GivStart(), p->GivEnd());
|
|
|
|
|
inst->SetToken(&token);
|
2012-03-08 18:32:05 +00:00
|
|
|
|
CBotToken* vartoken = p;
|
|
|
|
|
|
|
|
|
|
if ( NULL != (inst->m_var = CBotLeftExprVar::Compile( p, pStk )) )
|
|
|
|
|
{
|
|
|
|
|
((CBotLeftExprVar*)inst->m_var)->m_typevar = type;
|
2012-03-19 11:44:39 +00:00
|
|
|
|
if (pStk->CheckVarLocal(vartoken)) // red<65>finition de la variable
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
pStk->SetStartError(vartoken->GivStart());
|
|
|
|
|
pStk->SetError(TX_REDEFVAR, vartoken->GivEnd());
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IsOfType(p, ID_OPBRK)) // avec des indices ?
|
|
|
|
|
{
|
|
|
|
|
delete inst; // n'est pas de type CBotInt
|
|
|
|
|
p = vartoken; // revient sur le nom de la variable
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// compile une d<>claration de tableau
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
inst = (CBotClassInst*)CBotInstArray::Compile( p, pStk, type );
|
|
|
|
|
|
|
|
|
|
if (!pStk->IsOk() )
|
|
|
|
|
{
|
|
|
|
|
pStk->SetError(TX_CLBRK, p->GivStart());
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
2012-03-19 11:44:39 +00:00
|
|
|
|
goto suite; // pas d'assignation, variable d<>j<EFBFBD> cr<63><72>e
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CBotVar* var;
|
2012-03-19 11:44:39 +00:00
|
|
|
|
var = CBotVar::Create(vartoken->GivString(), type); // cr<63>e l'instance
|
2012-03-08 18:32:05 +00:00
|
|
|
|
// var->SetClass(pClass);
|
|
|
|
|
var->SetUniqNum(
|
|
|
|
|
((CBotLeftExprVar*)inst->m_var)->m_nIdent = CBotVar::NextUniqNum());
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// lui attribut un num<75>ro unique
|
2012-03-08 18:32:05 +00:00
|
|
|
|
pStack->AddVar(var); // la place sur la pile
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// regarde s'il y a des param<61>tres
|
2012-03-08 18:32:05 +00:00
|
|
|
|
inst->m_hasParams = (p->GivType() == ID_OPENPAR);
|
|
|
|
|
|
|
|
|
|
CBotVar* ppVars[1000];
|
|
|
|
|
inst->m_Parameters = CompileParams(p, pStk, ppVars);
|
|
|
|
|
if ( !pStk->IsOk() ) goto error;
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// s'il y a des param<61>tres, fait l'<27>quivalent de l'instruction new
|
|
|
|
|
// CPoint A ( 0, 0 ) est <20>quivalent <20>
|
2012-03-08 18:32:05 +00:00
|
|
|
|
// CPoint A = new CPoint( 0, 0 )
|
|
|
|
|
|
|
|
|
|
// if ( NULL != inst->m_Parameters )
|
|
|
|
|
if ( inst->m_hasParams )
|
|
|
|
|
{
|
|
|
|
|
// le constructeur existe-il ?
|
|
|
|
|
// CBotString noname;
|
|
|
|
|
CBotTypResult r = pClass->CompileMethode(pClass->GivName(), var, ppVars, pStk, inst->m_nMethodeIdent);
|
2012-03-19 11:44:39 +00:00
|
|
|
|
delete pStk->TokenStack(); // lib<69>re le suppl<70>ment de pile
|
2012-03-08 18:32:05 +00:00
|
|
|
|
int typ = r.GivType();
|
|
|
|
|
|
|
|
|
|
if (typ == TX_UNDEFCALL)
|
|
|
|
|
{
|
|
|
|
|
// si le constructeur n'existe pas
|
2012-03-19 11:44:39 +00:00
|
|
|
|
if (inst->m_Parameters != NULL) // avec des param<61>tres
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
pStk->SetError(TX_NOCONST, vartoken);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
typ = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (typ>20)
|
|
|
|
|
{
|
|
|
|
|
pStk->SetError(typ, vartoken->GivEnd());
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IsOfType(p, ID_ASS)) // avec une assignation ?
|
|
|
|
|
{
|
|
|
|
|
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 )
|
|
|
|
|
{
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// n'utilise pas le r<>sultat sur la pile, pour imposer la classe
|
2012-03-08 18:32:05 +00:00
|
|
|
|
CBotVar* pvar = CBotVar::Create("", pClass);
|
2012-03-19 11:44:39 +00:00
|
|
|
|
var->SetPointer( pvar ); // var d<>j<EFBFBD> d<>clar<61>e pointe l'instance
|
2012-03-08 18:32:05 +00:00
|
|
|
|
delete pvar; // supprime le second pointeur
|
|
|
|
|
}
|
2012-07-04 20:14:28 +00:00
|
|
|
|
var->SetInit(true); // marque le pointeur comme init
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
else if (inst->m_hasParams)
|
|
|
|
|
{
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// cr<63>e l'objet sur le "tas"
|
2012-03-08 18:32:05 +00:00
|
|
|
|
// avec un pointeur sur cet objet
|
|
|
|
|
if ( !bIntrinsic )
|
|
|
|
|
{
|
|
|
|
|
CBotVar* pvar = CBotVar::Create("", pClass);
|
2012-03-19 11:44:39 +00:00
|
|
|
|
var->SetPointer( pvar ); // var d<>j<EFBFBD> d<>clar<61>e pointe l'instance
|
2012-03-08 18:32:05 +00:00
|
|
|
|
delete pvar; // supprime le second pointeur
|
|
|
|
|
}
|
|
|
|
|
var->SetInit(2); // marque le pointeur comme init
|
|
|
|
|
}
|
|
|
|
|
suite:
|
2012-03-19 11:44:39 +00:00
|
|
|
|
if (IsOfType(p, ID_COMMA)) // plusieurs d<>finitions encha<68>n<EFBFBD>es
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
if ( NULL != ( inst->m_next = CBotClassInst::Compile(p, pStk, pClass) )) // compile la suivante
|
|
|
|
|
{
|
|
|
|
|
return pStack->Return(inst, pStk);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
if (IsOfType(p, ID_SEP)) // instruction termin<69>e
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
return pStack->Return(inst, pStk);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pStk->SetError(TX_ENDOF, p->GivStart());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
delete inst;
|
|
|
|
|
return pStack->Return(NULL, pStk);
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// d<>claration de l'instance d'une classe, par exemple:
|
2012-03-08 18:32:05 +00:00
|
|
|
|
// CPoint A, B;
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool CBotClassInst::Execute(CBotStack* &pj)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
CBotVar* pThis = NULL;
|
|
|
|
|
|
|
|
|
|
CBotStack* pile = pj->AddStack(this);//indispensable pour SetState()
|
2012-07-04 20:14:28 +00:00
|
|
|
|
// if ( pile == EOX ) return true;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
CBotToken* pt = &m_token;
|
|
|
|
|
CBotClass* pClass = CBotClass::Find(pt);
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool bIntrincic = pClass->IsIntrinsic();
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// cr<63>e la variable de type pointeur <20> l'objet
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
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 ));
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
pThis->SetUniqNum(((CBotLeftExprVar*)m_var)->m_nIdent); // lui attribut un num<75>ro unique
|
2012-03-08 18:32:05 +00:00
|
|
|
|
pile->AddVar(pThis); // la place sur la pile
|
|
|
|
|
pile->IncState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( pThis == NULL ) pThis = pile->FindVar(((CBotLeftExprVar*)m_var)->m_nIdent);
|
|
|
|
|
|
|
|
|
|
if ( pile->GivState()<3)
|
|
|
|
|
{
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// y a-t-il une assignation ou des param<61>tres (constructeur)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
// CBotVarClass* pInstance = NULL;
|
|
|
|
|
|
|
|
|
|
if ( m_expr != NULL )
|
|
|
|
|
{
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// <20>value l'expression pour l'assignation
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if (!m_expr->Execute(pile)) return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
if ( bIntrincic )
|
|
|
|
|
{
|
|
|
|
|
CBotVar* pv = pile->GivVar();
|
|
|
|
|
if ( pv == NULL || pv->GivPointer() == NULL )
|
|
|
|
|
{
|
|
|
|
|
pile->SetError(TX_NULLPT, &m_token);
|
|
|
|
|
return pj->Return(pile);
|
|
|
|
|
}
|
2012-07-04 20:14:28 +00:00
|
|
|
|
pThis->Copy(pile->GivVar(), false);
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
CBotVarClass* pInstance;
|
|
|
|
|
pInstance = ((CBotVarPointer*)pile->GivVar())->GivPointer(); // valeur pour l'assignation
|
|
|
|
|
pThis->SetPointer(pInstance);
|
|
|
|
|
}
|
2012-07-04 20:14:28 +00:00
|
|
|
|
pThis->SetInit(true);
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if ( m_hasParams )
|
|
|
|
|
{
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// <20>value le constructeur d'une instance
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
if ( !bIntrincic && pile->GivState() == 1)
|
|
|
|
|
{
|
|
|
|
|
CBotToken* pt = &m_token;
|
|
|
|
|
CBotClass* pClass = CBotClass::Find(pt);
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// cr<63>e une instance de la classe demand<6E>e
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
CBotVarClass* pInstance;
|
|
|
|
|
pInstance = (CBotVarClass*)CBotVar::Create("", pClass);
|
|
|
|
|
pThis->SetPointer(pInstance);
|
|
|
|
|
delete pInstance;
|
|
|
|
|
|
|
|
|
|
pile->IncState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CBotVar* ppVars[1000];
|
|
|
|
|
CBotStack* pile2 = pile;
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
CBotInstr* p = m_Parameters;
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// <20>value les param<61>tres
|
2012-03-08 18:32:05 +00:00
|
|
|
|
// et place les valeurs sur la pile
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// pour pouvoir <20>tre interrompu n'importe quand
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if ( p != NULL) while ( true )
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
2012-03-19 11:44:39 +00:00
|
|
|
|
pile2 = pile2->AddStack(); // de la place sur la pile pour les r<>sultats
|
2012-03-08 18:32:05 +00:00
|
|
|
|
if ( pile2->GivState() == 0 )
|
|
|
|
|
{
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if (!p->Execute(pile2)) return false; // interrompu ici ?
|
2012-03-08 18:32:05 +00:00
|
|
|
|
pile2->SetState(1);
|
|
|
|
|
}
|
|
|
|
|
ppVars[i++] = pile2->GivVar();
|
|
|
|
|
p = p->GivNext();
|
|
|
|
|
if ( p == NULL) break;
|
|
|
|
|
}
|
|
|
|
|
ppVars[i] = NULL;
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// cr<63>e une variable pour le r<>sultat
|
2012-03-08 18:32:05 +00:00
|
|
|
|
CBotVar* pResult = NULL; // constructeurs toujours void
|
|
|
|
|
|
|
|
|
|
if ( !pClass->ExecuteMethode(m_nMethodeIdent, pClass->GivName(),
|
|
|
|
|
pThis, ppVars,
|
2012-07-04 20:14:28 +00:00
|
|
|
|
pResult, pile2, GivToken())) return false; // interrompu
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
pThis->SetInit(true);
|
2012-03-19 11:44:39 +00:00
|
|
|
|
pThis->ConstructorSet(); // signale que le constructeur a <20>t<EFBFBD> appel<65>
|
|
|
|
|
pile->Return(pile2); // lib<69>re un bout de pile
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
// pInstance = pThis->GivPointer();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if ( !bIntrincic ) pThis->SetPointer(pInstance); // le fait pointer l'instance
|
|
|
|
|
|
|
|
|
|
pile->SetState(3); // fini cette partie
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if ( pile->IfStep() ) return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
if ( m_next2b != NULL &&
|
2012-07-04 20:14:28 +00:00
|
|
|
|
!m_next2b->Execute(pile)) return false; // autre(s) d<>finition(s)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
return pj->Return( pile ); // transmet en dessous
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
void CBotClassInst::RestoreState(CBotStack* &pj, bool bMain)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
CBotVar* pThis = NULL;
|
|
|
|
|
|
|
|
|
|
CBotStack* pile = pj;
|
|
|
|
|
if ( bMain ) pile = pj->RestoreStack(this);
|
|
|
|
|
if ( pile == NULL ) return;
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// cr<63>e la variable de type pointeur <20> l'objet
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
CBotString name = m_var->m_token.GivString();
|
|
|
|
|
pThis = pile->FindVar(name);
|
2012-03-19 11:44:39 +00:00
|
|
|
|
pThis->SetUniqNum(((CBotLeftExprVar*)m_var)->m_nIdent); // lui attribut un num<75>ro unique
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CBotToken* pt = &m_token;
|
|
|
|
|
CBotClass* pClass = CBotClass::Find(pt);
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool bIntrincic = pClass->IsIntrinsic();
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
if ( bMain && pile->GivState()<3)
|
|
|
|
|
{
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// y a-t-il une assignation ou des param<61>tres (constructeur)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
// CBotVarClass* pInstance = NULL;
|
|
|
|
|
|
|
|
|
|
if ( m_expr != NULL )
|
|
|
|
|
{
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// <20>value l'expression pour l'assignation
|
2012-03-08 18:32:05 +00:00
|
|
|
|
m_expr->RestoreState(pile, bMain);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if ( m_hasParams )
|
|
|
|
|
{
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// <20>value le constructeur d'une instance
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
if ( !bIntrincic && pile->GivState() == 1)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CBotVar* ppVars[1000];
|
|
|
|
|
CBotStack* pile2 = pile;
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
CBotInstr* p = m_Parameters;
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// <20>value les param<61>tres
|
2012-03-08 18:32:05 +00:00
|
|
|
|
// et place les valeurs sur la pile
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// pour pouvoir <20>tre interrompu n'importe quand
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if ( p != NULL) while ( true )
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
2012-03-19 11:44:39 +00:00
|
|
|
|
pile2 = pile2->RestoreStack(); // de la place sur la pile pour les r<>sultats
|
2012-03-08 18:32:05 +00:00
|
|
|
|
if ( pile2 == NULL ) return;
|
|
|
|
|
|
|
|
|
|
if ( pile2->GivState() == 0 )
|
|
|
|
|
{
|
|
|
|
|
p->RestoreState(pile2, bMain); // interrompu ici ?
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ppVars[i++] = pile2->GivVar();
|
|
|
|
|
p = p->GivNext();
|
|
|
|
|
if ( p == NULL) break;
|
|
|
|
|
}
|
|
|
|
|
ppVars[i] = NULL;
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// cr<63>e une variable pour le r<>sultat
|
2012-03-08 18:32:05 +00:00
|
|
|
|
CBotVar* pResult = NULL; // constructeurs toujours void
|
|
|
|
|
|
|
|
|
|
pClass->RestoreMethode(m_nMethodeIdent, pClass->GivName(), pThis, ppVars, pile2);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( m_next2b != NULL )
|
2012-03-19 11:44:39 +00:00
|
|
|
|
m_next2b->RestoreState(pile, bMain); // autre(s) d<>finition(s)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// test si un nom de proc<6F>dure est d<>j<EFBFBD> d<>fini quelque part
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
bool CBotClass::CheckCall(CBotToken* &pToken, CBotDefParam* pParam)
|
2012-03-08 18:32:05 +00:00
|
|
|
|
{
|
|
|
|
|
CBotString name = pToken->GivString();
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
if ( CBotCall::CheckCall(name) ) return true;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
|
|
|
|
|
CBotFunction* pp = m_pMethod;
|
|
|
|
|
while ( pp != NULL )
|
|
|
|
|
{
|
|
|
|
|
if ( pToken->GivString() == pp->GivName() )
|
|
|
|
|
{
|
2012-03-19 11:44:39 +00:00
|
|
|
|
// les param<61>tres sont-ils exactement les m<>mes ?
|
2012-03-08 18:32:05 +00:00
|
|
|
|
if ( pp->CheckParam( pParam ) )
|
2012-07-04 20:14:28 +00:00
|
|
|
|
return true;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
pp = pp->Next();
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-04 20:14:28 +00:00
|
|
|
|
return false;
|
2012-03-08 18:32:05 +00:00
|
|
|
|
}
|
|
|
|
|
|