Made CBotExternalCallList combatible with class calls
parent
ae544c71ae
commit
ff081aff49
|
@ -351,7 +351,7 @@ CBotTypResult CBotCStack::CompileCall(CBotToken* &p, CBotVar** ppVars, long& nId
|
||||||
nIdent = 0;
|
nIdent = 0;
|
||||||
CBotTypResult val(-1);
|
CBotTypResult val(-1);
|
||||||
|
|
||||||
val = m_prog->GetExternalCalls()->CompileCall(p, ppVars, this);
|
val = m_prog->GetExternalCalls()->CompileCall(p, nullptr, ppVars, this);
|
||||||
if (val.GetType() < 0)
|
if (val.GetType() < 0)
|
||||||
{
|
{
|
||||||
val = m_prog->GetFunctions()->CompileCall(p->GetString(), ppVars, nIdent);
|
val = m_prog->GetFunctions()->CompileCall(p->GetString(), ppVars, nIdent);
|
||||||
|
|
|
@ -37,7 +37,7 @@ bool CBotExternalCallList::AddFunction(const std::string& name, std::unique_ptr<
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CBotTypResult CBotExternalCallList::CompileCall(CBotToken*& p, CBotVar** ppVar, CBotCStack* pStack)
|
CBotTypResult CBotExternalCallList::CompileCall(CBotToken*& p, CBotVar* thisVar, CBotVar** ppVar, CBotCStack* pStack)
|
||||||
{
|
{
|
||||||
if (m_list.count(p->GetString()) == 0)
|
if (m_list.count(p->GetString()) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -45,7 +45,7 @@ CBotTypResult CBotExternalCallList::CompileCall(CBotToken*& p, CBotVar** ppVar,
|
||||||
CBotExternalCall* pt = m_list[p->GetString()].get();
|
CBotExternalCall* pt = m_list[p->GetString()].get();
|
||||||
|
|
||||||
std::unique_ptr<CBotVar> args = std::unique_ptr<CBotVar>(MakeListVars(ppVar));
|
std::unique_ptr<CBotVar> args = std::unique_ptr<CBotVar>(MakeListVars(ppVar));
|
||||||
CBotTypResult r = pt->Compile(args.get(), m_user);
|
CBotTypResult r = pt->Compile(thisVar, args.get(), m_user);
|
||||||
|
|
||||||
// if a class is returned, it is actually a pointer
|
// if a class is returned, it is actually a pointer
|
||||||
if (r.GetType() == CBotTypClass) r.SetType(CBotTypPointer);
|
if (r.GetType() == CBotTypClass) r.SetType(CBotTypPointer);
|
||||||
|
@ -68,7 +68,7 @@ bool CBotExternalCallList::CheckCall(const std::string& name)
|
||||||
return m_list.count(name) > 0;
|
return m_list.count(name) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CBotExternalCallList::DoCall(CBotToken* token, CBotVar** ppVar, CBotStack* pStack, const CBotTypResult& rettype)
|
int CBotExternalCallList::DoCall(CBotToken* token, CBotVar* thisVar, CBotVar** ppVar, CBotStack* pStack, const CBotTypResult& rettype)
|
||||||
{
|
{
|
||||||
if (token == nullptr)
|
if (token == nullptr)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -93,10 +93,10 @@ int CBotExternalCallList::DoCall(CBotToken* token, CBotVar** ppVar, CBotStack* p
|
||||||
pile2->SetVar(pResult);
|
pile2->SetVar(pResult);
|
||||||
|
|
||||||
pile->SetError(CBotNoErr, token); // save token for the position in case of error
|
pile->SetError(CBotNoErr, token); // save token for the position in case of error
|
||||||
return pt->Run(pStack);
|
return pt->Run(thisVar, pStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBotExternalCallList::RestoreCall(CBotToken* token, CBotVar** ppVar, CBotStack* pStack)
|
bool CBotExternalCallList::RestoreCall(CBotToken* token, CBotVar* thisVar, CBotVar** ppVar, CBotStack* pStack)
|
||||||
{
|
{
|
||||||
if (m_list.count(token->GetString()) == 0)
|
if (m_list.count(token->GetString()) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -123,7 +123,6 @@ CBotExternalCall::~CBotExternalCall()
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
CBotExternalCallDefault::CBotExternalCallDefault(RuntimeFunc rExec, CompileFunc rCompile)
|
CBotExternalCallDefault::CBotExternalCallDefault(RuntimeFunc rExec, CompileFunc rCompile)
|
||||||
: CBotExternalCall()
|
|
||||||
{
|
{
|
||||||
m_rExec = rExec;
|
m_rExec = rExec;
|
||||||
m_rComp = rCompile;
|
m_rComp = rCompile;
|
||||||
|
@ -133,12 +132,12 @@ CBotExternalCallDefault::~CBotExternalCallDefault()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CBotTypResult CBotExternalCallDefault::Compile(CBotVar* args, void* user)
|
CBotTypResult CBotExternalCallDefault::Compile(CBotVar* thisVar, CBotVar* args, void* user)
|
||||||
{
|
{
|
||||||
return m_rComp(args, user);
|
return m_rComp(args, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBotExternalCallDefault::Run(CBotStack* pStack)
|
bool CBotExternalCallDefault::Run(CBotVar* thisVar, CBotStack* pStack)
|
||||||
{
|
{
|
||||||
CBotStack* pile = pStack->AddStackEOX(this);
|
CBotStack* pile = pStack->AddStackEOX(this);
|
||||||
if ( pile == EOX ) return true;
|
if ( pile == EOX ) return true;
|
||||||
|
@ -164,3 +163,47 @@ bool CBotExternalCallDefault::Run(CBotStack* pStack)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
CBotExternalCallDefaultClass::CBotExternalCallDefaultClass(RuntimeFunc rExec, CompileFunc rCompile)
|
||||||
|
{
|
||||||
|
m_rExec = rExec;
|
||||||
|
m_rComp = rCompile;
|
||||||
|
}
|
||||||
|
|
||||||
|
CBotExternalCallDefaultClass::~CBotExternalCallDefaultClass()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CBotTypResult CBotExternalCallDefaultClass::Compile(CBotVar* thisVar, CBotVar* args, void* user)
|
||||||
|
{
|
||||||
|
return m_rComp(nullptr, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Figure out why classes do pStack->SetVar while normal calls do pStack->SetCopyVar
|
||||||
|
bool CBotExternalCallDefaultClass::Run(CBotVar* thisVar, CBotStack* pStack)
|
||||||
|
{
|
||||||
|
CBotStack* pile = pStack->AddStackEOX(this);
|
||||||
|
if ( pile == EOX ) return true;
|
||||||
|
CBotVar* args = pile->GetVar();
|
||||||
|
|
||||||
|
CBotStack* pile2 = pile->AddStack();
|
||||||
|
|
||||||
|
CBotVar* result = pile2->GetVar();
|
||||||
|
|
||||||
|
int exception = CBotNoErr; // TODO: Change to CBotError
|
||||||
|
bool res = m_rExec(thisVar, args, result, exception, pStack->GetPUser());
|
||||||
|
pStack->SetVar(result);
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
if (exception != CBotNoErr)
|
||||||
|
{
|
||||||
|
pStack->SetError(static_cast<CBotError>(exception));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -56,18 +56,20 @@ public:
|
||||||
/**
|
/**
|
||||||
* \brief Compile the function
|
* \brief Compile the function
|
||||||
*
|
*
|
||||||
|
* \param "this" variable for class calls, nullptr for normal calls
|
||||||
* \param Arguments (only types!) passed to the function
|
* \param Arguments (only types!) passed to the function
|
||||||
* \param User pointer provided to CBotProgram::Compile()
|
* \param User pointer provided to CBotProgram::Compile()
|
||||||
*/
|
*/
|
||||||
virtual CBotTypResult Compile(CBotVar* args, void* user) = 0;
|
virtual CBotTypResult Compile(CBotVar* thisVar, CBotVar* args, void* user) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Execute the function
|
* \brief Execute the function
|
||||||
*
|
*
|
||||||
|
* \param thisVar "this" variable for class calls, nullptr for normal calls
|
||||||
* \param pStack Stack to execute the function on
|
* \param pStack Stack to execute the function on
|
||||||
* \return false to request program interruption, true otherwise
|
* \return false to request program interruption, true otherwise
|
||||||
*/
|
*/
|
||||||
virtual bool Run(CBotStack* pStack) = 0;
|
virtual bool Run(CBotVar* thisVar, CBotStack* pStack) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,8 +94,38 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual ~CBotExternalCallDefault();
|
virtual ~CBotExternalCallDefault();
|
||||||
|
|
||||||
virtual CBotTypResult Compile(CBotVar* args, void* user);
|
virtual CBotTypResult Compile(CBotVar* thisVar, CBotVar* args, void* user);
|
||||||
virtual bool Run(CBotStack* pStack);
|
virtual bool Run(CBotVar* thisVar, CBotStack* pStack);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RuntimeFunc m_rExec;
|
||||||
|
CompileFunc m_rComp;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Default implementation of CBot external class call, using compilation and runtime functions
|
||||||
|
*/
|
||||||
|
class CBotExternalCallDefaultClass : public CBotExternalCall
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef bool (*RuntimeFunc)(CBotVar* thisVar, CBotVar* args, CBotVar* result, int& exception, void* user);
|
||||||
|
typedef CBotTypResult (*CompileFunc)(CBotVar* thisVar, CBotVar*& args); // TODO: Add user pointer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Constructor
|
||||||
|
* \param rExec Runtime function
|
||||||
|
* \param rCompile Compilation function
|
||||||
|
* \see CBotClass::AddFunction()
|
||||||
|
*/
|
||||||
|
CBotExternalCallDefaultClass(RuntimeFunc rExec, CompileFunc rCompile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Destructor
|
||||||
|
*/
|
||||||
|
virtual ~CBotExternalCallDefaultClass();
|
||||||
|
|
||||||
|
virtual CBotTypResult Compile(CBotVar* thisVar, CBotVar* args, void* user);
|
||||||
|
virtual bool Run(CBotVar* thisVar, CBotStack* pStack);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RuntimeFunc m_rExec;
|
RuntimeFunc m_rExec;
|
||||||
|
@ -124,10 +156,11 @@ public:
|
||||||
*
|
*
|
||||||
* \param p Token representing the function name
|
* \param p Token representing the function name
|
||||||
* \param ppVars List of arguments (only types!)
|
* \param ppVars List of arguments (only types!)
|
||||||
|
* \param thisVar "this" variable for class calls, nullptr for normal calls
|
||||||
* \param pStack Compilation stack
|
* \param pStack Compilation stack
|
||||||
* \return CBotTypResult representing the return type of the function (::CBotTypVar), or an error (::CBotError)
|
* \return CBotTypResult representing the return type of the function (::CBotTypVar), or an error (::CBotError)
|
||||||
*/
|
*/
|
||||||
CBotTypResult CompileCall(CBotToken*& p, CBotVar** ppVars, CBotCStack* pStack);
|
CBotTypResult CompileCall(CBotToken*& p, CBotVar* thisVar, CBotVar** ppVars, CBotCStack* pStack);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Check if function with given name has been defined
|
* \brief Check if function with given name has been defined
|
||||||
|
@ -142,22 +175,24 @@ public:
|
||||||
* This function sets an error in runtime stack in case of failure
|
* This function sets an error in runtime stack in case of failure
|
||||||
*
|
*
|
||||||
* \param token Token representing the function name
|
* \param token Token representing the function name
|
||||||
|
* \param thisVar "this" variable for class calls, nullptr for normal calls
|
||||||
* \param ppVars List of arguments
|
* \param ppVars List of arguments
|
||||||
* \param pStack Runtime stack
|
* \param pStack Runtime stack
|
||||||
* \param rettype Return type of the function, as returned by CompileCall()
|
* \param rettype Return type of the function, as returned by CompileCall()
|
||||||
* \return -1 if call failed (no such function), 0 if function requested interruption, 1 on success
|
* \return -1 if call failed (no such function), 0 if function requested interruption, 1 on success
|
||||||
*/
|
*/
|
||||||
int DoCall(CBotToken* token, CBotVar** ppVars, CBotStack* pStack, const CBotTypResult& rettype);
|
int DoCall(CBotToken* token, CBotVar* thisVar, CBotVar** ppVars, CBotStack* pStack, const CBotTypResult& rettype);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Restore execution status after loading saved state
|
* \brief Restore execution status after loading saved state
|
||||||
*
|
*
|
||||||
* \param token Token representing the function name
|
* \param token Token representing the function name
|
||||||
* \param ppVar List of arguments (TODO: unused)
|
* \param "this" variable for class calls, nullptr for normal calls
|
||||||
|
* \param ppVar List of arguments
|
||||||
* \param pStack Runtime stack
|
* \param pStack Runtime stack
|
||||||
* \return false on failure (e.g. function doesn't exist)
|
* \return false on failure (e.g. function doesn't exist)
|
||||||
*/
|
*/
|
||||||
bool RestoreCall(CBotToken* token, CBotVar** ppVar, CBotStack* pStack);
|
bool RestoreCall(CBotToken* token, CBotVar* thisVar, CBotVar** ppVar, CBotStack* pStack);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Set user pointer to pass to compile functions
|
* \brief Set user pointer to pass to compile functions
|
||||||
|
|
|
@ -637,7 +637,7 @@ bool CBotStack::Execute()
|
||||||
|
|
||||||
if ( instr == nullptr ) return true; // normal execution request
|
if ( instr == nullptr ) return true; // normal execution request
|
||||||
|
|
||||||
if (!instr->Run(pile)) return false; // \TODO exécution à partir de là
|
if (!instr->Run(nullptr, pile)) return false; // \TODO exécution à partir de là
|
||||||
|
|
||||||
#if STACKMEM
|
#if STACKMEM
|
||||||
pile->m_next->Delete();
|
pile->m_next->Delete();
|
||||||
|
@ -744,7 +744,7 @@ bool CBotStack::ExecuteCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBo
|
||||||
|
|
||||||
// first looks by the identifier
|
// first looks by the identifier
|
||||||
|
|
||||||
res = m_prog->GetExternalCalls()->DoCall(nullptr, ppVar, this, rettype);
|
res = m_prog->GetExternalCalls()->DoCall(nullptr, nullptr, ppVar, this, rettype);
|
||||||
if (res.GetType() >= 0) return res.GetType();
|
if (res.GetType() >= 0) return res.GetType();
|
||||||
|
|
||||||
res = m_prog->GetFunctions()->DoCall(nIdent, "", ppVar, this, token );
|
res = m_prog->GetFunctions()->DoCall(nIdent, "", ppVar, this, token );
|
||||||
|
@ -753,7 +753,7 @@ bool CBotStack::ExecuteCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBo
|
||||||
// if not found (recompile?) seeks by name
|
// if not found (recompile?) seeks by name
|
||||||
|
|
||||||
nIdent = 0;
|
nIdent = 0;
|
||||||
res = m_prog->GetExternalCalls()->DoCall(token, ppVar, this, rettype);
|
res = m_prog->GetExternalCalls()->DoCall(token, nullptr, ppVar, this, rettype);
|
||||||
if (res.GetType() >= 0) return res.GetType();
|
if (res.GetType() >= 0) return res.GetType();
|
||||||
|
|
||||||
res = m_prog->GetFunctions()->DoCall(nIdent, token->GetString(), ppVar, this, token );
|
res = m_prog->GetFunctions()->DoCall(nIdent, token->GetString(), ppVar, this, token );
|
||||||
|
@ -768,7 +768,7 @@ void CBotStack::RestoreCall(long& nIdent, CBotToken* token, CBotVar** ppVar)
|
||||||
{
|
{
|
||||||
if (m_next == nullptr) return;
|
if (m_next == nullptr) return;
|
||||||
|
|
||||||
if (m_prog->GetExternalCalls()->RestoreCall(token, ppVar, this))
|
if (m_prog->GetExternalCalls()->RestoreCall(token, nullptr, ppVar, this))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_prog->GetFunctions()->RestoreCall(nIdent, token->GetString(), ppVar, this);
|
m_prog->GetFunctions()->RestoreCall(nIdent, token->GetString(), ppVar, this);
|
||||||
|
|
Loading…
Reference in New Issue