colobot/src/CBot/CBotVar/CBotVar.cpp

748 lines
20 KiB
C++
Raw Normal View History

/*
* This file is part of the Colobot: Gold Edition source code
2015-08-22 14:40:02 +00:00
* 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/CBotVar/CBotVar.h"
2013-11-25 19:03:06 +00:00
#include "CBot/CBotStack.h"
#include "CBot/CBotVar/CBotVarArray.h"
#include "CBot/CBotVar/CBotVarPointer.h"
#include "CBot/CBotVar/CBotVarClass.h"
#include "CBot/CBotVar/CBotVarBoolean.h"
#include "CBot/CBotVar/CBotVarString.h"
#include "CBot/CBotVar/CBotVarFloat.h"
#include "CBot/CBotVar/CBotVarInt.h"
#include "CBot/CBotClass.h"
#include "CBot/CBotToken.h"
#include "CBot/CBotEnums.h"
2015-11-22 16:54:40 +00:00
// Local include
// Global include
2013-11-25 19:03:06 +00:00
#include <cassert>
#include <cmath>
#include <cstdio>
#include <string>
////////////////////////////////////////////////////////////////////////////////
long CBotVar::m_identcpt = 0;
////////////////////////////////////////////////////////////////////////////////
CBotVar::CBotVar( )
{
2015-08-16 10:43:42 +00:00
m_next = nullptr;
m_pMyThis = nullptr;
m_pUserPtr = nullptr;
m_InitExpr = nullptr;
m_LimExpr = nullptr;
m_type = -1;
m_binit = InitType::UNDEF;
m_ident = 0;
m_bStatic = false;
2015-12-21 22:07:40 +00:00
m_mPrivate = ProtectionLevel::Public;
}
////////////////////////////////////////////////////////////////////////////////
CBotVar::~CBotVar( )
{
delete m_token;
delete m_next;
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::ConstructorSet()
{
// nop
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetUserPtr(void* pUser)
{
m_pUserPtr = pUser;
if (m_type.Eq(CBotTypPointer) &&
2015-08-16 10:43:42 +00:00
(static_cast<CBotVarPointer*>(this))->m_pVarClass != nullptr )
(static_cast<CBotVarPointer*>(this))->m_pVarClass->SetUserPtr(pUser);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetIdent(long n)
{
if (m_type.Eq(CBotTypPointer) &&
2015-08-16 10:43:42 +00:00
(static_cast<CBotVarPointer*>(this))->m_pVarClass != nullptr )
(static_cast<CBotVarPointer*>(this))->m_pVarClass->SetIdent(n);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetUniqNum(long n)
{
m_ident = n;
2013-11-25 19:03:06 +00:00
if ( n == 0 ) assert(0);
}
////////////////////////////////////////////////////////////////////////////////
long CBotVar::NextUniqNum()
{
if (++m_identcpt < 10000) m_identcpt = 10000;
return m_identcpt;
}
////////////////////////////////////////////////////////////////////////////////
2012-08-11 18:59:35 +00:00
long CBotVar::GetUniqNum()
{
return m_ident;
}
////////////////////////////////////////////////////////////////////////////////
2012-08-11 18:59:35 +00:00
void* CBotVar::GetUserPtr()
{
return m_pUserPtr;
}
////////////////////////////////////////////////////////////////////////////////
bool CBotVar::Save1State(FILE* pf)
{
// this routine "virtual" must never be called,
// there must be a routine for each of the subclasses (CBotVarInt, CBotVarFloat, etc)
// ( see the type in m_type )
2013-11-25 19:03:06 +00:00
assert(0);
return false;
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::Maj(void* pUser, bool bContinu)
{
2015-08-16 10:43:42 +00:00
/* if (!bContinu && m_pMyThis != nullptr)
m_pMyThis->Maj(pUser, true);*/
}
////////////////////////////////////////////////////////////////////////////////
CBotVar* CBotVar::Create(const CBotToken* name, CBotType type )
{
CBotTypResult t(type);
return Create(name, t);
}
////////////////////////////////////////////////////////////////////////////////
CBotVar* CBotVar::Create(const CBotToken* name, CBotTypResult type)
{
2012-08-11 18:59:35 +00:00
switch (type.GetType())
{
case CBotTypShort:
case CBotTypInt:
return new CBotVarInt(name);
case CBotTypFloat:
return new CBotVarFloat(name);
case CBotTypBoolean:
return new CBotVarBoolean(name);
case CBotTypString:
return new CBotVarString(name);
case CBotTypPointer:
case CBotTypNullPointer:
return new CBotVarPointer(name, type);
case CBotTypIntrinsic:
return new CBotVarClass(name, type);
case CBotTypClass:
// creates a new instance of a class
// and returns the POINTER on this instance
{
CBotVarClass* instance = new CBotVarClass(name, type);
CBotVarPointer* pointer = new CBotVarPointer(name, type);
pointer->SetPointer( instance );
return pointer;
}
case CBotTypArrayPointer:
return new CBotVarArray(name, type);
case CBotTypArrayBody:
{
CBotVarClass* instance = new CBotVarClass(name, type);
CBotVarArray* array = new CBotVarArray(name, type);
array->SetPointer( instance );
CBotVar* pv = array;
while (type.Eq(CBotTypArrayBody))
{
2012-08-11 18:59:35 +00:00
type = type.GetTypElem();
pv = (static_cast<CBotVarArray*>(pv))->GetItem(0, true); // creates at least the element [0]
}
return array;
}
}
2013-11-25 19:03:06 +00:00
assert(0);
2015-08-16 10:43:42 +00:00
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
CBotVar* CBotVar::Create( CBotVar* pVar )
{
2012-08-11 18:59:35 +00:00
CBotVar* p = Create(pVar->m_token->GetString(), pVar->GetTypResult(2));
return p;
}
////////////////////////////////////////////////////////////////////////////////
CBotVar* CBotVar::Create(const std::string& n, CBotTypResult type)
{
CBotToken name(n);
2012-08-11 18:59:35 +00:00
switch (type.GetType())
{
case CBotTypShort:
case CBotTypInt:
return new CBotVarInt(&name);
case CBotTypFloat:
return new CBotVarFloat(&name);
case CBotTypBoolean:
return new CBotVarBoolean(&name);
case CBotTypString:
return new CBotVarString(&name);
case CBotTypPointer:
case CBotTypNullPointer:
{
CBotVarPointer* p = new CBotVarPointer(&name, type);
2012-08-11 18:59:35 +00:00
// p->SetClass(type.GetClass());
return p;
}
case CBotTypIntrinsic:
{
CBotVarClass* p = new CBotVarClass(&name, type);
2012-08-11 18:59:35 +00:00
// p->SetClass(type.GetClass());
return p;
}
case CBotTypClass:
// creates a new instance of a class
// and returns the POINTER on this instance
{
CBotVarClass* instance = new CBotVarClass(&name, type);
CBotVarPointer* pointer = new CBotVarPointer(&name, type);
pointer->SetPointer( instance );
2012-08-11 18:59:35 +00:00
// pointer->SetClass( type.GetClass() );
return pointer;
}
case CBotTypArrayPointer:
return new CBotVarArray(&name, type);
case CBotTypArrayBody:
{
CBotVarClass* instance = new CBotVarClass(&name, type);
CBotVarArray* array = new CBotVarArray(&name, type);
array->SetPointer( instance );
CBotVar* pv = array;
while (type.Eq(CBotTypArrayBody))
{
2012-08-11 18:59:35 +00:00
type = type.GetTypElem();
pv = (static_cast<CBotVarArray*>(pv))->GetItem(0, true); // creates at least the element [0]
}
return array;
}
}
2013-11-25 19:03:06 +00:00
assert(0);
2015-08-16 10:43:42 +00:00
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
CBotVar* CBotVar::Create(const std::string& name, CBotType type, CBotClass* pClass)
{
CBotToken token( name, "" );
CBotVar* pVar = Create( &token, type );
2015-08-16 10:43:42 +00:00
if ( type == CBotTypPointer && pClass == nullptr ) // pointer "null" ?
return pVar;
if ( type == CBotTypClass || type == CBotTypPointer ||
type == CBotTypIntrinsic )
{
2015-08-16 10:43:42 +00:00
if (pClass == nullptr)
{
delete pVar;
2015-08-16 10:43:42 +00:00
return nullptr;
}
pVar->SetClass( pClass );
}
return pVar;
}
////////////////////////////////////////////////////////////////////////////////
CBotVar* CBotVar::Create(const std::string& name, CBotClass* pClass)
{
CBotToken token( name, "" );
CBotVar* pVar = Create( &token, CBotTypResult( CBotTypClass, pClass ) );
// pVar->SetClass( pClass );
return pVar;
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::Destroy(CBotVar* var)
{
delete var;
}
////////////////////////////////////////////////////////////////////////////////
2012-08-11 18:59:35 +00:00
CBotTypResult CBotVar::GetTypResult(int mode)
{
CBotTypResult r = m_type;
if ( mode == 1 && m_type.Eq(CBotTypClass) )
r.SetType(CBotTypPointer);
if ( mode == 2 && m_type.Eq(CBotTypClass) )
r.SetType(CBotTypIntrinsic);
return r;
}
////////////////////////////////////////////////////////////////////////////////
CBotType CBotVar::GetType(int mode)
{
if ( mode == 1 && m_type.Eq(CBotTypClass) )
return CBotTypPointer;
if ( mode == 2 && m_type.Eq(CBotTypClass) )
return CBotTypIntrinsic;
return static_cast<CBotType>(m_type.GetType());
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetType(CBotTypResult& type)
{
m_type = type;
}
////////////////////////////////////////////////////////////////////////////////
CBotVar::InitType CBotVar::GetInit() const
{
if ( m_type.Eq(CBotTypClass) ) return InitType::DEF; // always set!
return m_binit;
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetInit(CBotVar::InitType initType)
{
m_binit = initType;
if (initType == CBotVar::InitType::IS_POINTER ) m_binit = CBotVar::InitType::DEF; // cas spécial
if ( m_type.Eq(CBotTypPointer) && initType == CBotVar::InitType::IS_POINTER )
{
2012-08-11 18:59:35 +00:00
CBotVarClass* instance = GetPointer();
2015-08-16 10:43:42 +00:00
if ( instance == nullptr )
{
2015-08-16 10:43:42 +00:00
instance = new CBotVarClass(nullptr, m_type);
// instance->SetClass((static_cast<CBotVarPointer*>(this))->m_classes);
SetPointer(instance);
}
instance->SetInit(CBotVar::InitType::DEF);
}
if ( m_type.Eq(CBotTypClass) || m_type.Eq(CBotTypIntrinsic) )
{
CBotVar* p = (static_cast<CBotVarClass*>(this))->m_pVar;
2015-08-16 10:43:42 +00:00
while( p != nullptr )
{
p->SetInit(initType);
p->m_pMyThis = static_cast<CBotVarClass*>(this);
2012-08-11 18:59:35 +00:00
p = p->GetNext();
}
}
}
////////////////////////////////////////////////////////////////////////////////
std::string CBotVar::GetName()
{
2012-08-11 18:59:35 +00:00
return m_token->GetString();
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetName(const std::string& name)
{
m_token->SetString(name);
}
////////////////////////////////////////////////////////////////////////////////
2012-08-11 18:59:35 +00:00
CBotToken* CBotVar::GetToken()
{
return m_token;
}
////////////////////////////////////////////////////////////////////////////////
CBotVar* CBotVar::GetItem(const std::string& name)
{
2013-11-25 19:03:06 +00:00
assert(0);
2015-08-16 10:43:42 +00:00
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
2012-08-11 18:59:35 +00:00
CBotVar* CBotVar::GetItemRef(int nIdent)
{
2013-11-25 19:03:06 +00:00
assert(0);
2015-08-16 10:43:42 +00:00
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
2012-08-11 18:59:35 +00:00
CBotVar* CBotVar::GetItemList()
{
2013-11-25 19:03:06 +00:00
assert(0);
2015-08-16 10:43:42 +00:00
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
CBotVar* CBotVar::GetItem(int index, bool grow)
{
2013-11-25 19:03:06 +00:00
assert(0);
2015-08-16 10:43:42 +00:00
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
bool CBotVar::IsElemOfClass(const std::string& name)
{
2015-08-16 10:43:42 +00:00
CBotClass* pc = nullptr;
if ( m_type.Eq(CBotTypPointer) )
{
pc = (static_cast<CBotVarPointer*>(this))->m_pClass;
}
if ( m_type.Eq(CBotTypClass) )
{
pc = (static_cast<CBotVarClass*>(this))->m_pClass;
}
2015-08-16 10:43:42 +00:00
while ( pc != nullptr )
{
2012-08-11 18:59:35 +00:00
if ( pc->GetName() == name ) return true;
pc = pc->GetParent();
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
2012-08-11 18:59:35 +00:00
CBotVar* CBotVar::GetStaticVar()
{
// makes the pointer to the variable if it is static
2015-08-16 10:43:42 +00:00
if ( m_bStatic == 0 || m_pMyThis == nullptr ) return this;
2012-08-11 18:59:35 +00:00
CBotClass* pClass = m_pMyThis->GetClass();
return pClass->GetItem( m_token->GetString() );
}
////////////////////////////////////////////////////////////////////////////////
2012-08-11 18:59:35 +00:00
CBotVar* CBotVar::GetNext()
{
return m_next;
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::AddNext(CBotVar* pVar)
{
CBotVar* p = this;
2015-08-16 10:43:42 +00:00
while (p->m_next != nullptr) p = p->m_next;
p->m_next = pVar;
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetVal(CBotVar* var)
{
2012-09-29 19:46:34 +00:00
switch (var->GetType())
{
case CBotTypBoolean:
2012-08-11 18:59:35 +00:00
SetValInt(var->GetValInt());
break;
case CBotTypInt:
SetValInt(var->GetValInt(), (static_cast<CBotVarInt*>(var))->m_defnum);
break;
case CBotTypFloat:
2012-08-11 18:59:35 +00:00
SetValFloat(var->GetValFloat());
break;
case CBotTypString:
2012-08-11 18:59:35 +00:00
SetValString(var->GetValString());
break;
case CBotTypPointer:
case CBotTypNullPointer:
case CBotTypArrayPointer:
2012-08-11 18:59:35 +00:00
SetPointer(var->GetPointer());
break;
case CBotTypClass:
{
delete (static_cast<CBotVarClass*>(this))->m_pVar;
2015-08-16 10:43:42 +00:00
(static_cast<CBotVarClass*>(this))->m_pVar = nullptr;
Copy(var, false);
}
break;
default:
2013-11-25 19:03:06 +00:00
assert(0);
}
m_binit = var->m_binit; // copie l'état nan s'il y a
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetStatic(bool bStatic)
{
m_bStatic = bStatic;
}
////////////////////////////////////////////////////////////////////////////////
2015-12-21 22:07:40 +00:00
void CBotVar::SetPrivate(ProtectionLevel mPrivate)
{
m_mPrivate = mPrivate;
}
////////////////////////////////////////////////////////////////////////////////
bool CBotVar::IsStatic()
{
return m_bStatic;
}
////////////////////////////////////////////////////////////////////////////////
bool CBotVar::IsPrivate(ProtectionLevel level)
{
return static_cast<int>(m_mPrivate) >= static_cast<int>(level);
}
////////////////////////////////////////////////////////////////////////////////
2015-12-21 22:07:40 +00:00
CBotVar::ProtectionLevel CBotVar::GetPrivate()
{
return m_mPrivate;
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetPointer(CBotVar* pVarClass)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
2012-08-11 18:59:35 +00:00
CBotVarClass* CBotVar::GetPointer()
{
2013-11-25 19:03:06 +00:00
assert(0);
2015-08-16 10:43:42 +00:00
return nullptr;
}
// All these functions must be defined in the subclasses
// derived from class CBotVar
////////////////////////////////////////////////////////////////////////////////
2012-08-11 18:59:35 +00:00
int CBotVar::GetValInt()
{
2013-11-25 19:03:06 +00:00
assert(0);
return 0;
}
////////////////////////////////////////////////////////////////////////////////
2012-08-11 18:59:35 +00:00
float CBotVar::GetValFloat()
{
2013-11-25 19:03:06 +00:00
assert(0);
return 0;
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetValInt(int c, const std::string& s)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetValFloat(float c)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::Mul(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::Power(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
CBotError CBotVar::Div(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
return CBotNoErr;
}
////////////////////////////////////////////////////////////////////////////////
CBotError CBotVar::Modulo(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
return CBotNoErr;
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::Add(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::Sub(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
bool CBotVar::Lo(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool CBotVar::Hi(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool CBotVar::Ls(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool CBotVar::Hs(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool CBotVar::Eq(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool CBotVar::Ne(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
return false;
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::And(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::Or(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::XOr(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::ASR(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SR(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SL(CBotVar* left, CBotVar* right)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::Neg()
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::Not()
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::Inc()
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::Dec()
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::Copy(CBotVar* pSrc, bool bName)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetValString(const std::string& val)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
std::string CBotVar::GetValString()
{
2013-11-25 19:03:06 +00:00
assert(0);
return std::string();
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetClass(CBotClass* pClass)
{
2013-11-25 19:03:06 +00:00
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
2012-08-11 18:59:35 +00:00
CBotClass* CBotVar::GetClass()
{
2013-11-25 19:03:06 +00:00
assert(0);
2015-08-16 10:43:42 +00:00
return nullptr;
}