Moving CBotCall class in its own header and source files.
parent
e54d8f1ebc
commit
394a49f5aa
|
@ -29,7 +29,6 @@
|
|||
#include "CBotDll.h" // public definitions
|
||||
#include "CBotToken.h" // token management
|
||||
|
||||
#define STACKRUN 1 /// \def return execution directly on a suspended routine
|
||||
#define STACKMEM 1 /// \def preserve memory for the execution stack
|
||||
#define MAXSTACK 990 /// \def stack size reserved
|
||||
|
||||
|
@ -525,58 +524,6 @@ extern void DEBUG( const char* text, int val, CBotStack* pile );
|
|||
#endif
|
||||
|
||||
///////////////////////////////////////////
|
||||
// class for routine calls (external)
|
||||
|
||||
class CBotCall
|
||||
{
|
||||
private:
|
||||
static
|
||||
CBotCall* m_ListCalls;
|
||||
static
|
||||
void* m_pUser;
|
||||
long m_nFuncIdent;
|
||||
|
||||
private:
|
||||
CBotString m_name;
|
||||
bool (*m_rExec) (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser) ;
|
||||
CBotTypResult
|
||||
(*m_rComp) (CBotVar* &pVar, void* pUser) ;
|
||||
CBotCall* m_next;
|
||||
|
||||
public:
|
||||
CBotCall(const char* name,
|
||||
bool rExec (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser),
|
||||
CBotTypResult rCompile (CBotVar* &pVar, void* pUser));
|
||||
~CBotCall();
|
||||
|
||||
static
|
||||
bool AddFunction(const char* name,
|
||||
bool rExec (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser),
|
||||
CBotTypResult rCompile (CBotVar* &pVar, void* pUser));
|
||||
|
||||
static
|
||||
CBotTypResult
|
||||
CompileCall(CBotToken* &p, CBotVar** ppVars, CBotCStack* pStack, long& nIdent);
|
||||
static
|
||||
bool CheckCall(const char* name);
|
||||
|
||||
// static
|
||||
// int DoCall(CBotToken* &p, CBotVar** ppVars, CBotStack* pStack, CBotTypResult& rettype);
|
||||
static
|
||||
int DoCall(long& nIdent, CBotToken* token, CBotVar** ppVars, CBotStack* pStack, CBotTypResult& rettype);
|
||||
#if STACKRUN
|
||||
bool Run(CBotStack* pStack);
|
||||
static
|
||||
bool RestoreCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBotStack* pStack);
|
||||
#endif
|
||||
|
||||
CBotString GetName();
|
||||
CBotCall* Next();
|
||||
|
||||
static void SetPUser(void* pUser);
|
||||
static void Free();
|
||||
};
|
||||
|
||||
// class managing the methods declared by AddFunction on a class
|
||||
|
||||
class CBotCallMethode
|
||||
|
|
|
@ -0,0 +1,311 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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://gnu.org/licenses
|
||||
*/
|
||||
|
||||
// Modules inlcude
|
||||
#include "CBotCall.h"
|
||||
|
||||
#include "CBotToken.h"
|
||||
#include "CBotStack.h"
|
||||
|
||||
#include "CBotUtils.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CBotCall* CBotCall::m_ListCalls = nullptr;
|
||||
void* CBotCall::m_pUser = nullptr;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotCall::CBotCall(const char* name,
|
||||
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 = nullptr;
|
||||
m_nFuncIdent = CBotVar::NextUniqNum();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotCall::~CBotCall()
|
||||
{
|
||||
if (m_next) delete m_next;
|
||||
m_next = nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCall::Free()
|
||||
{
|
||||
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))
|
||||
{
|
||||
CBotCall* p = m_ListCalls;
|
||||
CBotCall* pp = nullptr;
|
||||
|
||||
if ( p != nullptr ) while ( p->m_next != nullptr )
|
||||
{
|
||||
if ( p->GetName() == 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 = nullptr; // 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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotTypResult CBotCall::CompileCall(CBotToken* &p, CBotVar** ppVar, CBotCStack* pStack, long& nIdent)
|
||||
{
|
||||
nIdent = 0;
|
||||
CBotCall* pt = m_ListCalls;
|
||||
CBotString name = p->GetString();
|
||||
|
||||
while ( pt != nullptr )
|
||||
{
|
||||
if ( pt->m_name == name )
|
||||
{
|
||||
CBotVar* pVar = MakeListVars(ppVar);
|
||||
CBotVar* pVar2 = pVar;
|
||||
CBotTypResult r = pt->m_rComp(pVar2, m_pUser);
|
||||
int ret = r.GetType();
|
||||
|
||||
// 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->GetToken()*/ );
|
||||
}
|
||||
delete pVar;
|
||||
nIdent = pt->m_nFuncIdent;
|
||||
return r;
|
||||
}
|
||||
pt = pt->m_next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCall::SetPUser(void* pUser)
|
||||
{
|
||||
m_pUser = pUser;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotCall::CheckCall(const char* name)
|
||||
{
|
||||
CBotCall* p = m_ListCalls;
|
||||
|
||||
while ( p != nullptr )
|
||||
{
|
||||
if ( name == p->GetName() ) return true;
|
||||
p = p->m_next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotString CBotCall::GetName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotCall* CBotCall::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 != nullptr )
|
||||
{
|
||||
if ( pt->m_nFuncIdent == nIdent )
|
||||
{
|
||||
goto fund;
|
||||
}
|
||||
pt = pt->m_next;
|
||||
}
|
||||
|
||||
pt = m_ListCalls;
|
||||
|
||||
if ( token != nullptr )
|
||||
{
|
||||
CBotString name = token->GetString();
|
||||
while ( pt != nullptr )
|
||||
{
|
||||
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) ? nullptr : CBotVar::Create("", rettype);
|
||||
|
||||
CBotVar* pRes = pResult;
|
||||
int Exception = 0;
|
||||
int res = pt->m_rExec(pVar, pResult, Exception, pStack->GetPUser());
|
||||
|
||||
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.GetType() > 0 && pResult == nullptr )
|
||||
{
|
||||
pStack->SetError(TX_NORETVAL, token);
|
||||
}
|
||||
nIdent = pt->m_nFuncIdent;
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
CBotStack* pile = pStack->AddStackEOX(pt);
|
||||
if ( pile == EOX ) 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) ? nullptr : CBotVar::Create("", rettype);
|
||||
|
||||
pile->SetVar( pVar );
|
||||
|
||||
CBotStack* pile2 = pile->AddStack();
|
||||
pile2->SetVar( pResult );
|
||||
|
||||
pile->SetError(0, token); // for the position on error + away
|
||||
return pt->Run( pStack );
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if STACKRUN
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotCall::RestoreCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBotStack* pStack)
|
||||
{
|
||||
CBotCall* pt = m_ListCalls;
|
||||
|
||||
{
|
||||
CBotString name = token->GetString();
|
||||
while ( pt != nullptr )
|
||||
{
|
||||
if ( pt->m_name == name )
|
||||
{
|
||||
nIdent = pt->m_nFuncIdent;
|
||||
|
||||
CBotStack* pile = pStack->RestoreStackEOX(pt);
|
||||
if ( pile == nullptr ) return true;
|
||||
|
||||
// CBotStack* pile2 = pile->RestoreStack();
|
||||
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->GetVar();
|
||||
|
||||
CBotStack* pile2 = pile->AddStack();
|
||||
CBotVar* pResult = pile2->GetVar();
|
||||
CBotVar* pRes = pResult;
|
||||
|
||||
int Exception = 0;
|
||||
int res = m_rExec(pVar, pResult, Exception, pStack->GetPUser());
|
||||
|
||||
if (res == false)
|
||||
{
|
||||
if (Exception!=0)
|
||||
{
|
||||
pStack->SetError(Exception);
|
||||
}
|
||||
if ( pResult != pRes ) delete pResult; // different result if made
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( pResult != nullptr ) pStack->SetCopyVar( pResult );
|
||||
if ( pResult != pRes ) delete pResult; // different result if made
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Modules inlcude
|
||||
#include "CBotDll.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
#define STACKRUN 1 /// \def return execution directly on a suspended routine
|
||||
|
||||
/*!
|
||||
* \brief The CBotCall class. Class for routine calls (external).
|
||||
*/
|
||||
class CBotCall
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotCall
|
||||
* \param name
|
||||
* \param rExec
|
||||
* \param rCompile
|
||||
*/
|
||||
CBotCall(const char* name,
|
||||
bool rExec (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser),
|
||||
CBotTypResult rCompile (CBotVar* &pVar, void* pUser));
|
||||
|
||||
/*!
|
||||
* \brief ~CBotCall
|
||||
*/
|
||||
~CBotCall();
|
||||
|
||||
/*!
|
||||
* \brief AddFunction
|
||||
* \param name
|
||||
* \param rExec
|
||||
* \param rCompile
|
||||
* \return
|
||||
*/
|
||||
static bool AddFunction(const char* name,
|
||||
bool rExec (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser),
|
||||
CBotTypResult rCompile (CBotVar* &pVar, void* pUser));
|
||||
|
||||
/*!
|
||||
* \brief CompileCall Is acceptable by a call procedure name and given
|
||||
* parameters.
|
||||
* \param p
|
||||
* \param ppVars
|
||||
* \param pStack
|
||||
* \param nIdent
|
||||
* \return
|
||||
*/
|
||||
static CBotTypResult CompileCall(CBotToken* &p, CBotVar** ppVars, CBotCStack* pStack, long& nIdent);
|
||||
|
||||
/*!
|
||||
* \brief CheckCall
|
||||
* \param name
|
||||
* \return
|
||||
*/
|
||||
static bool CheckCall(const char* name);
|
||||
|
||||
/*!
|
||||
* \brief DoCall
|
||||
* \param nIdent
|
||||
* \param token
|
||||
* \param ppVars
|
||||
* \param pStack
|
||||
* \param rettype
|
||||
* \return
|
||||
*/
|
||||
static int DoCall(long& nIdent, CBotToken* token, CBotVar** ppVars, CBotStack* pStack, CBotTypResult& rettype);
|
||||
|
||||
#if STACKRUN
|
||||
|
||||
/*!
|
||||
* \brief Run
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
bool Run(CBotStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief RestoreCall
|
||||
* \param nIdent
|
||||
* \param token
|
||||
* \param ppVar
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static bool RestoreCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBotStack* pStack);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \brief GetName
|
||||
* \return
|
||||
*/
|
||||
CBotString GetName();
|
||||
|
||||
/*!
|
||||
* \brief Next
|
||||
* \return
|
||||
*/
|
||||
CBotCall* Next();
|
||||
|
||||
/*!
|
||||
* \brief SetPUser
|
||||
* \param pUser
|
||||
*/
|
||||
static void SetPUser(void* pUser);
|
||||
|
||||
/*!
|
||||
* \brief Free
|
||||
*/
|
||||
static void Free();
|
||||
|
||||
|
||||
private:
|
||||
static CBotCall* m_ListCalls;
|
||||
static void* m_pUser;
|
||||
long m_nFuncIdent;
|
||||
|
||||
CBotString m_name;
|
||||
bool (*m_rExec) (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser);
|
||||
CBotTypResult (*m_rComp) (CBotVar* &pVar, void* pUser);
|
||||
CBotCall* m_next;
|
||||
};
|
|
@ -22,6 +22,9 @@
|
|||
//
|
||||
|
||||
#include "CBot.h"
|
||||
|
||||
#include "CBotCall.h"
|
||||
|
||||
#include "CBotInstr/CBotNew.h"
|
||||
#include "CBotInstr/CBotLeftExprVar.h"
|
||||
#include "CBotInstr/CBotTwoOpExpr.h"
|
||||
|
|
|
@ -22,8 +22,11 @@
|
|||
|
||||
#include "CBot.h"
|
||||
|
||||
#include "CBotCall.h"
|
||||
#include "CBotStack.h"
|
||||
|
||||
#include "CBotUtils.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
CBotProgram::CBotProgram()
|
||||
|
@ -556,308 +559,6 @@ int CBotProgram::GetVersion()
|
|||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CBotCall* CBotCall::m_ListCalls = nullptr;
|
||||
|
||||
CBotCall::CBotCall(const char* name,
|
||||
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 = nullptr;
|
||||
m_nFuncIdent = CBotVar::NextUniqNum();
|
||||
}
|
||||
|
||||
CBotCall::~CBotCall()
|
||||
{
|
||||
if (m_next) delete m_next;
|
||||
m_next = nullptr;
|
||||
}
|
||||
|
||||
void CBotCall::Free()
|
||||
{
|
||||
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))
|
||||
{
|
||||
CBotCall* p = m_ListCalls;
|
||||
CBotCall* pp = nullptr;
|
||||
|
||||
if ( p != nullptr ) while ( p->m_next != nullptr )
|
||||
{
|
||||
if ( p->GetName() == 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 = nullptr; // 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;
|
||||
}
|
||||
|
||||
|
||||
// transforms the array of pointers to variables
|
||||
// in a chained list of variables
|
||||
CBotVar* MakeListVars(CBotVar** ppVars, bool bSetVal=false)
|
||||
{
|
||||
int i = 0;
|
||||
CBotVar* pVar = nullptr;
|
||||
|
||||
while( true )
|
||||
{
|
||||
// ppVars[i];
|
||||
if ( ppVars[i] == nullptr ) break;
|
||||
|
||||
CBotVar* pp = CBotVar::Create(ppVars[i]);
|
||||
if (bSetVal) pp->Copy(ppVars[i]);
|
||||
else
|
||||
if ( ppVars[i]->GetType() == CBotTypPointer )
|
||||
pp->SetClass( ppVars[i]->GetClass());
|
||||
// copy the pointer according to indirections
|
||||
if (pVar == nullptr) pVar = pp;
|
||||
else pVar->AddNext(pp);
|
||||
i++;
|
||||
}
|
||||
return pVar;
|
||||
}
|
||||
|
||||
// is acceptable by a call procedure name
|
||||
// and given parameters
|
||||
|
||||
CBotTypResult CBotCall::CompileCall(CBotToken* &p, CBotVar** ppVar, CBotCStack* pStack, long& nIdent)
|
||||
{
|
||||
nIdent = 0;
|
||||
CBotCall* pt = m_ListCalls;
|
||||
CBotString name = p->GetString();
|
||||
|
||||
while ( pt != nullptr )
|
||||
{
|
||||
if ( pt->m_name == name )
|
||||
{
|
||||
CBotVar* pVar = MakeListVars(ppVar);
|
||||
CBotVar* pVar2 = pVar;
|
||||
CBotTypResult r = pt->m_rComp(pVar2, m_pUser);
|
||||
int ret = r.GetType();
|
||||
|
||||
// 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->GetToken()*/ );
|
||||
}
|
||||
delete pVar;
|
||||
nIdent = pt->m_nFuncIdent;
|
||||
return r;
|
||||
}
|
||||
pt = pt->m_next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void* CBotCall::m_pUser = nullptr;
|
||||
|
||||
void CBotCall::SetPUser(void* pUser)
|
||||
{
|
||||
m_pUser = pUser;
|
||||
}
|
||||
|
||||
bool CBotCall::CheckCall(const char* name)
|
||||
{
|
||||
CBotCall* p = m_ListCalls;
|
||||
|
||||
while ( p != nullptr )
|
||||
{
|
||||
if ( name == p->GetName() ) return true;
|
||||
p = p->m_next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CBotString CBotCall::GetName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
CBotCall* CBotCall::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 != nullptr )
|
||||
{
|
||||
if ( pt->m_nFuncIdent == nIdent )
|
||||
{
|
||||
goto fund;
|
||||
}
|
||||
pt = pt->m_next;
|
||||
}
|
||||
|
||||
pt = m_ListCalls;
|
||||
|
||||
if ( token != nullptr )
|
||||
{
|
||||
CBotString name = token->GetString();
|
||||
while ( pt != nullptr )
|
||||
{
|
||||
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) ? nullptr : CBotVar::Create("", rettype);
|
||||
|
||||
CBotVar* pRes = pResult;
|
||||
int Exception = 0;
|
||||
int res = pt->m_rExec(pVar, pResult, Exception, pStack->GetPUser());
|
||||
|
||||
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.GetType() > 0 && pResult == nullptr )
|
||||
{
|
||||
pStack->SetError(TX_NORETVAL, token);
|
||||
}
|
||||
nIdent = pt->m_nFuncIdent;
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
CBotStack* pile = pStack->AddStackEOX(pt);
|
||||
if ( pile == EOX ) 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) ? nullptr : CBotVar::Create("", rettype);
|
||||
|
||||
pile->SetVar( pVar );
|
||||
|
||||
CBotStack* pile2 = pile->AddStack();
|
||||
pile2->SetVar( pResult );
|
||||
|
||||
pile->SetError(0, token); // for the position on error + away
|
||||
return pt->Run( pStack );
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if STACKRUN
|
||||
|
||||
bool CBotCall::RestoreCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBotStack* pStack)
|
||||
{
|
||||
CBotCall* pt = m_ListCalls;
|
||||
|
||||
{
|
||||
CBotString name = token->GetString();
|
||||
while ( pt != nullptr )
|
||||
{
|
||||
if ( pt->m_name == name )
|
||||
{
|
||||
nIdent = pt->m_nFuncIdent;
|
||||
|
||||
CBotStack* pile = pStack->RestoreStackEOX(pt);
|
||||
if ( pile == nullptr ) return true;
|
||||
|
||||
// CBotStack* pile2 = pile->RestoreStack();
|
||||
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->GetVar();
|
||||
|
||||
CBotStack* pile2 = pile->AddStack();
|
||||
CBotVar* pResult = pile2->GetVar();
|
||||
CBotVar* pRes = pResult;
|
||||
|
||||
int Exception = 0;
|
||||
int res = m_rExec(pVar, pResult, Exception, pStack->GetPUser());
|
||||
|
||||
if (res == false)
|
||||
{
|
||||
if (Exception!=0)
|
||||
{
|
||||
pStack->SetError(Exception);
|
||||
}
|
||||
if ( pResult != pRes ) delete pResult; // different result if made
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( pResult != nullptr ) pStack->SetCopyVar( pResult );
|
||||
if ( pResult != pRes ) delete pResult; // different result if made
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CBotCallMethode::CBotCallMethode(const char* name,
|
||||
bool rExec (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user),
|
||||
CBotTypResult rCompile (CBotVar* pThis, CBotVar* &pVar))
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
// Modules inlcude
|
||||
#include "CBotStack.h"
|
||||
#include "CBotCall.h"
|
||||
|
||||
// Local include
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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://gnu.org/licenses
|
||||
*/
|
||||
|
||||
// Modules inlcude
|
||||
#include "CBotUtils.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotVar* MakeListVars(CBotVar** ppVars, bool bSetVal)
|
||||
{
|
||||
int i = 0;
|
||||
CBotVar* pVar = nullptr;
|
||||
|
||||
while( true )
|
||||
{
|
||||
// ppVars[i];
|
||||
if ( ppVars[i] == nullptr ) break;
|
||||
|
||||
CBotVar* pp = CBotVar::Create(ppVars[i]);
|
||||
if (bSetVal) pp->Copy(ppVars[i]);
|
||||
else
|
||||
if ( ppVars[i]->GetType() == CBotTypPointer )
|
||||
pp->SetClass( ppVars[i]->GetClass());
|
||||
// copy the pointer according to indirections
|
||||
if (pVar == nullptr) pVar = pp;
|
||||
else pVar->AddNext(pp);
|
||||
i++;
|
||||
}
|
||||
return pVar;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Modules inlcude
|
||||
#include "CBotDll.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
/*!
|
||||
* \brief MakeListVars Transforms the array of pointers to variables in a
|
||||
* chained list of variables
|
||||
* \param ppVars
|
||||
* \param bSetVal
|
||||
* \return
|
||||
*/
|
||||
CBotVar* MakeListVars(CBotVar** ppVars, bool bSetVal=false);
|
|
@ -7,6 +7,8 @@ set(SOURCES
|
|||
CBotString.cpp
|
||||
CBotToken.cpp
|
||||
CBotVar.cpp
|
||||
CBotCall.cpp
|
||||
CBotUtils.cpp
|
||||
CBotInstr/CBotWhile.cpp
|
||||
CBotInstr/CBotDo.cpp
|
||||
CBotInstr/CBotFor.cpp
|
||||
|
|
Loading…
Reference in New Issue