commit
95eee3a340
3964
src/CBot/CBot.cpp
3964
src/CBot/CBot.cpp
File diff suppressed because it is too large
Load Diff
1671
src/CBot/CBot.h
1671
src/CBot/CBot.h
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
* 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 "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotToken.h"
|
||||
#include "CBot/CBotCall.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotFunction.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotProgram* CBotCStack::m_prog = nullptr; // init the static variable
|
||||
int CBotCStack::m_error = 0;
|
||||
int CBotCStack::m_end = 0;
|
||||
CBotTypResult CBotCStack::m_retTyp = CBotTypResult(0);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotCStack::CBotCStack(CBotCStack* ppapa)
|
||||
{
|
||||
m_next = nullptr;
|
||||
m_prev = ppapa;
|
||||
|
||||
if (ppapa == nullptr)
|
||||
{
|
||||
m_error = 0;
|
||||
m_start = 0;
|
||||
m_end = 0;
|
||||
m_bBlock = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_start = ppapa->m_start;
|
||||
m_bBlock = false;
|
||||
}
|
||||
|
||||
m_listVar = nullptr;
|
||||
m_var = nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotCStack::~CBotCStack()
|
||||
{
|
||||
if (m_next != nullptr) delete m_next;
|
||||
if (m_prev != nullptr) m_prev->m_next = nullptr; // removes chain
|
||||
|
||||
delete m_var;
|
||||
delete m_listVar;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotCStack* CBotCStack::TokenStack(CBotToken* pToken, bool bBlock)
|
||||
{
|
||||
if (m_next != nullptr) return m_next; // include on an existing stack
|
||||
|
||||
CBotCStack* p = new CBotCStack(this);
|
||||
m_next = p; // channel element
|
||||
p->m_bBlock = bBlock;
|
||||
|
||||
if (pToken != nullptr) p->SetStartError(pToken->GetStart());
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotCStack::Return(CBotInstr* inst, CBotCStack* pfils)
|
||||
{
|
||||
if ( pfils == this ) return inst;
|
||||
|
||||
if (m_var != nullptr) delete m_var; // value replaced?
|
||||
m_var = pfils->m_var; // result transmitted
|
||||
pfils->m_var = nullptr; // not to destroy the variable
|
||||
|
||||
if (m_error)
|
||||
{
|
||||
m_start = pfils->m_start; // retrieves the position of the error
|
||||
m_end = pfils->m_end;
|
||||
}
|
||||
|
||||
delete pfils;
|
||||
return inst;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotFunction* CBotCStack::ReturnFunc(CBotFunction* inst, CBotCStack* pfils)
|
||||
{
|
||||
if (m_var != nullptr) delete m_var; // value replaced?
|
||||
m_var = pfils->m_var; // result transmitted
|
||||
pfils->m_var = nullptr; // not to destroy the variable
|
||||
|
||||
if (m_error)
|
||||
{
|
||||
m_start = pfils->m_start; // retrieves the position of the error
|
||||
m_end = pfils->m_end;
|
||||
}
|
||||
|
||||
delete pfils;
|
||||
return inst;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CBotCStack::GetError(int& start, int& end)
|
||||
{
|
||||
start = m_start;
|
||||
end = m_end;
|
||||
return m_error;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CBotCStack::GetError()
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotTypResult CBotCStack::GetTypResult(int mode)
|
||||
{
|
||||
if (m_var == nullptr)
|
||||
return CBotTypResult(99);
|
||||
return m_var->GetTypResult(mode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CBotCStack::GetType(int mode)
|
||||
{
|
||||
if (m_var == nullptr)
|
||||
return 99;
|
||||
return m_var->GetType(mode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotClass* CBotCStack::GetClass()
|
||||
{
|
||||
if ( m_var == nullptr )
|
||||
return nullptr;
|
||||
if ( m_var->GetType(1) != CBotTypPointer ) return nullptr;
|
||||
|
||||
return m_var->GetClass();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCStack::SetType(CBotTypResult& type)
|
||||
{
|
||||
if (m_var == nullptr) return;
|
||||
m_var->SetType( type );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotVar* CBotCStack::FindVar(CBotToken* &pToken)
|
||||
{
|
||||
CBotCStack* p = this;
|
||||
CBotString name = pToken->GetString();
|
||||
|
||||
while (p != nullptr)
|
||||
{
|
||||
CBotVar* pp = p->m_listVar;
|
||||
while ( pp != nullptr)
|
||||
{
|
||||
if (name == pp->GetName())
|
||||
{
|
||||
return pp;
|
||||
}
|
||||
pp = pp->m_next;
|
||||
}
|
||||
p = p->m_prev;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotVar* CBotCStack::FindVar(CBotToken& Token)
|
||||
{
|
||||
CBotToken* pt = &Token;
|
||||
return FindVar(pt);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotVar* CBotCStack::CopyVar(CBotToken& Token)
|
||||
{
|
||||
CBotVar* pVar = FindVar( Token );
|
||||
|
||||
if ( pVar == nullptr) return nullptr;
|
||||
|
||||
CBotVar* pCopy = CBotVar::Create( "", pVar->GetType() );
|
||||
pCopy->Copy(pVar);
|
||||
return pCopy;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotCStack::IsOk()
|
||||
{
|
||||
return (m_error == 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCStack::SetStartError( int pos )
|
||||
{
|
||||
if ( m_error != 0) return; // does not change existing error
|
||||
m_start = pos;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCStack::SetError(int n, int pos)
|
||||
{
|
||||
if ( n!= 0 && m_error != 0) return; // does not change existing error
|
||||
m_error = n;
|
||||
m_end = pos;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCStack::SetError(int n, CBotToken* p)
|
||||
{
|
||||
if (m_error) return; // does not change existing error
|
||||
m_error = n;
|
||||
m_start = p->GetStart();
|
||||
m_end = p->GetEnd();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCStack::ResetError(int n, int start, int end)
|
||||
{
|
||||
m_error = n;
|
||||
m_start = start;
|
||||
m_end = end;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotCStack::NextToken(CBotToken* &p)
|
||||
{
|
||||
CBotToken* pp = p;
|
||||
|
||||
p = p->GetNext();
|
||||
if (p!=nullptr) return true;
|
||||
|
||||
SetError(TX_ENDOF, pp->GetEnd());
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCStack::SetBotCall(CBotProgram* p)
|
||||
{
|
||||
m_prog = p;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotProgram* CBotCStack::GetBotCall()
|
||||
{
|
||||
return m_prog;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCStack::SetRetType(CBotTypResult& type)
|
||||
{
|
||||
m_retTyp = type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotTypResult CBotCStack::GetRetType()
|
||||
{
|
||||
return m_retTyp;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCStack::SetVar( CBotVar* var )
|
||||
{
|
||||
if (m_var) delete m_var; // replacement of a variable
|
||||
m_var = var;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCStack::SetCopyVar( CBotVar* var )
|
||||
{
|
||||
if (m_var) delete m_var; // replacement of a variable
|
||||
|
||||
if ( var == nullptr ) return;
|
||||
m_var = CBotVar::Create("", var->GetTypResult(2));
|
||||
m_var->Copy( var );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotVar* CBotCStack::GetVar()
|
||||
{
|
||||
return m_var;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCStack::AddVar(CBotVar* pVar)
|
||||
{
|
||||
CBotCStack* p = this;
|
||||
|
||||
// returns to the father element
|
||||
while (p != nullptr && p->m_bBlock == 0) p = p->m_prev;
|
||||
|
||||
if ( p == nullptr ) return;
|
||||
|
||||
CBotVar** pp = &p->m_listVar;
|
||||
while ( *pp != nullptr ) pp = &(*pp)->m_next;
|
||||
|
||||
*pp = pVar; // added after
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ( pVar->GetUniqNum() == 0 ) assert(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotCStack::CheckVarLocal(CBotToken* &pToken)
|
||||
{
|
||||
CBotCStack* p = this;
|
||||
CBotString name = pToken->GetString();
|
||||
|
||||
while (p != nullptr)
|
||||
{
|
||||
CBotVar* pp = p->m_listVar;
|
||||
while ( pp != nullptr)
|
||||
{
|
||||
if (name == pp->GetName())
|
||||
return true;
|
||||
pp = pp->m_next;
|
||||
}
|
||||
if ( p->m_bBlock ) return false;
|
||||
p = p->m_prev;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotTypResult CBotCStack::CompileCall(CBotToken* &p, CBotVar** ppVars, long& nIdent)
|
||||
{
|
||||
nIdent = 0;
|
||||
CBotTypResult val(-1);
|
||||
|
||||
val = CBotCall::CompileCall(p, ppVars, this, nIdent);
|
||||
if (val.GetType() < 0)
|
||||
{
|
||||
val = m_prog->GetFunctions()->CompileCall(p->GetString(), ppVars, nIdent);
|
||||
if ( val.GetType() < 0 )
|
||||
{
|
||||
// pVar = nullptr; // the error is not on a particular parameter
|
||||
SetError( -val.GetType(), p );
|
||||
val.SetType(-val.GetType());
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotCStack::CheckCall(CBotToken* &pToken, CBotDefParam* pParam)
|
||||
{
|
||||
CBotString name = pToken->GetString();
|
||||
|
||||
if ( CBotCall::CheckCall(name) ) return true;
|
||||
|
||||
CBotFunction* pp = m_prog->GetFunctions();
|
||||
while ( pp != nullptr )
|
||||
{
|
||||
if ( pToken->GetString() == pp->GetName() )
|
||||
{
|
||||
// are parameters exactly the same?
|
||||
if ( pp->CheckParam( pParam ) )
|
||||
return true;
|
||||
}
|
||||
pp = pp->Next();
|
||||
}
|
||||
|
||||
pp = CBotFunction::m_listPublic;
|
||||
while ( pp != nullptr )
|
||||
{
|
||||
if ( pToken->GetString() == pp->GetName() )
|
||||
{
|
||||
// are parameters exactly the same?
|
||||
if ( pp->CheckParam( pParam ) )
|
||||
return true;
|
||||
}
|
||||
pp = pp->m_nextpublic;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* 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 "CBot/CBotProgram.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
class CBotInstr;
|
||||
class CBotDefParam;
|
||||
|
||||
/*!
|
||||
* \brief The CBotCStack class Management of the stack of compilation.
|
||||
*/
|
||||
class CBotCStack
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotCStack
|
||||
* \param ppapa
|
||||
*/
|
||||
CBotCStack(CBotCStack* ppapa);
|
||||
|
||||
/*!
|
||||
* \brief CBotCStack Destructor.
|
||||
*/
|
||||
~CBotCStack();
|
||||
|
||||
/*!
|
||||
* \brief IsOk
|
||||
* \return
|
||||
*/
|
||||
bool IsOk();
|
||||
|
||||
/*!
|
||||
* \brief GetError
|
||||
* \return
|
||||
*/
|
||||
int GetError();
|
||||
|
||||
/*!
|
||||
* \brief GetError Gives error number
|
||||
* \param start
|
||||
* \param end
|
||||
* \return
|
||||
*/
|
||||
int GetError(int& start, int& end);
|
||||
|
||||
/*!
|
||||
* \brief SetType Set the type of instruction on the stack.
|
||||
* \param type
|
||||
*/
|
||||
void SetType(CBotTypResult& type);
|
||||
|
||||
/*!
|
||||
* \brief GetTypResult Gives the type of value on the stack. Type of
|
||||
* instruction on the stack.
|
||||
* \param mode
|
||||
* \return
|
||||
*/
|
||||
CBotTypResult GetTypResult(int mode = 0);
|
||||
|
||||
/*!
|
||||
* \brief GetType Gives the type of value on the stack.
|
||||
* \param mode
|
||||
* \return
|
||||
*/
|
||||
int GetType(int mode = 0);
|
||||
|
||||
/*!
|
||||
* \brief GetClass Gives the class of the value on the stack.
|
||||
* \return
|
||||
*/
|
||||
CBotClass* GetClass();
|
||||
|
||||
/*!
|
||||
* \brief AddVar Adds a local variable.
|
||||
* \param p
|
||||
*/
|
||||
void AddVar(CBotVar* p);
|
||||
|
||||
/*!
|
||||
* \brief FindVar Finds a variable. Seeks a variable on the stack the token
|
||||
* may be a result of TokenTypVar (object of a class) or a pointer in the
|
||||
* source.
|
||||
* \param p
|
||||
* \return
|
||||
*/
|
||||
CBotVar* FindVar(CBotToken* &p);
|
||||
|
||||
/*!
|
||||
* \brief FindVar
|
||||
* \param Token
|
||||
* \return
|
||||
*/
|
||||
CBotVar* FindVar(CBotToken& Token);
|
||||
|
||||
/*!
|
||||
* \brief CheckVarLocal Test whether a variable is already defined locally.
|
||||
* \param pToken
|
||||
* \return
|
||||
*/
|
||||
bool CheckVarLocal(CBotToken* &pToken);
|
||||
|
||||
/*!
|
||||
* \brief CopyVar Finds and makes a copy.
|
||||
* \param Token
|
||||
* \return
|
||||
*/
|
||||
CBotVar* CopyVar(CBotToken& Token);
|
||||
|
||||
/*!
|
||||
* \brief TokenStack Used only at compile.
|
||||
* \param pToken
|
||||
* \param bBlock
|
||||
* \return
|
||||
*/
|
||||
CBotCStack* TokenStack(CBotToken* pToken = nullptr, bool bBlock = false);
|
||||
|
||||
/*!
|
||||
* \brief Return Transmits the result upper.
|
||||
* \param p
|
||||
* \param pParent
|
||||
* \return
|
||||
*/
|
||||
CBotInstr* Return(CBotInstr* p, CBotCStack* pParent);
|
||||
|
||||
/*!
|
||||
* \brief ReturnFunc Transmits the result upper.
|
||||
* \param p
|
||||
* \param pParent
|
||||
* \return
|
||||
*/
|
||||
CBotFunction* ReturnFunc(CBotFunction* p, CBotCStack* pParent);
|
||||
|
||||
/*!
|
||||
* \brief SetVar
|
||||
* \param var
|
||||
*/
|
||||
void SetVar( CBotVar* var );
|
||||
|
||||
/*!
|
||||
* \brief SetCopyVar Puts on the stack a copy of a variable.
|
||||
* \param var
|
||||
*/
|
||||
void SetCopyVar( CBotVar* var );
|
||||
|
||||
/*!
|
||||
* \brief GetVar
|
||||
* \return
|
||||
*/
|
||||
CBotVar* GetVar();
|
||||
|
||||
/*!
|
||||
* \brief SetStartError
|
||||
* \param pos
|
||||
*/
|
||||
void SetStartError(int pos);
|
||||
|
||||
/*!
|
||||
* \brief SetError
|
||||
* \param n
|
||||
* \param pos
|
||||
*/
|
||||
void SetError(int n, int pos);
|
||||
|
||||
/*!
|
||||
* \brief SetError
|
||||
* \param n
|
||||
* \param p
|
||||
*/
|
||||
void SetError(int n, CBotToken* p);
|
||||
|
||||
/*!
|
||||
* \brief ResetError
|
||||
* \param n
|
||||
* \param start
|
||||
* \param end
|
||||
*/
|
||||
void ResetError(int n, int start, int end);
|
||||
|
||||
/*!
|
||||
* \brief SetRetType
|
||||
* \param type
|
||||
*/
|
||||
void SetRetType(CBotTypResult& type);
|
||||
|
||||
/*!
|
||||
* \brief GetRetType
|
||||
* \return
|
||||
*/
|
||||
CBotTypResult GetRetType();
|
||||
|
||||
/*!
|
||||
* \brief SetBotCall
|
||||
* \param p
|
||||
*/
|
||||
void SetBotCall(CBotProgram* p);
|
||||
|
||||
/*!
|
||||
* \brief GetBotCall
|
||||
* \return
|
||||
*/
|
||||
CBotProgram* GetBotCall();
|
||||
|
||||
/*!
|
||||
* \brief CompileCall
|
||||
* \param p
|
||||
* \param ppVars
|
||||
* \param nIdent
|
||||
* \return
|
||||
*/
|
||||
CBotTypResult CompileCall(CBotToken* &p, CBotVar** ppVars, long& nIdent);
|
||||
|
||||
/*!
|
||||
* \brief CheckCall Test if a procedure name is already defined somewhere.
|
||||
* \param pToken
|
||||
* \param pParam
|
||||
* \return
|
||||
*/
|
||||
bool CheckCall(CBotToken* &pToken, CBotDefParam* pParam);
|
||||
|
||||
/*!
|
||||
* \brief NextToken
|
||||
* \param p
|
||||
* \return
|
||||
*/
|
||||
bool NextToken(CBotToken* &p);
|
||||
|
||||
private:
|
||||
CBotCStack* m_next;
|
||||
CBotCStack* m_prev;
|
||||
|
||||
static int m_error;
|
||||
static int m_end;
|
||||
int m_start;
|
||||
|
||||
//! Result of the operations.
|
||||
CBotVar* m_var;
|
||||
//! Is part of a block (variables are local to this block).
|
||||
bool m_bBlock;
|
||||
CBotVar* m_listVar;
|
||||
//! List of compiled functions.
|
||||
static CBotProgram* m_prog;
|
||||
static CBotTypResult m_retTyp;
|
||||
};
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
* 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 "CBot/CBotCall.h"
|
||||
|
||||
#include "CBot/CBotToken.h"
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
#include "CBot/CBotUtils.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.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,149 @@
|
|||
/*
|
||||
* 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 "CBot/CBotString.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
// Forward declaration
|
||||
class CBotStack;
|
||||
|
||||
#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;
|
||||
};
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* 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 "CBot/CBotCallMethode.h"
|
||||
|
||||
#include "CBot/CBotUtils.h"
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotCallMethode::CBotCallMethode(const char* name,
|
||||
bool rExec (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user),
|
||||
CBotTypResult rCompile (CBotVar* pThis, CBotVar* &pVar))
|
||||
{
|
||||
m_name = name;
|
||||
m_rExec = rExec;
|
||||
m_rComp = rCompile;
|
||||
m_next = nullptr;
|
||||
m_nFuncIdent = CBotVar::NextUniqNum();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotCallMethode::~CBotCallMethode()
|
||||
{
|
||||
delete m_next;
|
||||
m_next = nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotTypResult CBotCallMethode::CompileCall(const char* name,
|
||||
CBotVar* pThis,
|
||||
CBotVar** ppVar,
|
||||
CBotCStack* pStack,
|
||||
long& nIdent)
|
||||
{
|
||||
CBotCallMethode* pt = this;
|
||||
nIdent = 0;
|
||||
|
||||
while ( pt != nullptr )
|
||||
{
|
||||
if ( pt->m_name == name )
|
||||
{
|
||||
CBotVar* pVar = MakeListVars(ppVar, true);
|
||||
CBotVar* pVar2 = pVar;
|
||||
CBotTypResult r = pt->m_rComp(pThis, pVar2);
|
||||
int ret = r.GetType();
|
||||
if ( ret > 20 )
|
||||
{
|
||||
if (pVar2) pStack->SetError(ret, pVar2->GetToken());
|
||||
}
|
||||
delete pVar;
|
||||
nIdent = pt->m_nFuncIdent;
|
||||
return r;
|
||||
}
|
||||
pt = pt->m_next;
|
||||
}
|
||||
return CBotTypResult(-1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotString CBotCallMethode::GetName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotCallMethode* CBotCallMethode::Next()
|
||||
{
|
||||
return m_next;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCallMethode::AddNext(CBotCallMethode* pt)
|
||||
{
|
||||
CBotCallMethode* p = this;
|
||||
while ( p->m_next != nullptr ) p = p->m_next;
|
||||
|
||||
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 != nullptr )
|
||||
{
|
||||
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->GetPUser());
|
||||
pStack->SetVar(pResult);
|
||||
|
||||
if (res == false)
|
||||
{
|
||||
if (Exception!=0)
|
||||
{
|
||||
// pStack->SetError(Exception, pVar->GetToken());
|
||||
pStack->SetError(Exception, pToken);
|
||||
}
|
||||
delete pVarToDelete;
|
||||
return false;
|
||||
}
|
||||
delete pVarToDelete;
|
||||
return true;
|
||||
}
|
||||
pt = pt->m_next;
|
||||
}
|
||||
|
||||
// search by name
|
||||
|
||||
while ( pt != nullptr )
|
||||
{
|
||||
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->GetPUser());
|
||||
pStack->SetVar(pResult);
|
||||
|
||||
if (res == false)
|
||||
{
|
||||
if (Exception!=0)
|
||||
{
|
||||
// pStack->SetError(Exception, pVar->GetToken());
|
||||
pStack->SetError(Exception, pToken);
|
||||
}
|
||||
delete pVarToDelete;
|
||||
return false;
|
||||
}
|
||||
delete pVarToDelete;
|
||||
nIdent = pt->m_nFuncIdent;
|
||||
return true;
|
||||
}
|
||||
pt = pt->m_next;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* 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 "CBot/CBotTypResult.h"
|
||||
#include "CBot/CBotString.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
class CBotVar;
|
||||
class CBotCStack;
|
||||
class CBotStack;
|
||||
class CBotToken;
|
||||
|
||||
/*!
|
||||
* \brief The CBotCallMethode class Class managing the methods declared by
|
||||
* AddFunction on a class.
|
||||
*/
|
||||
class CBotCallMethode
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotCallMethode
|
||||
* \param name
|
||||
* \param rExec
|
||||
* \param rCompile
|
||||
*/
|
||||
CBotCallMethode(const char* name,
|
||||
bool rExec (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user),
|
||||
CBotTypResult rCompile (CBotVar* pThis, CBotVar* &pVar));
|
||||
|
||||
/*!
|
||||
* \brief ~CBotCallMethode
|
||||
*/
|
||||
~CBotCallMethode();
|
||||
|
||||
/*!
|
||||
* \brief CompileCall Is acceptable by a call procedure name and given
|
||||
* parameters.
|
||||
* \param name
|
||||
* \param pThis
|
||||
* \param ppVars
|
||||
* \param pStack
|
||||
* \param nIdent
|
||||
* \return
|
||||
*/
|
||||
CBotTypResult CompileCall(const char* name,
|
||||
CBotVar* pThis,
|
||||
CBotVar** ppVars,
|
||||
CBotCStack* pStack,
|
||||
long& nIdent);
|
||||
|
||||
/*!
|
||||
* \brief DoCall
|
||||
* \param nIdent
|
||||
* \param name
|
||||
* \param pThis
|
||||
* \param ppVars
|
||||
* \param pResult
|
||||
* \param pStack
|
||||
* \param pFunc
|
||||
* \return
|
||||
*/
|
||||
int DoCall(long& nIdent,
|
||||
const char* name,
|
||||
CBotVar* pThis,
|
||||
CBotVar** ppVars,
|
||||
CBotVar* &pResult,
|
||||
CBotStack* pStack,
|
||||
CBotToken* pFunc);
|
||||
|
||||
/*!
|
||||
* \brief GetName
|
||||
* \return
|
||||
*/
|
||||
CBotString GetName();
|
||||
|
||||
/*!
|
||||
* \brief Next
|
||||
* \return
|
||||
*/
|
||||
CBotCallMethode* Next();
|
||||
|
||||
/*!
|
||||
* \brief AddNext
|
||||
* \param p
|
||||
*/
|
||||
void AddNext(CBotCallMethode* p);
|
||||
|
||||
private:
|
||||
CBotString m_name;
|
||||
bool (*m_rExec) (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user);
|
||||
CBotTypResult (*m_rComp) (CBotVar* pThis, CBotVar* &pVar);
|
||||
CBotCallMethode* m_next;
|
||||
friend class CBotClass;
|
||||
long m_nFuncIdent;
|
||||
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,475 @@
|
|||
/*
|
||||
* 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 "CBot/CBotDefines.h"
|
||||
|
||||
#include "CBot/CBotTypResult.h"
|
||||
|
||||
#include "CBot/CBotString.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
// Forward declaration
|
||||
class CBotVar;
|
||||
class CBotClass;
|
||||
class CBotCallMethode;
|
||||
class CBotFunction;
|
||||
class CBotProgram;
|
||||
class CBotStack;
|
||||
class CBotDefParam;
|
||||
|
||||
/*!
|
||||
* \brief The CBotClass class Class to define new classes in the language CBOT
|
||||
* For example to define the class CPoint (x, y) see comments at end of this
|
||||
* file.
|
||||
*/
|
||||
class CBotClass
|
||||
{
|
||||
public:
|
||||
//! Mark if is set or not
|
||||
bool m_IsDef;
|
||||
|
||||
/*!
|
||||
* \brief CBotClass Constructor. Once a class is created, it is known around
|
||||
* CBot intrinsic mode gives a class that is not managed by pointers.
|
||||
* \param name
|
||||
* \param pParent
|
||||
* \param bIntrinsic
|
||||
*/
|
||||
CBotClass( const char* name,
|
||||
CBotClass* pParent,
|
||||
bool bIntrinsic = false );
|
||||
|
||||
/*!
|
||||
* \brief CBotClass Destructor.
|
||||
*/
|
||||
~CBotClass( );
|
||||
|
||||
/*!
|
||||
* \brief Create
|
||||
* \param name
|
||||
* \param parent
|
||||
* \param intrinsic
|
||||
* \return
|
||||
*/
|
||||
static CBotClass* Create(const char* name,
|
||||
CBotClass* parent,
|
||||
bool intrinsic = false);
|
||||
|
||||
/*!
|
||||
* \brief AddFunction This call allows to add as external new method
|
||||
* used by the objects of this class. See (**) at end of this file for
|
||||
* more details.
|
||||
* \param name
|
||||
* \param rExec
|
||||
* \param rCompile
|
||||
* \return
|
||||
*/
|
||||
bool AddFunction(const char* name,
|
||||
bool rExec (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user),
|
||||
CBotTypResult rCompile (CBotVar* pThis, CBotVar* &pVar));
|
||||
|
||||
/*!
|
||||
* \brief AddUpdateFunc Defines routine to be called to update the elements
|
||||
* of the class.
|
||||
* \param rMaj
|
||||
* \return
|
||||
*/
|
||||
bool AddUpdateFunc( void rMaj ( CBotVar* pThis, void* pUser ) );
|
||||
//
|
||||
|
||||
/*!
|
||||
* \brief AddItem Adds an element to the class.
|
||||
* \param name
|
||||
* \param type
|
||||
* \param mPrivate
|
||||
* \return
|
||||
*/
|
||||
bool AddItem(CBotString name, CBotTypResult type, int mPrivate = PR_PUBLIC);
|
||||
|
||||
/*!
|
||||
* \brief AddItem Adds an item by passing the pointer to an instance of a
|
||||
* variable the object is taken as is, so do not destroyed.
|
||||
* \param pVar
|
||||
* \return
|
||||
*/
|
||||
bool AddItem(CBotVar* pVar);
|
||||
|
||||
/*!
|
||||
* \brief AddNext
|
||||
* \param pClass
|
||||
*/
|
||||
void AddNext(CBotClass* pClass);
|
||||
|
||||
/*!
|
||||
* \brief GetName Gives the name of the class.
|
||||
* \return
|
||||
*/
|
||||
CBotString GetName();
|
||||
|
||||
/*!
|
||||
* \brief GetParent Gives the parent class (or nullptr).
|
||||
* \return
|
||||
*/
|
||||
CBotClass* GetParent();
|
||||
|
||||
/*!
|
||||
* \brief IsChildOf True if a class is derived (Extends) of another.
|
||||
* \param pClass
|
||||
* \return true also if the classes are identical
|
||||
*/
|
||||
bool IsChildOf(CBotClass* pClass);
|
||||
|
||||
/*!
|
||||
* \brief Find Trouve une classe d'après son nom
|
||||
* \param pToken
|
||||
* \return A class by it's its name.
|
||||
*/
|
||||
static CBotClass* Find(CBotToken* &pToken);
|
||||
|
||||
/*!
|
||||
* \brief Find
|
||||
* \param name
|
||||
* \return
|
||||
*/
|
||||
static CBotClass* Find(const char* name);
|
||||
|
||||
/*!
|
||||
* \brief GetVar Return the list of variables.
|
||||
* \return
|
||||
*/
|
||||
CBotVar* GetVar();
|
||||
/*!
|
||||
* \brief GetItem One of the variables according to its name.
|
||||
* \param name
|
||||
* \return
|
||||
*/
|
||||
CBotVar* GetItem(const char* name);
|
||||
|
||||
/*!
|
||||
* \brief GetItemRef
|
||||
* \param nIdent
|
||||
* \return
|
||||
*/
|
||||
CBotVar* GetItemRef(int nIdent);
|
||||
|
||||
/*!
|
||||
* \brief CompileMethode Compiles a method associated with an instance of
|
||||
* class the method can be declared by the user or AddFunction.
|
||||
* \param name
|
||||
* \param pThis
|
||||
* \param ppParams
|
||||
* \param pStack
|
||||
* \param nIdent
|
||||
* \return
|
||||
*/
|
||||
CBotTypResult CompileMethode(const char* name,
|
||||
CBotVar* pThis,
|
||||
CBotVar** ppParams,
|
||||
CBotCStack* pStack,
|
||||
long& nIdent);
|
||||
|
||||
/*!
|
||||
* \brief ExecuteMethode Executes a method.
|
||||
* \param nIdent
|
||||
* \param name
|
||||
* \param pThis
|
||||
* \param ppParams
|
||||
* \param pResult
|
||||
* \param pStack
|
||||
* \param pToken
|
||||
* \return
|
||||
*/
|
||||
bool ExecuteMethode(long& nIdent,
|
||||
const char* name,
|
||||
CBotVar* pThis,
|
||||
CBotVar** ppParams,
|
||||
CBotVar* &pResult,
|
||||
CBotStack* &pStack,
|
||||
CBotToken* pToken);
|
||||
|
||||
/*!
|
||||
* \brief RestoreMethode Restored the execution stack.
|
||||
* \param nIdent
|
||||
* \param name
|
||||
* \param pThis
|
||||
* \param ppParams
|
||||
* \param pStack
|
||||
*/
|
||||
void RestoreMethode(long& nIdent,
|
||||
const char* name,
|
||||
CBotVar* pThis,
|
||||
CBotVar** ppParams,
|
||||
CBotStack* &pStack);
|
||||
|
||||
/*!
|
||||
* \brief Compile Compiles a class declared by the user.
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotClass* Compile(CBotToken* &p,
|
||||
CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Compile1
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotClass* Compile1(CBotToken* &p,
|
||||
CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief CompileDefItem
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param bSecond
|
||||
* \return
|
||||
*/
|
||||
bool CompileDefItem(CBotToken* &p,
|
||||
CBotCStack* pStack,
|
||||
bool bSecond);
|
||||
|
||||
/*!
|
||||
* \brief IsIntrinsic
|
||||
* \return
|
||||
*/
|
||||
bool IsIntrinsic();
|
||||
|
||||
/*!
|
||||
* \brief Purge
|
||||
*/
|
||||
void Purge();
|
||||
|
||||
/*!
|
||||
* \brief Free
|
||||
*/
|
||||
static void Free();
|
||||
|
||||
/*!
|
||||
* \brief SaveStaticState
|
||||
* \param pf
|
||||
* \return
|
||||
*/
|
||||
static bool SaveStaticState(FILE* pf);
|
||||
|
||||
/*!
|
||||
* \brief RestoreStaticState
|
||||
* \param pf
|
||||
* \return
|
||||
*/
|
||||
static bool RestoreStaticState(FILE* pf);
|
||||
|
||||
/*!
|
||||
* \brief Lock
|
||||
* \param p
|
||||
* \return
|
||||
*/
|
||||
bool Lock(CBotProgram* p);
|
||||
|
||||
/*!
|
||||
* \brief Unlock
|
||||
*/
|
||||
void Unlock();
|
||||
|
||||
/*!
|
||||
* \brief FreeLock
|
||||
* \param p
|
||||
*/
|
||||
static void FreeLock(CBotProgram* p);
|
||||
|
||||
/*!
|
||||
* \brief CheckCall Test if a procedure name is already defined somewhere.
|
||||
* \param pToken
|
||||
* \param pParam
|
||||
* \return
|
||||
*/
|
||||
bool CheckCall(CBotToken* &pToken,
|
||||
CBotDefParam* pParam);
|
||||
|
||||
private:
|
||||
//! List of classes existing at a given time.
|
||||
static CBotClass* m_ExClass;
|
||||
//! For this general list.
|
||||
CBotClass* m_ExNext;
|
||||
//! For this general list.
|
||||
CBotClass* m_ExPrev;
|
||||
//! Parent class.
|
||||
CBotClass* m_pParent;
|
||||
//! Name of this class.
|
||||
CBotString m_name;
|
||||
//! Number of variables in the chain.
|
||||
int m_nbVar;
|
||||
//! Content of the class.
|
||||
CBotVar* m_pVar;
|
||||
//! Intrinsic class.
|
||||
bool m_bIntrinsic;
|
||||
//! The string class.
|
||||
CBotClass* m_next;
|
||||
//! List of methods defined in external.
|
||||
CBotCallMethode* m_pCalls;
|
||||
//! Compiled list of methods.
|
||||
CBotFunction* m_pMethod;
|
||||
void (*m_rMaj) ( CBotVar* pThis, void* pUser );
|
||||
friend class CBotVarClass;
|
||||
//! For Lock / UnLock.
|
||||
int m_cptLock;
|
||||
//! Lock for reentrancy.
|
||||
int m_cptOne;
|
||||
//! Processes waiting for sync.
|
||||
CBotProgram* m_ProgInLock[5];
|
||||
};
|
||||
|
||||
/*
|
||||
(**) Note:
|
||||
|
||||
To define an external function, proceed as follows:
|
||||
|
||||
a) define a routine for compilation this routine receive list of parameters
|
||||
(no values) and either returns a result type (CBotTyp... or 0 = void)
|
||||
or an error number.
|
||||
|
||||
b) define a routine for the execution this routine receive list of
|
||||
parameters (with valeurs), a variable to store the result
|
||||
(according to the given type at compile time)
|
||||
|
||||
For example, a routine which calculates the mean of a parameter list
|
||||
|
||||
int cMean(CBotVar* &pVar, CBotString& ClassName)
|
||||
{
|
||||
if ( pVar == nullptr ) return 6001; // there is no parameter!
|
||||
while ( pVar != nullptr )
|
||||
{
|
||||
if ( pVar->GetType() > CBotTypDouble ) return 6002; // this is not a number
|
||||
pVar = pVar -> GetNext();
|
||||
}
|
||||
return CBotTypFloat; // the type of the result may depend on the parameters!
|
||||
}
|
||||
|
||||
|
||||
bool rMean(CBotVar* pVar, CBotVar* pResult, int& Exception)
|
||||
{
|
||||
float total = 0;
|
||||
int nb = 0;
|
||||
while (pVar != nullptr)
|
||||
{
|
||||
total += pVar->GetValFloat();
|
||||
pVar = pVar->GetNext();
|
||||
nb++;
|
||||
}
|
||||
pResult->SetValFloat(total/nb); // returns the mean value
|
||||
return true; // operation fully completed
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Examples of use
|
||||
// Definition classes and functions
|
||||
|
||||
|
||||
// define the global class CPoint
|
||||
// --------------------------------
|
||||
m_pClassPoint = new CBotClass("CPoint", nullptr);
|
||||
// adds the component ".x"
|
||||
m_pClassPoint->AddItem("x", CBotTypResult(CBotTypFloat));
|
||||
// adds the component ".y"
|
||||
m_pClassPoint->AddItem("y", CBotTypResult(CBotTypFloat));
|
||||
// the player can then use the instructions
|
||||
// CPoint position; position.x = 12; position.y = -13.6
|
||||
|
||||
// define class CColobotObject
|
||||
// --------------------------------
|
||||
// This class manages all the objects in the world of COLOBOT
|
||||
// the "main" user program belongs to this class
|
||||
m_pClassObject = new CBotClass("CColobotObject", m_pClassBase);
|
||||
// adds the component ".position"
|
||||
m_pClassObject->AddItem("position", m_pClassPoint);
|
||||
// adds the component ".type"
|
||||
m_pClassObject->AddItem("type", CBotTypResult(CBotTypShort));
|
||||
// adds a definition of constant
|
||||
m_pClassObject->AddConst("ROBOT", CBotTypShort, 1); // ROBOT equivalent to the value 1
|
||||
// adds the FIND routine
|
||||
m_pClassObject->AddFunction( rCompFind, rDoFind );
|
||||
// the player can now use the instructions
|
||||
// CColobotObject chose; chose = FIND( ROBOT )
|
||||
|
||||
// define class CColobotRobot derived from CColobotObject
|
||||
// ---------------------------------------------------------
|
||||
// programs "main" associated with robots as a part of this class
|
||||
m_pClassRobot = new CBotClass("CColobotRobot", m_pClassObject);
|
||||
// add routine GOTO
|
||||
m_pClassRobot->AddFunction( rCompGoto, rDoGoto );
|
||||
// the player can now use
|
||||
// GOTO( FIND ( ROBOT ) );
|
||||
|
||||
|
||||
// creates an instance of the class Robot
|
||||
// ------------------------------------
|
||||
// for example a new robot which has just been manufactured
|
||||
CBotVar* m_pMonRobot = new CBotVar("MonRobot", m_pClassRobot);
|
||||
|
||||
|
||||
// compiles the program by hand for this robot
|
||||
// ------------------------------------------
|
||||
CString LeProgramme( "void main() {GOTO(0, 0); return 0;}" );
|
||||
if ( !m_pMonRobot->Compile( LeProgramme ) ) {error handling ...};
|
||||
|
||||
// build a stack for interpreter
|
||||
// --------------------------------------
|
||||
CBotStack* pStack = new CBotStack(nullptr);
|
||||
|
||||
// executes the main program
|
||||
// -------------------------
|
||||
while( false = m_pMonRobot->Execute( "main", pStack ))
|
||||
{
|
||||
// program suspended
|
||||
// could be pass a handle to another (safeguarding pstack for the robot one)
|
||||
};
|
||||
// programme "main" finished !
|
||||
|
||||
// routine that implements the GOTO (CPoint pos)
|
||||
bool rDoGoto( CBotVar* pVar, CBotVar* pResult, int& exception )
|
||||
{
|
||||
if (pVar->GetType() != CBotTypeClass ||
|
||||
pVar->IsElemOfClas("CPoint") ) { exception = 6522; return false; )
|
||||
// the parameter is not the right class?
|
||||
// in fact the control is done to the routine of compilation
|
||||
|
||||
m_PosToGo.Copy( pVar ); // keeps the target position (object type CBotVar)
|
||||
|
||||
// or so
|
||||
CBotVar* temp;
|
||||
temp = pVar->GetItem("x"); // is necessary for the object of type CPoint
|
||||
ASSERT (temp != nullptr && temp->GetType() == CBotTypFloat);
|
||||
m_PosToGo.x = temp->GetValFloat();
|
||||
|
||||
temp = pVar->GetItem("y"); // is necessary for the object of type CPoint
|
||||
ASSERT (temp != nullptr && temp->GetType() == CBotTypFloat);
|
||||
m_PosToGo.y = temp->GetValFloat();
|
||||
|
||||
return (m_CurentPos == m_PosToGo); // makes true if the position is reached
|
||||
// returns false if one had wait yet
|
||||
}
|
||||
|
||||
*/
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* 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 "CBot/CBotDefParam.h"
|
||||
|
||||
#include "CBot/CBotUtils.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVarClass.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
#include <cassert>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotDefParam::CBotDefParam()
|
||||
{
|
||||
m_next = nullptr;
|
||||
m_nIdent = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotDefParam::~CBotDefParam()
|
||||
{
|
||||
delete m_next;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotDefParam* CBotDefParam::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
// mainly not pStack->TokenStack here
|
||||
// declared variables must remain visible thereafter
|
||||
|
||||
pStack->SetStartError(p->GetStart());
|
||||
|
||||
if (IsOfType(p, ID_OPENPAR))
|
||||
{
|
||||
CBotDefParam* list = nullptr;
|
||||
|
||||
while (!IsOfType(p, ID_CLOSEPAR))
|
||||
{
|
||||
CBotDefParam* param = new CBotDefParam();
|
||||
if (list == nullptr) list = param;
|
||||
else list->AddNext(param); // added to the list
|
||||
|
||||
// CBotClass* pClass = nullptr;//= CBotClass::Find(p);
|
||||
param->m_typename = p->GetString();
|
||||
CBotTypResult type = param->m_type = TypeParam(p, pStack);
|
||||
// if ( type == CBotTypPointer ) type = CBotTypClass; // we must create a new object
|
||||
|
||||
if (param->m_type.GetType() > 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->GetString(), type); // creates the variable
|
||||
// if ( pClass ) var->SetClass(pClass);
|
||||
var->SetInit(CBotVar::InitType::IS_POINTER); // 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->GetType() == ID_CLOSEPAR)
|
||||
continue;
|
||||
}
|
||||
pStack->SetError(TX_CLOSEPAR, p->GetStart());
|
||||
}
|
||||
pStack->SetError(TX_NOTYP, p);
|
||||
delete list;
|
||||
return nullptr;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
pStack->SetError(TX_OPENPAR, p->GetStart());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotDefParam::AddNext(CBotDefParam* p)
|
||||
{
|
||||
CBotDefParam* pp = this;
|
||||
while (pp->m_next != nullptr) pp = pp->m_next;
|
||||
|
||||
pp->m_next = p;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotDefParam::Execute(CBotVar** ppVars, CBotStack* &pj)
|
||||
{
|
||||
int i = 0;
|
||||
CBotDefParam* p = this;
|
||||
|
||||
while ( p != nullptr )
|
||||
{
|
||||
// creates a local variable on the stack
|
||||
CBotVar* newvar = CBotVar::Create(p->m_token.GetString(), p->m_type);
|
||||
|
||||
// serves to make the transformation of types:
|
||||
if ( ppVars != nullptr && ppVars[i] != nullptr )
|
||||
{
|
||||
switch (p->m_type.GetType())
|
||||
{
|
||||
case CBotTypInt:
|
||||
newvar->SetValInt(ppVars[i]->GetValInt());
|
||||
break;
|
||||
case CBotTypFloat:
|
||||
newvar->SetValFloat(ppVars[i]->GetValFloat());
|
||||
break;
|
||||
case CBotTypString:
|
||||
newvar->SetValString(ppVars[i]->GetValString());
|
||||
break;
|
||||
case CBotTypBoolean:
|
||||
newvar->SetValInt(ppVars[i]->GetValInt());
|
||||
break;
|
||||
case CBotTypIntrinsic:
|
||||
(static_cast<CBotVarClass*>(newvar))->Copy(ppVars[i], false);
|
||||
break;
|
||||
case CBotTypPointer:
|
||||
case CBotTypArrayPointer:
|
||||
{
|
||||
newvar->SetPointer(ppVars[i]->GetPointer());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
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 != nullptr )
|
||||
{
|
||||
// creates a local variable on the stack
|
||||
CBotVar* var = pj->FindVar(p->m_token.GetString());
|
||||
var->SetUniqNum(p->m_nIdent);
|
||||
p = p->m_next;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CBotDefParam::GetType()
|
||||
{
|
||||
return m_type.GetType();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotTypResult CBotDefParam::GetTypResult()
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotDefParam* CBotDefParam::GetNext()
|
||||
{
|
||||
return m_next;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotString CBotDefParam::GetParamString()
|
||||
{
|
||||
CBotString param;
|
||||
|
||||
param = m_typename;
|
||||
param += ' ';
|
||||
|
||||
param += m_token.GetString();
|
||||
return param;
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* 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 "CBot/CBotToken.h"
|
||||
#include "CBot/CBotStack.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
class CBotCStack;
|
||||
class CBotStack;
|
||||
class CBotVar;
|
||||
|
||||
/*!
|
||||
* \brief The CBotDefParam class A list of parameters.
|
||||
*/
|
||||
class CBotDefParam
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotDefParam
|
||||
*/
|
||||
CBotDefParam();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotDefParam
|
||||
*/
|
||||
~CBotDefParam();
|
||||
|
||||
/*!
|
||||
* \brief Compile Compiles a list of parameters.
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotDefParam* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute
|
||||
* \param ppVars
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotVar** ppVars, CBotStack* &pj);
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain);
|
||||
|
||||
/*!
|
||||
* \brief AddNext
|
||||
* \param p
|
||||
*/
|
||||
void AddNext(CBotDefParam* p);
|
||||
|
||||
/*!
|
||||
* \brief GetType
|
||||
* \return
|
||||
*/
|
||||
int GetType();
|
||||
|
||||
/*!
|
||||
* \brief GetTypResult
|
||||
* \return
|
||||
*/
|
||||
CBotTypResult GetTypResult();
|
||||
|
||||
/*!
|
||||
* \brief GetNext
|
||||
* \return
|
||||
*/
|
||||
CBotDefParam* GetNext();
|
||||
|
||||
/*!
|
||||
* \brief GetParamString
|
||||
* \return
|
||||
*/
|
||||
CBotString GetParamString();
|
||||
|
||||
private:
|
||||
//! Name of the parameter.
|
||||
CBotToken m_token;
|
||||
//! Type name.
|
||||
CBotString m_typename;
|
||||
//! Type of paramteter.
|
||||
CBotTypResult m_type;
|
||||
//! Next parameter.
|
||||
CBotDefParam* m_next;
|
||||
long m_nIdent;
|
||||
};
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
#define STACKMEM 1 /// \def preserve memory for the execution stack
|
||||
#define MAXSTACK 990 /// \def stack size reserved
|
||||
|
||||
#define EOX (reinterpret_cast<CBotStack*>(-1)) /// \def tag special condition
|
||||
|
||||
#define MAXARRAYSIZE 9999
|
||||
|
||||
// variable type SetPrivate / IsPrivate
|
||||
#define PR_PUBLIC 0 // public variable
|
||||
#define PR_READ 1 // read only
|
||||
#define PR_PROTECT 2 // protected (inheritance)
|
||||
#define PR_PRIVATE 3 // strictly private
|
||||
|
||||
//! Define the current CBot version
|
||||
#define CBOTVERSION 104
|
||||
|
||||
// for SetUserPtr when deleting an object
|
||||
// \TODO define own types to distinct between different states of objects
|
||||
#define OBJECTDELETED (reinterpret_cast<void*>(-1))
|
||||
// value set before initialization
|
||||
#define OBJECTCREATED (reinterpret_cast<void*>(-2))
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Error Handling of compilation and execution
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Here are the list of errors that can be returned by the module
|
||||
// for compilation
|
||||
|
||||
#define CBotErrOpenPar 5000 // missing the opening parenthesis
|
||||
#define CBotErrClosePar 5001 // missing the closing parenthesis
|
||||
#define CBotErrNotBoolean 5002 // expression must be a boolean
|
||||
#define CBotErrUndefVar 5003 // undeclared variable
|
||||
#define CBotErrBadLeft 5004 // assignment impossible ( 5 = ... )
|
||||
#define CBotErrNoTerminator 5005 // semicolon expected
|
||||
#define CBotErrCaseOut 5006 // case outside a switch
|
||||
#define CBotErrCloseBlock 5008 // missing " } "
|
||||
#define CBotErrElseWhitoutIf 5009 // else without matching if
|
||||
#define CBotErrOpenBlock 5010 // missing " { "
|
||||
#define CBotErrBadType1 5011 // wrong type for the assignment
|
||||
#define CBotErrRedefVar 5012 // redefinition of the variable
|
||||
#define CBotErrBadType2 5013 // Two operands are incompatible
|
||||
#define CBotErrUndefCall 5014 // routine undefined
|
||||
#define CBotErrNoDoubleDots 5015 // " : " expected
|
||||
#define CBotErrBreakOutside 5017 // break outside of a loop
|
||||
#define CBotErrUndefLabel 5019 // label udnefined
|
||||
#define CBotErrLabel 5018 // label ne peut se mettre ici (label can not get here)
|
||||
#define CBotErrNoCase 5020 // missing " case "
|
||||
#define CBotErrBadNum 5021 // expected number
|
||||
#define CBotErrVoid 5022 // " void " not possible here
|
||||
#define CBotErrNoType 5023 // type declaration expected
|
||||
#define CBotErrNoVar 5024 // variable name expected
|
||||
#define CBotErrNoFunc 5025 // expected function name
|
||||
#define CBotErrOverParam 5026 // too many parameters
|
||||
#define CBotErrRedefFunc 5027 // this function already exists
|
||||
#define CBotErrLowParam 5028 // not enough parameters
|
||||
#define CBotErrBadParam 5029 // wrong types of parameters
|
||||
#define CBotErrNbParam 5030 // wrong number of parameters
|
||||
#define CBotErrUndefItem 5031 // element does not exist in the class
|
||||
#define CBotErrUndefClass 5032 // variable is not a class
|
||||
#define CBotErrNoConstruct 5033 // no appropriate constructor
|
||||
#define CBotErrRedefClass 5034 // class already exists
|
||||
#define CBotErrCloseIndex 5035 // " ] " expected
|
||||
#define CBotErrReserved 5036 // reserved word (for a DefineNum)
|
||||
#define CBotErrBadNew 5037 // wrong setting for new
|
||||
#define CBotErrOpenIndex 5038 // " [ " expected
|
||||
#define CBotErrBadString 5039 // expected string
|
||||
#define CBotErrBadIndex 5040 // wrong index type "[ false ]"
|
||||
#define CBotErrPrivate 5041 // protected item
|
||||
#define CBotErrNoPublic 5042 // missing word "public"
|
||||
|
||||
// here is the list of errors that can be returned by the module
|
||||
// for the execution
|
||||
|
||||
#define CBotErrZeroDiv 6000 // division by zero
|
||||
#define CBotErrNotInit 6001 // uninitialized variable
|
||||
#define CBotErrBadThrow 6002 // throw a negative value
|
||||
#define CBotErrNoRetVal 6003 // function did not return results
|
||||
#define CBotErrNoRun 6004 // Run() without active function
|
||||
#define CBotErrUndefFunc 6005 // calling a function that no longer exists
|
||||
#define CBotErrNotClass 6006 // this class does not exist
|
||||
#define CBotErrNull 6007 // null pointer
|
||||
#define CBotErrNan 6008 // calculation with a NAN
|
||||
#define CBotErrOutArray 6009 // index out of array
|
||||
#define CBotErrStackOver 6010 // stack overflow
|
||||
#define CBotErrDeletedPtr 6011 // pointer to an object destroyed
|
||||
#define CBotErrFileOpen 6012 // cannot open the file
|
||||
#define CBotErrNotOpen 6013 // channel not open
|
||||
#define CBotErrRead 6014 // error while reading
|
||||
#define CBotErrWrite 6015 // writing error
|
||||
|
||||
// other values may be returned
|
||||
// for example exceptions returned by external routines
|
||||
// and " throw " with any number.
|
||||
|
||||
// TODO: refactor & change to enum!
|
||||
|
||||
// Compile errors
|
||||
#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_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_BADSTRING 5039
|
||||
#define TX_BADINDEX 5040
|
||||
#define TX_PRIVATE 5041
|
||||
#define TX_NOPUBLIC 5042
|
||||
|
||||
// Runtime errors
|
||||
#define TX_DIVZERO 6000
|
||||
#define TX_NOTINIT 6001
|
||||
#define TX_BADTHROW 6002
|
||||
#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
|
||||
|
||||
// Max errors
|
||||
#define TX_MAX 6012
|
1233
src/CBot/CBotDll.h
1233
src/CBot/CBotDll.h
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
/*! \brief CBotType Defines known types. This types are modeled on Java types.
|
||||
* Do not change the order of elements
|
||||
*/
|
||||
enum CBotType
|
||||
{
|
||||
CBotTypVoid = 0,
|
||||
CBotTypByte = 1, //n
|
||||
CBotTypShort = 2, //n
|
||||
CBotTypChar = 3, //n
|
||||
CBotTypInt = 4,
|
||||
CBotTypLong = 5, //n
|
||||
CBotTypFloat = 6,
|
||||
CBotTypDouble = 7, //n
|
||||
CBotTypBoolean = 8,
|
||||
CBotTypString = 9,
|
||||
|
||||
CBotTypArrayPointer = 10, // array of variables
|
||||
CBotTypArrayBody = 11, // same but creates an instance
|
||||
|
||||
CBotTypPointer = 12, // pointer to an instance
|
||||
CBotTypNullPointer = 13, // null pointer is special
|
||||
CBotTypClass = 15,
|
||||
CBotTypIntrinsic = 16 // instance of a class intrinsic
|
||||
};
|
||||
//n = not implemented yet
|
||||
|
||||
//! \brief CBotGet Different modes for GetPosition.
|
||||
enum CBotGet
|
||||
{
|
||||
GetPosExtern = 1,
|
||||
GetPosNom = 2,
|
||||
GetPosParam = 3,
|
||||
GetPosBloc = 4
|
||||
};
|
||||
|
||||
|
||||
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_STATIC,
|
||||
ID_PROTECTED,
|
||||
ID_PRIVATE,
|
||||
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
|
||||
};
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* 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 "CBot/CBotFileUtils.h"
|
||||
|
||||
#include "CBot/CBotString.h"
|
||||
#include "CBot/CBotClass.h"
|
||||
|
||||
#include "CBot/CBotEnums.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
|
||||
// file management
|
||||
|
||||
// necessary because it is not possible to do the fopen in the main program
|
||||
// fwrite and fread in a dll or using the FILE * returned.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
FILE* fOpen(const char* name, const char* mode)
|
||||
{
|
||||
return fopen(name, mode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int fClose(FILE* filehandle)
|
||||
{
|
||||
return fclose(filehandle);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::size_t fWrite(const void *buffer,
|
||||
std::size_t elemsize,
|
||||
std::size_t length,
|
||||
FILE* filehandle)
|
||||
{
|
||||
return fwrite(buffer, elemsize, length, filehandle);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::size_t fRead(void *buffer,
|
||||
std::size_t elemsize,
|
||||
std::size_t length,
|
||||
FILE* filehandle)
|
||||
{
|
||||
return fread(buffer, elemsize, length, filehandle);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool ReadWord(FILE* pf, unsigned short& w)
|
||||
{
|
||||
size_t lg;
|
||||
|
||||
lg = fread(&w, sizeof( unsigned short ), 1, pf );
|
||||
|
||||
return (lg == 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool ReadFloat(FILE* pf, float& w)
|
||||
{
|
||||
size_t lg;
|
||||
|
||||
lg = fread(&w, sizeof( float ), 1, pf );
|
||||
|
||||
return (lg == 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool WriteLong(FILE* pf, long w)
|
||||
{
|
||||
size_t lg;
|
||||
|
||||
lg = fwrite(&w, sizeof( long ), 1, pf );
|
||||
|
||||
return (lg == 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool ReadLong(FILE* pf, long& w)
|
||||
{
|
||||
size_t lg;
|
||||
|
||||
lg = fread(&w, sizeof( long ), 1, pf );
|
||||
|
||||
return (lg == 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool ReadString(FILE* pf, CBotString& s)
|
||||
{
|
||||
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;
|
||||
|
||||
s = buf;
|
||||
return (lg1 == lg2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool WriteType(FILE* pf, const CBotTypResult &type)
|
||||
{
|
||||
int typ = type.GetType();
|
||||
if ( typ == CBotTypIntrinsic ) typ = CBotTypClass;
|
||||
if ( !WriteWord(pf, typ) ) return false;
|
||||
if ( typ == CBotTypClass )
|
||||
{
|
||||
CBotClass* p = type.GetClass();
|
||||
if ( !WriteString(pf, p->GetName()) ) return false;
|
||||
}
|
||||
if ( type.Eq( CBotTypArrayBody ) ||
|
||||
type.Eq( CBotTypArrayPointer ) )
|
||||
{
|
||||
if ( !WriteWord(pf, type.GetLimite()) ) return false;
|
||||
if ( !WriteType(pf, type.GetTypElem()) ) 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(static_cast<short>(ww));
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
#include <cstdio>
|
||||
|
||||
// Forward declaration
|
||||
class CBotVar;
|
||||
class CBotString;
|
||||
class CBotTypResult;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// routines for file management (* FILE)
|
||||
|
||||
/*!
|
||||
* \brief fOpen
|
||||
* \param name
|
||||
* \param mode
|
||||
* \return
|
||||
*/
|
||||
FILE* fOpen(const char* name, const char* mode);
|
||||
|
||||
/*!
|
||||
* \brief fClose
|
||||
* \param filehandle
|
||||
* \return
|
||||
*/
|
||||
int fClose(FILE* filehandle);
|
||||
|
||||
/*!
|
||||
* \brief fWrite
|
||||
* \param buffer
|
||||
* \param elemsize
|
||||
* \param length
|
||||
* \param filehandle
|
||||
* \return
|
||||
*/
|
||||
std::size_t fWrite(const void *buffer,
|
||||
std::size_t elemsize,
|
||||
std::size_t length,
|
||||
FILE* filehandle);
|
||||
|
||||
/*!
|
||||
* \brief fRead
|
||||
* \param buffer
|
||||
* \param elemsize
|
||||
* \param length
|
||||
* \param filehandle
|
||||
* \return
|
||||
*/
|
||||
std::size_t fRead(void *buffer,
|
||||
std::size_t elemsize,
|
||||
std::size_t length,
|
||||
FILE* filehandle);
|
||||
|
||||
/*!
|
||||
* \brief SaveVar
|
||||
* \param pf
|
||||
* \param pVar
|
||||
* \return
|
||||
*/
|
||||
bool SaveVar(FILE* pf, CBotVar* pVar);
|
||||
|
||||
/*!
|
||||
* \brief WriteWord
|
||||
* \param pf
|
||||
* \param w
|
||||
* \return
|
||||
*/
|
||||
bool WriteWord(FILE* pf, unsigned short w);
|
||||
|
||||
/*!
|
||||
* \brief ReadWord
|
||||
* \param pf
|
||||
* \param w
|
||||
* \return
|
||||
*/
|
||||
bool ReadWord(FILE* pf, unsigned short& w);
|
||||
|
||||
/*!
|
||||
* \brief ReadLong
|
||||
* \param pf
|
||||
* \param w
|
||||
* \return
|
||||
*/
|
||||
bool ReadLong(FILE* pf, long& w);
|
||||
|
||||
/*!
|
||||
* \brief WriteFloat
|
||||
* \param pf
|
||||
* \param w
|
||||
* \return
|
||||
*/
|
||||
bool WriteFloat(FILE* pf, float w);
|
||||
|
||||
/*!
|
||||
* \brief WriteLong
|
||||
* \param pf
|
||||
* \param w
|
||||
* \return
|
||||
*/
|
||||
bool WriteLong(FILE* pf, long w);
|
||||
|
||||
/*!
|
||||
* \brief ReadFloat
|
||||
* \param pf
|
||||
* \param w
|
||||
* \return
|
||||
*/
|
||||
bool ReadFloat(FILE* pf, float& w);
|
||||
|
||||
/*!
|
||||
* \brief ReadString
|
||||
* \param pf
|
||||
* \param s
|
||||
* \return
|
||||
*/
|
||||
bool ReadString(FILE* pf, CBotString& s);
|
||||
|
||||
/*!
|
||||
* \brief WriteType
|
||||
* \param pf
|
||||
* \param type
|
||||
* \return
|
||||
*/
|
||||
bool WriteType(FILE* pf, const CBotTypResult &type);
|
||||
|
||||
/*!
|
||||
* \brief ReadType
|
||||
* \param pf
|
||||
* \param type
|
||||
* \return
|
||||
*/
|
||||
bool ReadType(FILE* pf, CBotTypResult &type);
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotBlock.h"
|
||||
|
||||
#include "CBot/CBotCStack.h"
|
||||
#include "CBot/CBotInstr/CBotListInstr.h"
|
||||
|
||||
#include "CBot/CBotDefines.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotBlock::Compile(CBotToken* &p, CBotCStack* pStack, bool bLocal)
|
||||
{
|
||||
pStack->SetStartError(p->GetStart());
|
||||
|
||||
if (IsOfType(p, ID_OPBLK))
|
||||
{
|
||||
CBotInstr* inst = CBotListInstr::Compile(p, pStack, bLocal);
|
||||
|
||||
if (IsOfType(p, ID_CLBLK))
|
||||
{
|
||||
return inst;
|
||||
}
|
||||
|
||||
pStack->SetError(TX_CLOSEBLK, p->GetStart()); // missing parenthesis
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
pStack->SetError(TX_OPENBLK, p->GetStart());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotBlock::CompileBlkOrInst(CBotToken* &p, CBotCStack* pStack, bool bLocal)
|
||||
{
|
||||
// is this a new block
|
||||
if (p->GetType() == ID_OPBLK) return CBotBlock::Compile(p, pStack);
|
||||
|
||||
// otherwise, look for a single statement instead
|
||||
|
||||
// to handle the case with local definition instruction (*)
|
||||
CBotCStack* pStk = pStack->TokenStack(p, bLocal);
|
||||
|
||||
return pStack->Return( CBotInstr::Compile(p, pStk), // a single instruction
|
||||
pStk);
|
||||
}
|
||||
|
||||
// (*) is the case in the following statement
|
||||
// if (1 == 1) int x = 0;
|
||||
// where the variable x is known only in the block following the if
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotBlock class An instruction block { .... }.
|
||||
*/
|
||||
class CBotBlock : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief Compile Compiles a statement block " { i ; i ; } "
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param bLocal
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool bLocal = true);
|
||||
|
||||
/*!
|
||||
* \brief CompileBlkOrInst
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param bLocal
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* CompileBlkOrInst(CBotToken* &p, CBotCStack* pStack, bool bLocal = false);
|
||||
|
||||
private:
|
||||
|
||||
/*!
|
||||
* \brief CBotBlock This class have no constructor because there is never an
|
||||
* instance of this class the object returned by Compile is usually of type
|
||||
* CBotListInstr
|
||||
*/
|
||||
CBotBlock() = delete;
|
||||
CBotBlock(const CBotBlock &) = delete;
|
||||
};
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotBoolExpr.h"
|
||||
#include "CBot/CBotInstr/CBotTwoOpExpr.h"
|
||||
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotDefines.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotBoolExpr::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
pStack->SetStartError(p->GetStart());
|
||||
|
||||
CBotInstr* inst = CBotTwoOpExpr::Compile(p, pStack);
|
||||
|
||||
if (nullptr != inst)
|
||||
{
|
||||
if (pStack->GetTypResult().Eq(CBotTypBoolean))
|
||||
{
|
||||
return inst;
|
||||
}
|
||||
pStack->SetError(TX_NOTBOOL, p->GetStart()); // is not a boolean
|
||||
}
|
||||
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotBoolExpr class Compile a statement such as "(condition)"
|
||||
* the condition must be Boolean. This class has no constructor, because there
|
||||
* is never an instance of this class the object returned by Compile is usually
|
||||
* type CBotExpression
|
||||
*/
|
||||
class CBotBoolExpr : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
};
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotBoolean.h"
|
||||
#include "CBot/CBotInstr/CBotLeftExprVar.h"
|
||||
#include "CBot/CBotInstr/CBotTwoOpExpr.h"
|
||||
#include "CBot/CBotInstr/CBotInstArray.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotBoolean::CBotBoolean()
|
||||
{
|
||||
m_var =
|
||||
m_expr = nullptr;
|
||||
name = "CBotBoolean";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotBoolean::~CBotBoolean()
|
||||
{
|
||||
delete m_var;
|
||||
delete m_expr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotBoolean::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, bool noskip)
|
||||
{
|
||||
CBotToken* pp = cont ? nullptr : p;
|
||||
|
||||
if (!cont && !IsOfType(p, ID_BOOLEAN, ID_BOOL)) return nullptr;
|
||||
|
||||
CBotBoolean* inst = static_cast<CBotBoolean*>(CompileArray(p, pStack, CBotTypBoolean));
|
||||
if (inst != nullptr || !pStack->IsOk()) return inst;
|
||||
|
||||
CBotCStack* pStk = pStack->TokenStack(pp);
|
||||
|
||||
inst = new CBotBoolean();
|
||||
|
||||
inst->m_expr = nullptr;
|
||||
|
||||
CBotToken* vartoken = p;
|
||||
inst->SetToken(vartoken);
|
||||
CBotVar* var = nullptr;
|
||||
|
||||
if (nullptr != (inst->m_var = CBotLeftExprVar::Compile( p, pStk )))
|
||||
{
|
||||
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_typevar = CBotTypBoolean;
|
||||
if (pStk->CheckVarLocal(vartoken)) // redefinition of the variable
|
||||
{
|
||||
pStk->SetError(TX_REDEFVAR, vartoken);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_OPBRK))
|
||||
{
|
||||
delete inst; // type is not CBotInt
|
||||
p = vartoken; // resutns to the variable name
|
||||
|
||||
// compiles an array declaration
|
||||
|
||||
inst = static_cast<CBotBoolean*>(CBotInstArray::Compile(p, pStk, CBotTypBoolean));
|
||||
|
||||
if (!pStk->IsOk() )
|
||||
{
|
||||
pStk->SetError(TX_CLBRK, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
goto suite; // no assignment, variable already created
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_ASS))
|
||||
{
|
||||
if (nullptr == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
if (!pStk->GetTypResult().Eq(CBotTypBoolean))
|
||||
{
|
||||
pStk->SetError(TX_BADTYPE, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
var = CBotVar::Create(vartoken, CBotTypBoolean);// create the variable (evaluated after the assignment)
|
||||
var->SetInit(inst->m_expr != nullptr ? CBotVar::InitType::DEF : CBotVar::InitType::UNDEF);
|
||||
var->SetUniqNum(
|
||||
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_nIdent = CBotVar::NextUniqNum());
|
||||
pStack->AddVar(var);
|
||||
suite:
|
||||
if (IsOfType(p, ID_COMMA))
|
||||
{
|
||||
if (nullptr != ( inst->m_next2b = CBotBoolean::Compile(p, pStk, true, noskip)))
|
||||
{
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
}
|
||||
|
||||
if (noskip || IsOfType(p, ID_SEP))
|
||||
{
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
pStk->SetError(TX_ENDOF, p->GetStart());
|
||||
}
|
||||
|
||||
error:
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotBoolean::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);//essential for SetState()
|
||||
|
||||
if ( pile->GetState()==0)
|
||||
{
|
||||
if (m_expr && !m_expr->Execute(pile)) return false;
|
||||
m_var->Execute(pile);
|
||||
|
||||
if (!pile->SetState(1)) return false;
|
||||
}
|
||||
|
||||
if (pile->IfStep()) return false;
|
||||
|
||||
if ( m_next2b &&
|
||||
!m_next2b->Execute(pile)) return false;
|
||||
|
||||
return pj->Return(pile);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotBoolean::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
CBotStack* pile = pj;
|
||||
if (bMain)
|
||||
{
|
||||
pile = pj->RestoreStack(this);
|
||||
if (pile == nullptr) return;
|
||||
|
||||
if ( pile->GetState()==0)
|
||||
{
|
||||
if (m_expr) m_expr->RestoreState(pile, bMain); // initial value interrupted?
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_var->RestoreState(pile, bMain);
|
||||
|
||||
if (m_next2b)
|
||||
m_next2b->RestoreState(pile, bMain); // other(s) definition(s)
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotBoolean class Defining a boolean variable int a, b = false;
|
||||
*/
|
||||
class CBotBoolean : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotBoolean
|
||||
*/
|
||||
CBotBoolean();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotBoolean
|
||||
*/
|
||||
~CBotBoolean();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param cont
|
||||
* \param noskip
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool cont = false, bool noskip=false);
|
||||
|
||||
/*!
|
||||
* \brief Execute Executes a boolean variable definition.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
//! Variable to initialise.
|
||||
CBotInstr* m_var;
|
||||
//! A value to put, if there is.
|
||||
CBotInstr* m_expr;
|
||||
};
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotBreak.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotBreak::CBotBreak()
|
||||
{
|
||||
name = "CBotBreak"; // debug
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotBreak::~CBotBreak()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotBreak::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotToken* pp = p; // preserves at the ^ token (starting position)
|
||||
int type = p->GetType();
|
||||
|
||||
if (!IsOfType(p, ID_BREAK, ID_CONTINUE)) return nullptr; // should never happen
|
||||
|
||||
if ( !ChkLvl(CBotString(), type ) )
|
||||
{
|
||||
pStack->SetError(TX_BREAK, pp);
|
||||
return nullptr; // 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->GetString(); // register the name of label
|
||||
if ( !ChkLvl(inst->m_label, type ) )
|
||||
{
|
||||
delete inst;
|
||||
pStack->SetError(TX_NOLABEL, pp);
|
||||
return nullptr; // 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->GetStart());
|
||||
return nullptr; // no object, the error is on the stack
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotBreak :: Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
// if ( pile == EOX ) return true;
|
||||
|
||||
if ( pile->IfStep() ) return false;
|
||||
|
||||
pile->SetBreak(m_token.GetType()==ID_BREAK ? 1 : 2, m_label);
|
||||
return pj->Return(pile);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotBreak :: RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if ( bMain ) pj->RestoreStack(this);
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotBreak class Compiles instruction "break" or "continu".
|
||||
*/
|
||||
class CBotBreak : public CBotInstr
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotBreak
|
||||
*/
|
||||
CBotBreak();
|
||||
|
||||
/*!
|
||||
* \brief CBotBreak
|
||||
*/
|
||||
~CBotBreak();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute Execution of statement "break" or "continu"
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
|
||||
private:
|
||||
//! A label if there is
|
||||
CBotString m_label;
|
||||
|
||||
};
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotCase.h"
|
||||
#include "CBot/CBotInstr/CBotExprNum.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotCase::CBotCase()
|
||||
{
|
||||
m_Value = nullptr; // nullptr so that delete is not possible further
|
||||
name = "CBotCase"; // debug
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotCase::~CBotCase()
|
||||
{
|
||||
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 nullptr; // should never happen
|
||||
|
||||
if ( pp->GetType() == ID_CASE )
|
||||
{
|
||||
pp = p;
|
||||
inst->m_Value = CBotExprNum::Compile(p, pStack);
|
||||
if ( inst->m_Value == nullptr )
|
||||
{
|
||||
pStack->SetError( TX_BADNUM, pp );
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
if ( !IsOfType( p, ID_DOTS ))
|
||||
{
|
||||
pStack->SetError( TX_MISDOTS, p->GetStart() );
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotCase::Execute(CBotStack* &pj)
|
||||
{
|
||||
return true; // the "case" statement does nothing!
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCase::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotCase::CompCase(CBotStack* &pile, int val)
|
||||
{
|
||||
if ( m_Value == nullptr ) return true; // "default" case
|
||||
|
||||
while (!m_Value->Execute(pile)); // puts the value on the correspondent stack (without interruption)
|
||||
return (pile->GetVal() == val); // compared with the given value
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotCase class Compiles instruction "case" we are bound to the
|
||||
* statement block "switch".
|
||||
*/
|
||||
class CBotCase : public CBotInstr
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotCase
|
||||
*/
|
||||
CBotCase();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotCase
|
||||
*/
|
||||
~CBotCase();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute Execution of instruction "case".
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
/*!
|
||||
* \brief CompCase Routine to find the entry point of "case" corresponding
|
||||
* to the value seen.
|
||||
* \param pj
|
||||
* \param val
|
||||
* \return
|
||||
*/
|
||||
bool CompCase(CBotStack* &pj, int val) override;
|
||||
|
||||
private:
|
||||
//! Value to compare.
|
||||
CBotInstr* m_Value;
|
||||
};
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotCatch.h"
|
||||
#include "CBot/CBotInstr/CBotBlock.h"
|
||||
#include "CBot/CBotInstr/CBotExpression.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotCatch::CBotCatch()
|
||||
{
|
||||
m_Cond =
|
||||
m_Block = nullptr; // nullptr so that delete is not possible further
|
||||
m_next = nullptr;
|
||||
|
||||
name = "CBotCatch"; // debug
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotCatch::~CBotCatch()
|
||||
{
|
||||
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->GetStart());
|
||||
|
||||
inst->SetToken(p);
|
||||
if (!IsOfType(p, ID_CATCH)) return nullptr; // should never happen
|
||||
|
||||
if (IsOfType(p, ID_OPENPAR))
|
||||
{
|
||||
inst->m_Cond = CBotExpression::Compile(p, pStack);
|
||||
if (( pStack->GetType() < CBotTypLong ||
|
||||
pStack->GetTypResult().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->GetStart());
|
||||
}
|
||||
pStack->SetError(TX_BADTYPE, p->GetStart());
|
||||
}
|
||||
pStack->SetError(TX_OPENPAR, p->GetStart());
|
||||
delete inst; // error, frees up
|
||||
return nullptr; // no object, the error is on the stack
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotCatch :: Execute(CBotStack* &pj)
|
||||
{
|
||||
if ( m_Block == nullptr ) return true;
|
||||
return m_Block->Execute(pj); // executes the associated block
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCatch :: RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if ( bMain && m_Block != nullptr ) m_Block->RestoreState(pj, bMain);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotCatch :: RestoreCondState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
m_Cond->RestoreState(pj, bMain);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotCatch :: TestCatch(CBotStack* &pile, int val)
|
||||
{
|
||||
if ( !m_Cond->Execute(pile) ) return false;
|
||||
|
||||
if ( val > 0 || pile->GetType() != CBotTypBoolean )
|
||||
{
|
||||
CBotVar* var = CBotVar::Create(static_cast<CBotToken*>(nullptr), CBotTypBoolean);
|
||||
var->SetValInt( pile->GetVal() == val );
|
||||
pile->SetVar(var); // calls on the stack
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
/*!
|
||||
* \brief The CBotCatch class. Compiles instruction "catch".
|
||||
*/
|
||||
class CBotCatch : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotCatch
|
||||
*/
|
||||
CBotCatch();
|
||||
|
||||
/*!
|
||||
* \brief CBotCatch
|
||||
*/
|
||||
~CBotCatch();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotCatch* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief TestCatch Routine to see if the catch is to do or not.
|
||||
* \param pj
|
||||
* \param val
|
||||
* \return
|
||||
*/
|
||||
bool TestCatch(CBotStack* &pj, int val);
|
||||
|
||||
/*!
|
||||
* \brief Execute Execution of "catch".
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreCondState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreCondState(CBotStack* &pj, bool bMain);
|
||||
|
||||
|
||||
private:
|
||||
//! Instructions
|
||||
CBotInstr* m_Block;
|
||||
//! Condition
|
||||
CBotInstr* m_Cond;
|
||||
//! Following catch
|
||||
CBotCatch* m_next;
|
||||
|
||||
friend class CBotTry;
|
||||
};
|
|
@ -0,0 +1,441 @@
|
|||
/*
|
||||
* 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 "CBotClassInst.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotInstrUtils.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotLeftExprVar.h"
|
||||
#include "CBot/CBotInstr/CBotTwoOpExpr.h"
|
||||
#include "CBot/CBotInstr/CBotInstArray.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
#include "CBot/CBotClass.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVarPointer.h"
|
||||
#include "CBot/CBotVar/CBotVarClass.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotClassInst::CBotClassInst()
|
||||
{
|
||||
m_next = nullptr;
|
||||
m_var = nullptr;
|
||||
m_Parameters = nullptr;
|
||||
m_expr = nullptr;
|
||||
m_hasParams = false;
|
||||
m_nMethodeIdent = 0;
|
||||
name = "CBotClassInst";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotClassInst::~CBotClassInst()
|
||||
{
|
||||
delete m_var;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotClassInst::Compile(CBotToken* &p, CBotCStack* pStack, CBotClass* pClass)
|
||||
{
|
||||
// seeks the corresponding classes
|
||||
if ( pClass == nullptr )
|
||||
{
|
||||
pStack->SetStartError(p->GetStart());
|
||||
pClass = CBotClass::Find(p);
|
||||
if ( pClass == nullptr )
|
||||
{
|
||||
// not found? is bizare
|
||||
pStack->SetError(TX_NOCLASS, p);
|
||||
return nullptr;
|
||||
}
|
||||
p = p->GetNext();
|
||||
}
|
||||
|
||||
bool bIntrinsic = pClass->IsIntrinsic();
|
||||
CBotTypResult type = CBotTypResult( bIntrinsic ? CBotTypIntrinsic : CBotTypPointer, pClass );
|
||||
CBotClassInst* inst = static_cast<CBotClassInst*>(CompileArray(p, pStack, type));
|
||||
if ( inst != nullptr || !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->GetName(), CBotString(), p->GetStart(), p->GetEnd());
|
||||
inst->SetToken(&token);
|
||||
CBotToken* vartoken = p;
|
||||
|
||||
if ( nullptr != (inst->m_var = CBotLeftExprVar::Compile( p, pStk )) )
|
||||
{
|
||||
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_typevar = type;
|
||||
if (pStk->CheckVarLocal(vartoken)) // redefinition of the variable
|
||||
{
|
||||
pStk->SetStartError(vartoken->GetStart());
|
||||
pStk->SetError(TX_REDEFVAR, vartoken->GetEnd());
|
||||
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 = static_cast<CBotClassInst*>(CBotInstArray::Compile( p, pStk, type ));
|
||||
|
||||
if (!pStk->IsOk() )
|
||||
{
|
||||
pStk->SetError(TX_CLBRK, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
goto suite; // no assignment, variable already created
|
||||
}
|
||||
|
||||
|
||||
CBotVar* var;
|
||||
var = CBotVar::Create(vartoken->GetString(), type); // creates the instance
|
||||
// var->SetClass(pClass);
|
||||
var->SetUniqNum(
|
||||
(static_cast<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->GetType() == 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 ( nullptr != inst->m_Parameters )
|
||||
if ( inst->m_hasParams )
|
||||
{
|
||||
// the constructor is there?
|
||||
// CBotString noname;
|
||||
CBotTypResult r = pClass->CompileMethode(pClass->GetName(), var, ppVars, pStk, inst->m_nMethodeIdent);
|
||||
delete pStk->TokenStack(); // releases the supplement stack
|
||||
int typ = r.GetType();
|
||||
|
||||
if (typ == TX_UNDEFCALL)
|
||||
{
|
||||
// si le constructeur n'existe pas
|
||||
if (inst->m_Parameters != nullptr) // with parameters
|
||||
{
|
||||
pStk->SetError(TX_NOCONST, vartoken);
|
||||
goto error;
|
||||
}
|
||||
typ = 0;
|
||||
}
|
||||
|
||||
if (typ>20)
|
||||
{
|
||||
pStk->SetError(typ, vartoken->GetEnd());
|
||||
goto error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_ASS)) // with a assignment?
|
||||
{
|
||||
if (inst->m_hasParams)
|
||||
{
|
||||
pStk->SetError(TX_ENDOF, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ( nullptr == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )) )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
CBotClass* result = pStk->GetClass();
|
||||
if ( !pStk->GetTypResult(1).Eq(CBotTypNullPointer) &&
|
||||
( !pStk->GetTypResult(1).Eq(CBotTypPointer) ||
|
||||
( result != nullptr && !pClass->IsChildOf(result) ))) // type compatible ?
|
||||
{
|
||||
pStk->SetError(TX_BADTYPE, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
// if ( !bIntrinsic ) var->SetPointer(pStk->GetVar()->GetPointer());
|
||||
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(CBotVar::InitType::DEF); // 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(CBotVar::InitType::IS_POINTER); // marks the pointer as init
|
||||
}
|
||||
suite:
|
||||
if (IsOfType(p, ID_COMMA)) // several chained definitions
|
||||
{
|
||||
if ( nullptr != ( 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->GetStart());
|
||||
}
|
||||
|
||||
error:
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotClassInst::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotVar* pThis = nullptr;
|
||||
|
||||
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->GetState()==0)
|
||||
{
|
||||
CBotString name = m_var->m_token.GetString();
|
||||
if ( bIntrincic )
|
||||
{
|
||||
pThis = CBotVar::Create(name, CBotTypResult( CBotTypIntrinsic, pClass ));
|
||||
}
|
||||
else
|
||||
{
|
||||
pThis = CBotVar::Create(name, CBotTypResult( CBotTypPointer, pClass ));
|
||||
}
|
||||
|
||||
pThis->SetUniqNum((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent); // its attribute as unique number
|
||||
pile->AddVar(pThis); // place on the stack
|
||||
pile->IncState();
|
||||
}
|
||||
|
||||
if ( pThis == nullptr ) pThis = pile->FindVar((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent);
|
||||
|
||||
if ( pile->GetState()<3)
|
||||
{
|
||||
// ss there an assignment or parameters (contructor)
|
||||
|
||||
// CBotVarClass* pInstance = nullptr;
|
||||
|
||||
if ( m_expr != nullptr )
|
||||
{
|
||||
// evaluates the expression for the assignment
|
||||
if (!m_expr->Execute(pile)) return false;
|
||||
|
||||
if ( bIntrincic )
|
||||
{
|
||||
CBotVar* pv = pile->GetVar();
|
||||
if ( pv == nullptr || pv->GetPointer() == nullptr )
|
||||
{
|
||||
pile->SetError(TX_NULLPT, &m_token);
|
||||
return pj->Return(pile);
|
||||
}
|
||||
pThis->Copy(pile->GetVar(), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
CBotVarClass* pInstance;
|
||||
pInstance = (static_cast<CBotVarPointer*>(pile->GetVar()))->GetPointer(); // value for the assignment
|
||||
pThis->SetPointer(pInstance);
|
||||
}
|
||||
pThis->SetInit(CBotVar::InitType::DEF);
|
||||
}
|
||||
|
||||
else if ( m_hasParams )
|
||||
{
|
||||
// evaluates the constructor of an instance
|
||||
|
||||
if ( !bIntrincic && pile->GetState() == 1)
|
||||
{
|
||||
CBotToken* pt = &m_token;
|
||||
CBotClass* pClass = CBotClass::Find(pt);
|
||||
|
||||
// creates an instance of the requested class
|
||||
|
||||
CBotVarClass* pInstance;
|
||||
pInstance = static_cast<CBotVarClass*>(CBotVar::Create("", pClass));
|
||||
pThis->SetPointer(pInstance);
|
||||
delete pInstance;
|
||||
|
||||
pile->IncState();
|
||||
}
|
||||
|
||||
CBotVar* ppVars[1000];
|
||||
CBotStack* pile2 = pile;
|
||||
|
||||
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
|
||||
|
||||
if ( p != nullptr) while ( true )
|
||||
{
|
||||
pile2 = pile2->AddStack(); // place on the stack for the results
|
||||
if ( pile2->GetState() == 0 )
|
||||
{
|
||||
if (!p->Execute(pile2)) return false; // interrupted here?
|
||||
pile2->SetState(1);
|
||||
}
|
||||
ppVars[i++] = pile2->GetVar();
|
||||
p = p->GetNext();
|
||||
if ( p == nullptr) break;
|
||||
}
|
||||
ppVars[i] = nullptr;
|
||||
|
||||
// creates a variable for the result
|
||||
CBotVar* pResult = nullptr; // constructor still void
|
||||
|
||||
if ( !pClass->ExecuteMethode(m_nMethodeIdent, pClass->GetName(),
|
||||
pThis, ppVars,
|
||||
pResult, pile2, GetToken())) return false; // interrupt
|
||||
|
||||
pThis->SetInit(CBotVar::InitType::DEF);
|
||||
pThis->ConstructorSet(); // indicates that the constructor has been called
|
||||
pile->Return(pile2); // releases a piece of stack
|
||||
|
||||
// pInstance = pThis->GetPointer();
|
||||
|
||||
}
|
||||
|
||||
// if ( !bIntrincic ) pThis->SetPointer(pInstance); // a pointer to the instance
|
||||
|
||||
pile->SetState(3); // finished this part
|
||||
}
|
||||
|
||||
if ( pile->IfStep() ) return false;
|
||||
|
||||
if ( m_next2b != nullptr &&
|
||||
!m_next2b->Execute(pile)) return false; // other (s) definition (s)
|
||||
|
||||
return pj->Return( pile ); // transmits below (further)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotClassInst::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
CBotVar* pThis = nullptr;
|
||||
|
||||
CBotStack* pile = pj;
|
||||
if ( bMain ) pile = pj->RestoreStack(this);
|
||||
if ( pile == nullptr ) return;
|
||||
|
||||
// creates the variable of type pointer to the object
|
||||
{
|
||||
CBotString name = m_var->m_token.GetString();
|
||||
pThis = pile->FindVar(name);
|
||||
pThis->SetUniqNum((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent); // its attribute a unique number
|
||||
}
|
||||
|
||||
CBotToken* pt = &m_token;
|
||||
CBotClass* pClass = CBotClass::Find(pt);
|
||||
bool bIntrincic = pClass->IsIntrinsic();
|
||||
|
||||
if ( bMain && pile->GetState()<3)
|
||||
{
|
||||
// is there an assignment or parameters (constructor)
|
||||
|
||||
// CBotVarClass* pInstance = nullptr;
|
||||
|
||||
if ( m_expr != nullptr )
|
||||
{
|
||||
// evaluates the expression for the assignment
|
||||
m_expr->RestoreState(pile, bMain);
|
||||
return;
|
||||
}
|
||||
|
||||
else if ( m_hasParams )
|
||||
{
|
||||
// evaluates the constructor of an instance
|
||||
|
||||
if ( !bIntrincic && pile->GetState() == 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CBotVar* ppVars[1000];
|
||||
CBotStack* pile2 = pile;
|
||||
|
||||
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)
|
||||
|
||||
if ( p != nullptr) while ( true )
|
||||
{
|
||||
pile2 = pile2->RestoreStack(); // place on the stack for the results
|
||||
if ( pile2 == nullptr ) return;
|
||||
|
||||
if ( pile2->GetState() == 0 )
|
||||
{
|
||||
p->RestoreState(pile2, bMain); // interrupted here?
|
||||
return;
|
||||
}
|
||||
ppVars[i++] = pile2->GetVar();
|
||||
p = p->GetNext();
|
||||
if ( p == nullptr) break;
|
||||
}
|
||||
ppVars[i] = nullptr;
|
||||
|
||||
// creates a variable for the result
|
||||
// CBotVar* pResult = nullptr; // constructor still void
|
||||
|
||||
pClass->RestoreMethode(m_nMethodeIdent, pClass->GetName(), pThis, ppVars, pile2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_next2b != nullptr )
|
||||
m_next2b->RestoreState(pile, bMain); // other(s) definition(s)
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
/*!
|
||||
* \brief The CBotClassInst class Definition of an element of any class.
|
||||
*/
|
||||
class CBotClassInst : public CBotInstr
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotClassInst
|
||||
*/
|
||||
CBotClassInst();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotClassInst
|
||||
*/
|
||||
~CBotClassInst();
|
||||
|
||||
/*!
|
||||
* \brief Compile Definition of pointer (s) to an object style CPoint A, B ;
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param pClass
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, CBotClass* pClass = nullptr);
|
||||
|
||||
/*!
|
||||
* \brief Execute Declaration of the instance of a class, for example:
|
||||
* CPoint A, B;
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
|
||||
//! Variable to initialise.
|
||||
CBotInstr* m_var;
|
||||
//! Reference to the class.
|
||||
CBotClass* m_pClass;
|
||||
//! Parameters to be evaluated for the contructor.
|
||||
CBotInstr* m_Parameters;
|
||||
//! A value to put, if there is.
|
||||
CBotInstr* m_expr;
|
||||
//! Has it parameters.
|
||||
bool m_hasParams;
|
||||
long m_nMethodeIdent;
|
||||
|
||||
};
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotCondition.h"
|
||||
#include "CBot/CBotInstr/CBotBoolExpr.h"
|
||||
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotDefines.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotCondition::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
pStack->SetStartError(p->GetStart());
|
||||
if (IsOfType(p, ID_OPENPAR))
|
||||
{
|
||||
CBotInstr* inst = CBotBoolExpr::Compile(p, pStack);
|
||||
if (nullptr != inst)
|
||||
{
|
||||
if (IsOfType(p, ID_CLOSEPAR))
|
||||
{
|
||||
return inst;
|
||||
}
|
||||
pStack->SetError(TX_CLOSEPAR, p->GetStart()); // missing parenthesis
|
||||
}
|
||||
delete inst;
|
||||
}
|
||||
|
||||
pStack->SetError(TX_OPENPAR, p->GetStart()); // missing parenthesis
|
||||
|
||||
return nullptr;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
/*!
|
||||
* \brief The CBotCondition class This class has no constructor, because there
|
||||
* is never an instance of this class the object returned by Compile is usually
|
||||
* type CBotExpression
|
||||
*/
|
||||
class CBotCondition : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief Compile Compile a statement such as "(condition)" the condition
|
||||
* must be Boolean
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
};
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotDo.h"
|
||||
#include "CBot/CBotInstr/CBotBlock.h"
|
||||
#include "CBot/CBotInstr/CBotCondition.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotDo::CBotDo()
|
||||
{
|
||||
m_Condition =
|
||||
m_Block = nullptr; // nullptr 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
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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->GetString(); // register the name of label
|
||||
}
|
||||
|
||||
inst->SetToken(p);
|
||||
if (!IsOfType(p, ID_DO)) return nullptr; // 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 ( nullptr != (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->GetStart());
|
||||
}
|
||||
}
|
||||
pStk->SetError(TX_WHILE, p->GetStart());
|
||||
}
|
||||
|
||||
delete inst; // error, frees up
|
||||
return pStack->Return(nullptr, pStk); // no object, the error is on the stack
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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->GetState() ) // executes the loop
|
||||
{ // there are two possible states (depending on recovery)
|
||||
case 0:
|
||||
// evaluates the associated statement block
|
||||
if ( m_Block != nullptr &&
|
||||
!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
|
||||
}
|
||||
|
||||
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->GetVal() != 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 == nullptr ) return;
|
||||
|
||||
switch( pile->GetState() )
|
||||
{ // there are two possible states (depending on recovery)
|
||||
case 0:
|
||||
// restores the assosiated statement's block
|
||||
if ( m_Block != nullptr ) m_Block->RestoreState(pile, bMain);
|
||||
return;
|
||||
|
||||
case 1:
|
||||
// restores the condition
|
||||
m_Condition->RestoreState(pile, bMain);
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
class CBotDo : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotDo Default constructor.
|
||||
*/
|
||||
CBotDo();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotDo Destructor.
|
||||
*/
|
||||
~CBotDo();
|
||||
|
||||
/*!
|
||||
* \brief Compile Compile the instruction "do".
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
//! Instruction
|
||||
CBotInstr* m_Block;
|
||||
//! Conditions
|
||||
CBotInstr* m_Condition;
|
||||
//! A label if there is
|
||||
CBotString m_label;
|
||||
};
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotEmpty.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotEmpty::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotVar* pVar = CBotVar::Create("", CBotTypInt);
|
||||
pVar->SetValInt(-1);
|
||||
pj->SetVar(pVar);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotEmpty::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
/*!
|
||||
* \brief The CBotEmpty class
|
||||
*/
|
||||
class CBotEmpty : public CBotInstr
|
||||
{
|
||||
/*!
|
||||
* \brief Execute Special case for empty indexes.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
};
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotExprAlpha.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExprAlpha::CBotExprAlpha()
|
||||
{
|
||||
name = "CBotExprAlpha";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExprAlpha::~CBotExprAlpha()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotExprAlpha::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotCStack* pStk = pStack->TokenStack();
|
||||
|
||||
CBotExprAlpha* inst = new CBotExprAlpha();
|
||||
|
||||
inst->SetToken(p);
|
||||
p = p->GetNext();
|
||||
|
||||
CBotVar* var = CBotVar::Create(static_cast<CBotToken*>(nullptr), CBotTypString);
|
||||
pStk->SetVar(var);
|
||||
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotExprAlpha::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
|
||||
if (pile->IfStep()) return false;
|
||||
|
||||
CBotVar* var = CBotVar::Create(static_cast<CBotToken*>(nullptr), CBotTypString);
|
||||
|
||||
CBotString chaine = m_token.GetString();
|
||||
chaine = chaine.Mid(1, chaine.GetLength()-2); // removes the quotes
|
||||
|
||||
var->SetValString(chaine); // value of the number
|
||||
|
||||
pile->SetVar(var); // put on the stack
|
||||
|
||||
return pj->Return(pile);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotExprAlpha::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (bMain) pj->RestoreStack(this);
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
/*!
|
||||
* \brief The CBotExprAlpha class Expression representing a string.
|
||||
*/
|
||||
class CBotExprAlpha : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotExprAlpha
|
||||
*/
|
||||
CBotExprAlpha();
|
||||
|
||||
/*!
|
||||
* \brief CBotExprAlpha
|
||||
*/
|
||||
~CBotExprAlpha();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute Execute, returns the corresponding string.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
};
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotExprBool.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExprBool::CBotExprBool()
|
||||
{
|
||||
name = "CBotExprBool";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExprBool::~CBotExprBool()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotExprBool::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotCStack* pStk = pStack->TokenStack();
|
||||
CBotExprBool* inst = nullptr;
|
||||
|
||||
if ( p->GetType() == ID_TRUE ||
|
||||
p->GetType() == ID_FALSE )
|
||||
{
|
||||
inst = new CBotExprBool();
|
||||
inst->SetToken(p); // stores the operation false or true
|
||||
p = p->GetNext();
|
||||
|
||||
CBotVar* var = CBotVar::Create(static_cast<CBotToken*>(nullptr), CBotTypBoolean);
|
||||
pStk->SetVar(var);
|
||||
}
|
||||
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotExprBool::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
|
||||
if (pile->IfStep()) return false;
|
||||
|
||||
CBotVar* var = CBotVar::Create(static_cast<CBotToken*>(nullptr), CBotTypBoolean);
|
||||
|
||||
if (GetTokenType() == ID_TRUE) var->SetValInt(1);
|
||||
else var->SetValInt(0);
|
||||
|
||||
pile->SetVar(var); // put on the stack
|
||||
return pj->Return(pile); // forwards below
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotExprBool::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (bMain) pj->RestoreStack(this);
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotExprBool class Compile a token representing true or false.
|
||||
*/
|
||||
class CBotExprBool : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotExprBool
|
||||
*/
|
||||
CBotExprBool();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotExprBool
|
||||
*/
|
||||
~CBotExprBool();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute Executes, returns true or false.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
};
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotExprNan.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExprNan::CBotExprNan()
|
||||
{
|
||||
name = "CBotExprNan";
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExprNan::~CBotExprNan()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotExprNan::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
|
||||
if (pile->IfStep()) return false;
|
||||
CBotVar* var = CBotVar::Create(static_cast<CBotToken*>(nullptr), CBotTypInt);
|
||||
|
||||
var->SetInit(CBotVar::InitType::IS_NAN); // nan
|
||||
pile->SetVar(var); // put on the stack
|
||||
return pj->Return(pile); // forward below
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotExprNan::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (bMain) pj->RestoreStack(this);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
/*!
|
||||
* \brief The CBotExprNan class Management of the operand "nan".
|
||||
*/
|
||||
class CBotExprNan : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotExprNan
|
||||
*/
|
||||
CBotExprNan();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotExprNan
|
||||
*/
|
||||
~CBotExprNan();
|
||||
|
||||
/*!
|
||||
* \brief Execute Executes, returns null pointer.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
};
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotExprNull.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExprNull::CBotExprNull()
|
||||
{
|
||||
name = "CBotExprNull";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExprNull::~CBotExprNull()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotExprNull::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
|
||||
if (pile->IfStep()) return false;
|
||||
CBotVar* var = CBotVar::Create(static_cast<CBotToken*>(nullptr), CBotTypNullPointer);
|
||||
|
||||
var->SetInit(CBotVar::InitType::DEF); // null pointer valid
|
||||
pile->SetVar(var); // place on the stack
|
||||
return pj->Return(pile); // forwards below
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotExprNull::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (bMain) pj->RestoreStack(this);
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotExprNull class Management of the operand "null".
|
||||
*/
|
||||
class CBotExprNull : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotExprNull
|
||||
*/
|
||||
CBotExprNull();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotExprNull
|
||||
*/
|
||||
~CBotExprNull();
|
||||
|
||||
/*!
|
||||
* \brief Execute Executes, returns an empty pointer.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
};
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotExprNum.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExprNum::CBotExprNum()
|
||||
{
|
||||
name = "CBotExprNum";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExprNum::~CBotExprNum()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotExprNum::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotCStack* pStk = pStack->TokenStack();
|
||||
|
||||
CBotExprNum* inst = new CBotExprNum();
|
||||
|
||||
inst->SetToken(p);
|
||||
CBotString s = p->GetString();
|
||||
|
||||
inst->m_numtype = CBotTypInt;
|
||||
if (p->GetType() == TokenTypDef)
|
||||
{
|
||||
inst->m_valint = p->GetIdKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s.Find('.') >= 0 || ( s.Find('x') < 0 && ( s.Find('e') >= 0 || s.Find('E') >= 0 ) ))
|
||||
{
|
||||
inst->m_numtype = CBotTypFloat;
|
||||
inst->m_valfloat = GetNumFloat(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
inst->m_valint = GetNumInt(s);
|
||||
}
|
||||
}
|
||||
|
||||
if (pStk->NextToken(p))
|
||||
{
|
||||
CBotVar* var = CBotVar::Create(static_cast<CBotToken*>(nullptr), inst->m_numtype);
|
||||
pStk->SetVar(var);
|
||||
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotExprNum::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
|
||||
if (pile->IfStep()) return false;
|
||||
|
||||
CBotVar* var = CBotVar::Create(static_cast<CBotToken*>(nullptr), m_numtype);
|
||||
|
||||
CBotString nombre ;
|
||||
if (m_token.GetType() == TokenTypDef)
|
||||
{
|
||||
nombre = m_token.GetString();
|
||||
}
|
||||
|
||||
switch (m_numtype)
|
||||
{
|
||||
case CBotTypShort:
|
||||
case CBotTypInt:
|
||||
var->SetValInt(m_valint, nombre);
|
||||
break;
|
||||
case CBotTypFloat:
|
||||
var->SetValFloat(m_valfloat);
|
||||
break;
|
||||
}
|
||||
pile->SetVar(var); // place on the stack
|
||||
|
||||
return pj->Return(pile); // it's ok
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotExprNum::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (bMain) pj->RestoreStack(this);
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
/*!
|
||||
* \brief The CBotExprNum class Expression representing a number.
|
||||
*/
|
||||
class CBotExprNum : public CBotInstr
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotExprNum
|
||||
*/
|
||||
CBotExprNum();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotExprNum
|
||||
*/
|
||||
~CBotExprNum();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute Execute, returns the corresponding number.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
|
||||
//! The type of number.
|
||||
int m_numtype;
|
||||
//! Value for an int.
|
||||
long m_valint;
|
||||
//! Value for a float.
|
||||
float m_valfloat;
|
||||
|
||||
};
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotExprUnaire.h"
|
||||
#include "CBot/CBotInstr/CBotParExpr.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExprUnaire::CBotExprUnaire()
|
||||
{
|
||||
m_Expr = nullptr;
|
||||
name = "CBotExprUnaire";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExprUnaire::~CBotExprUnaire()
|
||||
{
|
||||
delete m_Expr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotExprUnaire::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
int op = p->GetType();
|
||||
CBotToken* pp = p;
|
||||
if (!IsOfTypeList( p, ID_ADD, ID_SUB, ID_LOG_NOT, ID_TXT_NOT, ID_NOT, 0 )) return nullptr;
|
||||
|
||||
CBotCStack* pStk = pStack->TokenStack(pp);
|
||||
|
||||
CBotExprUnaire* inst = new CBotExprUnaire();
|
||||
inst->SetToken(pp);
|
||||
|
||||
if (nullptr != (inst->m_Expr = CBotParExpr::Compile( p, pStk )))
|
||||
{
|
||||
if (op == ID_ADD && pStk->GetType() < CBotTypBoolean) // only with the number
|
||||
return pStack->Return(inst, pStk);
|
||||
if (op == ID_SUB && pStk->GetType() < CBotTypBoolean) // only with the numer
|
||||
return pStack->Return(inst, pStk);
|
||||
if (op == ID_NOT && pStk->GetType() < CBotTypFloat) // only with an integer
|
||||
return pStack->Return(inst, pStk);
|
||||
if (op == ID_LOG_NOT && pStk->GetTypResult().Eq(CBotTypBoolean))// only with boolean
|
||||
return pStack->Return(inst, pStk);
|
||||
if (op == ID_TXT_NOT && pStk->GetTypResult().Eq(CBotTypBoolean))// only with boolean
|
||||
return pStack->Return(inst, pStk);
|
||||
|
||||
pStk->SetError(TX_BADTYPE, &inst->m_token);
|
||||
}
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
// executes unary expression
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotExprUnaire::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
|
||||
if (pile->GetState() == 0)
|
||||
{
|
||||
if (!m_Expr->Execute(pile)) return false; // interrupted ?
|
||||
pile->IncState();
|
||||
}
|
||||
|
||||
CBotStack* pile2 = pile->AddStack();
|
||||
if (pile2->IfStep()) return false;
|
||||
|
||||
CBotVar* var = pile->GetVar(); // get the result on the stack
|
||||
|
||||
switch (GetTokenType())
|
||||
{
|
||||
case ID_ADD:
|
||||
break;
|
||||
case ID_SUB:
|
||||
var->Neg(); // change the sign
|
||||
break;
|
||||
case ID_NOT:
|
||||
case ID_LOG_NOT:
|
||||
case ID_TXT_NOT:
|
||||
var->Not();
|
||||
break;
|
||||
}
|
||||
return pj->Return(pile); // forwards below
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotExprUnaire::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (!bMain) return;
|
||||
|
||||
CBotStack* pile = pj->RestoreStack(this);
|
||||
if ( pile == nullptr) return;
|
||||
|
||||
if (pile->GetState() == 0)
|
||||
{
|
||||
m_Expr->RestoreState(pile, bMain); // interrupted here!
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotExprUnaire class Unary expression. Compile an unary expression
|
||||
* eg : (+, * -, not, !, ~)
|
||||
*/
|
||||
class CBotExprUnaire : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotExprUnaire
|
||||
*/
|
||||
CBotExprUnaire();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotExprUnaire
|
||||
*/
|
||||
~CBotExprUnaire();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pStack) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
//! Expression to be evaluated.
|
||||
CBotInstr* m_Expr;
|
||||
};
|
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotExprVar.h"
|
||||
#include "CBot/CBotInstr/CBotInstrMethode.h"
|
||||
#include "CBot/CBotInstr/CBotExpression.h"
|
||||
#include "CBot/CBotInstr/CBotIndexExpr.h"
|
||||
#include "CBot/CBotInstr/CBotFieldExpr.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVarArray.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExprVar::CBotExprVar()
|
||||
{
|
||||
name = "CBotExprVar";
|
||||
m_nIdent = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExprVar::~CBotExprVar()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotExprVar::Compile(CBotToken* &p, CBotCStack* pStack, int privat)
|
||||
{
|
||||
// CBotToken* pDebut = p;
|
||||
CBotCStack* pStk = pStack->TokenStack();
|
||||
|
||||
pStk->SetStartError(p->GetStart());
|
||||
|
||||
// is it a variable?
|
||||
if (p->GetType() == TokenTypVar)
|
||||
{
|
||||
CBotInstr* inst = new CBotExprVar(); // create the object
|
||||
|
||||
inst->SetToken(p);
|
||||
|
||||
CBotVar* var;
|
||||
|
||||
if (nullptr != (var = pStk->FindVar(p))) // seek if known variable
|
||||
{
|
||||
int ident = var->GetUniqNum();
|
||||
(static_cast<CBotExprVar*>(inst))->m_nIdent = ident; // identifies variable by its number
|
||||
|
||||
if (ident > 0 && ident < 9000)
|
||||
{
|
||||
if ( var->IsPrivate(privat) &&
|
||||
!pStk->GetBotCall()->m_bCompileClass)
|
||||
{
|
||||
pStk->SetError(TX_PRIVATE, p);
|
||||
goto err;
|
||||
}
|
||||
|
||||
// This is an element of the current class
|
||||
// ads the equivalent of this. before
|
||||
CBotToken token("this");
|
||||
inst->SetToken(&token);
|
||||
(static_cast<CBotExprVar*>(inst))->m_nIdent = -2; // identificator for this
|
||||
|
||||
CBotFieldExpr* i = new CBotFieldExpr(); // new element
|
||||
i->SetToken(p); // keeps the name of the token
|
||||
i->SetUniqNum(ident);
|
||||
inst->AddNext3(i); // added after
|
||||
}
|
||||
|
||||
p = p->GetNext(); // next token
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (var->GetType() == CBotTypArrayPointer)
|
||||
{
|
||||
if (IsOfType( p, ID_OPBRK )) // check if there is an aindex
|
||||
{
|
||||
CBotIndexExpr* i = new CBotIndexExpr();
|
||||
i->m_expr = CBotExpression::Compile(p, pStk); // compile the formula
|
||||
inst->AddNext3(i); // add to the chain
|
||||
|
||||
var = (static_cast<CBotVarArray*>(var))->GetItem(0,true); // gets the component [0]
|
||||
|
||||
if (i->m_expr == nullptr)
|
||||
{
|
||||
pStk->SetError(TX_BADINDEX, p->GetStart());
|
||||
goto err;
|
||||
}
|
||||
if (!pStk->IsOk() || !IsOfType( p, ID_CLBRK ))
|
||||
{
|
||||
pStk->SetError(TX_CLBRK, p->GetStart());
|
||||
goto err;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (var->GetType(1) == CBotTypPointer) // for classes
|
||||
{
|
||||
if (IsOfType(p, ID_DOT))
|
||||
{
|
||||
CBotToken* pp = p;
|
||||
|
||||
if (p->GetType() == TokenTypVar) // must be a name
|
||||
{
|
||||
if (p->GetNext()->GetType() == ID_OPENPAR) // a method call?
|
||||
{
|
||||
CBotInstr* i = CBotInstrMethode::Compile(p, pStk, var);
|
||||
if (!pStk->IsOk()) goto err;
|
||||
inst->AddNext3(i); // added after
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
else
|
||||
{
|
||||
CBotFieldExpr* i = new CBotFieldExpr(); // new element
|
||||
i->SetToken(pp); // keeps the name of the token
|
||||
inst->AddNext3(i); // add after
|
||||
var = var->GetItem(p->GetString()); // get item correspondent
|
||||
if (var != nullptr)
|
||||
{
|
||||
i->SetUniqNum(var->GetUniqNum());
|
||||
if ( var->IsPrivate() &&
|
||||
!pStk->GetBotCall()->m_bCompileClass)
|
||||
{
|
||||
pStk->SetError(TX_PRIVATE, pp);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (var != nullptr)
|
||||
{
|
||||
p = p->GetNext(); // skips the name
|
||||
continue;
|
||||
}
|
||||
pStk->SetError(TX_NOITEM, p);
|
||||
goto err;
|
||||
}
|
||||
pStk->SetError(TX_DOT, p->GetStart());
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
pStk->SetCopyVar(var); // place the copy of the variable on the stack (for type)
|
||||
if (pStk->IsOk()) return pStack->Return(inst, pStk);
|
||||
}
|
||||
pStk->SetError(TX_UNDEFVAR, p);
|
||||
err:
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotExprVar::CompileMethode(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotToken* pp = p;
|
||||
CBotCStack* pStk = pStack->TokenStack();
|
||||
|
||||
pStk->SetStartError(pp->GetStart());
|
||||
|
||||
// is it a variable ?
|
||||
if (pp->GetType() == TokenTypVar)
|
||||
{
|
||||
CBotToken pthis("this");
|
||||
CBotVar* var = pStk->FindVar(pthis);
|
||||
if (var == nullptr) return pStack->Return(nullptr, pStk);
|
||||
|
||||
CBotInstr* inst = new CBotExprVar();
|
||||
|
||||
// this is an element of the current class
|
||||
// adds the equivalent of this. before
|
||||
|
||||
inst->SetToken(&pthis);
|
||||
(static_cast<CBotExprVar*>(inst))->m_nIdent = -2; // ident for this
|
||||
|
||||
CBotToken* pp = p;
|
||||
|
||||
if (pp->GetType() == TokenTypVar)
|
||||
{
|
||||
if (pp->GetNext()->GetType() == ID_OPENPAR) // a method call?
|
||||
{
|
||||
CBotInstr* i = CBotInstrMethode::Compile(pp, pStk, var);
|
||||
if (pStk->IsOk())
|
||||
{
|
||||
inst->AddNext3(i); // add after
|
||||
p = pp; // previous instruction
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
pStk->SetError(0,0); // the error is not adressed here
|
||||
}
|
||||
}
|
||||
delete inst;
|
||||
}
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotExprVar::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotVar* pVar = nullptr;
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
|
||||
CBotStack* pile1 = pile;
|
||||
|
||||
if (pile1->GetState() == 0)
|
||||
{
|
||||
if (!ExecuteVar(pVar, pile, nullptr, true)) return false; // Get the variable fields and indexes according
|
||||
|
||||
if (pVar) pile1->SetCopyVar(pVar); // place a copy on the stack
|
||||
else
|
||||
{
|
||||
return pj->Return(pile1);
|
||||
}
|
||||
pile1->IncState();
|
||||
}
|
||||
|
||||
pVar = pile1->GetVar();
|
||||
|
||||
if (pVar == nullptr)
|
||||
{
|
||||
return pj->Return(pile1);
|
||||
}
|
||||
|
||||
if (pVar->IsUndefined())
|
||||
{
|
||||
CBotToken* pt = &m_token;
|
||||
while (pt->GetNext() != nullptr) pt = pt->GetNext();
|
||||
pile1->SetError(TX_NOTINIT, pt);
|
||||
return pj->Return(pile1);
|
||||
}
|
||||
return pj->Return(pile1); // operation completed
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotExprVar::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (!bMain) return;
|
||||
|
||||
CBotStack* pile = pj->RestoreStack(this);
|
||||
if (pile == nullptr) return;
|
||||
|
||||
CBotStack* pile1 = pile;
|
||||
|
||||
if (pile1->GetState() == 0)
|
||||
{
|
||||
RestoreStateVar(pile, bMain); // retrieves the variable fields and indexes according
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotExprVar::ExecuteVar(CBotVar* &pVar, CBotStack* &pj, CBotToken* prevToken, bool bStep)
|
||||
{
|
||||
CBotStack* pile = pj;
|
||||
pj = pj->AddStack(this);
|
||||
|
||||
if (bStep && m_nIdent>0 && pj->IfStep()) return false;
|
||||
|
||||
pVar = pj->FindVar(m_nIdent, true); // tries with the variable update if necessary
|
||||
if (pVar == nullptr)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
assert(0);
|
||||
#endif
|
||||
pj->SetError(1, &m_token);
|
||||
return false;
|
||||
}
|
||||
if ( m_next3 != nullptr &&
|
||||
!m_next3->ExecuteVar(pVar, pj, &m_token, bStep, false) )
|
||||
return false; // field of an instance, table, methode
|
||||
|
||||
return pile->ReturnKeep(pj); // does not put on stack but get the result if a method was called
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotExprVar::RestoreStateVar(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
pj = pj->RestoreStack(this);
|
||||
if (pj == nullptr) return;
|
||||
|
||||
if (m_next3 != nullptr)
|
||||
m_next3->RestoreStateVar(pj, bMain);
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* 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 "CBot/CBotDefines.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotExprVar class Expression for the variable name. Compile a
|
||||
* variable name check that it is known on the stack and it has been initialized.
|
||||
*/
|
||||
class CBotExprVar : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotExprVar
|
||||
*/
|
||||
CBotExprVar();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotExprVar
|
||||
*/
|
||||
~CBotExprVar();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param privat
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, int privat=PR_PROTECT);
|
||||
|
||||
/*!
|
||||
* \brief CompileMethode
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* CompileMethode(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute Execute, making the value of a variable.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
/*!
|
||||
* \brief ExecuteVar Fetch a variable at runtime.
|
||||
* \param pVar
|
||||
* \param pile
|
||||
* \param prevToken
|
||||
* \param bStep
|
||||
* \return
|
||||
*/
|
||||
bool ExecuteVar(CBotVar* &pVar, CBotStack* &pile, CBotToken* prevToken, bool bStep);
|
||||
|
||||
/*!
|
||||
* \brief RestoreStateVar Fetch variable at runtime.
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreStateVar(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
long m_nIdent;
|
||||
friend class CBotPostIncExpr;
|
||||
friend class CBotPreIncExpr;
|
||||
|
||||
};
|
|
@ -0,0 +1,298 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotExpression.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotInstrUtils.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotTwoOpExpr.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
#include <cassert>
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExpression::CBotExpression()
|
||||
{
|
||||
m_leftop = nullptr;
|
||||
m_rightop = nullptr;
|
||||
name = "CBotExpression";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotExpression::~CBotExpression()
|
||||
{
|
||||
delete m_leftop;
|
||||
delete m_rightop;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotExpression::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotToken* pp = p;
|
||||
|
||||
CBotExpression* inst = new CBotExpression();
|
||||
|
||||
inst->m_leftop = CBotLeftExpr::Compile(p, pStack);
|
||||
|
||||
inst->SetToken(p);
|
||||
int OpType = p->GetType();
|
||||
|
||||
if ( pStack->IsOk() &&
|
||||
IsOfTypeList(p, ID_ASS, ID_ASSADD, ID_ASSSUB, ID_ASSMUL, ID_ASSDIV, ID_ASSMODULO,
|
||||
ID_ASSAND, ID_ASSXOR, ID_ASSOR,
|
||||
ID_ASSSL , ID_ASSSR, ID_ASSASR, 0 ))
|
||||
{
|
||||
if (inst->m_leftop == nullptr)
|
||||
{
|
||||
pStack->SetError(TX_BADLEFT, p->GetEnd());
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inst->m_rightop = CBotExpression::Compile(p, pStack);
|
||||
if (inst->m_rightop == nullptr)
|
||||
{
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CBotTypResult type1 = pStack->GetTypResult();
|
||||
|
||||
// get the variable assigned to mark
|
||||
CBotVar* var = nullptr;
|
||||
inst->m_leftop->ExecuteVar(var, pStack);
|
||||
if (var == nullptr)
|
||||
{
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (OpType != ID_ASS && !var->IsDefined())
|
||||
{
|
||||
pStack->SetError(TX_NOTINIT, pp);
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CBotTypResult type2 = var->GetTypResult();
|
||||
|
||||
// what types are acceptable?
|
||||
switch (OpType)
|
||||
{
|
||||
case ID_ASS:
|
||||
// if (type2 == CBotTypClass) type2 = -1;
|
||||
if ((type1.Eq(CBotTypPointer) && type2.Eq(CBotTypPointer)) ||
|
||||
(type1.Eq(CBotTypClass) && type2.Eq(CBotTypClass) ) )
|
||||
{
|
||||
/* CBotClass* c1 = type1.GetClass();
|
||||
CBotClass* c2 = type2.GetClass();
|
||||
if (!c1->IsChildOf(c2)) type2.SetType(-1);
|
||||
//- if (!type1.Eq(CBotTypClass)) var->SetPointer(pStack->GetVar()->GetPointer());*/
|
||||
var->SetInit(CBotVar::InitType::IS_POINTER);
|
||||
}
|
||||
else
|
||||
var->SetInit(CBotVar::InitType::DEF);
|
||||
|
||||
break;
|
||||
case ID_ASSADD:
|
||||
if (type2.Eq(CBotTypBoolean) ||
|
||||
type2.Eq(CBotTypPointer) ) type2 = -1; // numbers and strings
|
||||
break;
|
||||
case ID_ASSSUB:
|
||||
case ID_ASSMUL:
|
||||
case ID_ASSDIV:
|
||||
case ID_ASSMODULO:
|
||||
if (type2.GetType() >= CBotTypBoolean) type2 = -1; // numbers only
|
||||
break;
|
||||
}
|
||||
|
||||
if (!TypeCompatible(type1, type2, OpType))
|
||||
{
|
||||
pStack->SetError(TX_BADTYPE, &inst->m_token);
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return inst; // compatible type?
|
||||
}
|
||||
|
||||
delete inst;
|
||||
int start, end, error = pStack->GetError(start, end);
|
||||
|
||||
p = pp; // returns to the top
|
||||
pStack->SetError(0,0); // forget the error
|
||||
|
||||
CBotInstr* i = CBotTwoOpExpr::Compile(p, pStack); // tries without assignment
|
||||
if (i != nullptr && error == TX_PRIVATE && p->GetType() == ID_ASS)
|
||||
pStack->ResetError(error, start, end);
|
||||
return i;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotExpression::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
|
||||
// CBotToken* pToken = m_leftop->GetToken();
|
||||
|
||||
CBotVar* pVar = nullptr;
|
||||
|
||||
CBotStack* pile1 = pile;
|
||||
|
||||
CBotVar::InitType initKind = CBotVar::InitType::DEF;
|
||||
CBotVar* result = nullptr;
|
||||
|
||||
// must be done before any indexes (stack can be changed)
|
||||
if (!m_leftop->ExecuteVar(pVar, pile, nullptr, false)) return false; // variable before accessing the value on the right
|
||||
|
||||
if ( pile1->GetState()==0)
|
||||
{
|
||||
pile1->SetCopyVar(pVar); // keeps the copy on the stack (if interrupted)
|
||||
pile1->IncState();
|
||||
}
|
||||
|
||||
CBotStack* pile2 = pile->AddStack();
|
||||
|
||||
if ( pile2->GetState()==0)
|
||||
{
|
||||
if (m_rightop && !m_rightop->Execute(pile2)) return false; // initial value // interrupted?
|
||||
pile2->IncState();
|
||||
}
|
||||
|
||||
if (pile1->GetState() == 1)
|
||||
{
|
||||
if (m_token.GetType() != ID_ASS)
|
||||
{
|
||||
pVar = pile1->GetVar(); // recovers if interrupted
|
||||
initKind = pVar->GetInit();
|
||||
if (initKind == CBotVar::InitType::IS_NAN)
|
||||
{
|
||||
pile2->SetError(TX_OPNAN, m_leftop->GetToken());
|
||||
return pj->Return(pile2);
|
||||
}
|
||||
result = CBotVar::Create("", pVar->GetTypResult(2));
|
||||
}
|
||||
|
||||
switch (m_token.GetType())
|
||||
{
|
||||
case ID_ASS:
|
||||
break;
|
||||
case ID_ASSADD:
|
||||
result->Add(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSSUB:
|
||||
result->Sub(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSMUL:
|
||||
result->Mul(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSDIV:
|
||||
if (initKind != CBotVar::InitType::UNDEF &&
|
||||
result->Div(pile1->GetVar(), pile2->GetVar()))
|
||||
pile2->SetError(TX_DIVZERO, &m_token);
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSMODULO:
|
||||
if (initKind != CBotVar::InitType::UNDEF &&
|
||||
result->Modulo(pile1->GetVar(), pile2->GetVar()))
|
||||
pile2->SetError(TX_DIVZERO, &m_token);
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSAND:
|
||||
result->And(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSXOR:
|
||||
result->XOr(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSOR:
|
||||
result->Or(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSSL:
|
||||
result->SL(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSSR:
|
||||
result->SR(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
case ID_ASSASR:
|
||||
result->ASR(pile1->GetVar(), pile2->GetVar());
|
||||
pile2->SetVar(result);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
if (initKind == CBotVar::InitType::UNDEF)
|
||||
pile2->SetError(TX_NOTINIT, m_leftop->GetToken());
|
||||
|
||||
pile1->IncState();
|
||||
}
|
||||
|
||||
if (!m_leftop->Execute( pile2, pile1 ))
|
||||
return false;
|
||||
|
||||
return pj->Return(pile2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotExpression::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (bMain)
|
||||
{
|
||||
// CBotToken* pToken = m_leftop->GetToken();
|
||||
// CBotVar* pVar = nullptr;
|
||||
|
||||
CBotStack* pile = pj->RestoreStack(this);
|
||||
if (pile == nullptr) return;
|
||||
|
||||
CBotStack* pile1 = pile;
|
||||
|
||||
if ( pile1->GetState()==0)
|
||||
{
|
||||
m_leftop->RestoreStateVar(pile, true);
|
||||
return;
|
||||
}
|
||||
|
||||
m_leftop->RestoreStateVar(pile, false);
|
||||
|
||||
CBotStack* pile2 = pile->RestoreStack();
|
||||
if (pile2 == nullptr) return;
|
||||
|
||||
if ( pile2->GetState()==0)
|
||||
{
|
||||
if (m_rightop) m_rightop->RestoreState(pile2, bMain);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotLeftExpr.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotExpression class Compiles a statement with or without
|
||||
* assignment.
|
||||
* eg :
|
||||
* - x = a;
|
||||
* - x * y + 3;
|
||||
* - x = 123
|
||||
* - z * 5 + 4
|
||||
*/
|
||||
|
||||
|
||||
// compiles a statement such as " " ou " z * 5 + 4 "
|
||||
//
|
||||
|
||||
class CBotExpression : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotExpression
|
||||
*/
|
||||
CBotExpression();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotExpression
|
||||
*/
|
||||
~CBotExpression();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute Executes an expression with assignment.
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pStack) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
//! Left operand
|
||||
CBotLeftExpr* m_leftop;
|
||||
//! Right operand
|
||||
CBotInstr* m_rightop;
|
||||
};
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotFieldExpr.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
#include "CBot/CBotClass.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVarClass.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
#include <cassert>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotFieldExpr::CBotFieldExpr()
|
||||
{
|
||||
name = "CBotFieldExpr";
|
||||
m_nIdent = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotFieldExpr::~CBotFieldExpr()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotFieldExpr::SetUniqNum(int num)
|
||||
{
|
||||
m_nIdent = num;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotFieldExpr::ExecuteVar(CBotVar* &pVar, CBotCStack* &pile)
|
||||
{
|
||||
if (pVar->GetType(1) != CBotTypPointer)
|
||||
assert(0);
|
||||
|
||||
pVar = pVar->GetItemRef(m_nIdent);
|
||||
if (pVar == nullptr)
|
||||
{
|
||||
pile->SetError(TX_NOITEM, &m_token);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( m_next3 != nullptr &&
|
||||
!m_next3->ExecuteVar(pVar, pile) ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotFieldExpr::ExecuteVar(CBotVar* &pVar, CBotStack* &pile, CBotToken* prevToken, bool bStep, bool bExtend)
|
||||
{
|
||||
CBotStack* pj = pile;
|
||||
pile = pile->AddStack(this); // changes in output stack
|
||||
if (pile == EOX) return true;
|
||||
|
||||
|
||||
if (pVar->GetType(1) != CBotTypPointer)
|
||||
assert(0);
|
||||
|
||||
CBotVarClass* pItem = pVar->GetPointer();
|
||||
if (pItem == nullptr)
|
||||
{
|
||||
pile->SetError(TX_NULLPT, prevToken);
|
||||
return pj->Return(pile);
|
||||
}
|
||||
if (pItem->GetUserPtr() == OBJECTDELETED)
|
||||
{
|
||||
pile->SetError(TX_DELETEDPT, prevToken);
|
||||
return pj->Return(pile);
|
||||
}
|
||||
|
||||
if (bStep && pile->IfStep()) return false;
|
||||
|
||||
pVar = pVar->GetItemRef(m_nIdent);
|
||||
if (pVar == nullptr)
|
||||
{
|
||||
pile->SetError(TX_NOITEM, &m_token);
|
||||
return pj->Return(pile);
|
||||
}
|
||||
|
||||
if (pVar->IsStatic())
|
||||
{
|
||||
// for a static variable, takes it in the class itself
|
||||
CBotClass* pClass = pItem->GetClass();
|
||||
pVar = pClass->GetItem(m_token.GetString());
|
||||
}
|
||||
|
||||
// request the update of the element, if applicable
|
||||
pVar->Maj(pile->GetPUser(), true);
|
||||
|
||||
if ( m_next3 != nullptr &&
|
||||
!m_next3->ExecuteVar(pVar, pile, &m_token, bStep, bExtend) ) return false;
|
||||
|
||||
// does not release the stack
|
||||
// to maintain the state SetState () corresponding to step
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotFieldExpr::RestoreStateVar(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
pj = pj->RestoreStack(this);
|
||||
if (pj == nullptr) return;
|
||||
|
||||
if (m_next3 != nullptr)
|
||||
m_next3->RestoreStateVar(pj, bMain);
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotFieldExpr class Management of the fields of an instance
|
||||
* (dot operator) eg : toto.x
|
||||
*/
|
||||
class CBotFieldExpr : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotFieldExpr
|
||||
*/
|
||||
CBotFieldExpr();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotFieldExpr
|
||||
*/
|
||||
~CBotFieldExpr();
|
||||
|
||||
/*!
|
||||
* \brief SetUniqNum
|
||||
* \param num
|
||||
*/
|
||||
void SetUniqNum(int num);
|
||||
|
||||
/*!
|
||||
* \brief ExecuteVar Find a field from the instance at compile.
|
||||
* \param pVar
|
||||
* \param pile
|
||||
* \return
|
||||
*/
|
||||
bool ExecuteVar(CBotVar* &pVar, CBotCStack* &pile) override;
|
||||
|
||||
/*!
|
||||
* \brief ExecuteVar
|
||||
* \param pVar
|
||||
* \param pile
|
||||
* \param prevToken
|
||||
* \param bStep
|
||||
* \param bExtend
|
||||
* \return
|
||||
*/
|
||||
bool ExecuteVar(CBotVar* &pVar, CBotStack* &pile, CBotToken* prevToken, bool bStep, bool bExtend) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreStateVar
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreStateVar(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
friend class CBotExpression;
|
||||
int m_nIdent;
|
||||
};
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotFloat.h"
|
||||
#include "CBot/CBotInstr/CBotLeftExprVar.h"
|
||||
#include "CBot/CBotInstr/CBotTwoOpExpr.h"
|
||||
#include "CBot/CBotInstr/CBotInstArray.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotFloat::CBotFloat()
|
||||
{
|
||||
m_var =
|
||||
m_expr = nullptr;
|
||||
name = "CBotFloat";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotFloat::~CBotFloat()
|
||||
{
|
||||
delete m_var;
|
||||
delete m_expr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, bool noskip)
|
||||
{
|
||||
CBotToken* pp = cont ? nullptr : p;
|
||||
|
||||
if (!cont && !IsOfType(p, ID_FLOAT)) return nullptr;
|
||||
|
||||
CBotFloat* inst = static_cast<CBotFloat*>(CompileArray(p, pStack, CBotTypFloat));
|
||||
if (inst != nullptr || !pStack->IsOk()) return inst;
|
||||
|
||||
CBotCStack* pStk = pStack->TokenStack(pp);
|
||||
|
||||
inst = new CBotFloat();
|
||||
|
||||
inst->m_expr = nullptr;
|
||||
|
||||
CBotToken* vartoken = p;
|
||||
CBotVar* var = nullptr;
|
||||
inst->SetToken(vartoken);
|
||||
|
||||
if (nullptr != (inst->m_var = CBotLeftExprVar::Compile( p, pStk )))
|
||||
{
|
||||
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_typevar = CBotTypFloat;
|
||||
if (pStk->CheckVarLocal(vartoken)) // redefinition of a variable
|
||||
{
|
||||
pStk->SetStartError(vartoken->GetStart());
|
||||
pStk->SetError(TX_REDEFVAR, vartoken->GetEnd());
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_OPBRK))
|
||||
{
|
||||
delete inst;
|
||||
p = vartoken;
|
||||
inst = static_cast<CBotFloat*>(CBotInstArray::Compile(p, pStk, CBotTypFloat));
|
||||
|
||||
if (!pStk->IsOk() )
|
||||
{
|
||||
pStk->SetError(TX_CLBRK, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
goto suite; // no assignment, variable already created
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_ASS))
|
||||
{
|
||||
if (nullptr == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
if (pStk->GetType() >= CBotTypBoolean)
|
||||
{
|
||||
pStk->SetError(TX_BADTYPE, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
var = CBotVar::Create(vartoken, CBotTypFloat);
|
||||
var->SetInit(inst->m_expr != nullptr ? CBotVar::InitType::DEF : CBotVar::InitType::UNDEF);
|
||||
var->SetUniqNum(
|
||||
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_nIdent = CBotVar::NextUniqNum());
|
||||
pStack->AddVar(var);
|
||||
suite:
|
||||
if (IsOfType(p, ID_COMMA))
|
||||
{
|
||||
if (nullptr != ( inst->m_next2b = CBotFloat::Compile(p, pStk, true, noskip)))
|
||||
{
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
}
|
||||
|
||||
if (noskip || IsOfType(p, ID_SEP))
|
||||
{
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
pStk->SetError(TX_ENDOF, p->GetStart());
|
||||
}
|
||||
|
||||
error:
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotFloat::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
|
||||
if ( pile->GetState()==0)
|
||||
{
|
||||
if (m_expr && !m_expr->Execute(pile)) return false;
|
||||
m_var->Execute(pile);
|
||||
|
||||
if (!pile->SetState(1)) return false;
|
||||
}
|
||||
|
||||
if (pile->IfStep()) return false;
|
||||
|
||||
if ( m_next2b &&
|
||||
!m_next2b->Execute(pile)) return false;
|
||||
|
||||
return pj->Return(pile);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotFloat::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
CBotStack* pile = pj;
|
||||
if (bMain)
|
||||
{
|
||||
pile = pj->RestoreStack(this);
|
||||
if (pile == nullptr) return;
|
||||
|
||||
if ( pile->GetState()==0)
|
||||
{
|
||||
if (m_expr) m_expr->RestoreState(pile, bMain);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_var->RestoreState(pile, bMain);
|
||||
|
||||
if (m_next2b)
|
||||
m_next2b->RestoreState(pile, bMain);
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotFloat class Definition of a real/float variable int a, b = 12.4;
|
||||
*/
|
||||
class CBotFloat : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotFloat
|
||||
*/
|
||||
CBotFloat();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotFloat
|
||||
*/
|
||||
~CBotFloat();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param cont
|
||||
* \param noskip
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool cont = false, bool noskip=false);
|
||||
|
||||
/*!
|
||||
* \brief Execute Executes the definition of a real variable.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
//! Variable to initialise.
|
||||
CBotInstr* m_var;
|
||||
//! A value to put, if there is.
|
||||
CBotInstr* m_expr;
|
||||
};
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotFor.h"
|
||||
#include "CBot/CBotInstr/CBotListExpression.h"
|
||||
#include "CBot/CBotInstr/CBotBlock.h"
|
||||
#include "CBot/CBotInstr/CBotBoolExpr.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotFor::CBotFor()
|
||||
{
|
||||
m_Init =
|
||||
m_Test =
|
||||
m_Incr =
|
||||
m_Block = nullptr; // nullptr 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
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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->GetString(); // register the name of label
|
||||
}
|
||||
|
||||
inst->SetToken(p);
|
||||
if (!IsOfType(p, ID_FOR)) return nullptr; // should never happen
|
||||
|
||||
if ( !IsOfType(p, ID_OPENPAR)) // missing parenthesis ?
|
||||
{
|
||||
pStack->SetError(TX_OPENPAR, p->GetStart());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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->GetStart());
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, 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->GetStart());
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, 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->GetStart());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete inst; // error, frees up
|
||||
return pStack->Return(nullptr, 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->GetState() ) // executes the loop
|
||||
{ // there are four possible states (depending on recovery)
|
||||
case 0:
|
||||
// initialize
|
||||
if ( m_Init != nullptr &&
|
||||
!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 != nullptr ) // 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->GetVal() != 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 != nullptr &&
|
||||
!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 != nullptr &&
|
||||
!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 == nullptr ) return;
|
||||
|
||||
switch( pile->GetState() )
|
||||
{ // there are four possible states (depending on recovery)
|
||||
case 0:
|
||||
// initialize
|
||||
if ( m_Init != nullptr ) m_Init->RestoreState(pile, true); // interrupted here !
|
||||
return;
|
||||
|
||||
case 1:
|
||||
if ( m_Init != nullptr ) m_Init->RestoreState(pile, false); // variables definitions
|
||||
|
||||
// evaluates the condition
|
||||
if ( m_Test != nullptr ) m_Test->RestoreState(pile, true); // interrupted here !
|
||||
return;
|
||||
|
||||
case 2:
|
||||
if ( m_Init != nullptr ) m_Init->RestoreState(pile, false); // variable definitions
|
||||
|
||||
// evaluates the associated statement block
|
||||
if ( m_Block != nullptr ) m_Block->RestoreState(pile, true);
|
||||
return;
|
||||
|
||||
case 3:
|
||||
if ( m_Init != nullptr ) m_Init->RestoreState(pile, false); // variable definitions
|
||||
|
||||
// evaluate the incrementation
|
||||
if ( m_Incr != nullptr ) m_Incr->RestoreState(pile, true); // interrupted here !
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotFor class
|
||||
*/
|
||||
class CBotFor : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotFor
|
||||
*/
|
||||
CBotFor();
|
||||
|
||||
/*!
|
||||
* \brief CBotFor
|
||||
*/
|
||||
~CBotFor();
|
||||
|
||||
/*!
|
||||
* \brief Compile Compiles instruction "for"
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
|
||||
//! Initial intruction
|
||||
CBotInstr* m_Init;
|
||||
//! Test Condition
|
||||
CBotInstr* m_Test;
|
||||
//! instruction for increment
|
||||
CBotInstr* m_Incr;
|
||||
//! Instructions
|
||||
CBotInstr* m_Block;
|
||||
//! A label if there is
|
||||
CBotString m_label;
|
||||
};
|
|
@ -17,18 +17,33 @@
|
|||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// compilation of various functions declared by the user
|
||||
//
|
||||
|
||||
#include "CBot.h"
|
||||
// Modules inlcude
|
||||
#include "CBot/CBotInstr/CBotFunction.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotInstrUtils.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotBlock.h"
|
||||
#include "CBot/CBotInstr/CBotTwoOpExpr.h"
|
||||
#include "CBot/CBotInstr/CBotExpression.h"
|
||||
#include "CBot/CBotInstr/CBotEmpty.h"
|
||||
#include "CBot/CBotInstr/CBotListArray.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
#include "CBot/CBotClass.h"
|
||||
#include "CBot/CBotDefParam.h"
|
||||
#include "CBot/CBotUtils.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
#include <cassert>
|
||||
|
||||
|
||||
// various constructors / destructors
|
||||
// \TODO translation:to liberate all according to esteblished tree
|
||||
// pour libérer tout selon l'arbre établi
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotFunction::CBotFunction()
|
||||
{
|
||||
m_Param = nullptr; // empty parameter list
|
||||
|
@ -44,8 +59,10 @@ CBotFunction::CBotFunction()
|
|||
m_bSynchro = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotFunction* CBotFunction::m_listPublic = nullptr;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotFunction::~CBotFunction()
|
||||
{
|
||||
delete m_Param; // empty parameter list
|
||||
|
@ -71,16 +88,19 @@ CBotFunction::~CBotFunction()
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotFunction::IsPublic()
|
||||
{
|
||||
return m_bPublic;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotFunction::IsExtern()
|
||||
{
|
||||
return m_bExtern;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotFunction::GetPosition(int& start, int& stop, CBotGet modestart, CBotGet modestop)
|
||||
{
|
||||
start = m_extern.GetStart();
|
||||
|
@ -122,61 +142,7 @@ bool CBotFunction::GetPosition(int& start, int& stop, CBotGet modestart, CBotGet
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
CBotTypResult ArrayType(CBotToken* &p, CBotCStack* pile, CBotTypResult type)
|
||||
{
|
||||
while ( IsOfType( p, ID_OPBRK ) )
|
||||
{
|
||||
if ( !IsOfType( p, ID_CLBRK ) )
|
||||
{
|
||||
pile->SetError(TX_CLBRK, p->GetStart());
|
||||
return CBotTypResult( -1 );
|
||||
}
|
||||
type = CBotTypResult( CBotTypArrayPointer, type );
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
CBotTypResult TypeParam(CBotToken* &p, CBotCStack* pile)
|
||||
{
|
||||
CBotClass* pClass = nullptr;
|
||||
|
||||
switch (p->GetType())
|
||||
{
|
||||
case ID_INT:
|
||||
p = p->GetNext();
|
||||
return ArrayType(p, pile, CBotTypResult( CBotTypInt ));
|
||||
case ID_FLOAT:
|
||||
p = p->GetNext();
|
||||
return ArrayType(p, pile, CBotTypResult( CBotTypFloat ));
|
||||
case ID_BOOLEAN:
|
||||
case ID_BOOL:
|
||||
p = p->GetNext();
|
||||
return ArrayType(p, pile, CBotTypResult( CBotTypBoolean ));
|
||||
case ID_STRING:
|
||||
p = p->GetNext();
|
||||
return ArrayType(p, pile, CBotTypResult( CBotTypString ));
|
||||
case ID_VOID:
|
||||
p = p->GetNext();
|
||||
return CBotTypResult( 0 );
|
||||
|
||||
case TokenTypVar:
|
||||
pClass = CBotClass::Find(p);
|
||||
if ( pClass != nullptr)
|
||||
{
|
||||
p = p->GetNext();
|
||||
return ArrayType(p, pile,
|
||||
pClass->IsIntrinsic() ?
|
||||
CBotTypResult( CBotTypIntrinsic, pClass ) :
|
||||
CBotTypResult( CBotTypPointer, pClass ) );
|
||||
}
|
||||
}
|
||||
return CBotTypResult( -1 );
|
||||
}
|
||||
|
||||
// compiles a new function
|
||||
// bLocal allows of the declaration of parameters on the same level
|
||||
// as the elements belonging to the class for methods
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotFunction* CBotFunction::Compile(CBotToken* &p, CBotCStack* pStack, CBotFunction* finput, bool bLocal)
|
||||
{
|
||||
CBotToken* pp;
|
||||
|
@ -289,7 +255,7 @@ bad:
|
|||
return pStack->ReturnFunc(nullptr, pStk);
|
||||
}
|
||||
|
||||
// pre-compile a new function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotFunction* CBotFunction::Compile1(CBotToken* &p, CBotCStack* pStack, CBotClass* pClass)
|
||||
{
|
||||
CBotFunction* func = new CBotFunction();
|
||||
|
@ -376,6 +342,7 @@ bad:
|
|||
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
|
||||
|
@ -425,7 +392,7 @@ bool CBotFunction::Execute(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInstance)
|
|||
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
|
||||
|
@ -454,6 +421,7 @@ void CBotFunction::RestoreState(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInst
|
|||
m_Block->RestoreState(pile2, true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotFunction::AddNext(CBotFunction* p)
|
||||
{
|
||||
CBotFunction* pp = this;
|
||||
|
@ -462,7 +430,7 @@ void CBotFunction::AddNext(CBotFunction* p)
|
|||
pp->m_next = p;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotTypResult CBotFunction::CompileCall(const char* name, CBotVar** ppVars, long& nIdent)
|
||||
{
|
||||
nIdent = 0;
|
||||
|
@ -473,10 +441,7 @@ CBotTypResult CBotFunction::CompileCall(const char* name, CBotVar** ppVars, long
|
|||
return type;
|
||||
}
|
||||
|
||||
|
||||
// is a function according to its unique identifier
|
||||
// if the identifier is not found, looking by name and parameters
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotFunction* CBotFunction::FindLocalOrPublic(long& nIdent, const char* name, CBotVar** ppVars, CBotTypResult& TypeOrError, bool bPublic)
|
||||
{
|
||||
TypeOrError.SetType(TX_UNDEFCALL); // no routine of the name
|
||||
|
@ -629,9 +594,7 @@ CBotFunction* CBotFunction::FindLocalOrPublic(long& nIdent, const char* name, CB
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
// fait un appel à une fonction
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CBotFunction::DoCall(long& nIdent, const char* name, CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken)
|
||||
{
|
||||
CBotTypResult type;
|
||||
|
@ -701,6 +664,7 @@ int CBotFunction::DoCall(long& nIdent, const char* name, CBotVar** ppVars, CBotS
|
|||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotFunction::RestoreCall(long& nIdent, const char* name, CBotVar** ppVars, CBotStack* pStack)
|
||||
{
|
||||
CBotTypResult type;
|
||||
|
@ -757,11 +721,7 @@ void CBotFunction::RestoreCall(long& nIdent, const char* name, CBotVar** ppVars,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// makes call of a method
|
||||
// note: this is already on the stack, the pointer pThis is just to simplify
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CBotFunction::DoCall(long& nIdent, const char* name, CBotVar* pThis, CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken, CBotClass* pClass)
|
||||
{
|
||||
CBotTypResult type;
|
||||
|
@ -842,6 +802,7 @@ int CBotFunction::DoCall(long& nIdent, const char* name, CBotVar* pThis, CBotVar
|
|||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotFunction::RestoreCall(long& nIdent, const char* name, CBotVar* pThis, CBotVar** ppVars, CBotStack* pStack, CBotClass* pClass)
|
||||
{
|
||||
CBotTypResult type;
|
||||
|
@ -874,7 +835,7 @@ void CBotFunction::RestoreCall(long& nIdent, const char* name, CBotVar* pThis, C
|
|||
}
|
||||
}
|
||||
|
||||
// see if the "signature" of parameters is identical
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotFunction::CheckParam(CBotDefParam* pParam)
|
||||
{
|
||||
CBotDefParam* pp = m_Param;
|
||||
|
@ -889,11 +850,13 @@ bool CBotFunction::CheckParam(CBotDefParam* pParam)
|
|||
return ( pp == nullptr && pParam == nullptr );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotString CBotFunction::GetName()
|
||||
{
|
||||
return m_token.GetString();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotString CBotFunction::GetParams()
|
||||
{
|
||||
if ( m_Param == nullptr ) return CBotString("()");
|
||||
|
@ -912,11 +875,13 @@ CBotString CBotFunction::GetParams()
|
|||
return params;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotFunction* CBotFunction::Next()
|
||||
{
|
||||
return m_next;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotFunction::AddPublic(CBotFunction* func)
|
||||
{
|
||||
if ( m_listPublic != nullptr )
|
||||
|
@ -926,748 +891,3 @@ void CBotFunction::AddPublic(CBotFunction* func)
|
|||
}
|
||||
m_listPublic = func;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// management of parameters
|
||||
|
||||
|
||||
CBotDefParam::CBotDefParam()
|
||||
{
|
||||
m_next = nullptr;
|
||||
m_nIdent = 0;
|
||||
}
|
||||
|
||||
CBotDefParam::~CBotDefParam()
|
||||
{
|
||||
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->GetStart());
|
||||
|
||||
if (IsOfType(p, ID_OPENPAR))
|
||||
{
|
||||
CBotDefParam* list = nullptr;
|
||||
|
||||
while (!IsOfType(p, ID_CLOSEPAR))
|
||||
{
|
||||
CBotDefParam* param = new CBotDefParam();
|
||||
if (list == nullptr) list = param;
|
||||
else list->AddNext(param); // added to the list
|
||||
|
||||
// CBotClass* pClass = nullptr;//= CBotClass::Find(p);
|
||||
param->m_typename = p->GetString();
|
||||
CBotTypResult type = param->m_type = TypeParam(p, pStack);
|
||||
// if ( type == CBotTypPointer ) type = CBotTypClass; // we must create a new object
|
||||
|
||||
if (param->m_type.GetType() > 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->GetString(), type); // creates the variable
|
||||
// if ( pClass ) var->SetClass(pClass);
|
||||
var->SetInit(CBotVar::InitType::IS_POINTER); // 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->GetType() == ID_CLOSEPAR)
|
||||
continue;
|
||||
}
|
||||
pStack->SetError(TX_CLOSEPAR, p->GetStart());
|
||||
}
|
||||
pStack->SetError(TX_NOTYP, p);
|
||||
delete list;
|
||||
return nullptr;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
pStack->SetError(TX_OPENPAR, p->GetStart());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CBotDefParam::AddNext(CBotDefParam* p)
|
||||
{
|
||||
CBotDefParam* pp = this;
|
||||
while (pp->m_next != nullptr) pp = pp->m_next;
|
||||
|
||||
pp->m_next = p;
|
||||
}
|
||||
|
||||
|
||||
bool CBotDefParam::Execute(CBotVar** ppVars, CBotStack* &pj)
|
||||
{
|
||||
int i = 0;
|
||||
CBotDefParam* p = this;
|
||||
|
||||
while ( p != nullptr )
|
||||
{
|
||||
// creates a local variable on the stack
|
||||
CBotVar* newvar = CBotVar::Create(p->m_token.GetString(), p->m_type);
|
||||
|
||||
// serves to make the transformation of types:
|
||||
if ( ppVars != nullptr && ppVars[i] != nullptr )
|
||||
{
|
||||
switch (p->m_type.GetType())
|
||||
{
|
||||
case CBotTypInt:
|
||||
newvar->SetValInt(ppVars[i]->GetValInt());
|
||||
break;
|
||||
case CBotTypFloat:
|
||||
newvar->SetValFloat(ppVars[i]->GetValFloat());
|
||||
break;
|
||||
case CBotTypString:
|
||||
newvar->SetValString(ppVars[i]->GetValString());
|
||||
break;
|
||||
case CBotTypBoolean:
|
||||
newvar->SetValInt(ppVars[i]->GetValInt());
|
||||
break;
|
||||
case CBotTypIntrinsic:
|
||||
(static_cast<CBotVarClass*>(newvar))->Copy(ppVars[i], false);
|
||||
break;
|
||||
case CBotTypPointer:
|
||||
case CBotTypArrayPointer:
|
||||
{
|
||||
newvar->SetPointer(ppVars[i]->GetPointer());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
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 != nullptr )
|
||||
{
|
||||
// creates a local variable on the stack
|
||||
CBotVar* var = pj->FindVar(p->m_token.GetString());
|
||||
var->SetUniqNum(p->m_nIdent);
|
||||
p = p->m_next;
|
||||
}
|
||||
}
|
||||
|
||||
int CBotDefParam::GetType()
|
||||
{
|
||||
return m_type.GetType();
|
||||
}
|
||||
|
||||
CBotTypResult CBotDefParam::GetTypResult()
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
CBotDefParam* CBotDefParam::GetNext()
|
||||
{
|
||||
return m_next;
|
||||
}
|
||||
|
||||
CBotString CBotDefParam::GetParamString()
|
||||
{
|
||||
CBotString param;
|
||||
|
||||
param = m_typename;
|
||||
param += ' ';
|
||||
|
||||
param += m_token.GetString();
|
||||
return param;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// return parameters
|
||||
|
||||
CBotReturn::CBotReturn()
|
||||
{
|
||||
m_Instr = nullptr;
|
||||
name = "CBotReturn"; // debug
|
||||
}
|
||||
|
||||
CBotReturn::~CBotReturn()
|
||||
{
|
||||
delete m_Instr;
|
||||
}
|
||||
|
||||
CBotInstr* CBotReturn::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotToken* pp = p;
|
||||
|
||||
if (!IsOfType(p, ID_RETURN)) return nullptr; // should never happen
|
||||
|
||||
CBotReturn* inst = new CBotReturn(); // creates the object
|
||||
inst->SetToken( pp );
|
||||
|
||||
CBotTypResult type = pStack->GetRetType();
|
||||
|
||||
if ( type.GetType() == 0 ) // returned void ?
|
||||
{
|
||||
if ( IsOfType( p, ID_SEP ) ) return inst;
|
||||
pStack->SetError( TX_BADTYPE, pp );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inst->m_Instr = CBotExpression::Compile(p, pStack);
|
||||
if ( pStack->IsOk() )
|
||||
{
|
||||
CBotTypResult retType = pStack->GetTypResult(2);
|
||||
if (TypeCompatible(retType, type, ID_ASS))
|
||||
{
|
||||
if ( IsOfType( p, ID_SEP ) )
|
||||
return inst;
|
||||
|
||||
pStack->SetError(TX_ENDOF, p->GetStart());
|
||||
}
|
||||
pStack->SetError(TX_BADTYPE, p->GetStart());
|
||||
}
|
||||
|
||||
delete inst;
|
||||
return nullptr; // no object, the error is on the stack
|
||||
}
|
||||
|
||||
bool CBotReturn::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
// if ( pile == EOX ) return true;
|
||||
|
||||
if ( pile->GetState() == 0 )
|
||||
{
|
||||
if ( m_Instr != nullptr && !m_Instr->Execute(pile) ) return false; // evaluate the result
|
||||
// the result is on the stack
|
||||
pile->IncState();
|
||||
}
|
||||
|
||||
if ( pile->IfStep() ) return false;
|
||||
|
||||
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 == nullptr ) return;
|
||||
|
||||
if ( pile->GetState() == 0 )
|
||||
{
|
||||
if ( m_Instr != nullptr ) m_Instr->RestoreState(pile, bMain); // evaluate the result
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Calls of these functions
|
||||
|
||||
CBotInstrCall::CBotInstrCall()
|
||||
{
|
||||
m_Parameters = nullptr;
|
||||
m_nFuncIdent = 0;
|
||||
name = "CBotInstrCall";
|
||||
}
|
||||
|
||||
CBotInstrCall::~CBotInstrCall()
|
||||
{
|
||||
delete m_Parameters;
|
||||
}
|
||||
|
||||
CBotInstr* CBotInstrCall::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotVar* ppVars[1000];
|
||||
|
||||
int i = 0;
|
||||
|
||||
CBotToken* pp = p;
|
||||
p = p->GetNext();
|
||||
|
||||
pStack->SetStartError(p->GetStart());
|
||||
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->GetStart();
|
||||
pile = pile->TokenStack(); // keeps the results on the stack
|
||||
|
||||
CBotInstr* param = CBotExpression::Compile(p, pile);
|
||||
end = p->GetStart();
|
||||
if ( inst->m_Parameters == nullptr ) inst->m_Parameters = param;
|
||||
else inst->m_Parameters->AddNext(param); // constructs the list
|
||||
|
||||
if ( !pile->IsOk() )
|
||||
{
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pile);
|
||||
}
|
||||
|
||||
if ( param != nullptr )
|
||||
{
|
||||
if ( pile->GetTypResult().Eq(99) )
|
||||
{
|
||||
delete pStack->TokenStack();
|
||||
pStack->SetError(TX_VOID, p->GetStart());
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
ppVars[i] = pile->GetVar();
|
||||
ppVars[i]->GetToken()->SetPos(start, end);
|
||||
i++;
|
||||
|
||||
if (IsOfType(p, ID_COMMA)) continue; // skips the comma
|
||||
if (IsOfType(p, ID_CLOSEPAR)) break;
|
||||
}
|
||||
|
||||
pStack->SetError(TX_CLOSEPAR, p->GetStart());
|
||||
delete pStack->TokenStack();
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
ppVars[i] = nullptr;
|
||||
|
||||
// the routine is known?
|
||||
// CBotClass* pClass = nullptr;
|
||||
inst->m_typRes = pStack->CompileCall(pp, ppVars, inst->m_nFuncIdent);
|
||||
if ( inst->m_typRes.GetType() >= 20 )
|
||||
{
|
||||
// if (pVar2!=nullptr) pp = pVar2->RetToken();
|
||||
pStack->SetError( inst->m_typRes.GetType(), pp );
|
||||
delete pStack->TokenStack();
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
delete pStack->TokenStack();
|
||||
if ( inst->m_typRes.GetType() > 0 )
|
||||
{
|
||||
CBotVar* pRes = CBotVar::Create("", inst->m_typRes);
|
||||
pStack->SetVar(pRes); // for knowing the type of the result
|
||||
}
|
||||
else pStack->SetVar(nullptr); // routine returns void
|
||||
|
||||
return inst;
|
||||
}
|
||||
p = pp;
|
||||
delete pStack->TokenStack();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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 != nullptr) while ( true )
|
||||
{
|
||||
pile = pile->AddStack(); // place on the stack for the results
|
||||
if ( pile->GetState() == 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->GetVar();
|
||||
p = p->GetNext();
|
||||
if ( p == nullptr) break;
|
||||
}
|
||||
ppVars[i] = nullptr;
|
||||
|
||||
CBotStack* pile2 = pile->AddStack();
|
||||
if ( pile2->IfStep() ) return false;
|
||||
|
||||
if ( !pile2->ExecuteCall(m_nFuncIdent, GetToken(), 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 == nullptr ) 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 != nullptr) while ( true )
|
||||
{
|
||||
pile = pile->RestoreStack(); // place on the stack for the results
|
||||
if ( pile == nullptr ) return;
|
||||
if ( pile->GetState() == 0 )
|
||||
{
|
||||
p->RestoreState(pile, bMain); // interrupt here!
|
||||
return;
|
||||
}
|
||||
ppVars[i++] = pile->GetVar(); // constructs the list of parameters
|
||||
p = p->GetNext();
|
||||
if ( p == nullptr) break;
|
||||
}
|
||||
ppVars[i] = nullptr;
|
||||
|
||||
CBotStack* pile2 = pile->RestoreStack();
|
||||
if ( pile2 == nullptr ) return;
|
||||
|
||||
pile2->RestoreCall(m_nFuncIdent, GetToken(), ppVars);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// statement of user classes
|
||||
|
||||
// pre-compile a new class
|
||||
// analysis is complete except the body of routines
|
||||
|
||||
CBotClass* CBotClass::Compile1(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
if ( !IsOfType(p, ID_PUBLIC) )
|
||||
{
|
||||
pStack->SetError(TX_NOPUBLIC, p);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( !IsOfType(p, ID_CLASS) ) return nullptr;
|
||||
|
||||
CBotString name = p->GetString();
|
||||
|
||||
CBotClass* pOld = CBotClass::Find(name);
|
||||
if ( pOld != nullptr && pOld->m_IsDef )
|
||||
{
|
||||
pStack->SetError( TX_REDEFCLASS, p );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// a name of the class is there?
|
||||
if (IsOfType(p, TokenTypVar))
|
||||
{
|
||||
CBotClass* pPapa = nullptr;
|
||||
if ( IsOfType( p, ID_EXTENDS ) )
|
||||
{
|
||||
CBotString name = p->GetString();
|
||||
pPapa = CBotClass::Find(name);
|
||||
|
||||
if (!IsOfType(p, TokenTypVar) || pPapa == nullptr )
|
||||
{
|
||||
pStack->SetError( TX_NOCLASS, p );
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
CBotClass* classe = (pOld == nullptr) ? 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 nullptr;
|
||||
}
|
||||
|
||||
while ( pStack->IsOk() && !IsOfType( p, ID_CLBLK ) )
|
||||
{
|
||||
classe->CompileDefItem(p, pStack, false);
|
||||
}
|
||||
|
||||
if (pStack->IsOk()) return classe;
|
||||
}
|
||||
pStack->SetError(TX_ENDOF, p);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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 = nullptr;
|
||||
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 = nullptr;
|
||||
while ( IsOfType( p, ID_OPBRK ) ) // a table?
|
||||
{
|
||||
CBotInstr* i = nullptr;
|
||||
|
||||
if ( p->GetType() != 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->GetStart());
|
||||
return false;
|
||||
}
|
||||
|
||||
/* CBotVar* pv = pStack->GetVar();
|
||||
if ( pv->GetType()>= CBotTypBoolean )
|
||||
{
|
||||
pStack->SetError(TX_BADTYPE, p->GetStart());
|
||||
return false;
|
||||
}*/
|
||||
|
||||
if (limites == nullptr) limites = i;
|
||||
else limites->AddNext3(i);
|
||||
}
|
||||
|
||||
if ( p->GetType() == ID_OPENPAR )
|
||||
{
|
||||
if ( !bSecond )
|
||||
{
|
||||
p = pBase;
|
||||
CBotFunction* f =
|
||||
CBotFunction::Compile1(p, pStack, this);
|
||||
|
||||
if ( f == nullptr ) return false;
|
||||
|
||||
if (m_pMethod == nullptr) m_pMethod = f;
|
||||
else m_pMethod->AddNext(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
// return a method precompiled in pass 1
|
||||
CBotFunction* pf = m_pMethod;
|
||||
CBotFunction* prev = nullptr;
|
||||
while ( pf != nullptr )
|
||||
{
|
||||
if (pf->GetName() == pp->GetString()) break;
|
||||
prev = pf;
|
||||
pf = pf->Next();
|
||||
}
|
||||
|
||||
bool bConstructor = (pp->GetString() == GetName());
|
||||
CBotCStack* pile = pStack->TokenStack(nullptr, 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 != nullptr)
|
||||
{
|
||||
// places a copy of variables of a class (this) on a stack
|
||||
CBotVar* pv = my->m_pVar;
|
||||
while (pv != nullptr)
|
||||
{
|
||||
CBotVar* pcopy = CBotVar::Create(pv);
|
||||
CBotVar::InitType initType = CBotVar::InitType::UNDEF;
|
||||
if (!bConstructor || pv->IsStatic())
|
||||
initType = CBotVar::InitType::DEF;
|
||||
pcopy->SetInit(initType);
|
||||
pcopy->SetUniqNum(pv->GetUniqNum());
|
||||
pile->AddVar(pcopy);
|
||||
pv = pv->GetNext();
|
||||
}
|
||||
my = my->m_pParent;
|
||||
}
|
||||
|
||||
// compiles a method
|
||||
p = pBase;
|
||||
CBotFunction* f =
|
||||
CBotFunction::Compile(p, pile, nullptr/*, false*/);
|
||||
|
||||
if ( f != nullptr )
|
||||
{
|
||||
f->m_pProg = pStack->GetBotCall();
|
||||
f->m_bSynchro = bSynchro;
|
||||
// replaces the element in the chain
|
||||
f->m_next = pf->m_next;
|
||||
pf->m_next = nullptr;
|
||||
delete pf;
|
||||
if (prev == nullptr) m_pMethod = f;
|
||||
else prev->m_next = f;
|
||||
}
|
||||
pStack->Return(nullptr, pile);
|
||||
}
|
||||
|
||||
return pStack->IsOk();
|
||||
}
|
||||
|
||||
// definition of an element
|
||||
if (type.Eq(0))
|
||||
{
|
||||
pStack->SetError(TX_ENDOF, p);
|
||||
return false;
|
||||
}
|
||||
|
||||
CBotInstr* i = nullptr;
|
||||
if ( IsOfType(p, ID_ASS ) )
|
||||
{
|
||||
if ( type.Eq(CBotTypArrayPointer) )
|
||||
{
|
||||
i = CBotListArray::Compile(p, pStack, type.GetTypElem());
|
||||
}
|
||||
else
|
||||
{
|
||||
// it has an assignmet to calculate
|
||||
i = CBotTwoOpExpr::Compile(p, pStack);
|
||||
}
|
||||
if ( !pStack->IsOk() ) return false;
|
||||
}
|
||||
|
||||
|
||||
if ( !bSecond )
|
||||
{
|
||||
CBotVar* pv = CBotVar::Create(pp->GetString(), type);
|
||||
pv -> SetStatic( bStatic );
|
||||
pv -> SetPrivate( mProtect );
|
||||
|
||||
AddItem( pv );
|
||||
|
||||
pv->m_InitExpr = i;
|
||||
pv->m_LimExpr = limites;
|
||||
|
||||
|
||||
if ( pv->IsStatic() && pv->m_InitExpr != nullptr )
|
||||
{
|
||||
CBotStack* pile = CBotStack::FirstStack(); // independent stack
|
||||
while(pile->IsOk() && !pv->m_InitExpr->Execute(pile)); // evaluates the expression without timer
|
||||
pv->SetVal( pile->GetVar() ) ;
|
||||
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 nullptr;
|
||||
if ( !IsOfType(p, ID_CLASS) ) return nullptr;
|
||||
|
||||
CBotString name = p->GetString();
|
||||
|
||||
// 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 ) )
|
||||
{
|
||||
// TODO: Not sure how correct is that - I have no idea how the precompilation (Compile1 method) works ~krzys_h
|
||||
CBotString name = p->GetString();
|
||||
CBotClass* pPapa = CBotClass::Find(name);
|
||||
|
||||
if (!IsOfType(p, TokenTypVar) || pPapa == nullptr)
|
||||
{
|
||||
pStack->SetError( TX_NOCLASS, p );
|
||||
return nullptr;
|
||||
}
|
||||
pOld->m_pParent = pPapa;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pOld != nullptr)
|
||||
{
|
||||
pOld->m_pParent = nullptr;
|
||||
}
|
||||
}
|
||||
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 nullptr;
|
||||
}
|
||||
|
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotFunction class A function declaration. Compilation of various
|
||||
* functions declared by the user
|
||||
*/
|
||||
class CBotFunction : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotFunction
|
||||
*/
|
||||
CBotFunction();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotFunction
|
||||
*/
|
||||
~CBotFunction();
|
||||
|
||||
/*!
|
||||
* \brief Compile Compiles a new function
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param pFunc
|
||||
* \param bLocal allows of the declaration of parameters on the same level
|
||||
* as the elements belonging to the class for methods.
|
||||
* \return
|
||||
*/
|
||||
static CBotFunction* Compile(CBotToken* &p,
|
||||
CBotCStack* pStack,
|
||||
CBotFunction* pFunc,
|
||||
bool bLocal = true);
|
||||
|
||||
/*!
|
||||
* \brief Compile1 Pre-compile a new function.
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param pClass
|
||||
* \return
|
||||
*/
|
||||
static CBotFunction* Compile1(CBotToken* &p,
|
||||
CBotCStack* pStack,
|
||||
CBotClass* pClass);
|
||||
|
||||
/*!
|
||||
* \brief Execute
|
||||
* \param ppVars
|
||||
* \param pj
|
||||
* \param pInstance
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotVar** ppVars,
|
||||
CBotStack* &pj,
|
||||
CBotVar* pInstance = nullptr);
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param ppVars
|
||||
* \param pj
|
||||
* \param pInstance
|
||||
*/
|
||||
void RestoreState(CBotVar** ppVars,
|
||||
CBotStack* &pj,
|
||||
CBotVar* pInstance = nullptr);
|
||||
|
||||
/*!
|
||||
* \brief AddNext
|
||||
* \param p
|
||||
*/
|
||||
void AddNext(CBotFunction* p);
|
||||
|
||||
/*!
|
||||
* \brief CompileCall
|
||||
* \param name
|
||||
* \param ppVars
|
||||
* \param nIdent
|
||||
* \return
|
||||
*/
|
||||
CBotTypResult CompileCall(const char* name,
|
||||
CBotVar** ppVars,
|
||||
long& nIdent);
|
||||
|
||||
/*!
|
||||
* \brief FindLocalOrPublic Is a function according to its unique identifier
|
||||
* if the identifier is not found, looking by name and parameters.
|
||||
* \param nIdent
|
||||
* \param name
|
||||
* \param ppVars
|
||||
* \param TypeOrError
|
||||
* \param bPublic
|
||||
* \return
|
||||
*/
|
||||
CBotFunction* FindLocalOrPublic(long& nIdent, const char* name,
|
||||
CBotVar** ppVars,
|
||||
CBotTypResult& TypeOrError,
|
||||
bool bPublic = true);
|
||||
|
||||
/*!
|
||||
* \brief DoCall Fait un appel à une fonction.
|
||||
* \param nIdent
|
||||
* \param name
|
||||
* \param ppVars
|
||||
* \param pStack
|
||||
* \param pToken
|
||||
* \return
|
||||
*/
|
||||
|
||||
int DoCall(long& nIdent,
|
||||
const char* name,
|
||||
CBotVar** ppVars,
|
||||
CBotStack* pStack,
|
||||
CBotToken* pToken);
|
||||
|
||||
/*!
|
||||
* \brief RestoreCall
|
||||
* \param nIdent
|
||||
* \param name
|
||||
* \param ppVars
|
||||
* \param pStack
|
||||
*/
|
||||
void RestoreCall(long& nIdent,
|
||||
const char* name,
|
||||
CBotVar** ppVars,
|
||||
CBotStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief DoCall Makes call of a method note: this is already on the stack,
|
||||
* the pointer pThis is just to simplify.
|
||||
* \param nIdent
|
||||
* \param name
|
||||
* \param pThis
|
||||
* \param ppVars
|
||||
* \param pStack
|
||||
* \param pToken
|
||||
* \param pClass
|
||||
* \return
|
||||
*/
|
||||
int DoCall(long& nIdent,
|
||||
const char* name,
|
||||
CBotVar* pThis,
|
||||
CBotVar** ppVars,
|
||||
CBotStack* pStack,
|
||||
CBotToken* pToken,
|
||||
CBotClass* pClass);
|
||||
|
||||
/*!
|
||||
* \brief RestoreCall
|
||||
* \param nIdent
|
||||
* \param name
|
||||
* \param pThis
|
||||
* \param ppVars
|
||||
* \param pStack
|
||||
* \param pClass
|
||||
*/
|
||||
void RestoreCall(long& nIdent,
|
||||
const char* name,
|
||||
CBotVar* pThis,
|
||||
CBotVar** ppVars,
|
||||
CBotStack* pStack,
|
||||
CBotClass* pClass);
|
||||
|
||||
/*!
|
||||
* \brief CheckParam See if the "signature" of parameters is identical.
|
||||
* \param pParam
|
||||
* \return
|
||||
*/
|
||||
bool CheckParam(CBotDefParam* pParam);
|
||||
|
||||
/*!
|
||||
* \brief AddPublic
|
||||
* \param pfunc
|
||||
*/
|
||||
static void AddPublic(CBotFunction* pfunc);
|
||||
|
||||
/*!
|
||||
* \brief GetName
|
||||
* \return
|
||||
*/
|
||||
CBotString GetName();
|
||||
|
||||
/*!
|
||||
* \brief GetParams
|
||||
* \return
|
||||
*/
|
||||
CBotString GetParams();
|
||||
|
||||
/*!
|
||||
* \brief IsPublic
|
||||
* \return
|
||||
*/
|
||||
bool IsPublic();
|
||||
|
||||
/*!
|
||||
* \brief IsExtern
|
||||
* \return
|
||||
*/
|
||||
bool IsExtern();
|
||||
|
||||
/*!
|
||||
* \brief Next
|
||||
* \return
|
||||
*/
|
||||
CBotFunction* Next();
|
||||
|
||||
/*!
|
||||
* \brief GetPosition
|
||||
* \param start
|
||||
* \param stop
|
||||
* \param modestart
|
||||
* \param modestop
|
||||
* \return
|
||||
*/
|
||||
bool GetPosition(int& start, int& stop,
|
||||
CBotGet modestart,
|
||||
CBotGet modestop);
|
||||
|
||||
private:
|
||||
CBotFunction* m_nextpublic;
|
||||
CBotFunction* m_prevpublic;
|
||||
long m_nFuncIdent;
|
||||
//! Synchronized method.
|
||||
bool m_bSynchro;
|
||||
|
||||
//! Parameter list.
|
||||
CBotDefParam* m_Param;
|
||||
//! The instruction block.
|
||||
CBotInstr* m_Block;
|
||||
CBotFunction* m_next;
|
||||
//! If returns CBotTypClass.
|
||||
CBotToken m_retToken;
|
||||
//! Complete type of the result.
|
||||
CBotTypResult m_retTyp;
|
||||
//! Public function.
|
||||
bool m_bPublic;
|
||||
//! Extern function.
|
||||
bool m_bExtern;
|
||||
//! Name of the class we derive.
|
||||
CBotString m_MasterClass;
|
||||
CBotProgram* m_pProg;
|
||||
//! For the position of the word "extern".
|
||||
CBotToken m_extern;
|
||||
CBotToken m_openpar;
|
||||
CBotToken m_closepar;
|
||||
CBotToken m_openblk;
|
||||
CBotToken m_closeblk;
|
||||
|
||||
//! Management of list of (static) public functions.
|
||||
static CBotFunction* m_listPublic;
|
||||
|
||||
friend class CBotProgram;
|
||||
friend class CBotClass;
|
||||
friend class CBotCStack;
|
||||
|
||||
};
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotIString.h"
|
||||
#include "CBot/CBotInstr/CBotLeftExprVar.h"
|
||||
#include "CBot/CBotInstr/CBotTwoOpExpr.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotIString::CBotIString()
|
||||
{
|
||||
m_var =
|
||||
m_expr = nullptr;
|
||||
name = "CBotIString";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotIString::~CBotIString()
|
||||
{
|
||||
delete m_var;
|
||||
delete m_expr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotIString::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, bool noskip)
|
||||
{
|
||||
CBotToken* pp = cont ? nullptr : p;
|
||||
|
||||
if (!cont && !IsOfType(p, ID_STRING)) return nullptr;
|
||||
|
||||
CBotIString* inst = static_cast<CBotIString*>(CompileArray(p, pStack, CBotTypString));
|
||||
if (inst != nullptr || !pStack->IsOk()) return inst;
|
||||
|
||||
CBotCStack* pStk = pStack->TokenStack(pp);
|
||||
|
||||
inst = new CBotIString();
|
||||
|
||||
inst->m_expr = nullptr;
|
||||
|
||||
CBotToken* vartoken = p;
|
||||
inst->SetToken(vartoken);
|
||||
|
||||
if (nullptr != (inst->m_var = CBotLeftExprVar::Compile( p, pStk )))
|
||||
{
|
||||
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_typevar = CBotTypString;
|
||||
if (pStk->CheckVarLocal(vartoken))
|
||||
{
|
||||
pStk->SetStartError(vartoken->GetStart());
|
||||
pStk->SetError(TX_REDEFVAR, vartoken->GetEnd());
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_ASS))
|
||||
{
|
||||
if (nullptr == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
/* if (!pStk->GetTypResult().Eq(CBotTypString)) // type compatible ?
|
||||
{
|
||||
pStk->SetError(TX_BADTYPE, p->GetStart());
|
||||
goto error;
|
||||
}*/
|
||||
}
|
||||
|
||||
CBotVar* var = CBotVar::Create(vartoken, CBotTypString);
|
||||
var->SetInit(inst->m_expr != nullptr ? CBotVar::InitType::DEF : CBotVar::InitType::UNDEF);
|
||||
var->SetUniqNum(
|
||||
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_nIdent = CBotVar::NextUniqNum());
|
||||
pStack->AddVar(var);
|
||||
|
||||
if (IsOfType(p, ID_COMMA))
|
||||
{
|
||||
if (nullptr != ( inst->m_next2b = CBotIString::Compile(p, pStk, true, noskip)))
|
||||
{
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
}
|
||||
|
||||
if (noskip || IsOfType(p, ID_SEP))
|
||||
{
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
pStk->SetError(TX_ENDOF, p->GetStart());
|
||||
}
|
||||
|
||||
error:
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotIString::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
|
||||
if ( pile->GetState()==0)
|
||||
{
|
||||
if (m_expr && !m_expr->Execute(pile)) return false;
|
||||
m_var->Execute(pile);
|
||||
|
||||
if (!pile->SetState(1)) return false;
|
||||
}
|
||||
|
||||
if (pile->IfStep()) return false;
|
||||
|
||||
if ( m_next2b &&
|
||||
!m_next2b->Execute(pile)) return false;
|
||||
|
||||
return pj->Return(pile);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotIString::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
CBotStack* pile = pj;
|
||||
|
||||
if (bMain)
|
||||
{
|
||||
pile = pj->RestoreStack(this);
|
||||
if (pile == nullptr) return;
|
||||
|
||||
if ( pile->GetState()==0)
|
||||
{
|
||||
if (m_expr) m_expr->RestoreState(pile, bMain);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_var->RestoreState(pile, bMain);
|
||||
|
||||
if (m_next2b)
|
||||
m_next2b->RestoreState(pile, bMain);
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotIString class Define a string variable eg : int a, b = "salut";
|
||||
*/
|
||||
class CBotIString : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotIString
|
||||
*/
|
||||
CBotIString();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotIString
|
||||
*/
|
||||
~CBotIString();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param cont
|
||||
* \param noskip
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool cont = false, bool noskip=false);
|
||||
|
||||
/*!
|
||||
* \brief Execute Executes the definition of the string variable.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
//! Variable to initialise.
|
||||
CBotInstr* m_var;
|
||||
//! A value to put, if there is.
|
||||
CBotInstr* m_expr;
|
||||
};
|
|
@ -17,12 +17,20 @@
|
|||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// instruction if (condition) operation1 else operation2;
|
||||
// Modules inlcude
|
||||
#include "CBot/CBotInstr/CBotIf.h"
|
||||
#include "CBot/CBotInstr/CBotBlock.h"
|
||||
#include "CBot/CBotInstr/CBotCondition.h"
|
||||
|
||||
#include "CBot.h"
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
// various constructors / destructors
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotIf::CBotIf()
|
||||
{
|
||||
m_Condition =
|
||||
|
@ -31,6 +39,7 @@ CBotIf::CBotIf()
|
|||
name = "CBotIf"; // debug
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotIf::~CBotIf()
|
||||
{
|
||||
delete m_Condition; // frees the condition
|
||||
|
@ -38,9 +47,7 @@ CBotIf::~CBotIf()
|
|||
delete m_BlockElse; // frees the block of instruction2
|
||||
}
|
||||
|
||||
// compilation (static routine)
|
||||
// called when the token "if" has been found
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotIf::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotToken* pp = p; // preserves at the ^ token (starting instruction)
|
||||
|
@ -86,9 +93,7 @@ CBotInstr* CBotIf::Compile(CBotToken* &p, CBotCStack* pStack)
|
|||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
|
||||
// execution of the instruction
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotIf :: Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this); // adds an item to the stack
|
||||
|
@ -131,7 +136,7 @@ bool CBotIf :: Execute(CBotStack* &pj)
|
|||
return pj->Return(pile);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotIf :: RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if ( !bMain ) return;
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotIf class Instruction if (condition) operation1 else operation2;
|
||||
*/
|
||||
class CBotIf : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotIf
|
||||
*/
|
||||
CBotIf();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotIf
|
||||
*/
|
||||
~CBotIf();
|
||||
|
||||
/*!
|
||||
* \brief Compile Compilation (static routine) called when the token "if"
|
||||
* has been found
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute Execution of the instruction.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
//! Condition
|
||||
CBotInstr* m_Condition;
|
||||
//! Instruction
|
||||
CBotInstr* m_Block;
|
||||
//! Instruction
|
||||
CBotInstr* m_BlockElse;
|
||||
};
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotIndexExpr.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVarArray.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
#include <cassert>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotIndexExpr::CBotIndexExpr()
|
||||
{
|
||||
m_expr = nullptr;
|
||||
name = "CBotIndexExpr";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotIndexExpr::~CBotIndexExpr()
|
||||
{
|
||||
delete m_expr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotIndexExpr::ExecuteVar(CBotVar* &pVar, CBotCStack* &pile)
|
||||
{
|
||||
if (pVar->GetType(1) != CBotTypArrayPointer)
|
||||
assert(0);
|
||||
|
||||
pVar = (static_cast<CBotVarArray*>(pVar))->GetItem(0, false); // at compile time makes the element [0]
|
||||
if (pVar == nullptr)
|
||||
{
|
||||
pile->SetError(TX_OUTARRAY, m_token.GetEnd());
|
||||
return false;
|
||||
}
|
||||
if (m_next3 != nullptr) return m_next3->ExecuteVar(pVar, pile);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotIndexExpr::ExecuteVar(CBotVar* &pVar, CBotStack* &pile, CBotToken* prevToken, bool bStep, bool bExtend)
|
||||
{
|
||||
CBotStack* pj = pile;
|
||||
|
||||
if (pVar->GetType(1) != CBotTypArrayPointer)
|
||||
assert(0);
|
||||
|
||||
pile = pile->AddStack();
|
||||
|
||||
if (pile->GetState() == 0)
|
||||
{
|
||||
if (!m_expr->Execute(pile)) return false;
|
||||
pile->IncState();
|
||||
}
|
||||
// handles array
|
||||
|
||||
CBotVar* p = pile->GetVar(); // result on the stack
|
||||
|
||||
if (p == nullptr || p->GetType() > CBotTypDouble)
|
||||
{
|
||||
pile->SetError(TX_BADINDEX, prevToken);
|
||||
return pj->Return(pile);
|
||||
}
|
||||
|
||||
int n = p->GetValInt(); // position in the table
|
||||
|
||||
pVar = (static_cast<CBotVarArray*>(pVar))->GetItem(n, bExtend);
|
||||
if (pVar == nullptr)
|
||||
{
|
||||
pile->SetError(TX_OUTARRAY, prevToken);
|
||||
return pj->Return(pile);
|
||||
}
|
||||
|
||||
pVar->Maj(pile->GetPUser(), true);
|
||||
|
||||
if ( m_next3 != nullptr &&
|
||||
!m_next3->ExecuteVar(pVar, pile, prevToken, bStep, bExtend) ) return false;
|
||||
|
||||
// does not release the stack
|
||||
// to avoid recalculation of the index twice where appropriate
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotIndexExpr::RestoreStateVar(CBotStack* &pile, bool bMain)
|
||||
{
|
||||
pile = pile->RestoreStack();
|
||||
if (pile == nullptr) return;
|
||||
|
||||
if (bMain && pile->GetState() == 0)
|
||||
{
|
||||
m_expr->RestoreState(pile, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_next3)
|
||||
m_next3->RestoreStateVar(pile, bMain);
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
/*!
|
||||
* \brief The CBotIndexExpr class Index management for arrays
|
||||
* eg :
|
||||
* - array [ expression ]
|
||||
*/
|
||||
class CBotIndexExpr : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotIndexExpr
|
||||
*/
|
||||
CBotIndexExpr();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotIndexExpr
|
||||
*/
|
||||
~CBotIndexExpr();
|
||||
|
||||
/*!
|
||||
* \brief ExecuteVar Finds a field from the instance at compile time.
|
||||
* \param pVar
|
||||
* \param pile
|
||||
* \return
|
||||
*/
|
||||
bool ExecuteVar(CBotVar* &pVar, CBotCStack* &pile) override;
|
||||
|
||||
/*!
|
||||
* \brief ExecuteVar Warning, changes the pointer to the stack intentionally
|
||||
* place the index calculated on the additional stack.
|
||||
* \param pVar
|
||||
* \param pile
|
||||
* \param prevToken
|
||||
* \param bStep
|
||||
* \param bExtend
|
||||
* \return
|
||||
*/
|
||||
bool ExecuteVar(CBotVar* &pVar, CBotStack* &pile, CBotToken* prevToken, bool bStep, bool bExtend) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreStateVar
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreStateVar(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
|
||||
private:
|
||||
//! Expression for calculating the index.
|
||||
CBotInstr* m_expr;
|
||||
friend class CBotLeftExpr;
|
||||
friend class CBotExprVar;
|
||||
};
|
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstArray.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotLeftExprVar.h"
|
||||
#include "CBot/CBotInstr/CBotExpression.h"
|
||||
#include "CBot/CBotInstr/CBotListArray.h"
|
||||
#include "CBot/CBotInstr/CBotEmpty.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotDefines.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstArray::CBotInstArray()
|
||||
{
|
||||
m_var = nullptr;
|
||||
m_listass = nullptr;
|
||||
name = "CBotInstArray";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstArray::~CBotInstArray()
|
||||
{
|
||||
delete m_var;
|
||||
delete m_listass;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotInstArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResult type)
|
||||
{
|
||||
CBotCStack* pStk = pStack->TokenStack(p);
|
||||
|
||||
CBotInstArray* inst = new CBotInstArray();
|
||||
|
||||
CBotToken* vartoken = p;
|
||||
inst->SetToken(vartoken);
|
||||
|
||||
// determinse the expression is valid for the item on the left side
|
||||
if (nullptr != (inst->m_var = CBotLeftExprVar::Compile( p, pStk )))
|
||||
{
|
||||
if (pStk->CheckVarLocal(vartoken)) // redefinition of the variable?
|
||||
{
|
||||
pStk->SetError(TX_REDEFVAR, vartoken);
|
||||
goto error;
|
||||
}
|
||||
|
||||
CBotInstr* i;
|
||||
while (IsOfType(p, ID_OPBRK))
|
||||
{
|
||||
if (p->GetType() != ID_CLBRK)
|
||||
i = CBotExpression::Compile(p, pStk); // expression for the value
|
||||
else
|
||||
i = new CBotEmpty(); // if no special formula
|
||||
|
||||
inst->AddNext3b(i); // construct a list
|
||||
type = CBotTypResult(CBotTypArrayPointer, type);
|
||||
|
||||
if (!pStk->IsOk() || !IsOfType(p, ID_CLBRK ))
|
||||
{
|
||||
pStk->SetError(TX_CLBRK, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
CBotVar* var = CBotVar::Create(vartoken, type); // create an instance
|
||||
inst->m_typevar = type;
|
||||
|
||||
var->SetUniqNum(
|
||||
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_nIdent = CBotVar::NextUniqNum());
|
||||
pStack->AddVar(var); // place it on the stack
|
||||
|
||||
if (IsOfType(p, ID_ASS)) // with an assignment
|
||||
{
|
||||
inst->m_listass = CBotListArray::Compile(p, pStk, type.GetTypElem());
|
||||
}
|
||||
|
||||
if (pStk->IsOk()) return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
error:
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotInstArray::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile1 = pj->AddStack(this);
|
||||
|
||||
CBotStack* pile = pile1;
|
||||
|
||||
if (pile1->GetState() == 0)
|
||||
{
|
||||
// seek the maximum dimension of the table
|
||||
CBotInstr* p = GetNext3b(); // the different formulas
|
||||
int nb = 0;
|
||||
|
||||
while (p != nullptr)
|
||||
{
|
||||
pile = pile->AddStack(); // little room to work
|
||||
nb++;
|
||||
if (pile->GetState() == 0)
|
||||
{
|
||||
if (!p->Execute(pile)) return false; // size calculation //interrupted?
|
||||
pile->IncState();
|
||||
}
|
||||
p = p->GetNext3b();
|
||||
}
|
||||
|
||||
p = GetNext3b();
|
||||
pile = pile1; // returns to the stack
|
||||
int n = 0;
|
||||
int max[100];
|
||||
|
||||
while (p != nullptr)
|
||||
{
|
||||
pile = pile->AddStack();
|
||||
CBotVar* v = pile->GetVar(); // result
|
||||
max[n] = v->GetValInt(); // value
|
||||
if (max[n]>MAXARRAYSIZE)
|
||||
{
|
||||
pile->SetError(TX_OUTARRAY, &m_token);
|
||||
return pj->Return (pile);
|
||||
}
|
||||
n++;
|
||||
p = p->GetNext3b();
|
||||
}
|
||||
while (n<100) max[n++] = 0;
|
||||
|
||||
m_typevar.SetArray(max); // store the limitations
|
||||
|
||||
// create simply a nullptr pointer
|
||||
CBotVar* var = CBotVar::Create(m_var->GetToken(), m_typevar);
|
||||
var->SetPointer(nullptr);
|
||||
var->SetUniqNum((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent);
|
||||
pj->AddVar(var);
|
||||
|
||||
#if STACKMEM
|
||||
pile1->AddStack()->Delete();
|
||||
#else
|
||||
delete pile1->AddStack(); // need more indices
|
||||
#endif
|
||||
pile1->IncState();
|
||||
}
|
||||
|
||||
if (pile1->GetState() == 1)
|
||||
{
|
||||
if (m_listass != nullptr) // there is the assignment for this table
|
||||
{
|
||||
CBotVar* pVar = pj->FindVar((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent);
|
||||
|
||||
if (!m_listass->Execute(pile1, pVar)) return false;
|
||||
}
|
||||
pile1->IncState();
|
||||
}
|
||||
|
||||
if (pile1->IfStep()) return false;
|
||||
|
||||
if ( m_next2b &&
|
||||
!m_next2b->Execute(pile1 )) return false;
|
||||
|
||||
return pj->Return(pile1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotInstArray::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
CBotStack* pile1 = pj;
|
||||
|
||||
CBotVar* var = pj->FindVar(m_var->GetToken()->GetString());
|
||||
if (var != nullptr) var->SetUniqNum((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent);
|
||||
|
||||
if (bMain)
|
||||
{
|
||||
pile1 = pj->RestoreStack(this);
|
||||
CBotStack* pile = pile1;
|
||||
if (pile == nullptr) return;
|
||||
|
||||
if (pile1->GetState() == 0)
|
||||
{
|
||||
// seek the maximum dimension of the table
|
||||
CBotInstr* p = GetNext3b();
|
||||
|
||||
while (p != nullptr)
|
||||
{
|
||||
pile = pile->RestoreStack();
|
||||
if (pile == nullptr) return;
|
||||
if (pile->GetState() == 0)
|
||||
{
|
||||
p->RestoreState(pile, bMain);
|
||||
return;
|
||||
}
|
||||
p = p->GetNext3b();
|
||||
}
|
||||
}
|
||||
if (pile1->GetState() == 1 && m_listass != nullptr)
|
||||
{
|
||||
m_listass->RestoreState(pile1, bMain);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (m_next2b ) m_next2b->RestoreState( pile1, bMain);
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotInstArray class Definition of an array.
|
||||
* Defining an array of any type
|
||||
* int a[12];
|
||||
* point x[];
|
||||
*/
|
||||
class CBotInstArray : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotInstArray
|
||||
*/
|
||||
CBotInstArray();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotInstArray
|
||||
*/
|
||||
~CBotInstArray();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param type
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResult type);
|
||||
|
||||
/*!
|
||||
* \brief Execute Executes the definition of an array.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
|
||||
//! The variables to initialize.
|
||||
CBotInstr* m_var;
|
||||
//! List of assignments for array.
|
||||
CBotInstr* m_listass;
|
||||
//! Type of elements.
|
||||
CBotTypResult m_typevar;
|
||||
|
||||
};
|
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotFor.h"
|
||||
#include "CBot/CBotInstr/CBotDo.h"
|
||||
#include "CBot/CBotInstr/CBotBreak.h"
|
||||
#include "CBot/CBotInstr/CBotSwitch.h"
|
||||
#include "CBot/CBotInstr/CBotTry.h"
|
||||
#include "CBot/CBotInstr/CBotThrow.h"
|
||||
#include "CBot/CBotInstr/CBotInt.h"
|
||||
#include "CBot/CBotInstr/CBotFloat.h"
|
||||
#include "CBot/CBotInstr/CBotWhile.h"
|
||||
#include "CBot/CBotInstr/CBotIString.h"
|
||||
#include "CBot/CBotInstr/CBotBoolean.h"
|
||||
#include "CBot/CBotInstr/CBotIf.h"
|
||||
#include "CBot/CBotInstr/CBotReturn.h"
|
||||
#include "CBot/CBotInstr/CBotClassInst.h"
|
||||
#include "CBot/CBotInstr/CBotExpression.h"
|
||||
#include "CBot/CBotInstr/CBotInstArray.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
#include "CBot/CBotClass.h"
|
||||
#include "CBot/CBotStack.h"
|
||||
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
#include <cassert>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CBotInstr::m_LoopLvl = 0;
|
||||
CBotStringArray CBotInstr::m_labelLvl = CBotStringArray();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr::CBotInstr()
|
||||
{
|
||||
name = "CBotInstr";
|
||||
m_next = nullptr;
|
||||
m_next2b = nullptr;
|
||||
m_next3 = nullptr;
|
||||
m_next3b = nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr::~CBotInstr()
|
||||
{
|
||||
delete m_next;
|
||||
delete m_next2b;
|
||||
delete m_next3;
|
||||
delete m_next3b;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotInstr::IncLvl(CBotString& label)
|
||||
{
|
||||
m_labelLvl.SetSize(m_LoopLvl+1);
|
||||
m_labelLvl[m_LoopLvl] = label;
|
||||
m_LoopLvl++;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotInstr::IncLvl()
|
||||
{
|
||||
m_labelLvl.SetSize(m_LoopLvl+1);
|
||||
m_labelLvl[m_LoopLvl] = "#SWITCH";
|
||||
m_LoopLvl++;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotInstr::DecLvl()
|
||||
{
|
||||
m_LoopLvl--;
|
||||
m_labelLvl[m_LoopLvl].Empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotInstr::ChkLvl(const CBotString& label, int type)
|
||||
{
|
||||
int i = m_LoopLvl;
|
||||
while (--i>=0)
|
||||
{
|
||||
if ( type == ID_CONTINUE && m_labelLvl[i] == "#SWITCH") continue;
|
||||
if (label.IsEmpty()) return true;
|
||||
if (m_labelLvl[i] == label) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotInstr::IsOfClass(CBotString n)
|
||||
{
|
||||
return name == n;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotInstr::SetToken(CBotToken* p)
|
||||
{
|
||||
m_token = *p;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CBotInstr::GetTokenType()
|
||||
{
|
||||
return m_token.GetType();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotToken* CBotInstr::GetToken()
|
||||
{
|
||||
return &m_token;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotInstr::AddNext(CBotInstr* n)
|
||||
{
|
||||
CBotInstr* p = this;
|
||||
while (p->m_next != nullptr) p = p->m_next;
|
||||
p->m_next = n;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotInstr::AddNext3(CBotInstr* n)
|
||||
{
|
||||
CBotInstr* p = this;
|
||||
while (p->m_next3 != nullptr) p = p->m_next3;
|
||||
p->m_next3 = n;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotInstr::AddNext3b(CBotInstr* n)
|
||||
{
|
||||
CBotInstr* p = this;
|
||||
while (p->m_next3b != nullptr) p = p->m_next3b;
|
||||
p->m_next3b = n;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotInstr::GetNext()
|
||||
{
|
||||
return m_next;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotInstr::GetNext3()
|
||||
{
|
||||
return m_next3;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotInstr::GetNext3b()
|
||||
{
|
||||
return m_next3b;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotInstr::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotToken* pp = p;
|
||||
|
||||
if (p == nullptr) return nullptr;
|
||||
|
||||
int type = p->GetType(); // what is the next token
|
||||
|
||||
// is it a lable?
|
||||
if (IsOfType(pp, TokenTypVar) &&
|
||||
IsOfType(pp, ID_DOTS))
|
||||
{
|
||||
type = pp->GetType();
|
||||
// these instructions accept only lable
|
||||
if (!IsOfTypeList(pp, ID_WHILE, ID_FOR, ID_DO, 0))
|
||||
{
|
||||
pStack->SetError(TX_LABEL, pp->GetStart());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// call routine corresponding to the compilation token found
|
||||
switch (type)
|
||||
{
|
||||
case ID_WHILE:
|
||||
return CBotWhile::Compile(p, pStack);
|
||||
|
||||
case ID_FOR:
|
||||
return CBotFor::Compile(p, pStack);
|
||||
|
||||
case ID_DO:
|
||||
return CBotDo::Compile(p, pStack);
|
||||
|
||||
case ID_BREAK:
|
||||
case ID_CONTINUE:
|
||||
return CBotBreak::Compile(p, pStack);
|
||||
|
||||
case ID_SWITCH:
|
||||
return CBotSwitch::Compile(p, pStack);
|
||||
|
||||
case ID_TRY:
|
||||
return CBotTry::Compile(p, pStack);
|
||||
|
||||
case ID_THROW:
|
||||
return CBotThrow::Compile(p, pStack);
|
||||
|
||||
case ID_INT:
|
||||
return CBotInt::Compile(p, pStack);
|
||||
|
||||
case ID_FLOAT:
|
||||
return CBotFloat::Compile(p, pStack);
|
||||
|
||||
case ID_STRING:
|
||||
return CBotIString::Compile(p, pStack);
|
||||
|
||||
case ID_BOOLEAN:
|
||||
case ID_BOOL:
|
||||
return CBotBoolean::Compile(p, pStack);
|
||||
|
||||
case ID_IF:
|
||||
return CBotIf::Compile(p, pStack);
|
||||
|
||||
case ID_RETURN:
|
||||
return CBotReturn::Compile(p, pStack);
|
||||
|
||||
case ID_ELSE:
|
||||
pStack->SetStartError(p->GetStart());
|
||||
pStack->SetError(TX_ELSEWITHOUTIF, p->GetEnd());
|
||||
return nullptr;
|
||||
|
||||
case ID_CASE:
|
||||
pStack->SetStartError(p->GetStart());
|
||||
pStack->SetError(TX_OUTCASE, p->GetEnd());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
pStack->SetStartError(p->GetStart());
|
||||
|
||||
// should not be a reserved word DefineNum
|
||||
if (p->GetType() == TokenTypDef)
|
||||
{
|
||||
pStack->SetError(TX_RESERVED, p);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// this might be an instance of class definnition
|
||||
CBotToken* ppp = p;
|
||||
if (IsOfType(ppp, TokenTypVar))
|
||||
{
|
||||
if (CBotClass::Find(p) != nullptr)
|
||||
{
|
||||
// yes, compiles the declaration of the instance
|
||||
return CBotClassInst::Compile(p, pStack);
|
||||
}
|
||||
}
|
||||
|
||||
// this can be an arythmetic instruction
|
||||
CBotInstr* inst = CBotExpression::Compile(p, pStack);
|
||||
if (IsOfType(p, ID_SEP))
|
||||
{
|
||||
return inst;
|
||||
}
|
||||
pStack->SetError(TX_ENDOF, p->GetStart());
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotInstr::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotString ClassManquante = name;
|
||||
assert(0); // should never go through this routine
|
||||
// but use the routines of the subclasses
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotInstr::Execute(CBotStack* &pj, CBotVar* pVar)
|
||||
{
|
||||
if (!Execute(pj)) return false;
|
||||
pVar->SetVal(pj->GetVar());
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotInstr::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
CBotString ClassManquante = name;
|
||||
assert(0); // should never go through this routine
|
||||
// but use the routines of the subclasses
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotInstr::ExecuteVar(CBotVar* &pVar, CBotCStack* &pile)
|
||||
{
|
||||
assert(0); // dad do not know, see the girls
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotInstr::ExecuteVar(CBotVar* &pVar, CBotStack* &pile, CBotToken* prevToken, bool bStep, bool bExtend)
|
||||
{
|
||||
assert(0); // dad do not know, see the girls
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotInstr::RestoreStateVar(CBotStack* &pile, bool bMain)
|
||||
{
|
||||
assert(0); // dad do not know, see the girls
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotInstr::CompCase(CBotStack* &pj, int val)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotInstr::CompileArray(CBotToken* &p, CBotCStack* pStack, CBotTypResult type, bool first)
|
||||
{
|
||||
if (IsOfType(p, ID_OPBRK))
|
||||
{
|
||||
if (!IsOfType(p, ID_CLBRK))
|
||||
{
|
||||
pStack->SetError(TX_CLBRK, p->GetStart());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CBotInstr* inst = CompileArray(p, pStack, CBotTypResult(CBotTypArrayPointer, type), false);
|
||||
if (inst != nullptr || !pStack->IsOk()) return inst;
|
||||
}
|
||||
|
||||
// compiles an array declaration
|
||||
if (first) return nullptr ;
|
||||
|
||||
CBotInstr* inst = CBotInstArray::Compile(p, pStack, type);
|
||||
if (inst == nullptr) return nullptr;
|
||||
|
||||
if (IsOfType(p, ID_COMMA)) // several definitions
|
||||
{
|
||||
if (nullptr != ( inst->m_next2b = CBotInstArray::CompileArray(p, pStack, type, false))) // compiles next one
|
||||
{
|
||||
return inst;
|
||||
}
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_SEP)) // end of instruction
|
||||
{
|
||||
return inst;
|
||||
}
|
||||
|
||||
delete inst;
|
||||
pStack->SetError(TX_ENDOF, p->GetStart());
|
||||
return nullptr;
|
||||
}
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* 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 "CBot/CBotToken.h"
|
||||
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
/*
|
||||
for example, the following program
|
||||
int x[]; x[1] = 4;
|
||||
int y[x[1]][10], z;
|
||||
is generated
|
||||
CBotInstrArray
|
||||
m_next3b-> CBotEmpty
|
||||
m_next->
|
||||
CBotExpression ....
|
||||
m_next->
|
||||
CBotInstrArray
|
||||
m_next3b-> CBotExpression ('x') ( m_next3-> CBotIndexExpr ('1') )
|
||||
m_next3b-> CBotExpression ('10')
|
||||
m_next2-> 'z'
|
||||
m_next->...
|
||||
|
||||
*/
|
||||
/*!
|
||||
* \brief The CBotInstr class Class defining an instruction.
|
||||
*/
|
||||
class CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotInstr
|
||||
*/
|
||||
CBotInstr();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotInstr
|
||||
*/
|
||||
virtual ~CBotInstr();
|
||||
|
||||
/*!
|
||||
* \brief Compile Compile an instruction which can be while, do, try,
|
||||
* throw, if, for, switch, break, continue, return, int, float, boolean,
|
||||
* string, declaration of an instance of a class, arbitrary expression.
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p,
|
||||
CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief CompileArray
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param type
|
||||
* \param first
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* CompileArray(CBotToken* &p,
|
||||
CBotCStack* pStack,
|
||||
CBotTypResult type,
|
||||
bool first = true);
|
||||
|
||||
/*!
|
||||
* \brief Execute
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
virtual bool Execute(CBotStack* &pj);
|
||||
|
||||
/*!
|
||||
* \brief Execute
|
||||
* \param pj
|
||||
* \param pVar
|
||||
* \return
|
||||
*/
|
||||
virtual bool Execute(CBotStack* &pj,
|
||||
CBotVar* pVar);
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
virtual void RestoreState(CBotStack* &pj,
|
||||
bool bMain);
|
||||
|
||||
/*!
|
||||
* \brief ExecuteVar
|
||||
* \param pVar
|
||||
* \param pile
|
||||
* \return
|
||||
*/
|
||||
virtual bool ExecuteVar(CBotVar* &pVar,
|
||||
CBotCStack* &pile);
|
||||
|
||||
/*!
|
||||
* \brief ExecuteVar
|
||||
* \param pVar
|
||||
* \param pile
|
||||
* \param prevToken
|
||||
* \param bStep
|
||||
* \param bExtend
|
||||
* \return
|
||||
*/
|
||||
virtual bool ExecuteVar(CBotVar* &pVar,
|
||||
CBotStack* &pile,
|
||||
CBotToken* prevToken,
|
||||
bool bStep,
|
||||
bool bExtend);
|
||||
|
||||
/*!
|
||||
* \brief RestoreStateVar
|
||||
* \param pile
|
||||
* \param bMain
|
||||
*/
|
||||
virtual void RestoreStateVar(CBotStack* &pile,
|
||||
bool bMain);
|
||||
|
||||
/*!
|
||||
* \brief CompCase This routine is defined only for the subclass CBotCase
|
||||
* this allows to make the call on all instructions CompCase to see if it's
|
||||
* a case to the desired value..
|
||||
* \param pj
|
||||
* \param val
|
||||
* \return
|
||||
*/
|
||||
virtual bool CompCase(CBotStack* &pj,
|
||||
int val);
|
||||
|
||||
/*!
|
||||
* \brief SetToken Set the token corresponding to the instruction.
|
||||
* \param p
|
||||
*/
|
||||
void SetToken(CBotToken* p);
|
||||
|
||||
/*!
|
||||
* \brief GetTokenType Return the type of the token assicated with the
|
||||
* instruction.
|
||||
* \return
|
||||
*/
|
||||
int GetTokenType();
|
||||
|
||||
/*!
|
||||
* \brief GetToken Return associated token.
|
||||
* \return
|
||||
*/
|
||||
CBotToken* GetToken();
|
||||
|
||||
/*!
|
||||
* \brief AddNext Adds the statement following the other.
|
||||
* \param n
|
||||
*/
|
||||
void AddNext(CBotInstr* n);
|
||||
|
||||
/*!
|
||||
* \brief GetNext Returns next statement.
|
||||
* \return
|
||||
*/
|
||||
CBotInstr* GetNext();
|
||||
|
||||
/*!
|
||||
* \brief AddNext3
|
||||
* \param n
|
||||
*/
|
||||
void AddNext3(CBotInstr* n);
|
||||
|
||||
/*!
|
||||
* \brief GetNext3
|
||||
* \return
|
||||
*/
|
||||
CBotInstr* GetNext3();
|
||||
|
||||
/*!
|
||||
* \brief AddNext3b
|
||||
* \param n
|
||||
*/
|
||||
void AddNext3b(CBotInstr* n);
|
||||
|
||||
/*!
|
||||
* \brief GetNext3b
|
||||
* \return
|
||||
*/
|
||||
CBotInstr* GetNext3b();
|
||||
|
||||
/*!
|
||||
* \brief IncLvl Adds a level with a label.
|
||||
* \param label
|
||||
*/
|
||||
static void IncLvl(CBotString& label);
|
||||
|
||||
/*!
|
||||
* \brief IncLvl Adds a level (switch statement).
|
||||
*/
|
||||
static void IncLvl();
|
||||
|
||||
/*!
|
||||
* \brief DecLvl Free a level.
|
||||
*/
|
||||
static void DecLvl();
|
||||
|
||||
/*!
|
||||
* \brief ChkLvl Control validity of break and continue.
|
||||
* \param label
|
||||
* \param type
|
||||
* \return
|
||||
*/
|
||||
static bool ChkLvl(const CBotString& label, int type);
|
||||
|
||||
/*!
|
||||
* \brief IsOfClass
|
||||
* \param name
|
||||
* \return
|
||||
*/
|
||||
bool IsOfClass(CBotString name);
|
||||
|
||||
protected:
|
||||
|
||||
//! Keeps the token.
|
||||
CBotToken m_token;
|
||||
//! Debug.
|
||||
CBotString name;
|
||||
//! Linked command.
|
||||
CBotInstr* m_next;
|
||||
//! Second list definition chain.
|
||||
CBotInstr* m_next2b;
|
||||
//! Third list for indices and fields.
|
||||
CBotInstr* m_next3;
|
||||
//! Necessary for reporting tables.
|
||||
CBotInstr* m_next3b;
|
||||
|
||||
//! Counter of nested loops, to determine the break and continue valid.
|
||||
static int m_LoopLvl;
|
||||
friend class CBotClassInst;
|
||||
friend class CBotInt;
|
||||
friend class CBotListArray;
|
||||
|
||||
private:
|
||||
//! List of labels used.
|
||||
static CBotStringArray m_labelLvl;
|
||||
};
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* 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 "CBotInstrCall.h"
|
||||
#include "CBot/CBotInstr/CBotExpression.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstrCall::CBotInstrCall()
|
||||
{
|
||||
m_Parameters = nullptr;
|
||||
m_nFuncIdent = 0;
|
||||
name = "CBotInstrCall";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstrCall::~CBotInstrCall()
|
||||
{
|
||||
delete m_Parameters;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotInstrCall::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotVar* ppVars[1000];
|
||||
|
||||
int i = 0;
|
||||
|
||||
CBotToken* pp = p;
|
||||
p = p->GetNext();
|
||||
|
||||
pStack->SetStartError(p->GetStart());
|
||||
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->GetStart();
|
||||
pile = pile->TokenStack(); // keeps the results on the stack
|
||||
|
||||
CBotInstr* param = CBotExpression::Compile(p, pile);
|
||||
end = p->GetStart();
|
||||
if ( inst->m_Parameters == nullptr ) inst->m_Parameters = param;
|
||||
else inst->m_Parameters->AddNext(param); // constructs the list
|
||||
|
||||
if ( !pile->IsOk() )
|
||||
{
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pile);
|
||||
}
|
||||
|
||||
if ( param != nullptr )
|
||||
{
|
||||
if ( pile->GetTypResult().Eq(99) )
|
||||
{
|
||||
delete pStack->TokenStack();
|
||||
pStack->SetError(TX_VOID, p->GetStart());
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
ppVars[i] = pile->GetVar();
|
||||
ppVars[i]->GetToken()->SetPos(start, end);
|
||||
i++;
|
||||
|
||||
if (IsOfType(p, ID_COMMA)) continue; // skips the comma
|
||||
if (IsOfType(p, ID_CLOSEPAR)) break;
|
||||
}
|
||||
|
||||
pStack->SetError(TX_CLOSEPAR, p->GetStart());
|
||||
delete pStack->TokenStack();
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
ppVars[i] = nullptr;
|
||||
|
||||
// the routine is known?
|
||||
// CBotClass* pClass = nullptr;
|
||||
inst->m_typRes = pStack->CompileCall(pp, ppVars, inst->m_nFuncIdent);
|
||||
if ( inst->m_typRes.GetType() >= 20 )
|
||||
{
|
||||
// if (pVar2!=nullptr) pp = pVar2->RetToken();
|
||||
pStack->SetError( inst->m_typRes.GetType(), pp );
|
||||
delete pStack->TokenStack();
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
delete pStack->TokenStack();
|
||||
if ( inst->m_typRes.GetType() > 0 )
|
||||
{
|
||||
CBotVar* pRes = CBotVar::Create("", inst->m_typRes);
|
||||
pStack->SetVar(pRes); // for knowing the type of the result
|
||||
}
|
||||
else pStack->SetVar(nullptr); // routine returns void
|
||||
|
||||
return inst;
|
||||
}
|
||||
p = pp;
|
||||
delete pStack->TokenStack();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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 != nullptr) while ( true )
|
||||
{
|
||||
pile = pile->AddStack(); // place on the stack for the results
|
||||
if ( pile->GetState() == 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->GetVar();
|
||||
p = p->GetNext();
|
||||
if ( p == nullptr) break;
|
||||
}
|
||||
ppVars[i] = nullptr;
|
||||
|
||||
CBotStack* pile2 = pile->AddStack();
|
||||
if ( pile2->IfStep() ) return false;
|
||||
|
||||
if ( !pile2->ExecuteCall(m_nFuncIdent, GetToken(), 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 == nullptr ) 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 != nullptr) while ( true )
|
||||
{
|
||||
pile = pile->RestoreStack(); // place on the stack for the results
|
||||
if ( pile == nullptr ) return;
|
||||
if ( pile->GetState() == 0 )
|
||||
{
|
||||
p->RestoreState(pile, bMain); // interrupt here!
|
||||
return;
|
||||
}
|
||||
ppVars[i++] = pile->GetVar(); // constructs the list of parameters
|
||||
p = p->GetNext();
|
||||
if ( p == nullptr) break;
|
||||
}
|
||||
ppVars[i] = nullptr;
|
||||
|
||||
CBotStack* pile2 = pile->RestoreStack();
|
||||
if ( pile2 == nullptr ) return;
|
||||
|
||||
pile2->RestoreCall(m_nFuncIdent, GetToken(), ppVars);
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotInstrCall class Calls of these functions.
|
||||
*/
|
||||
class CBotInstrCall : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotInstrCall
|
||||
*/
|
||||
CBotInstrCall();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotInstrCall
|
||||
*/
|
||||
~CBotInstrCall();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
//! The parameters to be evaluated.
|
||||
CBotInstr* m_Parameters;
|
||||
//! Complete type of the result.
|
||||
CBotTypResult m_typRes;
|
||||
//! Id of a function.
|
||||
long m_nFuncIdent;
|
||||
};
|
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstrMethode.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotInstrUtils.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
#include "CBot/CBotClass.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstrMethode::CBotInstrMethode()
|
||||
{
|
||||
m_Parameters = nullptr;
|
||||
m_MethodeIdent = 0;
|
||||
name = "CBotInstrMethode";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstrMethode::~CBotInstrMethode()
|
||||
{
|
||||
delete m_Parameters;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotInstrMethode::Compile(CBotToken* &p, CBotCStack* pStack, CBotVar* var)
|
||||
{
|
||||
CBotInstrMethode* inst = new CBotInstrMethode();
|
||||
inst->SetToken(p); // corresponding token
|
||||
|
||||
if (nullptr != var)
|
||||
{
|
||||
CBotToken* pp = p;
|
||||
p = p->GetNext();
|
||||
|
||||
if (p->GetType() == ID_OPENPAR)
|
||||
{
|
||||
inst->m_NomMethod = pp->GetString();
|
||||
|
||||
// compiles the list of parameters
|
||||
CBotVar* ppVars[1000];
|
||||
inst->m_Parameters = CompileParams(p, pStack, ppVars);
|
||||
|
||||
if (pStack->IsOk())
|
||||
{
|
||||
CBotClass* pClass = var->GetClass(); // pointer to the class
|
||||
inst->m_ClassName = pClass->GetName(); // name of the class
|
||||
CBotTypResult r = pClass->CompileMethode(inst->m_NomMethod, var, ppVars,
|
||||
pStack, inst->m_MethodeIdent);
|
||||
delete pStack->TokenStack(); // release parameters on the stack
|
||||
inst->m_typRes = r;
|
||||
|
||||
if (inst->m_typRes.GetType() > 20)
|
||||
{
|
||||
pStack->SetError(inst->m_typRes.GetType(), pp);
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
// put the result on the stack to have something
|
||||
if (inst->m_typRes.GetType() > 0)
|
||||
{
|
||||
CBotVar* pResult = CBotVar::Create("", inst->m_typRes);
|
||||
if (inst->m_typRes.Eq(CBotTypClass))
|
||||
{
|
||||
pResult->SetClass(inst->m_typRes.GetClass());
|
||||
}
|
||||
pStack->SetVar(pResult);
|
||||
}
|
||||
return inst;
|
||||
}
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
pStack->SetError(1234, p);
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotInstrMethode::ExecuteVar(CBotVar* &pVar, CBotStack* &pj, CBotToken* prevToken, bool bStep, bool bExtend)
|
||||
{
|
||||
CBotVar* ppVars[1000];
|
||||
CBotStack* pile1 = pj->AddStack(this, true); // a place for the copy of This
|
||||
|
||||
if (pVar->GetPointer() == nullptr)
|
||||
{
|
||||
pj->SetError(TX_NULLPT, prevToken);
|
||||
}
|
||||
|
||||
if (pile1->IfStep()) return false;
|
||||
|
||||
CBotStack* pile2 = pile1->AddStack(); // for the next parameters
|
||||
|
||||
if ( pile1->GetState() == 0)
|
||||
{
|
||||
CBotVar* pThis = CBotVar::Create(pVar);
|
||||
pThis->Copy(pVar);
|
||||
// this value should be taken before the evaluation parameters
|
||||
// Test.Action (Test = Other);
|
||||
// action must act on the value before test = Other!
|
||||
|
||||
pThis->SetName("this");
|
||||
pThis->SetUniqNum(-2);
|
||||
pile1->AddVar(pThis);
|
||||
pile1->IncState();
|
||||
}
|
||||
int i = 0;
|
||||
|
||||
CBotInstr* p = m_Parameters;
|
||||
// evaluate the parameters
|
||||
// and places the values on the stack
|
||||
// to be interrupted at any time
|
||||
|
||||
if (p != nullptr) while ( true)
|
||||
{
|
||||
if (pile2->GetState() == 0)
|
||||
{
|
||||
if (!p->Execute(pile2)) return false; // interrupted here?
|
||||
if (!pile2->SetState(1)) return false; // special mark to recognize parameters
|
||||
}
|
||||
ppVars[i++] = pile2->GetVar(); // construct the list of pointers
|
||||
pile2 = pile2->AddStack(); // space on the stack for the result
|
||||
p = p->GetNext();
|
||||
if ( p == nullptr) break;
|
||||
}
|
||||
ppVars[i] = nullptr;
|
||||
|
||||
CBotClass* pClass = CBotClass::Find(m_ClassName);
|
||||
CBotVar* pThis = pile1->FindVar(-2);
|
||||
CBotVar* pResult = nullptr;
|
||||
if (m_typRes.GetType() > 0) pResult = CBotVar::Create("", m_typRes);
|
||||
if (m_typRes.Eq(CBotTypClass))
|
||||
{
|
||||
pResult->SetClass(m_typRes.GetClass());
|
||||
}
|
||||
CBotVar* pRes = pResult;
|
||||
|
||||
if ( !pClass->ExecuteMethode(m_MethodeIdent, m_NomMethod,
|
||||
pThis, ppVars,
|
||||
pResult, pile2, GetToken())) return false;
|
||||
if (pRes != pResult) delete pRes;
|
||||
|
||||
pVar = nullptr; // does not return value for this
|
||||
return pj->Return(pile2); // release the entire stack
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotInstrMethode::RestoreStateVar(CBotStack* &pile, bool bMain)
|
||||
{
|
||||
if (!bMain) return;
|
||||
|
||||
CBotVar* ppVars[1000];
|
||||
CBotStack* pile1 = pile->RestoreStack(this); // place for the copy of This
|
||||
if (pile1 == nullptr) return;
|
||||
|
||||
CBotStack* pile2 = pile1->RestoreStack(); // and for the parameters coming
|
||||
if (pile2 == nullptr) return;
|
||||
|
||||
CBotVar* pThis = pile1->FindVar("this");
|
||||
pThis->SetUniqNum(-2);
|
||||
|
||||
int i = 0;
|
||||
|
||||
CBotInstr* p = m_Parameters;
|
||||
// evaluate the parameters
|
||||
// and places the values on the stack
|
||||
// to be interrupted at any time
|
||||
|
||||
if (p != nullptr) while ( true)
|
||||
{
|
||||
if (pile2->GetState() == 0)
|
||||
{
|
||||
p->RestoreState(pile2, true); // interrupted here!
|
||||
return;
|
||||
}
|
||||
ppVars[i++] = pile2->GetVar(); // construct the list of pointers
|
||||
pile2 = pile2->RestoreStack();
|
||||
if (pile2 == nullptr) return;
|
||||
|
||||
p = p->GetNext();
|
||||
if ( p == nullptr) break;
|
||||
}
|
||||
ppVars[i] = nullptr;
|
||||
|
||||
CBotClass* pClass = CBotClass::Find(m_ClassName);
|
||||
// CBotVar* pResult = nullptr;
|
||||
|
||||
// CBotVar* pRes = pResult;
|
||||
|
||||
pClass->RestoreMethode(m_MethodeIdent, m_NomMethod,
|
||||
pThis, ppVars, pile2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotInstrMethode::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotVar* ppVars[1000];
|
||||
CBotStack* pile1 = pj->AddStack(this, true); // place for the copy of This
|
||||
|
||||
if (pile1->IfStep()) return false;
|
||||
|
||||
CBotStack* pile2 = pile1->AddStack(); // and for the parameters coming
|
||||
|
||||
if ( pile1->GetState() == 0)
|
||||
{
|
||||
CBotVar* pThis = pile1->CopyVar(m_token);
|
||||
// this value should be taken before the evaluation parameters
|
||||
// Test.Action (Test = Other);
|
||||
// Action must act on the value before test = Other!
|
||||
pThis->SetName("this");
|
||||
pile1->AddVar(pThis);
|
||||
pile1->IncState();
|
||||
}
|
||||
int i = 0;
|
||||
|
||||
CBotInstr* p = m_Parameters;
|
||||
// evaluate the parameters
|
||||
// and places the values on the stack
|
||||
// to be interrupted at any time
|
||||
if (p != nullptr) while ( true)
|
||||
{
|
||||
if (pile2->GetState() == 0)
|
||||
{
|
||||
if (!p->Execute(pile2)) return false; // interrupted here?
|
||||
if (!pile2->SetState(1)) return false; // special mark to recognize parameters
|
||||
}
|
||||
ppVars[i++] = pile2->GetVar(); // construct the list of pointers
|
||||
pile2 = pile2->AddStack(); // space on the stack for the results
|
||||
p = p->GetNext();
|
||||
if ( p == nullptr) break;
|
||||
}
|
||||
ppVars[i] = nullptr;
|
||||
|
||||
CBotClass* pClass = CBotClass::Find(m_ClassName);
|
||||
CBotVar* pThis = pile1->FindVar("this");
|
||||
CBotVar* pResult = nullptr;
|
||||
if (m_typRes.GetType()>0) pResult = CBotVar::Create("", m_typRes);
|
||||
if (m_typRes.Eq(CBotTypClass))
|
||||
{
|
||||
pResult->SetClass(m_typRes.GetClass());
|
||||
}
|
||||
CBotVar* pRes = pResult;
|
||||
|
||||
if ( !pClass->ExecuteMethode(m_MethodeIdent, m_NomMethod,
|
||||
pThis, ppVars,
|
||||
pResult, pile2, GetToken())) return false; // interupted
|
||||
|
||||
// set the new value of this in place of the old variable
|
||||
CBotVar* old = pile1->FindVar(m_token);
|
||||
old->Copy(pThis, false);
|
||||
|
||||
if (pRes != pResult) delete pRes;
|
||||
|
||||
return pj->Return(pile2); // release the entire stack
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotInstrMethode class A call of method. Compile a method call.
|
||||
*/
|
||||
class CBotInstrMethode : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotInstrMethode
|
||||
*/
|
||||
CBotInstrMethode();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotInstrMethode
|
||||
*/
|
||||
~CBotInstrMethode();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param pVar
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, CBotVar* pVar);
|
||||
|
||||
/*!
|
||||
* \brief Execute
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief ExecuteVar Execute the method call.
|
||||
* \param pVar
|
||||
* \param pj
|
||||
* \param prevToken
|
||||
* \param bStep
|
||||
* \param bExtend
|
||||
* \return
|
||||
*/
|
||||
bool ExecuteVar(CBotVar* &pVar, CBotStack* &pj, CBotToken* prevToken, bool bStep, bool bExtend) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreStateVar
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreStateVar(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
//! The parameters to be evaluated.
|
||||
CBotInstr *m_Parameters;
|
||||
//! Complete type of the result.
|
||||
CBotTypResult m_typRes;
|
||||
//! Name of the method.
|
||||
CBotString m_NomMethod;
|
||||
//! Identifier of the method.
|
||||
long m_MethodeIdent;
|
||||
//! Name of the class.
|
||||
CBotString m_ClassName;
|
||||
};
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstrUtils.h"
|
||||
|
||||
#include "CBot/CBotToken.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
#include "CBot/CBotTypResult.h"
|
||||
#include "CBot/CBotInstr/CBotExpression.h"
|
||||
#include "CBot/CBotClass.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CompileParams(CBotToken* &p, CBotCStack* pStack, CBotVar** ppVars)
|
||||
{
|
||||
bool first = true;
|
||||
CBotInstr* ret = nullptr; // to return to the list
|
||||
|
||||
CBotCStack* pile = pStack;
|
||||
int i = 0;
|
||||
|
||||
if (IsOfType(p, ID_OPENPAR))
|
||||
{
|
||||
int start, end;
|
||||
if (!IsOfType(p, ID_CLOSEPAR)) while (true)
|
||||
{
|
||||
start = p->GetStart();
|
||||
pile = pile->TokenStack(); // keeps the result on the stack
|
||||
|
||||
if (first) pStack->SetStartError(start);
|
||||
first = false;
|
||||
|
||||
CBotInstr* param = CBotExpression::Compile(p, pile);
|
||||
end = p->GetStart();
|
||||
|
||||
if (!pile->IsOk())
|
||||
{
|
||||
return pStack->Return(nullptr, pile);
|
||||
}
|
||||
|
||||
if (ret == nullptr) ret = param;
|
||||
else ret->AddNext(param); // construct the list
|
||||
|
||||
if (param != nullptr)
|
||||
{
|
||||
if (pile->GetTypResult().Eq(99))
|
||||
{
|
||||
delete pStack->TokenStack();
|
||||
pStack->SetError(TX_VOID, p->GetStart());
|
||||
return nullptr;
|
||||
}
|
||||
ppVars[i] = pile->GetVar();
|
||||
ppVars[i]->GetToken()->SetPos(start, end);
|
||||
i++;
|
||||
|
||||
if (IsOfType(p, ID_COMMA)) continue; // skips the comma
|
||||
if (IsOfType(p, ID_CLOSEPAR)) break;
|
||||
}
|
||||
|
||||
pStack->SetError(TX_CLOSEPAR, p->GetStart());
|
||||
delete pStack->TokenStack();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
ppVars[i] = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TypeCompatible(CBotTypResult& type1, CBotTypResult& type2, int op)
|
||||
{
|
||||
int t1 = type1.GetType();
|
||||
int t2 = type2.GetType();
|
||||
|
||||
int max = (t1 > t2) ? t1 : t2;
|
||||
|
||||
if (max == 99) return false; // result is void?
|
||||
|
||||
// special case for strin concatenation
|
||||
if (op == ID_ADD && max >= CBotTypString) return true;
|
||||
if (op == ID_ASSADD && max >= CBotTypString) return true;
|
||||
if (op == ID_ASS && t1 == CBotTypString) return true;
|
||||
|
||||
if (max >= CBotTypBoolean)
|
||||
{
|
||||
if ( (op == ID_EQ || op == ID_NE) &&
|
||||
(t1 == CBotTypPointer && t2 == CBotTypNullPointer)) return true;
|
||||
if ( (op == ID_EQ || op == ID_NE || op == ID_ASS) &&
|
||||
(t2 == CBotTypPointer && t1 == CBotTypNullPointer)) return true;
|
||||
if ( (op == ID_EQ || op == ID_NE) &&
|
||||
(t1 == CBotTypArrayPointer && t2 == CBotTypNullPointer)) return true;
|
||||
if ( (op == ID_EQ || op == ID_NE || op == ID_ASS) &&
|
||||
(t2 == CBotTypArrayPointer && t1 == CBotTypNullPointer)) return true;
|
||||
if (t2 != t1) return false;
|
||||
if (t1 == CBotTypArrayPointer) return type1.Compare(type2);
|
||||
if (t1 == CBotTypPointer ||
|
||||
t1 == CBotTypClass ||
|
||||
t1 == CBotTypIntrinsic )
|
||||
{
|
||||
CBotClass* c1 = type1.GetClass();
|
||||
CBotClass* c2 = type2.GetClass();
|
||||
|
||||
return c1->IsChildOf(c2) || c2->IsChildOf(c1);
|
||||
// accept the case in reverse
|
||||
// the transaction will be denied at runtime if the pointer is not
|
||||
// compatible
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
type1.SetType(max);
|
||||
type2.SetType(max);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TypesCompatibles(const CBotTypResult& type1, const CBotTypResult& type2)
|
||||
{
|
||||
int t1 = type1.GetType();
|
||||
int t2 = type2.GetType();
|
||||
|
||||
if (t1 == CBotTypIntrinsic) t1 = CBotTypClass;
|
||||
if (t2 == CBotTypIntrinsic) t2 = CBotTypClass;
|
||||
|
||||
int max = (t1 > t2) ? t1 : t2;
|
||||
|
||||
if (max == 99) return false; // result is void?
|
||||
|
||||
if (max >= CBotTypBoolean)
|
||||
{
|
||||
if (t2 != t1) return false;
|
||||
|
||||
if (max == CBotTypArrayPointer)
|
||||
return TypesCompatibles(type1.GetTypElem(), type2.GetTypElem());
|
||||
|
||||
if (max == CBotTypClass || max == CBotTypPointer)
|
||||
return type1.GetClass() == type2.GetClass() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
// Forward declaration
|
||||
class CBotInstr;
|
||||
class CBotToken;
|
||||
class CBotCStack;
|
||||
class CBotVar;
|
||||
class CBotTypResult;
|
||||
|
||||
/*!
|
||||
* \brief CompileParams Compile a list of parameters.
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param ppVars
|
||||
* \return
|
||||
*/
|
||||
CBotInstr* CompileParams(CBotToken* &p, CBotCStack* pStack, CBotVar** ppVars);
|
||||
|
||||
/*!
|
||||
* \brief TypeCompatible Check if two results are consistent to make an
|
||||
* operation.
|
||||
* \param type1
|
||||
* \param type2
|
||||
* \param op
|
||||
* \return
|
||||
*/
|
||||
bool TypeCompatible(CBotTypResult& type1, CBotTypResult& type2, int op = 0);
|
||||
|
||||
/*!
|
||||
* \brief TypesCompatibles Check if two variables are compatible for parameter
|
||||
* passing.
|
||||
* \param type1
|
||||
* \param type2
|
||||
* \return
|
||||
*/
|
||||
bool TypesCompatibles(const CBotTypResult& type1, const CBotTypResult& type2);
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInt.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotLeftExprVar.h"
|
||||
#include "CBot/CBotInstr/CBotInstArray.h"
|
||||
#include "CBot/CBotInstr/CBotTwoOpExpr.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInt::CBotInt()
|
||||
{
|
||||
m_next = nullptr; // for multiple definitions
|
||||
m_var =
|
||||
m_expr = nullptr;
|
||||
name = "CBotInt";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInt::~CBotInt()
|
||||
{
|
||||
delete m_var;
|
||||
delete m_expr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, bool noskip)
|
||||
{
|
||||
CBotToken* pp = cont ? nullptr : p; // no repetition of the token "int"
|
||||
|
||||
if (!cont && !IsOfType(p, ID_INT)) return nullptr;
|
||||
|
||||
CBotInt* inst = static_cast<CBotInt*>(CompileArray(p, pStack, CBotTypInt));
|
||||
if (inst != nullptr || !pStack->IsOk()) return inst;
|
||||
|
||||
CBotCStack* pStk = pStack->TokenStack(pp);
|
||||
|
||||
inst = new CBotInt();
|
||||
|
||||
inst->m_expr = nullptr;
|
||||
|
||||
CBotToken* vartoken = p;
|
||||
inst->SetToken(vartoken);
|
||||
|
||||
// determines the expression is valid for the item on the left side
|
||||
if (nullptr != (inst->m_var = CBotLeftExprVar::Compile( p, pStk )))
|
||||
{
|
||||
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_typevar = CBotTypInt;
|
||||
if (pStk->CheckVarLocal(vartoken)) // redefinition of the variable
|
||||
{
|
||||
pStk->SetError(TX_REDEFVAR, vartoken);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_OPBRK))
|
||||
{
|
||||
delete inst; // type is not CBotInt
|
||||
p = vartoken; // returns the variable name
|
||||
|
||||
// compiles an array declaration
|
||||
|
||||
CBotInstr* inst2 = CBotInstArray::Compile(p, pStk, CBotTypInt);
|
||||
|
||||
if (!pStk->IsOk() )
|
||||
{
|
||||
pStk->SetError(TX_CLBRK, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_COMMA)) // several definition chained
|
||||
{
|
||||
if (nullptr != ( inst2->m_next2b = CBotInt::Compile(p, pStk, true, noskip))) // compile the next one
|
||||
{
|
||||
return pStack->Return(inst2, pStk);
|
||||
}
|
||||
}
|
||||
inst = static_cast<CBotInt*>(inst2);
|
||||
goto suite; // no assignment, variable already created
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_ASS)) // with an assignment?
|
||||
{
|
||||
if (nullptr == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
if (pStk->GetType() >= CBotTypBoolean) // compatible type ?
|
||||
{
|
||||
pStk->SetError(TX_BADTYPE, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
CBotVar* var = CBotVar::Create(vartoken, CBotTypInt);// create the variable (evaluated after the assignment)
|
||||
var->SetInit(inst->m_expr != nullptr ? CBotVar::InitType::DEF : CBotVar::InitType::UNDEF); // if initialized with assignment
|
||||
var->SetUniqNum( //set it with a unique number
|
||||
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_nIdent = CBotVar::NextUniqNum());
|
||||
pStack->AddVar(var); // place it on the stack
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_COMMA)) // chained several definitions
|
||||
{
|
||||
if (nullptr != ( inst->m_next2b = CBotInt::Compile(p, pStk, true, noskip))) // compile next one
|
||||
{
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
}
|
||||
suite:
|
||||
if (noskip || IsOfType(p, ID_SEP)) // instruction is completed
|
||||
{
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
pStk->SetError(TX_ENDOF, p->GetStart());
|
||||
}
|
||||
|
||||
error:
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotInt::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this); // essential for SetState()
|
||||
|
||||
if ( pile->GetState()==0)
|
||||
{
|
||||
if (m_expr && !m_expr->Execute(pile)) return false; // initial value // interrupted?
|
||||
m_var->Execute(pile); // creates and assign the result
|
||||
|
||||
if (!pile->SetState(1)) return false;
|
||||
}
|
||||
|
||||
if (pile->IfStep()) return false;
|
||||
|
||||
if ( m_next2b &&
|
||||
!m_next2b->Execute(pile)) return false; // other(s) definition(s)
|
||||
|
||||
return pj->Return(pile); // forward below
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotInt::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
CBotStack* pile = pj;
|
||||
if (bMain)
|
||||
{
|
||||
pile = pj->RestoreStack(this);
|
||||
if (pile == nullptr) return;
|
||||
|
||||
if ( pile->GetState()==0)
|
||||
{
|
||||
if (m_expr) m_expr->RestoreState(pile, bMain); // initial value // interrupted?
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_var->RestoreState(pile, bMain);
|
||||
|
||||
if (m_next2b) m_next2b->RestoreState(pile, bMain); // other(s) definition(s)
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotInt class Definition of an integer variable
|
||||
* int a, b = 12;
|
||||
*/
|
||||
class CBotInt : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotInt
|
||||
*/
|
||||
CBotInt();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotInt
|
||||
*/
|
||||
~CBotInt();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param cont
|
||||
* \param noskip
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool cont = false, bool noskip = false);
|
||||
|
||||
/*!
|
||||
* \brief Execute Execute the definition of the integer variable.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
|
||||
//! The variable to initialize.
|
||||
CBotInstr* m_var;
|
||||
//! A value to put, if there is.
|
||||
CBotInstr* m_expr;
|
||||
};
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotLeftExpr.h"
|
||||
#include "CBot/CBotInstr/CBotFieldExpr.h"
|
||||
#include "CBot/CBotInstr/CBotIndexExpr.h"
|
||||
#include "CBot/CBotInstr/CBotExpression.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
#include "CBot/CBotClass.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVarArray.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
CBotLeftExpr::CBotLeftExpr()
|
||||
{
|
||||
name = "CBotLeftExpr";
|
||||
m_nIdent = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotLeftExpr::~CBotLeftExpr()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotLeftExpr* CBotLeftExpr::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotCStack* pStk = pStack->TokenStack();
|
||||
|
||||
pStk->SetStartError(p->GetStart());
|
||||
|
||||
// is it a variable name?
|
||||
if (p->GetType() == TokenTypVar)
|
||||
{
|
||||
CBotLeftExpr* inst = new CBotLeftExpr(); // creates the object
|
||||
|
||||
inst->SetToken(p);
|
||||
|
||||
CBotVar* var;
|
||||
|
||||
if (nullptr != (var = pStk->FindVar(p))) // seek if known variable
|
||||
{
|
||||
inst->m_nIdent = var->GetUniqNum();
|
||||
if (inst->m_nIdent > 0 && inst->m_nIdent < 9000)
|
||||
{
|
||||
if ( var->IsPrivate(PR_READ) &&
|
||||
!pStk->GetBotCall()->m_bCompileClass)
|
||||
{
|
||||
pStk->SetError(TX_PRIVATE, p);
|
||||
goto err;
|
||||
}
|
||||
// this is an element of the current class
|
||||
// adds the equivalent of this. before
|
||||
CBotToken pthis("this");
|
||||
inst->SetToken(&pthis);
|
||||
inst->m_nIdent = -2; // indent for this
|
||||
|
||||
CBotFieldExpr* i = new CBotFieldExpr(); // new element
|
||||
i->SetToken(p); // keeps the name of the token
|
||||
inst->AddNext3(i); // add after
|
||||
|
||||
var = pStk->FindVar(pthis);
|
||||
var = var->GetItem(p->GetString());
|
||||
i->SetUniqNum(var->GetUniqNum());
|
||||
}
|
||||
p = p->GetNext(); // next token
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (var->GetType() == CBotTypArrayPointer)
|
||||
{
|
||||
if (IsOfType( p, ID_OPBRK ))
|
||||
{
|
||||
CBotIndexExpr* i = new CBotIndexExpr();
|
||||
i->m_expr = CBotExpression::Compile(p, pStk);
|
||||
inst->AddNext3(i); // add to the chain
|
||||
|
||||
var = (static_cast<CBotVarArray*>(var))->GetItem(0,true); // gets the component [0]
|
||||
|
||||
if (i->m_expr == nullptr)
|
||||
{
|
||||
pStk->SetError(TX_BADINDEX, p->GetStart());
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!pStk->IsOk() || !IsOfType( p, ID_CLBRK ))
|
||||
{
|
||||
pStk->SetError(TX_CLBRK, p->GetStart());
|
||||
goto err;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (var->GetType(1) == CBotTypPointer) // for classes
|
||||
{
|
||||
if (IsOfType(p, ID_DOT))
|
||||
{
|
||||
CBotToken* pp = p;
|
||||
|
||||
CBotFieldExpr* i = new CBotFieldExpr(); // new element
|
||||
i->SetToken(pp); // keeps the name of the token
|
||||
inst->AddNext3(i); // adds after
|
||||
|
||||
if (p->GetType() == TokenTypVar) // must be a name
|
||||
{
|
||||
var = var->GetItem(p->GetString()); // get item correspondent
|
||||
if (var != nullptr)
|
||||
{
|
||||
if ( var->IsPrivate(PR_READ) &&
|
||||
!pStk->GetBotCall()->m_bCompileClass)
|
||||
{
|
||||
pStk->SetError(TX_PRIVATE, pp);
|
||||
goto err;
|
||||
}
|
||||
|
||||
i->SetUniqNum(var->GetUniqNum());
|
||||
p = p->GetNext(); // skips the name
|
||||
continue;
|
||||
}
|
||||
pStk->SetError(TX_NOITEM, p);
|
||||
}
|
||||
pStk->SetError(TX_DOT, p->GetStart());
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (pStk->IsOk()) return static_cast<CBotLeftExpr*> (pStack->Return(inst, pStk));
|
||||
}
|
||||
pStk->SetError(TX_UNDEFVAR, p);
|
||||
err:
|
||||
delete inst;
|
||||
return static_cast<CBotLeftExpr*> ( pStack->Return(nullptr, pStk));
|
||||
}
|
||||
|
||||
return static_cast<CBotLeftExpr*> ( pStack->Return(nullptr, pStk));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotLeftExpr::Execute(CBotStack* &pj, CBotStack* array)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack();
|
||||
|
||||
CBotVar* var1 = nullptr;
|
||||
CBotVar* var2 = nullptr;
|
||||
// fetch a variable (not copy)
|
||||
if (!ExecuteVar(var1, array, nullptr, false)) return false;
|
||||
|
||||
if (pile->IfStep()) return false;
|
||||
|
||||
if (var1)
|
||||
{
|
||||
var2 = pj->GetVar(); // result on the input stack
|
||||
if (var2)
|
||||
{
|
||||
CBotTypResult t1 = var1->GetTypResult();
|
||||
CBotTypResult t2 = var2->GetTypResult();
|
||||
if (t2.Eq(CBotTypPointer))
|
||||
{
|
||||
CBotClass* c1 = t1.GetClass();
|
||||
CBotClass* c2 = t2.GetClass();
|
||||
if ( !c2->IsChildOf(c1))
|
||||
{
|
||||
CBotToken* pt = &m_token;
|
||||
pile->SetError(TX_BADTYPE, pt);
|
||||
return pj->Return(pile); // operation performed
|
||||
}
|
||||
}
|
||||
var1->SetVal(var2); // do assignment
|
||||
}
|
||||
pile->SetCopyVar(var1); // replace the stack with the copy of the variable
|
||||
// (for name)
|
||||
}
|
||||
|
||||
return pj->Return(pile); // operation performed
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotLeftExpr::ExecuteVar(CBotVar* &pVar, CBotCStack* &pile)
|
||||
{
|
||||
pVar = pile->FindVar(m_token);
|
||||
if (pVar == nullptr) return false;
|
||||
|
||||
if ( m_next3 != nullptr &&
|
||||
!m_next3->ExecuteVar(pVar, pile) ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotLeftExpr::ExecuteVar(CBotVar* &pVar, CBotStack* &pile, CBotToken* prevToken, bool bStep)
|
||||
{
|
||||
pile = pile->AddStack(this);
|
||||
|
||||
pVar = pile->FindVar(m_nIdent);
|
||||
if (pVar == nullptr)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
assert(0);
|
||||
#endif
|
||||
pile->SetError(2, &m_token);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bStep && m_next3 == nullptr && pile->IfStep()) return false;
|
||||
|
||||
if ( m_next3 != nullptr &&
|
||||
!m_next3->ExecuteVar(pVar, pile, &m_token, bStep, true) ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotLeftExpr::RestoreStateVar(CBotStack* &pile, bool bMain)
|
||||
{
|
||||
pile = pile->RestoreStack(this);
|
||||
if (pile == nullptr) return;
|
||||
|
||||
if (m_next3 != nullptr)
|
||||
m_next3->RestoreStateVar(pile, bMain);
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotLeftExpr class Accept the expressions that be to the left of
|
||||
* assignment.
|
||||
*/
|
||||
class CBotLeftExpr : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotLeftExpr
|
||||
*/
|
||||
CBotLeftExpr();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotLeftExpr
|
||||
*/
|
||||
~CBotLeftExpr();
|
||||
|
||||
/*!
|
||||
* \brief Compile Compiles an expression for a left-operand
|
||||
* (left of an assignment).
|
||||
* eg :
|
||||
* - toto
|
||||
* - toto[ 3 ]
|
||||
* - toto.x
|
||||
* - toto.pos.x
|
||||
* - toto[2].pos.x
|
||||
* - toto[1].pos[2].x
|
||||
* - toto[1][2][3]
|
||||
*
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotLeftExpr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute Runs, is a variable and assigns the result to the stack.
|
||||
* \param pStack
|
||||
* \param array
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pStack, CBotStack* array);
|
||||
|
||||
/*!
|
||||
* \brief ExecuteVar Fetch a variable during compilation.
|
||||
* \param pVar
|
||||
* \param pile
|
||||
* \return
|
||||
*/
|
||||
bool ExecuteVar(CBotVar* &pVar, CBotCStack* &pile) override;
|
||||
|
||||
/*!
|
||||
* \brief ExecuteVar Fetch the variable at runtume.
|
||||
* \param pVar
|
||||
* \param pile
|
||||
* \param prevToken
|
||||
* \param bStep
|
||||
* \return
|
||||
*/
|
||||
bool ExecuteVar(CBotVar* &pVar, CBotStack* &pile, CBotToken* prevToken, bool bStep);
|
||||
|
||||
/*!
|
||||
* \brief RestoreStateVar
|
||||
* \param pile
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreStateVar(CBotStack* &pile, bool bMain) override;
|
||||
|
||||
private:
|
||||
long m_nIdent;
|
||||
};
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotLeftExprVar.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
#include <assert.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotLeftExprVar::CBotLeftExprVar()
|
||||
{
|
||||
name = "CBotLeftExprVar";
|
||||
m_typevar = -1;
|
||||
m_nIdent = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotLeftExprVar::~CBotLeftExprVar()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotLeftExprVar::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
// verifies that the token is a variable name
|
||||
if (p->GetType() != TokenTypVar)
|
||||
{
|
||||
pStack->SetError( TX_NOVAR, p->GetStart());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CBotLeftExprVar* inst = new CBotLeftExprVar();
|
||||
inst->SetToken(p);
|
||||
p = p->GetNext();
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotLeftExprVar::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotVar* var1;
|
||||
CBotVar* var2;
|
||||
|
||||
var1 = CBotVar::Create(m_token.GetString(), m_typevar);
|
||||
var1->SetUniqNum(m_nIdent); // with the unique identifier
|
||||
pj->AddVar(var1); // place it on the stack
|
||||
|
||||
var2 = pj->GetVar(); // result on the stack
|
||||
if (var2) var1->SetVal(var2); // do the assignment
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotLeftExprVar::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
CBotVar* var1;
|
||||
|
||||
var1 = pj->FindVar(m_token.GetString());
|
||||
if (var1 == nullptr) assert(0);
|
||||
|
||||
var1->SetUniqNum(m_nIdent); // with the unique identifier
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotLeftExprVar class Compilation of an element to the left of an assignment.
|
||||
*/
|
||||
class CBotLeftExprVar : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotLeftExprVar
|
||||
*/
|
||||
CBotLeftExprVar();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotLeftExprVar
|
||||
*/
|
||||
~CBotLeftExprVar();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute Creates a variable and assigns the result to the stack.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
public:
|
||||
|
||||
//! Type of variable declared.
|
||||
CBotTypResult m_typevar;
|
||||
//! Unique identifier for that variable.
|
||||
long m_nIdent;
|
||||
};
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotListArray.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotInstrUtils.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotExprNull.h"
|
||||
#include "CBot/CBotInstr/CBotTwoOpExpr.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotListArray::CBotListArray()
|
||||
{
|
||||
m_expr = nullptr;
|
||||
name = "CBotListArray";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotListArray::~CBotListArray()
|
||||
{
|
||||
delete m_expr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotListArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResult type)
|
||||
{
|
||||
CBotCStack* pStk = pStack->TokenStack(p);
|
||||
|
||||
CBotToken* pp = p;
|
||||
|
||||
if (IsOfType( p, ID_NULL ))
|
||||
{
|
||||
CBotInstr* inst = new CBotExprNull ();
|
||||
inst->SetToken(pp);
|
||||
return pStack->Return(inst, pStk); // ok with empty element
|
||||
}
|
||||
|
||||
CBotListArray* inst = new CBotListArray();
|
||||
|
||||
if (IsOfType( p, ID_OPENPAR ))
|
||||
{
|
||||
// each element takes the one after the other
|
||||
if (type.Eq( CBotTypArrayPointer ))
|
||||
{
|
||||
type = type.GetTypElem();
|
||||
|
||||
pStk->SetStartError(p->GetStart());
|
||||
if (nullptr == ( inst->m_expr = CBotListArray::Compile( p, pStk, type ) ))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
while (IsOfType( p, ID_COMMA )) // other elements?
|
||||
{
|
||||
pStk->SetStartError(p->GetStart());
|
||||
|
||||
CBotInstr* i = CBotListArray::Compile(p, pStk, type);
|
||||
if (nullptr == i)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
inst->m_expr->AddNext3(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pStk->SetStartError(p->GetStart());
|
||||
if (nullptr == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
CBotVar* pv = pStk->GetVar(); // result of the expression
|
||||
|
||||
if (pv == nullptr || !TypesCompatibles( type, pv->GetTypResult())) // compatible type?
|
||||
{
|
||||
pStk->SetError(TX_BADTYPE, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
|
||||
while (IsOfType( p, ID_COMMA )) // other elements?
|
||||
{
|
||||
pStk->SetStartError(p->GetStart());
|
||||
|
||||
CBotInstr* i = CBotTwoOpExpr::Compile(p, pStk) ;
|
||||
if (nullptr == i)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
CBotVar* pv = pStk->GetVar(); // result of the expression
|
||||
|
||||
if (pv == nullptr || !TypesCompatibles( type, pv->GetTypResult())) // compatible type?
|
||||
{
|
||||
pStk->SetError(TX_BADTYPE, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
inst->m_expr->AddNext3(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsOfType(p, ID_CLOSEPAR) )
|
||||
{
|
||||
pStk->SetError(TX_CLOSEPAR, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
error:
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotListArray::Execute(CBotStack* &pj, CBotVar* pVar)
|
||||
{
|
||||
CBotStack* pile1 = pj->AddStack();
|
||||
CBotVar* pVar2;
|
||||
|
||||
CBotInstr* p = m_expr;
|
||||
|
||||
int n = 0;
|
||||
|
||||
for (; p != nullptr ; n++, p = p->GetNext3())
|
||||
{
|
||||
if (pile1->GetState() > n) continue;
|
||||
|
||||
pVar2 = pVar->GetItem(n, true);
|
||||
|
||||
if (!p->Execute(pile1, pVar2)) return false; // evaluate expression
|
||||
|
||||
pile1->IncState();
|
||||
}
|
||||
|
||||
return pj->Return(pile1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotListArray::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (bMain)
|
||||
{
|
||||
CBotStack* pile = pj->RestoreStack(this);
|
||||
if (pile == nullptr) return;
|
||||
|
||||
CBotInstr* p = m_expr;
|
||||
|
||||
int state = pile->GetState();
|
||||
|
||||
while(state-- > 0) p = p->GetNext3() ;
|
||||
|
||||
p->RestoreState(pile, bMain); // size calculation //interrupted!
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotListArray class Definition of a assignment list for a table
|
||||
* int [ ] a [ ] = ( ( 1, 2, 3 ) , ( 3, 2, 1 ) ) ;
|
||||
*/
|
||||
class CBotListArray : public CBotInstr
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotListArray
|
||||
*/
|
||||
CBotListArray();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotListArray
|
||||
*/
|
||||
~CBotListArray();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param type
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResult type);
|
||||
|
||||
/*!
|
||||
* \brief Execute Executes the definition of an array.
|
||||
* \param pj
|
||||
* \param pVar
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj, CBotVar* pVar) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
//! An expression for an element others are linked with CBotInstr :: m_next3;
|
||||
CBotInstr* m_expr;
|
||||
};
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotListExpression.h"
|
||||
#include "CBot/CBotInstr/CBotExpression.h"
|
||||
#include "CBot/CBotInstr/CBotIString.h"
|
||||
#include "CBot/CBotInstr/CBotFloat.h"
|
||||
#include "CBotBoolean.h"
|
||||
#include "CBot/CBotInstr/CBotInt.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// 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== nullptr ) i = CBotFloat::Compile( p, pStack, false, true ); // or a real number?
|
||||
if ( i== nullptr ) i = CBotBoolean::Compile( p, pStack, false, true ); // or a boolean?
|
||||
if ( i== nullptr ) i = CBotIString::Compile( p, pStack, false, true ); // ar a string?
|
||||
if ( i== nullptr ) i = CBotExpression::Compile( p, pStack ); // compiles an expression
|
||||
return i;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotListExpression::CBotListExpression()
|
||||
{
|
||||
m_Expr = nullptr;
|
||||
name = "CBotListExpression";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotListExpression::~CBotListExpression()
|
||||
{
|
||||
delete m_Expr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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 nullptr; // no object, the error is on the stack
|
||||
}
|
||||
}
|
||||
return inst;
|
||||
}
|
||||
delete inst;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotListExpression::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(); // essential
|
||||
CBotInstr* p = m_Expr; // the first expression
|
||||
|
||||
int state = pile->GetState();
|
||||
while (state-->0) p = p->GetNext(); // returns to the interrupted operation
|
||||
|
||||
if ( p != nullptr ) while (true)
|
||||
{
|
||||
if ( !p->Execute(pile) ) return false;
|
||||
p = p->GetNext();
|
||||
if ( p == nullptr ) 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 == nullptr ) return;
|
||||
state = pile->GetState();
|
||||
}
|
||||
|
||||
CBotInstr* p = m_Expr; // the first expression
|
||||
|
||||
while (p != nullptr && state-->0)
|
||||
{
|
||||
p->RestoreState(pile, false);
|
||||
p = p->GetNext(); // returns to the interrupted operation
|
||||
}
|
||||
|
||||
if ( p != nullptr )
|
||||
{
|
||||
p->RestoreState(pile, bMain);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
/*!
|
||||
* \brief The CBotListExpression class. Compiles a list of expressions is used
|
||||
* only in "for" statement in incrementing and intitialisation.
|
||||
*/
|
||||
class CBotListExpression : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotListExpression
|
||||
*/
|
||||
CBotListExpression();
|
||||
|
||||
/*!
|
||||
* \brief CBotListExpression
|
||||
*/
|
||||
~CBotListExpression();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pStack) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
//! The first expression to be evaluated
|
||||
CBotInstr* m_Expr;
|
||||
};
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotListInstr.h"
|
||||
#include "CBot/CBotInstr/CBotBlock.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotListInstr::CBotListInstr()
|
||||
{
|
||||
m_Instr = nullptr;
|
||||
name = "CBotListInstr";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotListInstr::~CBotListInstr()
|
||||
{
|
||||
delete m_Instr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotListInstr::Compile(CBotToken* &p, CBotCStack* pStack, bool bLocal)
|
||||
{
|
||||
CBotCStack* pStk = pStack->TokenStack(p, bLocal); // variables are local
|
||||
|
||||
CBotListInstr* inst = new CBotListInstr();
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (p == nullptr) break;
|
||||
|
||||
if (IsOfType(p, ID_SEP)) continue; // empty statement ignored
|
||||
if (p->GetType() == ID_CLBLK) break;
|
||||
|
||||
if (IsOfType(p, 0))
|
||||
{
|
||||
pStack->SetError(TX_CLOSEBLK, p->GetStart());
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
CBotInstr* i = CBotBlock::CompileBlkOrInst(p, pStk); // compiles next
|
||||
|
||||
if (!pStk->IsOk())
|
||||
{
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
if (inst->m_Instr == nullptr) inst->m_Instr = i;
|
||||
else inst->m_Instr->AddNext(i); // added a result
|
||||
}
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotListInstr::Execute(CBotStack* &pj)
|
||||
{
|
||||
|
||||
CBotStack* pile = pj->AddStack(this, true); //needed for SetState()
|
||||
if (pile->StackOver() ) return pj->Return( pile);
|
||||
|
||||
|
||||
CBotInstr* p = m_Instr; // the first expression
|
||||
|
||||
int state = pile->GetState();
|
||||
while (state-->0) p = p->GetNext(); // returns to the interrupted operation
|
||||
|
||||
if (p != nullptr) while (true)
|
||||
{
|
||||
if (!p->Execute(pile)) return false;
|
||||
p = p->GetNext();
|
||||
if (p == nullptr) break;
|
||||
(void)pile->IncState(); // ready for next
|
||||
}
|
||||
|
||||
return pj->Return(pile);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotListInstr::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (!bMain) return;
|
||||
|
||||
CBotStack* pile = pj->RestoreStack(this);
|
||||
if (pile == nullptr) return;
|
||||
|
||||
CBotInstr* p = m_Instr; // the first expression
|
||||
|
||||
int state = pile->GetState();
|
||||
while ( p != nullptr && state-- > 0)
|
||||
{
|
||||
p->RestoreState(pile, false);
|
||||
p = p->GetNext(); // returns to the interrupted operation
|
||||
}
|
||||
|
||||
if (p != nullptr) p->RestoreState(pile, true);
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotListInstr class Compiles a list of instructions separated by
|
||||
* semicolons eg : ... ; ... ; ... ; ... ;
|
||||
*/
|
||||
class CBotListInstr : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotListInstr
|
||||
*/
|
||||
CBotListInstr();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotListInstr
|
||||
*/
|
||||
~CBotListInstr();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \param bLocal
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool bLocal = true);
|
||||
|
||||
/*!
|
||||
* \brief Execute Executes a set of instructions.
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
//! Instructions to do.
|
||||
CBotInstr* m_Instr;
|
||||
};
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotLogicExpr.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotLogicExpr::CBotLogicExpr()
|
||||
{
|
||||
m_condition =
|
||||
m_op1 =
|
||||
m_op2 = nullptr; // nullptr to be able to delete without other
|
||||
name = "CBotLogicExpr"; // debug
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotLogicExpr::~CBotLogicExpr()
|
||||
{
|
||||
delete m_condition;
|
||||
delete m_op1;
|
||||
delete m_op2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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->GetState() == 0 )
|
||||
{
|
||||
if ( !m_condition->Execute(pStk1) ) return false;
|
||||
if (!pStk1->SetState(1)) return false;
|
||||
}
|
||||
|
||||
if ( pStk1->GetVal() == 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 == nullptr ) return;
|
||||
|
||||
if ( pStk1->GetState() == 0 )
|
||||
{
|
||||
m_condition->RestoreState(pStk1, bMain);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pStk1->GetVal() == true )
|
||||
{
|
||||
m_op1->RestoreState(pStk1, bMain);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_op2->RestoreState(pStk1, bMain);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotLogicExpr class
|
||||
*/
|
||||
class CBotLogicExpr : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotLogicExpr
|
||||
*/
|
||||
CBotLogicExpr();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotLogicExpr
|
||||
*/
|
||||
~CBotLogicExpr();
|
||||
|
||||
/*!
|
||||
* \brief Execute
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pStack) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
|
||||
//! Test to evaluate
|
||||
CBotInstr* m_condition;
|
||||
//! Left element
|
||||
CBotInstr* m_op1;
|
||||
//! Right element
|
||||
CBotInstr* m_op2;
|
||||
friend class CBotTwoOpExpr;
|
||||
};
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotNew.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
#include "CBot/CBotClass.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotInstrUtils.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotNew::CBotNew()
|
||||
{
|
||||
name = "CBotNew";
|
||||
m_Parameters = nullptr;
|
||||
m_nMethodeIdent = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotNew::~CBotNew()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotNew::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotToken* pp = p;
|
||||
if (!IsOfType(p, ID_NEW)) return nullptr;
|
||||
|
||||
// verifies that the token is a class name
|
||||
if (p->GetType() != TokenTypVar) return nullptr;
|
||||
|
||||
CBotClass* pClass = CBotClass::Find(p);
|
||||
if (pClass == nullptr)
|
||||
{
|
||||
pStack->SetError(TX_BADNEW, p);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CBotNew* inst = new CBotNew();
|
||||
inst->SetToken(pp);
|
||||
|
||||
inst->m_vartoken = p;
|
||||
p = p->GetNext();
|
||||
|
||||
// creates the object on the "job"
|
||||
// with a pointer to the object
|
||||
CBotVar* pVar = CBotVar::Create("", pClass);
|
||||
|
||||
// do the call of the creator
|
||||
CBotCStack* pStk = pStack->TokenStack();
|
||||
{
|
||||
// check if there are parameters
|
||||
CBotVar* ppVars[1000];
|
||||
inst->m_Parameters = CompileParams(p, pStk, ppVars);
|
||||
if (!pStk->IsOk()) goto error;
|
||||
|
||||
// constructor exist?
|
||||
CBotTypResult r = pClass->CompileMethode(pClass->GetName(), pVar, ppVars, pStk, inst->m_nMethodeIdent);
|
||||
delete pStk->TokenStack(); // release extra stack
|
||||
int typ = r.GetType();
|
||||
|
||||
// if there is no constructor, and no parameters either, it's ok
|
||||
if (typ == TX_UNDEFCALL && inst->m_Parameters == nullptr) typ = 0;
|
||||
pVar->SetInit(CBotVar::InitType::DEF); // mark the instance as init
|
||||
|
||||
if (typ>20)
|
||||
{
|
||||
pStk->SetError(typ, inst->m_vartoken.GetEnd());
|
||||
goto error;
|
||||
}
|
||||
|
||||
// if the constructor does not exist, but there are parameters
|
||||
if (typ<0 && inst->m_Parameters != nullptr)
|
||||
{
|
||||
pStk->SetError(TX_NOCONST, &inst->m_vartoken);
|
||||
goto error;
|
||||
}
|
||||
|
||||
// makes pointer to the object on the stack
|
||||
pStk->SetVar(pVar);
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
error:
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotNew::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this); //main stack
|
||||
|
||||
if (pile->IfStep()) return false;
|
||||
|
||||
CBotStack* pile1 = pj->AddStack2(); //secondary stack
|
||||
|
||||
CBotVar* pThis = nullptr;
|
||||
|
||||
CBotToken* pt = &m_vartoken;
|
||||
CBotClass* pClass = CBotClass::Find(pt);
|
||||
|
||||
// create the variable "this" pointer type to the stack
|
||||
|
||||
if ( pile->GetState()==0)
|
||||
{
|
||||
// create an instance of the requested class
|
||||
// and initialize the pointer to that object
|
||||
|
||||
|
||||
pThis = CBotVar::Create("this", pClass);
|
||||
pThis->SetUniqNum(-2) ;
|
||||
|
||||
pile1->SetVar(pThis); // place on stack1
|
||||
pile->IncState();
|
||||
}
|
||||
|
||||
// fetch the this pointer if it was interrupted
|
||||
if ( pThis == nullptr)
|
||||
{
|
||||
pThis = pile1->GetVar(); // find the pointer
|
||||
}
|
||||
|
||||
// is there an assignment or parameters (constructor)
|
||||
if ( pile->GetState()==1)
|
||||
{
|
||||
// evaluates the constructor of the instance
|
||||
|
||||
CBotVar* ppVars[1000];
|
||||
CBotStack* pile2 = pile;
|
||||
|
||||
int i = 0;
|
||||
|
||||
CBotInstr* p = m_Parameters;
|
||||
// evaluate the parameters
|
||||
// and places the values on the stack
|
||||
// to be interrupted at any time
|
||||
|
||||
if (p != nullptr) while ( true)
|
||||
{
|
||||
pile2 = pile2->AddStack(); // space on the stack for the result
|
||||
if (pile2->GetState() == 0)
|
||||
{
|
||||
if (!p->Execute(pile2)) return false; // interrupted here?
|
||||
pile2->SetState(1);
|
||||
}
|
||||
ppVars[i++] = pile2->GetVar();
|
||||
p = p->GetNext();
|
||||
if ( p == nullptr) break;
|
||||
}
|
||||
ppVars[i] = nullptr;
|
||||
|
||||
// create a variable for the result
|
||||
CBotVar* pResult = nullptr; // constructos still void
|
||||
|
||||
if ( !pClass->ExecuteMethode(m_nMethodeIdent, pClass->GetName(),
|
||||
pThis, ppVars,
|
||||
pResult, pile2, GetToken())) return false; // interrupt
|
||||
|
||||
pThis->ConstructorSet(); // indicates that the constructor has been called
|
||||
}
|
||||
|
||||
return pj->Return(pile1); // passes below
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotNew::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (!bMain) return;
|
||||
|
||||
CBotStack* pile = pj->RestoreStack(this); //primary stack
|
||||
if (pile == nullptr) return;
|
||||
|
||||
CBotStack* pile1 = pj->AddStack2(); //secondary stack
|
||||
|
||||
CBotToken* pt = &m_vartoken;
|
||||
CBotClass* pClass = CBotClass::Find(pt);
|
||||
|
||||
// create the variable "this" pointer type to the object
|
||||
|
||||
if ( pile->GetState()==0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CBotVar* pThis = pile1->GetVar(); // find the pointer
|
||||
pThis->SetUniqNum(-2);
|
||||
|
||||
// is ther an assignment or parameters (constructor)
|
||||
if ( pile->GetState()==1)
|
||||
{
|
||||
// evaluates the constructor of the instance
|
||||
|
||||
CBotVar* ppVars[1000];
|
||||
CBotStack* pile2 = pile;
|
||||
|
||||
int i = 0;
|
||||
|
||||
CBotInstr* p = m_Parameters;
|
||||
// evaluate the parameters
|
||||
// and places the values on the stack
|
||||
// to be interrupted at any time
|
||||
|
||||
if (p != nullptr) while ( true)
|
||||
{
|
||||
pile2 = pile2->RestoreStack(); // space on the stack for the result
|
||||
if (pile2 == nullptr) return;
|
||||
|
||||
if (pile2->GetState() == 0)
|
||||
{
|
||||
p->RestoreState(pile2, bMain); // interrupt here!
|
||||
return;
|
||||
}
|
||||
ppVars[i++] = pile2->GetVar();
|
||||
p = p->GetNext();
|
||||
if ( p == nullptr) break;
|
||||
}
|
||||
ppVars[i] = nullptr;
|
||||
|
||||
pClass->RestoreMethode(m_nMethodeIdent, m_vartoken.GetString(), pThis,
|
||||
ppVars, pile2) ; // interrupt here!
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotNew class Compile an instruction "new".
|
||||
*/
|
||||
class CBotNew : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotNew
|
||||
*/
|
||||
CBotNew();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotNew
|
||||
*/
|
||||
~CBotNew();
|
||||
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/*!
|
||||
* \brief Execute Executes instruction "new".
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
//! The parameters to be evaluated
|
||||
CBotInstr* m_Parameters;
|
||||
long m_nMethodeIdent;
|
||||
CBotToken m_vartoken;
|
||||
|
||||
};
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotParExpr.h"
|
||||
#include "CBot/CBotInstr/CBotExprUnaire.h"
|
||||
#include "CBot/CBotInstr/CBotExprVar.h"
|
||||
#include "CBot/CBotInstr/CBotInstrCall.h"
|
||||
#include "CBot/CBotInstr/CBotPostIncExpr.h"
|
||||
#include "CBot/CBotInstr/CBotPreIncExpr.h"
|
||||
#include "CBot/CBotInstr/CBotExprNum.h"
|
||||
#include "CBot/CBotInstr/CBotExprAlpha.h"
|
||||
#include "CBot/CBotInstr/CBotExprBool.h"
|
||||
#include "CBot/CBotInstr/CBotNew.h"
|
||||
#include "CBot/CBotInstr/CBotExprNull.h"
|
||||
#include "CBot/CBotInstr/CBotExprNan.h"
|
||||
#include "CBot/CBotInstr/CBotExpression.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotParExpr::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotCStack* pStk = pStack->TokenStack();
|
||||
|
||||
pStk->SetStartError(p->GetStart());
|
||||
|
||||
// is it an expression in parentheses?
|
||||
if (IsOfType(p, ID_OPENPAR))
|
||||
{
|
||||
CBotInstr* inst = CBotExpression::Compile(p, pStk);
|
||||
|
||||
if (nullptr != inst)
|
||||
{
|
||||
if (IsOfType(p, ID_CLOSEPAR))
|
||||
{
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
pStk->SetError(TX_CLOSEPAR, p->GetStart());
|
||||
}
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
// is this a unary operation?
|
||||
CBotInstr* inst = CBotExprUnaire::Compile(p, pStk);
|
||||
if (inst != nullptr || !pStk->IsOk())
|
||||
return pStack->Return(inst, pStk);
|
||||
|
||||
// is it a variable name?
|
||||
if (p->GetType() == TokenTypVar)
|
||||
{
|
||||
// this may be a method call without the "this." before
|
||||
inst = CBotExprVar::CompileMethode(p, pStk);
|
||||
if (inst != nullptr) return pStack->Return(inst, pStk);
|
||||
|
||||
|
||||
// is it a procedure call?
|
||||
inst = CBotInstrCall::Compile(p, pStk);
|
||||
if (inst != nullptr || !pStk->IsOk())
|
||||
return pStack->Return(inst, pStk);
|
||||
|
||||
|
||||
CBotToken* pvar = p;
|
||||
// no, it an "ordinaty" variable
|
||||
inst = CBotExprVar::Compile(p, pStk);
|
||||
|
||||
CBotToken* pp = p;
|
||||
// post incremented or decremented?
|
||||
if (IsOfType(p, ID_INC, ID_DEC))
|
||||
{
|
||||
if (pStk->GetType() >= CBotTypBoolean)
|
||||
{
|
||||
pStk->SetError(TX_BADTYPE, pp);
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
// recompile the variable for read-only
|
||||
delete inst;
|
||||
p = pvar;
|
||||
inst = CBotExprVar::Compile(p, pStk, PR_READ);
|
||||
p = p->GetNext();
|
||||
|
||||
CBotPostIncExpr* i = new CBotPostIncExpr();
|
||||
i->SetToken(pp);
|
||||
i->m_Instr = inst; // associated statement
|
||||
return pStack->Return(i, pStk);
|
||||
}
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
// pre increpemted or pre decremented?
|
||||
CBotToken* pp = p;
|
||||
if (IsOfType(p, ID_INC, ID_DEC))
|
||||
{
|
||||
CBotPreIncExpr* i = new CBotPreIncExpr();
|
||||
i->SetToken(pp);
|
||||
|
||||
if (p->GetType() == TokenTypVar)
|
||||
{
|
||||
if (nullptr != (i->m_Instr = CBotExprVar::Compile(p, pStk, PR_READ)))
|
||||
{
|
||||
if (pStk->GetType() >= CBotTypBoolean)
|
||||
{
|
||||
pStk->SetError(TX_BADTYPE, pp);
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
return pStack->Return(i, pStk);
|
||||
}
|
||||
delete i;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
}
|
||||
|
||||
// is it a number or DefineNum?
|
||||
if (p->GetType() == TokenTypNum ||
|
||||
p->GetType() == TokenTypDef )
|
||||
{
|
||||
CBotInstr* inst = CBotExprNum::Compile(p, pStk);
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
// is this a chaine?
|
||||
if (p->GetType() == TokenTypString)
|
||||
{
|
||||
CBotInstr* inst = CBotExprAlpha::Compile(p, pStk);
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
// is a "true" or "false"
|
||||
if (p->GetType() == ID_TRUE ||
|
||||
p->GetType() == ID_FALSE )
|
||||
{
|
||||
CBotInstr* inst = CBotExprBool::Compile(p, pStk);
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
// is an object to be created with new
|
||||
if (p->GetType() == ID_NEW)
|
||||
{
|
||||
CBotInstr* inst = CBotNew::Compile(p, pStk);
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
// is a null pointer
|
||||
if (IsOfType(p, ID_NULL))
|
||||
{
|
||||
CBotInstr* inst = new CBotExprNull ();
|
||||
inst->SetToken(pp);
|
||||
CBotVar* var = CBotVar::Create("", CBotTypNullPointer);
|
||||
pStk->SetVar(var);
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
// is a number nan
|
||||
if (IsOfType(p, ID_NAN))
|
||||
{
|
||||
CBotInstr* inst = new CBotExprNan ();
|
||||
inst->SetToken(pp);
|
||||
CBotVar* var = CBotVar::Create("", CBotTypInt);
|
||||
var->SetInit(CBotVar::InitType::IS_NAN);
|
||||
pStk->SetVar(var);
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
||||
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// possibly an expression in parentheses ( ... )
|
||||
// there is never an instance of this class
|
||||
// being the object returned inside the parenthesis
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// compile either:
|
||||
// instruction in parentheses (...)
|
||||
// a unary expression (negative, not)
|
||||
// variable name
|
||||
// variables pre and post-incremented or decremented
|
||||
// a given number DefineNum
|
||||
// a constant
|
||||
// procedure call
|
||||
// new statement
|
||||
//
|
||||
// this class has no constructor, because there is never an instance of this class
|
||||
// the object returned by Compile is the class corresponding to the instruction
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
* \brief The CBotParExpr class
|
||||
*/
|
||||
class CBotParExpr : public CBotInstr
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* \brief Compile
|
||||
* \param p
|
||||
* \param pStack
|
||||
* \return
|
||||
*/
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
};
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotPostIncExpr.h"
|
||||
#include "CBot/CBotInstr/CBotExprVar.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotPostIncExpr::CBotPostIncExpr()
|
||||
{
|
||||
m_Instr = nullptr;
|
||||
name = "CBotPostIncExpr";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotPostIncExpr::~CBotPostIncExpr()
|
||||
{
|
||||
delete m_Instr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotPostIncExpr::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile1 = pj->AddStack(this);
|
||||
CBotStack* pile2 = pile1;
|
||||
|
||||
CBotVar* var1 = nullptr;
|
||||
|
||||
// retrieves the variable fields and indexes according
|
||||
if (!(static_cast<CBotExprVar*>(m_Instr))->ExecuteVar(var1, pile2, nullptr, true)) return false;
|
||||
|
||||
pile1->SetState(1);
|
||||
pile1->SetCopyVar(var1); // places the result (before incrementation);
|
||||
|
||||
CBotStack* pile3 = pile2->AddStack(this);
|
||||
if (pile3->IfStep()) return false;
|
||||
|
||||
if (var1->IsNAN())
|
||||
{
|
||||
pile1->SetError(TX_OPNAN, &m_token);
|
||||
}
|
||||
|
||||
if (!var1->IsDefined())
|
||||
{
|
||||
pile1->SetError(TX_NOTINIT, &m_token);
|
||||
}
|
||||
|
||||
if (GetTokenType() == ID_INC) var1->Inc();
|
||||
else var1->Dec();
|
||||
|
||||
return pj->Return(pile1); // operation done, result on pile2
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotPostIncExpr::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (!bMain) return;
|
||||
|
||||
CBotStack* pile1 = pj->RestoreStack(this);
|
||||
if (pile1 == nullptr) return;
|
||||
|
||||
(static_cast<CBotExprVar*>(m_Instr))->RestoreStateVar(pile1, bMain);
|
||||
|
||||
if (pile1 != nullptr) pile1->RestoreStack(this);
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Management of pre-and post increment / decrement
|
||||
// There is no routine Compiles, the object is created directly
|
||||
// Compiles in CBotParExpr ::
|
||||
|
||||
/*!
|
||||
* \brief The CBotPostIncExpr class
|
||||
*/
|
||||
class CBotPostIncExpr : public CBotInstr
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotPostIncExpr
|
||||
*/
|
||||
CBotPostIncExpr();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotPostIncExpr
|
||||
*/
|
||||
~CBotPostIncExpr();
|
||||
|
||||
/*!
|
||||
* \brief Execute
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
CBotInstr* m_Instr;
|
||||
friend class CBotParExpr;
|
||||
};
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotPreIncExpr.h"
|
||||
#include "CBot/CBotInstr/CBotExprVar.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
|
||||
#include "CBot/CBotVar/CBotVar.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotPreIncExpr::CBotPreIncExpr()
|
||||
{
|
||||
m_Instr = nullptr;
|
||||
name = "CBotPreIncExpr";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotPreIncExpr::~CBotPreIncExpr()
|
||||
{
|
||||
delete m_Instr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotPreIncExpr::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
|
||||
if (pile->IfStep()) return false;
|
||||
|
||||
CBotVar* var1;
|
||||
|
||||
if (pile->GetState() == 0)
|
||||
{
|
||||
CBotStack* pile2 = pile;
|
||||
// retrieves the variable fields and indexes according
|
||||
// pile2 is modified on return
|
||||
if (!(static_cast<CBotExprVar*>(m_Instr))->ExecuteVar(var1, pile2, nullptr, true)) return false;
|
||||
|
||||
if (var1->IsNAN())
|
||||
{
|
||||
pile->SetError(TX_OPNAN, &m_token);
|
||||
return pj->Return(pile); // operation performed
|
||||
}
|
||||
|
||||
if (!var1->IsDefined())
|
||||
{
|
||||
pile->SetError(TX_NOTINIT, &m_token);
|
||||
return pj->Return(pile); // operation performed
|
||||
}
|
||||
|
||||
if (GetTokenType() == ID_INC) var1->Inc();
|
||||
else var1->Dec(); // ((CBotVarInt*)var1)->m_val
|
||||
|
||||
pile->IncState();
|
||||
}
|
||||
|
||||
if (!m_Instr->Execute(pile)) return false;
|
||||
return pj->Return(pile); // operation performed
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotPreIncExpr::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if (!bMain) return;
|
||||
|
||||
CBotStack* pile = pj->RestoreStack(this);
|
||||
if (pile == nullptr) return;
|
||||
|
||||
if (pile->GetState() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Instr->RestoreState(pile, bMain);
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The CBotPreIncExpr class Management of pre increment. There is no
|
||||
* routine Compiles, the object is created directly. Compiles in CBotParExpr
|
||||
*/
|
||||
class CBotPreIncExpr : public CBotInstr
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief CBotPreIncExpr
|
||||
*/
|
||||
CBotPreIncExpr();
|
||||
|
||||
/*!
|
||||
* \brief ~CBotPreIncExpr
|
||||
*/
|
||||
~CBotPreIncExpr();
|
||||
|
||||
/*!
|
||||
* \brief Execute
|
||||
* \param pj
|
||||
* \return
|
||||
*/
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/*!
|
||||
* \brief RestoreState
|
||||
* \param pj
|
||||
* \param bMain
|
||||
*/
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
private:
|
||||
CBotInstr* m_Instr;
|
||||
friend class CBotParExpr;
|
||||
};
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* 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 "CBot/CBotInstr/CBotReturn.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotInstrUtils.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotExpression.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotReturn::CBotReturn()
|
||||
{
|
||||
m_Instr = nullptr;
|
||||
name = "CBotReturn"; // debug
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotReturn::~CBotReturn()
|
||||
{
|
||||
delete m_Instr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotInstr* CBotReturn::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotToken* pp = p;
|
||||
|
||||
if (!IsOfType(p, ID_RETURN)) return nullptr; // should never happen
|
||||
|
||||
CBotReturn* inst = new CBotReturn(); // creates the object
|
||||
inst->SetToken( pp );
|
||||
|
||||
CBotTypResult type = pStack->GetRetType();
|
||||
|
||||
if ( type.GetType() == 0 ) // returned void ?
|
||||
{
|
||||
if ( IsOfType( p, ID_SEP ) ) return inst;
|
||||
pStack->SetError( TX_BADTYPE, pp );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inst->m_Instr = CBotExpression::Compile(p, pStack);
|
||||
if ( pStack->IsOk() )
|
||||
{
|
||||
CBotTypResult retType = pStack->GetTypResult(2);
|
||||
if (TypeCompatible(retType, type, ID_ASS))
|
||||
{
|
||||
if ( IsOfType( p, ID_SEP ) )
|
||||
return inst;
|
||||
|
||||
pStack->SetError(TX_ENDOF, p->GetStart());
|
||||
}
|
||||
pStack->SetError(TX_BADTYPE, p->GetStart());
|
||||
}
|
||||
|
||||
delete inst;
|
||||
return nullptr; // no object, the error is on the stack
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CBotReturn::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this);
|
||||
// if ( pile == EOX ) return true;
|
||||
|
||||
if ( pile->GetState() == 0 )
|
||||
{
|
||||
if ( m_Instr != nullptr && !m_Instr->Execute(pile) ) return false; // evaluate the result
|
||||
// the result is on the stack
|
||||
pile->IncState();
|
||||
}
|
||||
|
||||
if ( pile->IfStep() ) return false;
|
||||
|
||||
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 == nullptr ) return;
|
||||
|
||||
if ( pile->GetState() == 0 )
|
||||
{
|
||||
if ( m_Instr != nullptr ) m_Instr->RestoreState(pile, bMain); // evaluate the result
|
||||
return;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue