2248 lines
50 KiB
C++
2248 lines
50 KiB
C++
// * This file is part of the COLOBOT source code
|
|
// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
|
|
// *
|
|
// * This program is free software: you can redistribute it and/or modify
|
|
// * it under the terms of the GNU General Public License as published by
|
|
// * the Free Software Foundation, either version 3 of the License, or
|
|
// * (at your option) any later version.
|
|
// *
|
|
// * This program is distributed in the hope that it will be useful,
|
|
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// * GNU General Public License for more details.
|
|
// *
|
|
// * You should have received a copy of the GNU General Public License
|
|
// * along with this program. If not, see http://www.gnu.org/licenses/.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Definition for the class CBotVar
|
|
// variables management of the language CBoT
|
|
|
|
// it never creates an instance of the class mother CBotVar
|
|
|
|
#include "CBot.h"
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
|
|
long CBotVar::m_identcpt = 0;
|
|
|
|
CBotVar::CBotVar( )
|
|
{
|
|
m_next = NULL;
|
|
m_pMyThis = NULL;
|
|
m_pUserPtr = NULL;
|
|
m_InitExpr = NULL;
|
|
m_LimExpr = NULL;
|
|
m_type = -1;
|
|
m_binit = false;
|
|
m_ident = 0;
|
|
m_bStatic = false;
|
|
m_mPrivate = 0;
|
|
}
|
|
|
|
CBotVarInt::CBotVarInt( const CBotToken* name )
|
|
{
|
|
m_token = new CBotToken(name);
|
|
m_next = NULL;
|
|
m_pMyThis = NULL;
|
|
m_pUserPtr = NULL;
|
|
m_InitExpr = NULL;
|
|
m_LimExpr = NULL;
|
|
m_type = CBotTypInt;
|
|
m_binit = false;
|
|
m_bStatic = false;
|
|
m_mPrivate = 0;
|
|
|
|
m_val = 0;
|
|
}
|
|
|
|
CBotVarFloat::CBotVarFloat( const CBotToken* name )
|
|
{
|
|
m_token = new CBotToken(name);
|
|
m_next = NULL;
|
|
m_pMyThis = NULL;
|
|
m_pUserPtr = NULL;
|
|
m_InitExpr = NULL;
|
|
m_LimExpr = NULL;
|
|
m_type = CBotTypFloat;
|
|
m_binit = false;
|
|
m_bStatic = false;
|
|
m_mPrivate = 0;
|
|
|
|
m_val = 0;
|
|
}
|
|
|
|
CBotVarString::CBotVarString( const CBotToken* name )
|
|
{
|
|
m_token = new CBotToken(name);
|
|
m_next = NULL;
|
|
m_pMyThis = NULL;
|
|
m_pUserPtr = NULL;
|
|
m_InitExpr = NULL;
|
|
m_LimExpr = NULL;
|
|
m_type = CBotTypString;
|
|
m_binit = false;
|
|
m_bStatic = false;
|
|
m_mPrivate = 0;
|
|
|
|
m_val.Empty();
|
|
}
|
|
|
|
CBotVarBoolean::CBotVarBoolean( const CBotToken* name )
|
|
{
|
|
m_token = new CBotToken(name);
|
|
m_next = NULL;
|
|
m_pMyThis = NULL;
|
|
m_pUserPtr = NULL;
|
|
m_InitExpr = NULL;
|
|
m_LimExpr = NULL;
|
|
m_type = CBotTypBoolean;
|
|
m_binit = false;
|
|
m_bStatic = false;
|
|
m_mPrivate = 0;
|
|
|
|
m_val = 0;
|
|
}
|
|
|
|
CBotVarClass* CBotVarClass::m_ExClass = NULL;
|
|
|
|
CBotVarClass::CBotVarClass( const CBotToken* name, const CBotTypResult& type)
|
|
{
|
|
/*
|
|
// int nIdent = 0;
|
|
InitCBotVarClass( name, type ) //, nIdent );
|
|
}
|
|
|
|
CBotVarClass::CBotVarClass( const CBotToken* name, CBotTypResult& type) //, int &nIdent )
|
|
{
|
|
InitCBotVarClass( name, type ); //, nIdent );
|
|
}
|
|
|
|
void CBotVarClass::InitCBotVarClass( const CBotToken* name, CBotTypResult& type ) //, int &nIdent )
|
|
{*/
|
|
if ( !type.Eq(CBotTypClass) &&
|
|
!type.Eq(CBotTypIntrinsic) && // by convenience there accepts these types
|
|
!type.Eq(CBotTypPointer) &&
|
|
!type.Eq(CBotTypArrayPointer) &&
|
|
!type.Eq(CBotTypArrayBody)) ASM_TRAP();
|
|
|
|
m_token = new CBotToken(name);
|
|
m_next = NULL;
|
|
m_pMyThis = NULL;
|
|
m_pUserPtr = OBJECTCREATED;//NULL;
|
|
m_InitExpr = NULL;
|
|
m_LimExpr = NULL;
|
|
m_pVar = NULL;
|
|
m_type = type;
|
|
if ( type.Eq(CBotTypArrayPointer) ) m_type.SetType( CBotTypArrayBody );
|
|
else if ( !type.Eq(CBotTypArrayBody) ) m_type.SetType( CBotTypClass );
|
|
// officel type for this object
|
|
|
|
m_pClass = NULL;
|
|
m_pParent = NULL;
|
|
m_binit = false;
|
|
m_bStatic = false;
|
|
m_mPrivate = 0;
|
|
m_bConstructor = false;
|
|
m_CptUse = 0;
|
|
m_ItemIdent = type.Eq(CBotTypIntrinsic) ? 0 : CBotVar::NextUniqNum();
|
|
|
|
// se place tout seul dans la liste
|
|
// TODO stands alone in the list (stands only in a list)
|
|
if (m_ExClass) m_ExClass->m_ExPrev = this;
|
|
m_ExNext = m_ExClass;
|
|
m_ExPrev = NULL;
|
|
m_ExClass = this;
|
|
|
|
CBotClass* pClass = type.GetClass();
|
|
CBotClass* pClass2 = pClass->GetParent();
|
|
if ( pClass2 != NULL )
|
|
{
|
|
// also creates an instance of the parent class
|
|
m_pParent = new CBotVarClass(name, CBotTypResult(type.GetType(),pClass2) ); //, nIdent);
|
|
}
|
|
|
|
SetClass( pClass ); //, nIdent );
|
|
|
|
}
|
|
|
|
CBotVarClass::~CBotVarClass( )
|
|
{
|
|
if ( m_CptUse != 0 )
|
|
ASM_TRAP();
|
|
|
|
if ( m_pParent ) delete m_pParent;
|
|
m_pParent = NULL;
|
|
|
|
// frees the indirect object if necessary
|
|
// if ( m_Indirect != NULL )
|
|
// m_Indirect->DecrementUse();
|
|
|
|
// removes the class list
|
|
if ( m_ExPrev ) m_ExPrev->m_ExNext = m_ExNext;
|
|
else m_ExClass = m_ExNext;
|
|
|
|
if ( m_ExNext ) m_ExNext->m_ExPrev = m_ExPrev;
|
|
m_ExPrev = NULL;
|
|
m_ExNext = NULL;
|
|
|
|
delete m_pVar;
|
|
}
|
|
|
|
void CBotVarClass::ConstructorSet()
|
|
{
|
|
m_bConstructor = true;
|
|
}
|
|
|
|
|
|
CBotVar::~CBotVar( )
|
|
{
|
|
delete m_token;
|
|
delete m_next;
|
|
}
|
|
|
|
void CBotVar::debug()
|
|
{
|
|
// const char* p = static_cast<const char*>( m_token->GetString());
|
|
CBotString s = static_cast<const char*>( GetValString());
|
|
// const char* v = static_cast<const char*> (s);
|
|
|
|
if ( m_type.Eq(CBotTypClass) )
|
|
{
|
|
CBotVar* pv = (static_cast<CBotVarClass*>(this))->m_pVar;
|
|
while (pv != NULL)
|
|
{
|
|
pv->debug();
|
|
pv = pv->GetNext();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CBotVar::ConstructorSet()
|
|
{
|
|
// nop
|
|
}
|
|
|
|
void CBotVar::SetUserPtr(void* pUser)
|
|
{
|
|
m_pUserPtr = pUser;
|
|
if (m_type.Eq(CBotTypPointer) &&
|
|
(static_cast<CBotVarPointer*>(this))->m_pVarClass != NULL )
|
|
(static_cast<CBotVarPointer*>(this))->m_pVarClass->SetUserPtr(pUser);
|
|
}
|
|
|
|
void CBotVar::SetIdent(long n)
|
|
{
|
|
if (m_type.Eq(CBotTypPointer) &&
|
|
(static_cast<CBotVarPointer*>(this))->m_pVarClass != NULL )
|
|
(static_cast<CBotVarPointer*>(this))->m_pVarClass->SetIdent(n);
|
|
}
|
|
|
|
void CBotVar::SetUniqNum(long n)
|
|
{
|
|
m_ident = n;
|
|
|
|
if ( n == 0 ) ASM_TRAP();
|
|
}
|
|
|
|
long CBotVar::NextUniqNum()
|
|
{
|
|
if (++m_identcpt < 10000) m_identcpt = 10000;
|
|
return m_identcpt;
|
|
}
|
|
|
|
long CBotVar::GetUniqNum()
|
|
{
|
|
return m_ident;
|
|
}
|
|
|
|
|
|
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 )
|
|
ASM_TRAP();
|
|
return false;
|
|
}
|
|
|
|
void CBotVar::Maj(void* pUser, bool bContinu)
|
|
{
|
|
/* if (!bContinu && m_pMyThis != NULL)
|
|
m_pMyThis->Maj(pUser, true);*/
|
|
}
|
|
|
|
|
|
// creates a variable depending on its type
|
|
|
|
CBotVar* CBotVar::Create(const CBotToken* name, int type )
|
|
{
|
|
CBotTypResult t(type);
|
|
return Create(name, t);
|
|
}
|
|
|
|
CBotVar* CBotVar::Create(const CBotToken* name, CBotTypResult type)
|
|
{
|
|
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))
|
|
{
|
|
type = type.GetTypElem();
|
|
pv = (static_cast<CBotVarArray*>(pv))->GetItem(0, true); // creates at least the element [0]
|
|
}
|
|
|
|
return array;
|
|
}
|
|
}
|
|
|
|
ASM_TRAP();
|
|
return NULL;
|
|
}
|
|
|
|
CBotVar* CBotVar::Create( CBotVar* pVar )
|
|
{
|
|
CBotVar* p = Create(pVar->m_token->GetString(), pVar->GetTypResult(2));
|
|
return p;
|
|
}
|
|
|
|
|
|
CBotVar* CBotVar::Create( const char* n, CBotTypResult type)
|
|
{
|
|
CBotToken name(n);
|
|
|
|
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);
|
|
// p->SetClass(type.GetClass());
|
|
return p;
|
|
}
|
|
case CBotTypIntrinsic:
|
|
{
|
|
CBotVarClass* p = new CBotVarClass(&name, type);
|
|
// 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 );
|
|
// 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))
|
|
{
|
|
type = type.GetTypElem();
|
|
pv = (static_cast<CBotVarArray*>(pv))->GetItem(0, true); // creates at least the element [0]
|
|
}
|
|
|
|
return array;
|
|
}
|
|
}
|
|
|
|
ASM_TRAP();
|
|
return NULL;
|
|
}
|
|
|
|
CBotVar* CBotVar::Create( const char* name, int type, CBotClass* pClass)
|
|
{
|
|
CBotToken token( name, "" );
|
|
CBotVar* pVar = Create( &token, type );
|
|
|
|
if ( type == CBotTypPointer && pClass == NULL ) // pointer "null" ?
|
|
return pVar;
|
|
|
|
if ( type == CBotTypClass || type == CBotTypPointer ||
|
|
type == CBotTypIntrinsic )
|
|
{
|
|
if (pClass == NULL)
|
|
{
|
|
delete pVar;
|
|
return NULL;
|
|
}
|
|
pVar->SetClass( pClass );
|
|
}
|
|
return pVar;
|
|
}
|
|
|
|
CBotVar* CBotVar::Create( const char* name, CBotClass* pClass)
|
|
{
|
|
CBotToken token( name, "" );
|
|
CBotVar* pVar = Create( &token, CBotTypResult( CBotTypClass, pClass ) );
|
|
// pVar->SetClass( pClass );
|
|
return pVar;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
int CBotVar::GetType(int mode)
|
|
{
|
|
if ( mode == 1 && m_type.Eq(CBotTypClass) )
|
|
return CBotTypPointer;
|
|
if ( mode == 2 && m_type.Eq(CBotTypClass) )
|
|
return CBotTypIntrinsic;
|
|
return m_type.GetType();
|
|
}
|
|
|
|
void CBotVar::SetType(CBotTypResult& type)
|
|
{
|
|
m_type = type;
|
|
}
|
|
|
|
|
|
int CBotVar::GetInit()
|
|
{
|
|
if ( m_type.Eq(CBotTypClass) ) return IS_DEF; // always set!
|
|
|
|
return m_binit;
|
|
}
|
|
|
|
void CBotVar::SetInit(int bInit)
|
|
{
|
|
m_binit = bInit;
|
|
if ( bInit == 2 ) m_binit = IS_DEF; // cas spécial
|
|
|
|
if ( m_type.Eq(CBotTypPointer) && bInit == 2 )
|
|
{
|
|
CBotVarClass* instance = GetPointer();
|
|
if ( instance == NULL )
|
|
{
|
|
instance = new CBotVarClass(NULL, m_type);
|
|
// instance->SetClass((static_cast<CBotVarPointer*>(this))->m_pClass);
|
|
SetPointer(instance);
|
|
}
|
|
instance->SetInit(1);
|
|
}
|
|
|
|
if ( m_type.Eq(CBotTypClass) || m_type.Eq(CBotTypIntrinsic) )
|
|
{
|
|
CBotVar* p = (static_cast<CBotVarClass*>(this))->m_pVar;
|
|
while( p != NULL )
|
|
{
|
|
p->SetInit( bInit );
|
|
p->m_pMyThis = static_cast<CBotVarClass*>(this);
|
|
p = p->GetNext();
|
|
}
|
|
}
|
|
}
|
|
|
|
CBotString CBotVar::GetName()
|
|
{
|
|
return m_token->GetString();
|
|
}
|
|
|
|
void CBotVar::SetName(const char* name)
|
|
{
|
|
m_token->SetString(name);
|
|
}
|
|
|
|
CBotToken* CBotVar::GetToken()
|
|
{
|
|
return m_token;
|
|
}
|
|
|
|
CBotVar* CBotVar::GetItem(const char* name)
|
|
{
|
|
ASM_TRAP();
|
|
return NULL;
|
|
}
|
|
|
|
CBotVar* CBotVar::GetItemRef(int nIdent)
|
|
{
|
|
ASM_TRAP();
|
|
return NULL;
|
|
}
|
|
|
|
CBotVar* CBotVar::GetItemList()
|
|
{
|
|
ASM_TRAP();
|
|
return NULL;
|
|
}
|
|
|
|
CBotVar* CBotVar::GetItem(int row, bool bGrow)
|
|
{
|
|
ASM_TRAP();
|
|
return NULL;
|
|
}
|
|
|
|
// check if a variable belongs to a given class
|
|
bool CBotVar::IsElemOfClass(const char* name)
|
|
{
|
|
CBotClass* pc = NULL;
|
|
|
|
if ( m_type.Eq(CBotTypPointer) )
|
|
{
|
|
pc = (static_cast<CBotVarPointer*>(this))->m_pClass;
|
|
}
|
|
if ( m_type.Eq(CBotTypClass) )
|
|
{
|
|
pc = (static_cast<CBotVarClass*>(this))->m_pClass;
|
|
}
|
|
|
|
while ( pc != NULL )
|
|
{
|
|
if ( pc->GetName() == name ) return true;
|
|
pc = pc->GetParent();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
CBotVar* CBotVar::GetStaticVar()
|
|
{
|
|
// makes the pointer to the variable if it is static
|
|
if ( m_bStatic == 0 || m_pMyThis == NULL ) return this;
|
|
|
|
CBotClass* pClass = m_pMyThis->GetClass();
|
|
return pClass->GetItem( m_token->GetString() );
|
|
}
|
|
|
|
|
|
CBotVar* CBotVar::GetNext()
|
|
{
|
|
return m_next;
|
|
}
|
|
|
|
void CBotVar::AddNext(CBotVar* pVar)
|
|
{
|
|
CBotVar* p = this;
|
|
while (p->m_next != NULL) p = p->m_next;
|
|
|
|
p->m_next = pVar;
|
|
}
|
|
|
|
void CBotVar::SetVal(CBotVar* var)
|
|
{
|
|
switch (var->GetType())
|
|
{
|
|
case CBotTypBoolean:
|
|
SetValInt(var->GetValInt());
|
|
break;
|
|
case CBotTypInt:
|
|
SetValInt(var->GetValInt(), (static_cast<CBotVarInt*>(var))->m_defnum);
|
|
break;
|
|
case CBotTypFloat:
|
|
SetValFloat(var->GetValFloat());
|
|
break;
|
|
case CBotTypString:
|
|
SetValString(var->GetValString());
|
|
break;
|
|
case CBotTypPointer:
|
|
case CBotTypNullPointer:
|
|
case CBotTypArrayPointer:
|
|
SetPointer(var->GetPointer());
|
|
break;
|
|
case CBotTypClass:
|
|
{
|
|
delete (static_cast<CBotVarClass*>(this))->m_pVar;
|
|
(static_cast<CBotVarClass*>(this))->m_pVar = NULL;
|
|
Copy(var, false);
|
|
}
|
|
break;
|
|
default:
|
|
ASM_TRAP();
|
|
}
|
|
|
|
m_binit = var->m_binit; // copie l'état nan s'il y a
|
|
}
|
|
|
|
void CBotVar::SetStatic(bool bStatic)
|
|
{
|
|
m_bStatic = bStatic;
|
|
}
|
|
|
|
void CBotVar::SetPrivate(int mPrivate)
|
|
{
|
|
m_mPrivate = mPrivate;
|
|
}
|
|
|
|
bool CBotVar::IsStatic()
|
|
{
|
|
return m_bStatic;
|
|
}
|
|
|
|
bool CBotVar::IsPrivate(int mode)
|
|
{
|
|
return m_mPrivate >= mode;
|
|
}
|
|
|
|
int CBotVar::GetPrivate()
|
|
{
|
|
return m_mPrivate;
|
|
}
|
|
|
|
|
|
void CBotVar::SetPointer(CBotVar* pVarClass)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
CBotVarClass* CBotVar::GetPointer()
|
|
{
|
|
ASM_TRAP();
|
|
return NULL;
|
|
}
|
|
|
|
// All these functions must be defined in the subclasses
|
|
// derived from class CBotVar
|
|
|
|
int CBotVar::GetValInt()
|
|
{
|
|
ASM_TRAP();
|
|
return 0;
|
|
}
|
|
|
|
float CBotVar::GetValFloat()
|
|
{
|
|
ASM_TRAP();
|
|
return 0;
|
|
}
|
|
|
|
void CBotVar::SetValInt(int c, const char* s)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
void CBotVar::SetValFloat(float c)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
void CBotVar::Mul(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
void CBotVar::Power(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
int CBotVar::Div(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
return 0;
|
|
}
|
|
|
|
int CBotVar::Modulo(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
return 0;
|
|
}
|
|
|
|
void CBotVar::Add(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
void CBotVar::Sub(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
bool CBotVar::Lo(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
return false;
|
|
}
|
|
|
|
bool CBotVar::Hi(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
return false;
|
|
}
|
|
|
|
bool CBotVar::Ls(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
return false;
|
|
}
|
|
|
|
bool CBotVar::Hs(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
return false;
|
|
}
|
|
|
|
bool CBotVar::Eq(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
return false;
|
|
}
|
|
|
|
bool CBotVar::Ne(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
return false;
|
|
}
|
|
|
|
void CBotVar::And(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
void CBotVar::Or(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
void CBotVar::XOr(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
void CBotVar::ASR(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
void CBotVar::SR(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
void CBotVar::SL(CBotVar* left, CBotVar* right)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
void CBotVar::Neg()
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
void CBotVar::Not()
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
void CBotVar::Inc()
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
void CBotVar::Dec()
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
void CBotVar::Copy(CBotVar* pSrc, bool bName)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
void CBotVar::SetValString(const char* p)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
CBotString CBotVar::GetValString()
|
|
{
|
|
ASM_TRAP();
|
|
return CBotString();
|
|
}
|
|
|
|
void CBotVar::SetClass(CBotClass* pClass)
|
|
{
|
|
ASM_TRAP();
|
|
}
|
|
|
|
CBotClass* CBotVar::GetClass()
|
|
{
|
|
ASM_TRAP();
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
void CBotVar::SetIndirection(CBotVar* pVar)
|
|
{
|
|
// nop, only CBotVarPointer::SetIndirection
|
|
}
|
|
*/
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// copy a variable in to another
|
|
void CBotVarInt::Copy(CBotVar* pSrc, bool bName)
|
|
{
|
|
CBotVarInt* p = static_cast<CBotVarInt*>(pSrc);
|
|
|
|
if ( bName) *m_token = *p->m_token;
|
|
m_type = p->m_type;
|
|
m_val = p->m_val;
|
|
m_binit = p->m_binit;
|
|
m_pMyThis = NULL;
|
|
m_pUserPtr = p->m_pUserPtr;
|
|
|
|
// identificator is the same (by défaut)
|
|
if (m_ident == 0 ) m_ident = p->m_ident;
|
|
|
|
m_defnum = p->m_defnum;
|
|
}
|
|
|
|
|
|
|
|
|
|
void CBotVarInt::SetValInt(int val, const char* defnum)
|
|
{
|
|
m_val = val;
|
|
m_binit = true;
|
|
m_defnum = defnum;
|
|
}
|
|
|
|
|
|
|
|
void CBotVarInt::SetValFloat(float val)
|
|
{
|
|
m_val = static_cast<int>(val);
|
|
m_binit = true;
|
|
}
|
|
|
|
int CBotVarInt::GetValInt()
|
|
{
|
|
return m_val;
|
|
}
|
|
|
|
float CBotVarInt::GetValFloat()
|
|
{
|
|
return static_cast<float>(m_val);
|
|
}
|
|
|
|
CBotString CBotVarInt::GetValString()
|
|
{
|
|
if ( !m_defnum.IsEmpty() ) return m_defnum;
|
|
|
|
CBotString res;
|
|
|
|
if ( !m_binit )
|
|
{
|
|
res.LoadString(TX_UNDEF);
|
|
return res;
|
|
}
|
|
if ( m_binit == IS_NAN )
|
|
{
|
|
res.LoadString(TX_NAN);
|
|
return res;
|
|
}
|
|
|
|
char buffer[300];
|
|
sprintf(buffer, "%d", m_val);
|
|
res = buffer;
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
void CBotVarInt::Mul(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValInt() * right->GetValInt();
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarInt::Power(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = static_cast<int>( pow( static_cast<double>( left->GetValInt()) , static_cast<double>( left->GetValInt()) ));
|
|
m_binit = true;
|
|
}
|
|
|
|
int CBotVarInt::Div(CBotVar* left, CBotVar* right)
|
|
{
|
|
int r = right->GetValInt();
|
|
if ( r != 0 )
|
|
{
|
|
m_val = left->GetValInt() / r;
|
|
m_binit = true;
|
|
}
|
|
return ( r == 0 ? TX_DIVZERO : 0 );
|
|
}
|
|
|
|
int CBotVarInt::Modulo(CBotVar* left, CBotVar* right)
|
|
{
|
|
int r = right->GetValInt();
|
|
if ( r != 0 )
|
|
{
|
|
m_val = left->GetValInt() % r;
|
|
m_binit = true;
|
|
}
|
|
return ( r == 0 ? TX_DIVZERO : 0 );
|
|
}
|
|
|
|
void CBotVarInt::Add(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValInt() + right->GetValInt();
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarInt::Sub(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValInt() - right->GetValInt();
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarInt::XOr(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValInt() ^ right->GetValInt();
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarInt::And(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValInt() & right->GetValInt();
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarInt::Or(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValInt() | right->GetValInt();
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarInt::SL(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValInt() << right->GetValInt();
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarInt::ASR(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValInt() >> right->GetValInt();
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarInt::SR(CBotVar* left, CBotVar* right)
|
|
{
|
|
int source = left->GetValInt();
|
|
int shift = right->GetValInt();
|
|
if (shift>=1) source &= 0x7fffffff;
|
|
m_val = source >> shift;
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarInt::Neg()
|
|
{
|
|
m_val = -m_val;
|
|
}
|
|
|
|
void CBotVarInt::Not()
|
|
{
|
|
m_val = ~m_val;
|
|
}
|
|
|
|
void CBotVarInt::Inc()
|
|
{
|
|
m_val++;
|
|
m_defnum.Empty();
|
|
}
|
|
|
|
void CBotVarInt::Dec()
|
|
{
|
|
m_val--;
|
|
m_defnum.Empty();
|
|
}
|
|
|
|
bool CBotVarInt::Lo(CBotVar* left, CBotVar* right)
|
|
{
|
|
return left->GetValInt() < right->GetValInt();
|
|
}
|
|
|
|
bool CBotVarInt::Hi(CBotVar* left, CBotVar* right)
|
|
{
|
|
return left->GetValInt() > right->GetValInt();
|
|
}
|
|
|
|
bool CBotVarInt::Ls(CBotVar* left, CBotVar* right)
|
|
{
|
|
return left->GetValInt() <= right->GetValInt();
|
|
}
|
|
|
|
bool CBotVarInt::Hs(CBotVar* left, CBotVar* right)
|
|
{
|
|
return left->GetValInt() >= right->GetValInt();
|
|
}
|
|
|
|
bool CBotVarInt::Eq(CBotVar* left, CBotVar* right)
|
|
{
|
|
return left->GetValInt() == right->GetValInt();
|
|
}
|
|
|
|
bool CBotVarInt::Ne(CBotVar* left, CBotVar* right)
|
|
{
|
|
return left->GetValInt() != right->GetValInt();
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// copy a variable into another
|
|
void CBotVarFloat::Copy(CBotVar* pSrc, bool bName)
|
|
{
|
|
CBotVarFloat* p = static_cast<CBotVarFloat*>(pSrc);
|
|
|
|
if (bName) *m_token = *p->m_token;
|
|
m_type = p->m_type;
|
|
m_val = p->m_val;
|
|
m_binit = p->m_binit;
|
|
//- m_bStatic = p->m_bStatic;
|
|
m_next = NULL;
|
|
m_pMyThis = NULL;//p->m_pMyThis;
|
|
m_pUserPtr = p->m_pUserPtr;
|
|
|
|
// keeps indentificator the same (by default)
|
|
if (m_ident == 0 ) m_ident = p->m_ident;
|
|
}
|
|
|
|
|
|
|
|
|
|
void CBotVarFloat::SetValInt(int val, const char* s)
|
|
{
|
|
m_val = static_cast<float>(val);
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarFloat::SetValFloat(float val)
|
|
{
|
|
m_val = val;
|
|
m_binit = true;
|
|
}
|
|
|
|
int CBotVarFloat::GetValInt()
|
|
{
|
|
return static_cast<int>(m_val);
|
|
}
|
|
|
|
float CBotVarFloat::GetValFloat()
|
|
{
|
|
return m_val;
|
|
}
|
|
|
|
CBotString CBotVarFloat::GetValString()
|
|
{
|
|
CBotString res;
|
|
|
|
if ( !m_binit )
|
|
{
|
|
res.LoadString(TX_UNDEF);
|
|
return res;
|
|
}
|
|
if ( m_binit == IS_NAN )
|
|
{
|
|
res.LoadString(TX_NAN);
|
|
return res;
|
|
}
|
|
|
|
char buffer[300];
|
|
sprintf(buffer, "%.2f", m_val);
|
|
res = buffer;
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
void CBotVarFloat::Mul(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValFloat() * right->GetValFloat();
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarFloat::Power(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = static_cast<float>(pow( left->GetValFloat() , right->GetValFloat() ));
|
|
m_binit = true;
|
|
}
|
|
|
|
int CBotVarFloat::Div(CBotVar* left, CBotVar* right)
|
|
{
|
|
float r = right->GetValFloat();
|
|
if ( r != 0 )
|
|
{
|
|
m_val = left->GetValFloat() / r;
|
|
m_binit = true;
|
|
}
|
|
return ( r == 0 ? TX_DIVZERO : 0 );
|
|
}
|
|
|
|
int CBotVarFloat::Modulo(CBotVar* left, CBotVar* right)
|
|
{
|
|
float r = right->GetValFloat();
|
|
if ( r != 0 )
|
|
{
|
|
m_val = static_cast<float>(fmod( left->GetValFloat() , r ));
|
|
m_binit = true;
|
|
}
|
|
return ( r == 0 ? TX_DIVZERO : 0 );
|
|
}
|
|
|
|
void CBotVarFloat::Add(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValFloat() + right->GetValFloat();
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarFloat::Sub(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValFloat() - right->GetValFloat();
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarFloat::Neg()
|
|
{
|
|
m_val = -m_val;
|
|
}
|
|
|
|
void CBotVarFloat::Inc()
|
|
{
|
|
m_val++;
|
|
}
|
|
|
|
void CBotVarFloat::Dec()
|
|
{
|
|
m_val--;
|
|
}
|
|
|
|
|
|
bool CBotVarFloat::Lo(CBotVar* left, CBotVar* right)
|
|
{
|
|
return left->GetValFloat() < right->GetValFloat();
|
|
}
|
|
|
|
bool CBotVarFloat::Hi(CBotVar* left, CBotVar* right)
|
|
{
|
|
return left->GetValFloat() > right->GetValFloat();
|
|
}
|
|
|
|
bool CBotVarFloat::Ls(CBotVar* left, CBotVar* right)
|
|
{
|
|
return left->GetValFloat() <= right->GetValFloat();
|
|
}
|
|
|
|
bool CBotVarFloat::Hs(CBotVar* left, CBotVar* right)
|
|
{
|
|
return left->GetValFloat() >= right->GetValFloat();
|
|
}
|
|
|
|
bool CBotVarFloat::Eq(CBotVar* left, CBotVar* right)
|
|
{
|
|
return left->GetValFloat() == right->GetValFloat();
|
|
}
|
|
|
|
bool CBotVarFloat::Ne(CBotVar* left, CBotVar* right)
|
|
{
|
|
return left->GetValFloat() != right->GetValFloat();
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// copy a variable into another
|
|
void CBotVarBoolean::Copy(CBotVar* pSrc, bool bName)
|
|
{
|
|
CBotVarBoolean* p = static_cast<CBotVarBoolean*>(pSrc);
|
|
|
|
if (bName) *m_token = *p->m_token;
|
|
m_type = p->m_type;
|
|
m_val = p->m_val;
|
|
m_binit = p->m_binit;
|
|
//- m_bStatic = p->m_bStatic;
|
|
m_next = NULL;
|
|
m_pMyThis = NULL;//p->m_pMyThis;
|
|
m_pUserPtr = p->m_pUserPtr;
|
|
|
|
// keeps indentificator the same (by default)
|
|
if (m_ident == 0 ) m_ident = p->m_ident;
|
|
}
|
|
|
|
|
|
|
|
|
|
void CBotVarBoolean::SetValInt(int val, const char* s)
|
|
{
|
|
m_val = static_cast<bool>(val);
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarBoolean::SetValFloat(float val)
|
|
{
|
|
m_val = static_cast<bool>(val);
|
|
m_binit = true;
|
|
}
|
|
|
|
int CBotVarBoolean::GetValInt()
|
|
{
|
|
return m_val;
|
|
}
|
|
|
|
float CBotVarBoolean::GetValFloat()
|
|
{
|
|
return static_cast<float>(m_val);
|
|
}
|
|
|
|
CBotString CBotVarBoolean::GetValString()
|
|
{
|
|
CBotString ret;
|
|
|
|
CBotString res;
|
|
|
|
if ( !m_binit )
|
|
{
|
|
res.LoadString(TX_UNDEF);
|
|
return res;
|
|
}
|
|
if ( m_binit == IS_NAN )
|
|
{
|
|
res.LoadString(TX_NAN);
|
|
return res;
|
|
}
|
|
|
|
ret.LoadString( m_val > 0 ? ID_TRUE : ID_FALSE );
|
|
return ret;
|
|
}
|
|
|
|
void CBotVarBoolean::And(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValInt() && right->GetValInt();
|
|
m_binit = true;
|
|
}
|
|
void CBotVarBoolean::Or(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValInt() || right->GetValInt();
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarBoolean::XOr(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValInt() ^ right->GetValInt();
|
|
m_binit = true;
|
|
}
|
|
|
|
void CBotVarBoolean::Not()
|
|
{
|
|
m_val = m_val ? false : true ;
|
|
}
|
|
|
|
bool CBotVarBoolean::Eq(CBotVar* left, CBotVar* right)
|
|
{
|
|
return left->GetValInt() == right->GetValInt();
|
|
}
|
|
|
|
bool CBotVarBoolean::Ne(CBotVar* left, CBotVar* right)
|
|
{
|
|
return left->GetValInt() != right->GetValInt();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// copy a variable into another
|
|
void CBotVarString::Copy(CBotVar* pSrc, bool bName)
|
|
{
|
|
CBotVarString* p = static_cast<CBotVarString*>(pSrc);
|
|
|
|
if (bName) *m_token = *p->m_token;
|
|
m_type = p->m_type;
|
|
m_val = p->m_val;
|
|
m_binit = p->m_binit;
|
|
//- m_bStatic = p->m_bStatic;
|
|
m_next = NULL;
|
|
m_pMyThis = NULL;//p->m_pMyThis;
|
|
m_pUserPtr = p->m_pUserPtr;
|
|
|
|
// keeps indentificator the same (by default)
|
|
if (m_ident == 0 ) m_ident = p->m_ident;
|
|
}
|
|
|
|
|
|
void CBotVarString::SetValString(const char* p)
|
|
{
|
|
m_val = p;
|
|
m_binit = true;
|
|
}
|
|
|
|
CBotString CBotVarString::GetValString()
|
|
{
|
|
if ( !m_binit )
|
|
{
|
|
CBotString res;
|
|
res.LoadString(TX_UNDEF);
|
|
return res;
|
|
}
|
|
if ( m_binit == IS_NAN )
|
|
{
|
|
CBotString res;
|
|
res.LoadString(TX_NAN);
|
|
return res;
|
|
}
|
|
|
|
return m_val;
|
|
}
|
|
|
|
|
|
void CBotVarString::Add(CBotVar* left, CBotVar* right)
|
|
{
|
|
m_val = left->GetValString() + right->GetValString();
|
|
m_binit = true;
|
|
}
|
|
|
|
bool CBotVarString::Eq(CBotVar* left, CBotVar* right)
|
|
{
|
|
return (left->GetValString() == right->GetValString());
|
|
}
|
|
|
|
bool CBotVarString::Ne(CBotVar* left, CBotVar* right)
|
|
{
|
|
return (left->GetValString() != right->GetValString());
|
|
}
|
|
|
|
|
|
bool CBotVarString::Lo(CBotVar* left, CBotVar* right)
|
|
{
|
|
return (left->GetValString() == right->GetValString());
|
|
}
|
|
|
|
bool CBotVarString::Hi(CBotVar* left, CBotVar* right)
|
|
{
|
|
return (left->GetValString() == right->GetValString());
|
|
}
|
|
|
|
bool CBotVarString::Ls(CBotVar* left, CBotVar* right)
|
|
{
|
|
return (left->GetValString() == right->GetValString());
|
|
}
|
|
|
|
bool CBotVarString::Hs(CBotVar* left, CBotVar* right)
|
|
{
|
|
return (left->GetValString() == right->GetValString());
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// copy a variable into another
|
|
void CBotVarClass::Copy(CBotVar* pSrc, bool bName)
|
|
{
|
|
pSrc = pSrc->GetPointer(); // if source given by a pointer
|
|
|
|
if ( pSrc->GetType() != CBotTypClass )
|
|
ASM_TRAP();
|
|
|
|
CBotVarClass* p = static_cast<CBotVarClass*>(pSrc);
|
|
|
|
if (bName) *m_token = *p->m_token;
|
|
|
|
m_type = p->m_type;
|
|
m_binit = p->m_binit;
|
|
//- m_bStatic = p->m_bStatic;
|
|
m_pClass = p->m_pClass;
|
|
if ( p->m_pParent )
|
|
{
|
|
ASM_TRAP(); // "que faire du pParent";
|
|
}
|
|
|
|
// m_next = NULL;
|
|
m_pUserPtr = p->m_pUserPtr;
|
|
m_pMyThis = NULL;//p->m_pMyThis;
|
|
m_ItemIdent = p->m_ItemIdent;
|
|
|
|
// keeps indentificator the same (by default)
|
|
if (m_ident == 0 ) m_ident = p->m_ident;
|
|
|
|
delete m_pVar;
|
|
m_pVar = NULL;
|
|
|
|
CBotVar* pv = p->m_pVar;
|
|
while( pv != NULL )
|
|
{
|
|
CBotVar* pn = CBotVar::Create(pv);
|
|
pn->Copy( pv );
|
|
if ( m_pVar == NULL ) m_pVar = pn;
|
|
else m_pVar->AddNext(pn);
|
|
|
|
pv = pv->GetNext();
|
|
}
|
|
}
|
|
|
|
void CBotVarClass::SetItemList(CBotVar* pVar)
|
|
{
|
|
delete m_pVar;
|
|
m_pVar = pVar; // replaces the existing pointer
|
|
}
|
|
|
|
void CBotVarClass::SetIdent(long n)
|
|
{
|
|
m_ItemIdent = n;
|
|
}
|
|
|
|
void CBotVarClass::SetClass(CBotClass* pClass)//, int &nIdent)
|
|
{
|
|
m_type.m_pClass = pClass;
|
|
|
|
if ( m_pClass == pClass ) return;
|
|
|
|
m_pClass = pClass;
|
|
|
|
// initializes the variables associated with this class
|
|
delete m_pVar;
|
|
m_pVar = NULL;
|
|
|
|
if (pClass == NULL) return;
|
|
|
|
CBotVar* pv = pClass->GetVar(); // first on a list
|
|
while ( pv != NULL )
|
|
{
|
|
// seeks the maximum dimensions of the table
|
|
CBotInstr* p = pv->m_LimExpr; // the different formulas
|
|
if ( p != NULL )
|
|
{
|
|
CBotStack* pile = CBotStack::FirstStack(); // an independent stack
|
|
int n = 0;
|
|
int max[100];
|
|
|
|
while (p != NULL)
|
|
{
|
|
while( pile->IsOk() && !p->Execute(pile) ) ; // calculate size without interruptions
|
|
CBotVar* v = pile->GetVar(); // result
|
|
max[n] = v->GetValInt(); // value
|
|
n++;
|
|
p = p->GetNext3();
|
|
}
|
|
while (n<100) max[n++] = 0;
|
|
|
|
pv->m_type.SetArray( max ); // stores the limitations
|
|
pile->Delete();
|
|
}
|
|
|
|
CBotVar* pn = CBotVar::Create( pv ); // a copy
|
|
pn->SetStatic(pv->IsStatic());
|
|
pn->SetPrivate(pv->GetPrivate());
|
|
|
|
if ( pv->m_InitExpr != NULL ) // expression for initialization?
|
|
{
|
|
#if STACKMEM
|
|
CBotStack* pile = CBotStack::FirstStack(); // an independent stack
|
|
|
|
while(pile->IsOk() && !pv->m_InitExpr->Execute(pile, pn)); // evaluates the expression without timer
|
|
|
|
pile->Delete();
|
|
#else
|
|
CBotStack* pile = new CBotStack(NULL); // an independent stack
|
|
while(!pv->m_InitExpr->Execute(pile)); // evaluates the expression without timer
|
|
pn->SetVal( pile->GetVar() ) ;
|
|
delete pile;
|
|
#endif
|
|
}
|
|
|
|
// pn->SetUniqNum(CBotVar::NextUniqNum()); // enumerate elements
|
|
pn->SetUniqNum(pv->GetUniqNum()); //++nIdent
|
|
pn->m_pMyThis = this;
|
|
|
|
if ( m_pVar == NULL) m_pVar = pn;
|
|
else m_pVar->AddNext( pn );
|
|
pv = pv->GetNext();
|
|
}
|
|
}
|
|
|
|
CBotClass* CBotVarClass::GetClass()
|
|
{
|
|
return m_pClass;
|
|
}
|
|
|
|
|
|
void CBotVarClass::Maj(void* pUser, bool bContinu)
|
|
{
|
|
/* if (!bContinu && m_pMyThis != NULL)
|
|
m_pMyThis->Maj(pUser, true);*/
|
|
|
|
// an update routine exist?
|
|
|
|
if ( m_pClass->m_rMaj == NULL ) return;
|
|
|
|
// retrieves the user pointer according to the class
|
|
// or according to the parameter passed to CBotProgram::Run()
|
|
|
|
if ( m_pUserPtr != NULL) pUser = m_pUserPtr;
|
|
if ( pUser == OBJECTDELETED ||
|
|
pUser == OBJECTCREATED ) return;
|
|
m_pClass->m_rMaj( this, pUser );
|
|
}
|
|
|
|
CBotVar* CBotVarClass::GetItem(const char* name)
|
|
{
|
|
CBotVar* p = m_pVar;
|
|
|
|
while ( p != NULL )
|
|
{
|
|
if ( p->GetName() == name ) return p;
|
|
p = p->GetNext();
|
|
}
|
|
|
|
if ( m_pParent != NULL ) return m_pParent->GetItem(name);
|
|
return NULL;
|
|
}
|
|
|
|
CBotVar* CBotVarClass::GetItemRef(int nIdent)
|
|
{
|
|
CBotVar* p = m_pVar;
|
|
|
|
while ( p != NULL )
|
|
{
|
|
if ( p->GetUniqNum() == nIdent ) return p;
|
|
p = p->GetNext();
|
|
}
|
|
|
|
if ( m_pParent != NULL ) return m_pParent->GetItemRef(nIdent);
|
|
return NULL;
|
|
}
|
|
|
|
// for the management of an array
|
|
// bExtend can enlarge the table, but not beyond the threshold size of SetArray ()
|
|
|
|
CBotVar* CBotVarClass::GetItem(int n, bool bExtend)
|
|
{
|
|
CBotVar* p = m_pVar;
|
|
|
|
if ( n < 0 ) return NULL;
|
|
if ( n > MAXARRAYSIZE ) return NULL;
|
|
|
|
if ( m_type.GetLimite() >= 0 && n >= m_type.GetLimite() ) return NULL;
|
|
|
|
if ( p == NULL && bExtend )
|
|
{
|
|
p = CBotVar::Create("", m_type.GetTypElem());
|
|
m_pVar = p;
|
|
}
|
|
|
|
if ( n == 0 ) return p;
|
|
|
|
while ( n-- > 0 )
|
|
{
|
|
if ( p->m_next == NULL )
|
|
{
|
|
if ( bExtend ) p->m_next = CBotVar::Create("", m_type.GetTypElem());
|
|
if ( p->m_next == NULL ) return NULL;
|
|
}
|
|
p = p->m_next;
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
CBotVar* CBotVarClass::GetItemList()
|
|
{
|
|
return m_pVar;
|
|
}
|
|
|
|
|
|
CBotString CBotVarClass::GetValString()
|
|
{
|
|
// if ( m_Indirect != NULL) return m_Indirect->GetValString();
|
|
|
|
CBotString res;
|
|
|
|
if ( m_pClass != NULL ) // not used for an array
|
|
{
|
|
res = m_pClass->GetName() + CBotString("( ");
|
|
|
|
CBotVarClass* my = this;
|
|
while ( my != NULL )
|
|
{
|
|
CBotVar* pv = my->m_pVar;
|
|
while ( pv != NULL )
|
|
{
|
|
res += pv->GetName() + CBotString("=");
|
|
|
|
if ( pv->IsStatic() )
|
|
{
|
|
CBotVar* pvv = my->m_pClass->GetItem(pv->GetName());
|
|
res += pvv->GetValString();
|
|
}
|
|
else
|
|
{
|
|
res += pv->GetValString();
|
|
}
|
|
pv = pv->GetNext();
|
|
if ( pv != NULL ) res += ", ";
|
|
}
|
|
my = my->m_pParent;
|
|
if ( my != NULL )
|
|
{
|
|
res += ") extends ";
|
|
res += my->m_pClass->GetName();
|
|
res += " (";
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
res = "( ";
|
|
|
|
CBotVar* pv = m_pVar;
|
|
while ( pv != NULL )
|
|
{
|
|
res += pv->GetValString();
|
|
if ( pv->GetNext() != NULL ) res += ", ";
|
|
pv = pv->GetNext();
|
|
}
|
|
}
|
|
|
|
res += " )";
|
|
return res;
|
|
}
|
|
|
|
void CBotVarClass::IncrementUse()
|
|
{
|
|
m_CptUse++;
|
|
}
|
|
|
|
void CBotVarClass::DecrementUse()
|
|
{
|
|
m_CptUse--;
|
|
if ( m_CptUse == 0 )
|
|
{
|
|
// if there is one, call the destructor
|
|
// but only if a constructor had been called.
|
|
if ( m_bConstructor )
|
|
{
|
|
m_CptUse++; // does not return to the destructor
|
|
|
|
// m_error is static in the stack
|
|
// saves the value for return
|
|
int err, start, end;
|
|
CBotStack* pile = NULL;
|
|
err = pile->GetError(start,end); // stack == NULL it does not bother!
|
|
|
|
pile = CBotStack::FirstStack(); // clears the error
|
|
CBotVar* ppVars[1];
|
|
ppVars[0] = NULL;
|
|
|
|
CBotVar* pThis = CBotVar::Create("this", CBotTypNullPointer);
|
|
pThis->SetPointer(this);
|
|
CBotVar* pResult = NULL;
|
|
|
|
CBotString nom = "~" + m_pClass->GetName();
|
|
long ident = 0;
|
|
|
|
while ( pile->IsOk() && !m_pClass->ExecuteMethode(ident, nom, pThis, ppVars, pResult, pile, NULL)) ; // waits for the end
|
|
|
|
pile->ResetError(err, start,end);
|
|
|
|
pile->Delete();
|
|
delete pThis;
|
|
m_CptUse--;
|
|
}
|
|
|
|
delete this; // self-destructs!
|
|
}
|
|
}
|
|
|
|
CBotVarClass* CBotVarClass::GetPointer()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
|
|
// makes an instance according to its unique number
|
|
|
|
CBotVarClass* CBotVarClass::Find(long id)
|
|
{
|
|
CBotVarClass* p = m_ExClass;
|
|
|
|
while ( p != NULL )
|
|
{
|
|
if ( p->m_ItemIdent == id ) return p;
|
|
p = p->m_ExNext;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool CBotVarClass::Eq(CBotVar* left, CBotVar* right)
|
|
{
|
|
CBotVar* l = left->GetItemList();
|
|
CBotVar* r = right->GetItemList();
|
|
|
|
while ( l != NULL && r != NULL )
|
|
{
|
|
if ( l->Ne(l, r) ) return false;
|
|
l = l->GetNext();
|
|
r = r->GetNext();
|
|
}
|
|
|
|
// should always arrived simultaneously at the end (same classes)
|
|
return l == r;
|
|
}
|
|
|
|
bool CBotVarClass::Ne(CBotVar* left, CBotVar* right)
|
|
{
|
|
CBotVar* l = left->GetItemList();
|
|
CBotVar* r = right->GetItemList();
|
|
|
|
while ( l != NULL && r != NULL )
|
|
{
|
|
if ( l->Ne(l, r) ) return true;
|
|
l = l->GetNext();
|
|
r = r->GetNext();
|
|
}
|
|
|
|
// should always arrived simultaneously at the end (same classes)
|
|
return l != r;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// management of arrays
|
|
|
|
CBotVarArray::CBotVarArray(const CBotToken* name, CBotTypResult& type )
|
|
{
|
|
if ( !type.Eq(CBotTypArrayPointer) &&
|
|
!type.Eq(CBotTypArrayBody)) ASM_TRAP();
|
|
|
|
m_token = new CBotToken(name);
|
|
m_next = NULL;
|
|
m_pMyThis = NULL;
|
|
m_pUserPtr = NULL;
|
|
|
|
m_type = type;
|
|
m_type.SetType(CBotTypArrayPointer);
|
|
m_binit = false;
|
|
|
|
m_pInstance = NULL; // the list of the array elements
|
|
}
|
|
|
|
CBotVarArray::~CBotVarArray()
|
|
{
|
|
if ( m_pInstance != NULL ) m_pInstance->DecrementUse(); // the lowest reference
|
|
}
|
|
|
|
// copy a variable into another
|
|
void CBotVarArray::Copy(CBotVar* pSrc, bool bName)
|
|
{
|
|
if ( pSrc->GetType() != CBotTypArrayPointer )
|
|
ASM_TRAP();
|
|
|
|
CBotVarArray* p = static_cast<CBotVarArray*>(pSrc);
|
|
|
|
if ( bName) *m_token = *p->m_token;
|
|
m_type = p->m_type;
|
|
m_pInstance = p->GetPointer();
|
|
|
|
if ( m_pInstance != NULL )
|
|
m_pInstance->IncrementUse(); // a reference increase
|
|
|
|
m_binit = p->m_binit;
|
|
//- m_bStatic = p->m_bStatic;
|
|
m_pMyThis = NULL;//p->m_pMyThis;
|
|
m_pUserPtr = p->m_pUserPtr;
|
|
|
|
// keeps indentificator the same (by default)
|
|
if (m_ident == 0 ) m_ident = p->m_ident;
|
|
}
|
|
|
|
void CBotVarArray::SetPointer(CBotVar* pVarClass)
|
|
{
|
|
m_binit = true; // init, even on a null pointer
|
|
|
|
if ( m_pInstance == pVarClass) return; // Special, not decrement and reincrement
|
|
// because the decrement can destroy the object
|
|
|
|
if ( pVarClass != NULL )
|
|
{
|
|
if ( pVarClass->GetType() == CBotTypArrayPointer )
|
|
pVarClass = pVarClass->GetPointer(); // the real pointer to the object
|
|
|
|
if ( !pVarClass->m_type.Eq(CBotTypClass) &&
|
|
!pVarClass->m_type.Eq(CBotTypArrayBody))
|
|
ASM_TRAP();
|
|
|
|
(static_cast<CBotVarClass*>(pVarClass))->IncrementUse(); // incement the reference
|
|
}
|
|
|
|
if ( m_pInstance != NULL ) m_pInstance->DecrementUse();
|
|
m_pInstance = static_cast<CBotVarClass*>(pVarClass);
|
|
}
|
|
|
|
|
|
CBotVarClass* CBotVarArray::GetPointer()
|
|
{
|
|
if ( m_pInstance == NULL ) return NULL;
|
|
return m_pInstance->GetPointer();
|
|
}
|
|
|
|
CBotVar* CBotVarArray::GetItem(int n, bool bExtend)
|
|
{
|
|
if ( m_pInstance == NULL )
|
|
{
|
|
if ( !bExtend ) return NULL;
|
|
// creates an instance of the table
|
|
|
|
CBotVarClass* instance = new CBotVarClass(NULL, m_type);
|
|
SetPointer( instance );
|
|
}
|
|
return m_pInstance->GetItem(n, bExtend);
|
|
}
|
|
|
|
CBotVar* CBotVarArray::GetItemList()
|
|
{
|
|
if ( m_pInstance == NULL) return NULL;
|
|
return m_pInstance->GetItemList();
|
|
}
|
|
|
|
CBotString CBotVarArray::GetValString()
|
|
{
|
|
if ( m_pInstance == NULL ) return ( CBotString( "Null pointer" ) ) ;
|
|
return m_pInstance->GetValString();
|
|
}
|
|
|
|
bool CBotVarArray::Save1State(FILE* pf)
|
|
{
|
|
if ( !WriteType(pf, m_type) ) return false;
|
|
return SaveVar(pf, m_pInstance); // saves the instance that manages the table
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// gestion des pointeurs à une instance donnée
|
|
// TODO management of pointers to a given instance
|
|
|
|
CBotVarPointer::CBotVarPointer(const CBotToken* name, CBotTypResult& type )
|
|
{
|
|
if ( !type.Eq(CBotTypPointer) &&
|
|
!type.Eq(CBotTypNullPointer) &&
|
|
!type.Eq(CBotTypClass) && // for convenience accepts Class and Intrinsic
|
|
!type.Eq(CBotTypIntrinsic) ) ASM_TRAP();
|
|
|
|
m_token = new CBotToken(name);
|
|
m_next = NULL;
|
|
m_pMyThis = NULL;
|
|
m_pUserPtr = NULL;
|
|
|
|
m_type = type;
|
|
if ( !type.Eq(CBotTypNullPointer) )
|
|
m_type.SetType(CBotTypPointer); // anyway, this is a pointer
|
|
m_binit = false;
|
|
m_pClass = NULL;
|
|
m_pVarClass = NULL; // will be defined by a SetPointer()
|
|
|
|
SetClass(type.GetClass() );
|
|
}
|
|
|
|
CBotVarPointer::~CBotVarPointer()
|
|
{
|
|
if ( m_pVarClass != NULL ) m_pVarClass->DecrementUse(); // decrement reference
|
|
}
|
|
|
|
|
|
void CBotVarPointer::Maj(void* pUser, bool bContinu)
|
|
{
|
|
/* if ( !bContinu && m_pMyThis != NULL )
|
|
m_pMyThis->Maj(pUser, false);*/
|
|
|
|
if ( m_pVarClass != NULL) m_pVarClass->Maj(pUser, false);
|
|
}
|
|
|
|
CBotVar* CBotVarPointer::GetItem(const char* name)
|
|
{
|
|
if ( m_pVarClass == NULL) // no existing instance?
|
|
return m_pClass->GetItem(name); // makes the pointer in the class itself
|
|
|
|
return m_pVarClass->GetItem(name);
|
|
}
|
|
|
|
CBotVar* CBotVarPointer::GetItemRef(int nIdent)
|
|
{
|
|
if ( m_pVarClass == NULL) // no existing instance?
|
|
return m_pClass->GetItemRef(nIdent);// makes the pointer to the class itself
|
|
|
|
return m_pVarClass->GetItemRef(nIdent);
|
|
}
|
|
|
|
CBotVar* CBotVarPointer::GetItemList()
|
|
{
|
|
if ( m_pVarClass == NULL) return NULL;
|
|
return m_pVarClass->GetItemList();
|
|
}
|
|
|
|
CBotString CBotVarPointer::GetValString()
|
|
{
|
|
CBotString s = "Pointer to ";
|
|
if ( m_pVarClass == NULL ) s = "Null pointer" ;
|
|
else s += m_pVarClass->GetValString();
|
|
return s;
|
|
}
|
|
|
|
|
|
void CBotVarPointer::ConstructorSet()
|
|
{
|
|
if ( m_pVarClass != NULL) m_pVarClass->ConstructorSet();
|
|
}
|
|
|
|
// initializes the pointer to the instance of a class
|
|
|
|
void CBotVarPointer::SetPointer(CBotVar* pVarClass)
|
|
{
|
|
m_binit = true; // init, even on a null pointer
|
|
|
|
if ( m_pVarClass == pVarClass) return; // special, not decrement and reincrement
|
|
// because the decrement can destroy the object
|
|
|
|
if ( pVarClass != NULL )
|
|
{
|
|
if ( pVarClass->GetType() == CBotTypPointer )
|
|
pVarClass = pVarClass->GetPointer(); // the real pointer to the object
|
|
|
|
// if ( pVarClass->GetType() != CBotTypClass )
|
|
if ( !pVarClass->m_type.Eq(CBotTypClass) )
|
|
ASM_TRAP();
|
|
|
|
(static_cast<CBotVarClass*>(pVarClass))->IncrementUse(); // increment the reference
|
|
m_pClass = (static_cast<CBotVarClass*>(pVarClass))->m_pClass;
|
|
m_pUserPtr = pVarClass->m_pUserPtr; // not really necessary
|
|
m_type = CBotTypResult(CBotTypPointer, m_pClass); // what kind of a pointer
|
|
}
|
|
|
|
if ( m_pVarClass != NULL ) m_pVarClass->DecrementUse();
|
|
m_pVarClass = static_cast<CBotVarClass*>(pVarClass);
|
|
|
|
}
|
|
|
|
CBotVarClass* CBotVarPointer::GetPointer()
|
|
{
|
|
if ( m_pVarClass == NULL ) return NULL;
|
|
return m_pVarClass->GetPointer();
|
|
}
|
|
|
|
void CBotVarPointer::SetIdent(long n)
|
|
{
|
|
if ( m_pVarClass == NULL ) return;
|
|
m_pVarClass->SetIdent( n );
|
|
}
|
|
|
|
long CBotVarPointer::GetIdent()
|
|
{
|
|
if ( m_pVarClass == NULL ) return 0;
|
|
return m_pVarClass->m_ItemIdent;
|
|
}
|
|
|
|
|
|
void CBotVarPointer::SetClass(CBotClass* pClass)
|
|
{
|
|
// int nIdent = 0;
|
|
m_type.m_pClass = m_pClass = pClass;
|
|
if ( m_pVarClass != NULL ) m_pVarClass->SetClass(pClass); //, nIdent);
|
|
}
|
|
|
|
CBotClass* CBotVarPointer::GetClass()
|
|
{
|
|
if ( m_pVarClass != NULL ) return m_pVarClass->GetClass();
|
|
|
|
return m_pClass;
|
|
}
|
|
|
|
|
|
bool CBotVarPointer::Save1State(FILE* pf)
|
|
{
|
|
if ( m_pClass )
|
|
{
|
|
if (!WriteString(pf, m_pClass->GetName())) return false; // name of the class
|
|
}
|
|
else
|
|
{
|
|
if (!WriteString(pf, "")) return false;
|
|
}
|
|
|
|
if (!WriteLong(pf, GetIdent())) return false; // the unique reference
|
|
|
|
// also saves the proceedings copies
|
|
return SaveVar(pf, GetPointer());
|
|
}
|
|
|
|
// copy a variable into another
|
|
void CBotVarPointer::Copy(CBotVar* pSrc, bool bName)
|
|
{
|
|
if ( pSrc->GetType() != CBotTypPointer &&
|
|
pSrc->GetType() != CBotTypNullPointer)
|
|
ASM_TRAP();
|
|
|
|
CBotVarPointer* p = static_cast<CBotVarPointer*>(pSrc);
|
|
|
|
if ( bName) *m_token = *p->m_token;
|
|
m_type = p->m_type;
|
|
// m_pVarClass = p->m_pVarClass;
|
|
m_pVarClass = p->GetPointer();
|
|
|
|
if ( m_pVarClass != NULL )
|
|
m_pVarClass->IncrementUse(); // incerement the reference
|
|
|
|
m_pClass = p->m_pClass;
|
|
m_binit = p->m_binit;
|
|
//- m_bStatic = p->m_bStatic;
|
|
m_next = NULL;
|
|
m_pMyThis = NULL;//p->m_pMyThis;
|
|
m_pUserPtr = p->m_pUserPtr;
|
|
|
|
// keeps indentificator the same (by default)
|
|
if (m_ident == 0 ) m_ident = p->m_ident;
|
|
}
|
|
|
|
bool CBotVarPointer::Eq(CBotVar* left, CBotVar* right)
|
|
{
|
|
CBotVarClass* l = left->GetPointer();
|
|
CBotVarClass* r = right->GetPointer();
|
|
|
|
if ( l == r ) return true;
|
|
if ( l == NULL && r->GetUserPtr() == OBJECTDELETED ) return true;
|
|
if ( r == NULL && l->GetUserPtr() == OBJECTDELETED ) return true;
|
|
return false;
|
|
}
|
|
|
|
bool CBotVarPointer::Ne(CBotVar* left, CBotVar* right)
|
|
{
|
|
CBotVarClass* l = left->GetPointer();
|
|
CBotVarClass* r = right->GetPointer();
|
|
|
|
if ( l == r ) return false;
|
|
if ( l == NULL && r->GetUserPtr() == OBJECTDELETED ) return false;
|
|
if ( r == NULL && l->GetUserPtr() == OBJECTDELETED ) return false;
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////
|
|
// management of results types
|
|
|
|
|
|
CBotTypResult::CBotTypResult(int type)
|
|
{
|
|
m_type = type;
|
|
m_pNext = NULL;
|
|
m_pClass = NULL;
|
|
m_limite = -1;
|
|
}
|
|
|
|
CBotTypResult::CBotTypResult(int type, const char* name)
|
|
{
|
|
m_type = type;
|
|
m_pNext = NULL;
|
|
m_pClass = NULL;
|
|
m_limite = -1;
|
|
|
|
if ( type == CBotTypPointer ||
|
|
type == CBotTypClass ||
|
|
type == CBotTypIntrinsic )
|
|
{
|
|
m_pClass = CBotClass::Find(name);
|
|
if ( m_pClass && m_pClass->IsIntrinsic() ) m_type = CBotTypIntrinsic;
|
|
}
|
|
}
|
|
|
|
CBotTypResult::CBotTypResult(int type, CBotClass* pClass)
|
|
{
|
|
m_type = type;
|
|
m_pNext = NULL;
|
|
m_pClass = pClass;
|
|
m_limite = -1;
|
|
|
|
if ( m_pClass && m_pClass->IsIntrinsic() ) m_type = CBotTypIntrinsic;
|
|
}
|
|
|
|
CBotTypResult::CBotTypResult(int type, CBotTypResult elem)
|
|
{
|
|
m_type = type;
|
|
m_pNext = NULL;
|
|
m_pClass = NULL;
|
|
m_limite = -1;
|
|
|
|
if ( type == CBotTypArrayPointer ||
|
|
type == CBotTypArrayBody )
|
|
m_pNext = new CBotTypResult( elem );
|
|
}
|
|
|
|
CBotTypResult::CBotTypResult(const CBotTypResult& typ)
|
|
{
|
|
m_type = typ.m_type;
|
|
m_pClass = typ.m_pClass;
|
|
m_pNext = NULL;
|
|
m_limite = typ.m_limite;
|
|
|
|
if ( typ.m_pNext )
|
|
m_pNext = new CBotTypResult( *typ.m_pNext );
|
|
}
|
|
|
|
CBotTypResult::CBotTypResult()
|
|
{
|
|
m_type = 0;
|
|
m_limite = -1;
|
|
m_pNext = NULL;
|
|
m_pClass = NULL;
|
|
}
|
|
|
|
CBotTypResult::~CBotTypResult()
|
|
{
|
|
delete m_pNext;
|
|
}
|
|
|
|
int CBotTypResult::GetType(int mode) const
|
|
{
|
|
#ifdef _DEBUG
|
|
if ( m_type == CBotTypPointer ||
|
|
m_type == CBotTypClass ||
|
|
m_type == CBotTypIntrinsic )
|
|
|
|
if ( m_pClass == NULL ) ASM_TRAP();
|
|
|
|
|
|
if ( m_type == CBotTypArrayPointer )
|
|
if ( m_pNext == NULL ) ASM_TRAP();
|
|
#endif
|
|
if ( mode == 3 && m_type == CBotTypNullPointer ) return CBotTypPointer;
|
|
return m_type;
|
|
}
|
|
|
|
void CBotTypResult::SetType(int n)
|
|
{
|
|
m_type = n;
|
|
}
|
|
|
|
CBotClass* CBotTypResult::GetClass() const
|
|
{
|
|
return m_pClass;
|
|
}
|
|
|
|
CBotTypResult& CBotTypResult::GetTypElem() const
|
|
{
|
|
return *m_pNext;
|
|
}
|
|
|
|
int CBotTypResult::GetLimite() const
|
|
{
|
|
return m_limite;
|
|
}
|
|
|
|
void CBotTypResult::SetLimite(int n)
|
|
{
|
|
m_limite = n;
|
|
}
|
|
|
|
void CBotTypResult::SetArray( int* max )
|
|
{
|
|
m_limite = *max;
|
|
if (m_limite < 1) m_limite = -1;
|
|
|
|
if ( m_pNext != NULL ) // last dimension?
|
|
{
|
|
m_pNext->SetArray( max+1 );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool CBotTypResult::Compare(const CBotTypResult& typ) const
|
|
{
|
|
if ( m_type != typ.m_type ) return false;
|
|
|
|
if ( m_type == CBotTypArrayPointer ) return m_pNext->Compare(*typ.m_pNext);
|
|
|
|
if ( m_type == CBotTypPointer ||
|
|
m_type == CBotTypClass ||
|
|
m_type == CBotTypIntrinsic )
|
|
{
|
|
return m_pClass == typ.m_pClass;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CBotTypResult::Eq(int type) const
|
|
{
|
|
return m_type == type;
|
|
}
|
|
|
|
CBotTypResult&
|
|
CBotTypResult::operator=(const CBotTypResult& src)
|
|
{
|
|
m_type = src.m_type;
|
|
m_limite = src.m_limite;
|
|
m_pClass = src.m_pClass;
|
|
m_pNext = NULL;
|
|
if ( src.m_pNext != NULL )
|
|
{
|
|
m_pNext = new CBotTypResult(*src.m_pNext);
|
|
}
|
|
return *this;
|
|
}
|
|
|