Add missing primitive data types in CBOT

blender-script
melex750 2019-04-11 04:19:29 -04:00
parent 250ea57e8b
commit c0cdd84e85
29 changed files with 717 additions and 84 deletions

View File

@ -173,14 +173,34 @@ bool CBotDefParam::Execute(CBotVar** ppVars, CBotStack* &pj)
{
switch (p->m_type.GetType())
{
case CBotTypByte:
newvar->SetValByte(pVar->GetValByte());
newvar->SetInit(pVar->GetInit()); // copy nan
break;
case CBotTypShort:
newvar->SetValShort(pVar->GetValShort());
newvar->SetInit(pVar->GetInit()); // copy nan
break;
case CBotTypChar:
newvar->SetValChar(pVar->GetValChar());
newvar->SetInit(pVar->GetInit()); // copy nan
break;
case CBotTypInt:
newvar->SetValInt(pVar->GetValInt());
newvar->SetInit(pVar->GetInit()); // copy nan
break;
case CBotTypLong:
newvar->SetValLong(pVar->GetValLong());
newvar->SetInit(pVar->GetInit()); // copy nan
break;
case CBotTypFloat:
newvar->SetValFloat(pVar->GetValFloat());
newvar->SetInit(pVar->GetInit()); // copy nan
break;
case CBotTypDouble:
newvar->SetValDouble(pVar->GetValDouble());
newvar->SetInit(pVar->GetInit()); // copy nan
break;
case CBotTypString:
newvar->SetValString(pVar->GetValString());
break;

View File

@ -35,13 +35,13 @@ namespace CBot
enum CBotType
{
CBotTypVoid = 0, //!< void
CBotTypByte = 1, //!< byte (NOT IMPLEMENTED)
CBotTypShort = 2, //!< short (NOT IMPLEMENTED)
CBotTypChar = 3, //!< char (NOT IMPLEMENTED)
CBotTypByte = 1, //!< byte
CBotTypShort = 2, //!< short
CBotTypChar = 3, //!< char
CBotTypInt = 4, //!< int
CBotTypLong = 5, //!< long (NOT IMPLEMENTED)
CBotTypLong = 5, //!< long
CBotTypFloat = 6, //!< float
CBotTypDouble = 7, //!< double (NOT IMPLEMENTED)
CBotTypDouble = 7, //!< double
CBotTypBoolean = 8, //!< bool
CBotTypString = 9, //!< string
@ -106,6 +106,11 @@ enum TokenId
ID_STRING,
ID_VOID,
ID_BOOL,
ID_BYTE,
ID_SHORT,
ID_CHAR,
ID_LONG,
ID_DOUBLE,
TokenKeyVal = 2200, //!< keywords that represent values (true, false, null, nan)
ID_TRUE = 2200,

View File

@ -151,6 +151,16 @@ bool ReadShort(std::istream &istr, short &s)
return ReadSignedBinary<short>(istr, s);
}
bool WriteUInt32(std::ostream &ostr, uint32_t i)
{
return WriteBinary<uint32_t>(ostr, i);
}
bool ReadUInt32(std::istream &istr, uint32_t &i)
{
return ReadBinary<uint32_t>(istr, i);
}
bool WriteInt(std::ostream &ostr, int i)
{
return WriteSignedBinary<int>(ostr, i);

View File

@ -84,6 +84,22 @@ bool WriteShort(std::ostream &ostr, short s);
*/
bool ReadShort(std::istream &istr, short &s);
/*!
* \brief WriteUInt32
* \param ostr Output stream
* \param i
* \return true on success
*/
bool WriteUInt32(std::ostream &ostr, uint32_t i);
/*!
* \brief ReadUInt32
* \param istr Input stream
* \param[out] i
* \return true on success
*/
bool ReadUInt32(std::istream &istr, uint32_t &i);
/*!
* \brief WriteInt
* \param ostr Output stream

View File

@ -51,7 +51,7 @@ CBotInstr* CBotCase::Compile(CBotToken* &p, CBotCStack* pStack)
if ( pp->GetType() == ID_CASE )
{
pp = p;
inst->m_value = CBotExprLitNum::Compile(p, pStack);
inst->m_value = CBot::CompileExprLitNum(p, pStack);
if (inst->m_value == nullptr )
{
pStack->SetError( CBotErrBadNum, pp );

View File

@ -46,13 +46,22 @@ CBotDefFloat::~CBotDefFloat()
}
////////////////////////////////////////////////////////////////////////////////
CBotInstr* CBotDefFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, bool noskip)
CBotInstr* CBotDefFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, bool noskip, CBotTypResult vartype)
{
CBotToken* pp = cont ? nullptr : p;
if (!cont && !IsOfType(p, ID_FLOAT)) return nullptr;
if (!cont)
{
switch (p->GetType())
{
case ID_FLOAT: vartype.SetType(CBotTypFloat ); break;
case ID_DOUBLE: vartype.SetType(CBotTypDouble); break;
default: return nullptr;
}
p = p->GetNext();
}
CBotDefFloat* inst = static_cast<CBotDefFloat*>(CompileArray(p, pStack, CBotTypFloat));
CBotDefFloat* inst = static_cast<CBotDefFloat*>(CompileArray(p, pStack, vartype));
if (inst != nullptr || !pStack->IsOk()) return inst;
CBotCStack* pStk = pStack->TokenStack(pp);
@ -67,7 +76,7 @@ CBotInstr* CBotDefFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, b
if (nullptr != (inst->m_var = CBotLeftExprVar::Compile( p, pStk )))
{
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_typevar = CBotTypFloat;
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_typevar = vartype;
if (pStk->CheckVarLocal(vartoken)) // redefinition of a variable
{
pStk->SetStartError(vartoken->GetStart());
@ -79,7 +88,7 @@ CBotInstr* CBotDefFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, b
{
delete inst;
p = vartoken;
inst = static_cast<CBotDefFloat*>(CBotDefArray::Compile(p, pStk, CBotTypFloat));
inst = static_cast<CBotDefFloat*>(CBotDefArray::Compile(p, pStk, vartype));
goto suite; // no assignment, variable already created
}
@ -103,7 +112,7 @@ CBotInstr* CBotDefFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, b
}
}
var = CBotVar::Create(*vartoken, CBotTypFloat);
var = CBotVar::Create(*vartoken, vartype);
var->SetInit(inst->m_expr != nullptr ? CBotVar::InitType::DEF : CBotVar::InitType::UNDEF);
var->SetUniqNum(
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_nIdent = CBotVar::NextUniqNum());
@ -111,7 +120,7 @@ CBotInstr* CBotDefFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, b
suite:
if (pStk->IsOk() && IsOfType(p, ID_COMMA))
{
if (nullptr != ( inst->m_next2b = CBotDefFloat::Compile(p, pStk, true, noskip)))
if (nullptr != ( inst->m_next2b = CBotDefFloat::Compile(p, pStk, true, noskip, vartype)))
{
return pStack->Return(inst, pStk);
}

View File

@ -41,7 +41,7 @@ public:
* \param noskip
* \return
*/
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool cont = false, bool noskip=false);
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool cont = false, bool noskip=false, CBotTypResult vartype = CBotTypFloat);
/*!
* \brief Execute Executes the definition of a real variable.

View File

@ -47,13 +47,25 @@ CBotDefInt::~CBotDefInt()
}
////////////////////////////////////////////////////////////////////////////////
CBotInstr* CBotDefInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, bool noskip)
CBotInstr* CBotDefInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, bool noskip, CBotTypResult vartype)
{
CBotToken* pp = cont ? nullptr : p; // no repetition of the token "int"
if (!cont && !IsOfType(p, ID_INT)) return nullptr;
if (!cont)
{
switch (p->GetType())
{
case ID_BYTE: vartype.SetType(CBotTypByte ); break;
case ID_SHORT: vartype.SetType(CBotTypShort); break;
case ID_CHAR: vartype.SetType(CBotTypChar ); break;
case ID_INT: vartype.SetType(CBotTypInt ); break;
case ID_LONG: vartype.SetType(CBotTypLong ); break;
default: return nullptr;
}
p = p->GetNext();
}
CBotDefInt* inst = static_cast<CBotDefInt*>(CompileArray(p, pStack, CBotTypInt));
CBotDefInt* inst = static_cast<CBotDefInt*>(CompileArray(p, pStack, vartype));
if (inst != nullptr || !pStack->IsOk()) return inst;
CBotCStack* pStk = pStack->TokenStack(pp);
@ -68,7 +80,7 @@ CBotInstr* CBotDefInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, boo
// 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;
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_typevar = vartype;
if (pStk->CheckVarLocal(vartoken)) // redefinition of the variable
{
pStk->SetError(CBotErrRedefVar, vartoken);
@ -82,7 +94,7 @@ CBotInstr* CBotDefInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, boo
// compiles an array declaration
CBotInstr* inst2 = CBotDefArray::Compile(p, pStk, CBotTypInt);
CBotInstr* inst2 = CBotDefArray::Compile(p, pStk, vartype);
inst = static_cast<CBotDefInt*>(inst2);
goto suite; // no assignment, variable already created
@ -108,7 +120,7 @@ CBotInstr* CBotDefInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, boo
}
{
CBotVar* var = CBotVar::Create(*vartoken, CBotTypInt);// create the variable (evaluated after the assignment)
CBotVar* var = CBotVar::Create(*vartoken, vartype); // 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());
@ -117,7 +129,7 @@ CBotInstr* CBotDefInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, boo
suite:
if (pStk->IsOk() && IsOfType(p, ID_COMMA)) // chained several definitions
{
if (nullptr != ( inst->m_next2b = CBotDefInt::Compile(p, pStk, true, noskip))) // compile next one
if (nullptr != ( inst->m_next2b = CBotDefInt::Compile(p, pStk, true, noskip, vartype))) // compile next one
{
return pStack->Return(inst, pStk);
}

View File

@ -41,7 +41,7 @@ public:
* \param noskip
* \return
*/
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool cont = false, bool noskip = false);
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool cont = false, bool noskip = false, CBotTypResult vartype = CBotTypInt);
/*!
* \brief Execute Execute the definition of the integer variable.

View File

@ -25,52 +25,87 @@
#include "CBot/CBotUtils.h"
#include <limits>
#include <sstream>
namespace CBot
{
////////////////////////////////////////////////////////////////////////////////
CBotExprLitNum::CBotExprLitNum()
template <>
CBotExprLitNum<int>::CBotExprLitNum(int val) : m_numtype(CBotTypInt), m_value(val)
{
}
////////////////////////////////////////////////////////////////////////////////
CBotExprLitNum::~CBotExprLitNum()
template <>
CBotExprLitNum<long>::CBotExprLitNum(long val) : m_numtype(CBotTypLong), m_value(val)
{
}
////////////////////////////////////////////////////////////////////////////////
CBotInstr* CBotExprLitNum::Compile(CBotToken* &p, CBotCStack* pStack)
template <>
CBotExprLitNum<float>::CBotExprLitNum(float val) : m_numtype(CBotTypFloat), m_value(val)
{
}
template <>
CBotExprLitNum<double>::CBotExprLitNum(double val) : m_numtype(CBotTypDouble), m_value(val)
{
}
template <typename T>
CBotExprLitNum<T>::~CBotExprLitNum()
{
}
CBotInstr* CompileExprLitNum(CBotToken* &p, CBotCStack* pStack)
{
CBotCStack* pStk = pStack->TokenStack();
CBotExprLitNum* inst = new CBotExprLitNum();
const auto& s = p->GetString();
inst->SetToken(p);
std::string s = p->GetString();
CBotInstr* inst = nullptr;
CBotType numtype = CBotTypInt;
inst->m_numtype = CBotTypInt;
if (p->GetType() == TokenTypDef)
{
inst->m_valint = p->GetKeywordId();
inst = new CBotExprLitNum<int>(static_cast<int>(p->GetKeywordId()));
}
else
{
if (s.find('.') != std::string::npos || ( s.find('x') == std::string::npos && ( s.find_first_of("eE") != std::string::npos ) ))
{
inst->m_numtype = CBotTypFloat;
inst->m_valfloat = GetNumFloat(s);
double val = GetNumFloat(s);
if (val < static_cast<double>(std::numeric_limits<float>::min()) &&
val > static_cast<double>(std::numeric_limits<float>::max()) )
{
numtype = CBotTypDouble;
inst = new CBotExprLitNum<double>(val);
}
else
{
numtype = CBotTypFloat;
inst = new CBotExprLitNum<float>(static_cast<float>(val));
}
}
else
{
inst->m_valint = GetNumInt(s);
long val = GetNumInt(s);
if (val < std::numeric_limits<int>::min() &&
val > std::numeric_limits<int>::max() )
{
numtype = CBotTypLong;
inst = new CBotExprLitNum<long>(val);
}
else
{
inst = new CBotExprLitNum<int>(static_cast<int>(val));
}
}
}
inst->SetToken(p);
if (pStk->NextToken(p))
{
CBotVar* var = CBotVar::Create("", inst->m_numtype);
CBotVar* var = CBotVar::Create("", numtype);
pStk->SetVar(var);
return pStack->Return(inst, pStk);
@ -79,8 +114,8 @@ CBotInstr* CBotExprLitNum::Compile(CBotToken* &p, CBotCStack* pStack)
return pStack->Return(nullptr, pStk);
}
////////////////////////////////////////////////////////////////////////////////
bool CBotExprLitNum::Execute(CBotStack* &pj)
template <typename T>
bool CBotExprLitNum<T>::Execute(CBotStack* &pj)
{
CBotStack* pile = pj->AddStack(this);
@ -88,39 +123,38 @@ bool CBotExprLitNum::Execute(CBotStack* &pj)
CBotVar* var = CBotVar::Create("", m_numtype);
std::string nombre ;
if (m_token.GetType() == TokenTypDef)
{
nombre = m_token.GetString();
var->SetValInt(m_value, m_token.GetString());
}
switch (m_numtype)
else
{
case CBotTypShort:
case CBotTypInt:
var->SetValInt(m_valint, nombre);
break;
case CBotTypFloat:
var->SetValFloat(m_valfloat);
break;
default:
assert(false);
*var = m_value;
}
pile->SetVar(var); // place on the stack
return pj->Return(pile); // it's ok
}
////////////////////////////////////////////////////////////////////////////////
void CBotExprLitNum::RestoreState(CBotStack* &pj, bool bMain)
template <typename T>
void CBotExprLitNum<T>::RestoreState(CBotStack* &pj, bool bMain)
{
if (bMain) pj->RestoreStack(this);
}
std::string CBotExprLitNum::GetDebugData()
template <typename T>
std::string CBotExprLitNum<T>::GetDebugData()
{
std::stringstream ss;
ss << "(" << (m_numtype == CBotTypFloat ? "float" : "int") << ") " << (m_numtype == CBotTypFloat ? m_valfloat : m_valint);
switch (m_numtype)
{
case CBotTypInt : ss << "(int) "; break;
case CBotTypLong : ss << "(long) "; break;
case CBotTypFloat : ss << "(float) "; break;
case CBotTypDouble: ss << "(double) "; break;
default: assert(false);
}
ss << m_value;
return ss.str();
}

View File

@ -24,26 +24,21 @@
namespace CBot
{
CBotInstr* CompileExprLitNum(CBotToken* &p, CBotCStack* pStack);
/**
* \brief A number literal - 5, 1, 2.5, 3.75, etc. or a predefined numerical constant (see CBotToken::DefineNum())
*
* Can be of type ::CBotTypInt or ::CBotTypFloat
* Can be of type ::CBotTypInt, ::CBotTypLong, ::CBotTypFloat, or ::CBotTypDouble
*/
template <typename T>
class CBotExprLitNum : public CBotInstr
{
public:
CBotExprLitNum();
CBotExprLitNum(T val);
~CBotExprLitNum();
/*!
* \brief Compile
* \param p
* \param pStack
* \return
*/
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
/*!
* \brief Execute Execute, returns the corresponding number.
* \param pj
@ -65,10 +60,8 @@ protected:
private:
//! The type of number.
CBotType m_numtype;
//! Value for an int.
long m_valint;
//! Value for a float.
float m_valfloat;
//! Value
T m_value;
};

View File

@ -208,10 +208,15 @@ CBotInstr* CBotInstr::Compile(CBotToken* &p, CBotCStack* pStack)
case ID_THROW:
return CBotThrow::Compile(p, pStack);
case ID_BYTE:
case ID_SHORT:
case ID_CHAR:
case ID_INT:
case ID_LONG:
return CBotDefInt::Compile(p, pStack);
case ID_FLOAT:
case ID_DOUBLE:
return CBotDefFloat::Compile(p, pStack);
case ID_STRING:

View File

@ -151,7 +151,7 @@ CBotInstr* CBotParExpr::CompileLitExpr(CBotToken* &p, CBotCStack* pStack)
if (p->GetType() == TokenTypNum ||
p->GetType() == TokenTypDef )
{
CBotInstr* inst = CBotExprLitNum::Compile(p, pStk);
CBotInstr* inst = CBot::CompileExprLitNum(p, pStk);
return pStack->Return(inst, pStk);
}

View File

@ -399,7 +399,10 @@ bool CBotTwoOpExpr::Execute(CBotStack* &pStack)
TypeRes = CBotTypBoolean;
break;
case ID_DIV:
TypeRes = std::max(TypeRes, static_cast<int>(CBotTypFloat));
if (TypeRes == CBotTypFloat)
{
if (type1.Eq(CBotTypLong) || type2.Eq(CBotTypLong)) TypeRes = CBotTypDouble;
}
}
// creates a variable for the result

View File

@ -833,10 +833,28 @@ bool CBotVar::RestoreState(std::istream &istr, CBotVar* &pVar)
switch (w)
{
case CBotTypBoolean:
char valBool;
if (!ReadByte(istr, valBool)) return false;
pNew = CBotVar::Create(token, w); // creates a variable
pNew->SetValInt(valBool);
break;
case CBotTypByte:
char valByte;
if (!ReadByte(istr, valByte)) return false;
pNew = CBotVar::Create(token, w); // creates a variable
pNew->SetValInt(valByte);
pNew->SetValByte(valByte);
break;
case CBotTypShort:
short valShort;
if (!ReadShort(istr, valShort)) return false;
pNew = CBotVar::Create(token, w); // creates a variable
pNew->SetValShort(valShort);
break;
case CBotTypChar:
uint32_t valChar;
if (!ReadUInt32(istr, valChar)) return false;
pNew = CBotVar::Create(token, w); // creates a variable
pNew->SetValChar(valChar);
break;
case CBotTypInt:
int valInt;
@ -844,12 +862,24 @@ bool CBotVar::RestoreState(std::istream &istr, CBotVar* &pVar)
pNew = CBotVar::Create(token, w); // creates a variable
pNew->SetValInt(valInt, defnum);
break;
case CBotTypLong:
long valLong;
if (!ReadLong(istr, valLong)) return false;
pNew = CBotVar::Create(token, w); // creates a variable
pNew->SetValInt(valLong);
break;
case CBotTypFloat:
float valFloat;
if (!ReadFloat(istr, valFloat)) return false;
pNew = CBotVar::Create(token, w); // creates a variable
pNew->SetValFloat(valFloat);
break;
case CBotTypDouble:
double valDouble;
if (!ReadDouble(istr, valDouble)) return false;
pNew = CBotVar::Create(token, w); // creates a variable
pNew->SetValDouble(valDouble);
break;
case CBotTypString:
{
std::string valString;

View File

@ -71,6 +71,11 @@ static const boost::bimap<TokenId, std::string> KEYWORDS = makeBimap<TokenId, st
{ID_STRING, "string"},
{ID_VOID, "void"},
{ID_BOOL, "bool"},
{ID_BYTE, "byte"},
{ID_SHORT, "short"},
{ID_CHAR, "char"},
{ID_LONG, "long"},
{ID_DOUBLE, "double"},
{ID_TRUE, "true"},
{ID_FALSE, "false"},
{ID_NULL, "null"},

View File

@ -185,8 +185,13 @@ std::string CBotTypResult::ToString()
switch (m_type)
{
case CBotTypVoid: return "void";
case CBotTypByte: return "byte";
case CBotTypShort: return "short";
case CBotTypChar: return "char";
case CBotTypInt: return "int";
case CBotTypLong: return "long";
case CBotTypFloat: return "float";
case CBotTypDouble: return "double";
case CBotTypBoolean: return "bool";
case CBotTypString: return "string";
case CBotTypArrayPointer: return m_next->ToString() + "[]";

View File

@ -62,12 +62,27 @@ CBotTypResult TypeParam(CBotToken* &p, CBotCStack* pile)
switch (p->GetType())
{
case ID_BYTE:
p = p->GetNext();
return ArrayType(p, pile, CBotTypResult( CBotTypByte ));
case ID_SHORT:
p = p->GetNext();
return ArrayType(p, pile, CBotTypResult( CBotTypShort ));
case ID_CHAR:
p = p->GetNext();
return ArrayType(p, pile, CBotTypResult( CBotTypChar ));
case ID_INT:
p = p->GetNext();
return ArrayType(p, pile, CBotTypResult( CBotTypInt ));
case ID_LONG:
p = p->GetNext();
return ArrayType(p, pile, CBotTypResult( CBotTypLong ));
case ID_FLOAT:
p = p->GetNext();
return ArrayType(p, pile, CBotTypResult( CBotTypFloat ));
case ID_DOUBLE:
p = p->GetNext();
return ArrayType(p, pile, CBotTypResult( CBotTypDouble ));
case ID_BOOLEAN:
case ID_BOOL:
p = p->GetNext();
@ -144,7 +159,7 @@ long GetNumInt(const std::string& str)
}
////////////////////////////////////////////////////////////////////////////////
float GetNumFloat(const std::string& str)
double GetNumFloat(const std::string& str)
{
const char* p = str.c_str();
double num = 0;
@ -201,7 +216,7 @@ float GetNumFloat(const std::string& str)
}
if (bNeg) num = -num;
return static_cast<float>(num);
return num;
}
bool CharInList(const char c, const char* list)

View File

@ -71,7 +71,7 @@ long GetNumInt(const std::string& str);
* \param str
* \return
*/
float GetNumFloat(const std::string& str);
double GetNumFloat(const std::string& str);
/*!
* \brief Search a null-terminated string for a char value.

View File

@ -24,12 +24,17 @@
#include "CBot/CBotInstr/CBotInstr.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/CBotVarByte.h"
#include "CBot/CBotVar/CBotVarChar.h"
#include "CBot/CBotVar/CBotVarClass.h"
#include "CBot/CBotVar/CBotVarDouble.h"
#include "CBot/CBotVar/CBotVarFloat.h"
#include "CBot/CBotVar/CBotVarInt.h"
#include "CBot/CBotVar/CBotVarLong.h"
#include "CBot/CBotVar/CBotVarPointer.h"
#include "CBot/CBotVar/CBotVarShort.h"
#include "CBot/CBotVar/CBotVarString.h"
#include "CBot/CBotClass.h"
#include "CBot/CBotToken.h"
@ -160,11 +165,20 @@ CBotVar* CBotVar::Create(const CBotToken& name, CBotTypResult type)
{
switch (type.GetType())
{
case CBotTypByte:
return new CBotVarByte(name);
case CBotTypShort:
return new CBotVarShort(name);
case CBotTypChar:
return new CBotVarChar(name);
case CBotTypInt:
return new CBotVarInt(name);
case CBotTypLong:
return new CBotVarLong(name);
case CBotTypFloat:
return new CBotVarFloat(name);
case CBotTypDouble:
return new CBotVarDouble(name);
case CBotTypBoolean:
return new CBotVarBoolean(name);
case CBotTypString:
@ -223,11 +237,20 @@ CBotVar* CBotVar::Create(const std::string& n, CBotTypResult type)
switch (type.GetType())
{
case CBotTypByte:
return new CBotVarByte(name);
case CBotTypShort:
return new CBotVarShort(name);
case CBotTypChar:
return new CBotVarChar(name);
case CBotTypInt:
return new CBotVarInt(name);
case CBotTypLong:
return new CBotVarLong(name);
case CBotTypFloat:
return new CBotVarFloat(name);
case CBotTypDouble:
return new CBotVarDouble(name);
case CBotTypBoolean:
return new CBotVarBoolean(name);
case CBotTypString:
@ -472,12 +495,27 @@ void CBotVar::SetVal(CBotVar* var)
case CBotTypBoolean:
SetValInt(var->GetValInt());
break;
case CBotTypByte:
SetValByte(var->GetValByte());
break;
case CBotTypShort:
SetValShort(var->GetValShort());
break;
case CBotTypChar:
SetValChar(var->GetValChar());
break;
case CBotTypInt:
SetValInt(var->GetValInt(), (static_cast<CBotVarInt*>(var))->m_defnum);
break;
case CBotTypLong:
SetValLong(var->GetValLong());
break;
case CBotTypFloat:
SetValFloat(var->GetValFloat());
break;
case CBotTypDouble:
SetValDouble(var->GetValDouble());
break;
case CBotTypString:
SetValString(var->GetValString());
break;
@ -545,33 +583,84 @@ CBotVarClass* CBotVar::GetPointer()
// All these functions must be defined in the subclasses
// derived from class CBotVar
////////////////////////////////////////////////////////////////////////////////
signed char CBotVar::GetValByte()
{
assert(0);
return 0;
}
short CBotVar::GetValShort()
{
assert(0);
return 0;
}
uint32_t CBotVar::GetValChar()
{
assert(0);
return 0;
}
int CBotVar::GetValInt()
{
assert(0);
return 0;
}
////////////////////////////////////////////////////////////////////////////////
long CBotVar::GetValLong()
{
assert(0);
return 0;
}
float CBotVar::GetValFloat()
{
assert(0);
return 0;
}
////////////////////////////////////////////////////////////////////////////////
double CBotVar::GetValDouble()
{
assert(0);
return 0;
}
void CBotVar::SetValByte(signed char val)
{
assert(false);
}
void CBotVar::SetValShort(short val)
{
assert(false);
}
void CBotVar::SetValChar(uint32_t val)
{
assert(false);
}
void CBotVar::SetValInt(int c, const std::string& s)
{
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetValLong(long val)
{
assert(false);
}
void CBotVar::SetValFloat(float c)
{
assert(0);
}
////////////////////////////////////////////////////////////////////////////////
void CBotVar::SetValDouble(double val)
{
assert(false);
}
void CBotVar::Mul(CBotVar* left, CBotVar* right)
{
assert(0);
@ -757,16 +846,41 @@ CBotVar::operator bool()
return static_cast<bool>(GetValInt());
}
CBotVar::operator signed char()
{
return GetValByte();
}
CBotVar::operator short()
{
return GetValShort();
}
CBotVar::operator uint32_t()
{
return GetValChar();
}
CBotVar::operator int()
{
return GetValInt();
}
CBotVar::operator long()
{
return GetValLong();
}
CBotVar::operator float()
{
return GetValFloat();
}
CBotVar::operator double()
{
return GetValDouble();
}
CBotVar::operator std::string()
{
return GetValString();
@ -777,16 +891,41 @@ void CBotVar::operator=(const CBotVar &var)
SetVal(const_cast<CBotVar*>(&var));
}
void CBotVar::operator=(signed char x)
{
SetValByte(x);
}
void CBotVar::operator=(short x)
{
SetValShort(x);
}
void CBotVar::operator=(uint32_t x)
{
SetValChar(x);
}
void CBotVar::operator=(int x)
{
SetValInt(x);
}
void CBotVar::operator=(long x)
{
SetValLong(x);
}
void CBotVar::operator=(float x)
{
SetValFloat(x);
}
void CBotVar::operator=(double x)
{
SetValDouble(x);
}
void CBotVar::operator=(const std::string &x)
{
SetValString(x);

View File

@ -445,12 +445,22 @@ public:
//@{
operator bool();
operator signed char();
operator short();
operator uint32_t();
operator int();
operator long();
operator float();
operator double();
operator std::string();
void operator=(const CBotVar& var);
void operator=(signed char x);
void operator=(short x);
void operator=(uint32_t x);
void operator=(int x);
void operator=(long x);
void operator=(float x);
void operator=(double x);
void operator=(const std::string &x);
/**
@ -466,6 +476,12 @@ public:
*/
virtual void Copy(CBotVar* pSrc, bool bName = true);
virtual void SetValByte(signed char val);
virtual void SetValShort(short val);
virtual void SetValChar(uint32_t val);
/**
* \brief Set value as an integer
*
@ -476,30 +492,44 @@ public:
*/
virtual void SetValInt(int val, const std::string& name = "");
virtual void SetValLong(long val);
/**
* \brief Set value as float
* \param val New value
*/
virtual void SetValFloat(float val);
virtual void SetValDouble(double val);
/**
* \brief Set value as string
* \param val New value
*/
virtual void SetValString(const std::string& val);
virtual signed char GetValByte();
virtual short GetValShort();
virtual uint32_t GetValChar();
/**
* \brief Get value as integer
* \return Current value
*/
virtual int GetValInt();
virtual long GetValLong();
/**
* \brief Get value as float
* \return Current value
*/
virtual float GetValFloat();
virtual double GetValDouble();
/**
* \brief Get value as string
*

View File

@ -0,0 +1,46 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2018, 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
#include "CBot/CBotVar/CBotVarValue.h"
namespace CBot
{
/**
* \brief CBotVar subclass for managing 1-byte integer values (::CBotTypByte)
*/
class CBotVarByte : public CBotVarInteger<signed char, CBotTypByte>
{
public:
CBotVarByte(const CBotToken &name) : CBotVarInteger(name) {}
void SR(CBotVar* left, CBotVar* right) override
{
SetValByte(static_cast<unsigned char>(left->GetValByte()) >> right->GetValInt());
}
bool Save1State(std::ostream &ostr) override
{
return WriteByte(ostr, m_val);
}
};
} // namespace CBot

View File

@ -0,0 +1,59 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2018, 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
#include "CBot/CBotVar/CBotVarValue.h"
namespace CBot
{
/**
* \brief CBotVar subclass for managing 32-bit Unicode values (::CBotTypChar)
*/
class CBotVarChar : public CBotVarInteger<uint32_t, CBotTypChar>
{
public:
CBotVarChar(const CBotToken &name) : CBotVarInteger(name) {}
std::string GetValString() override
{
if (m_binit == CBotVar::InitType::UNDEF)
return LoadString(TX_UNDEF);
if (m_binit == CBotVar::InitType::IS_NAN)
return LoadString(TX_NAN);
if (0x10FFFF < m_val || (0xD7FF < m_val && m_val < 0xE000))
return "\xEF\xBF\xBD"; // replacement character U+FFFD
return CodePointToUTF8(m_val);
}
void SR(CBotVar* left, CBotVar* right) override
{
SetValChar(left->GetValChar() >> right->GetValInt());
}
bool Save1State(std::ostream &ostr) override
{
return WriteUInt32(ostr, m_val);
}
};
} // namespace CBot

View File

@ -0,0 +1,41 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2018, 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
#include "CBot/CBotVar/CBotVarValue.h"
namespace CBot
{
/**
* \brief CBotVar subclass for managing double values (::CBotTypDouble)
*/
class CBotVarDouble : public CBotVarNumber<double, CBotTypDouble>
{
public:
CBotVarDouble(const CBotToken &name) : CBotVarNumber(name) {}
bool Save1State(std::ostream &ostr) override
{
return WriteDouble(ostr, m_val);
}
};
} // namespace CBot

View File

@ -0,0 +1,46 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2018, 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
#include "CBot/CBotVar/CBotVarValue.h"
namespace CBot
{
/**
* \brief CBotVar subclass for managing long integer values (::CBotTypLong)
*/
class CBotVarLong : public CBotVarInteger<long, CBotTypLong>
{
public:
CBotVarLong(const CBotToken &name) : CBotVarInteger(name) {}
void SR(CBotVar* left, CBotVar* right) override
{
SetValLong(static_cast<unsigned long>(left->GetValLong()) >> right->GetValInt());
}
bool Save1State(std::ostream &ostr) override
{
return WriteLong(ostr, m_val);
}
};
} // namespace CBot

View File

@ -0,0 +1,46 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2018, 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
#include "CBot/CBotVar/CBotVarValue.h"
namespace CBot
{
/**
* \brief CBotVar subclass for managing short integer values (::CBotTypShort)
*/
class CBotVarShort : public CBotVarInteger<short, CBotTypShort>
{
public:
CBotVarShort(const CBotToken &name) : CBotVarInteger(name) {}
void SR(CBotVar* left, CBotVar* right) override
{
SetValShort(static_cast<unsigned short>(left->GetValShort()) >> right->GetValInt());
}
bool Save1State(std::ostream &ostr) override
{
return WriteShort(ostr, m_val);
}
};
} // namespace CBot

View File

@ -98,26 +98,75 @@ public:
this->m_val = static_cast<T>(0);
}
void SetValByte(signed char val) override
{
this->SetValue(static_cast<T>(val));
}
void SetValShort(short val) override
{
this->SetValue(static_cast<T>(val));
}
void SetValChar(uint32_t val) override
{
this->SetValue(static_cast<T>(val));
}
void SetValInt(int val, const std::string &s = "") override
{
this->SetValue(static_cast<T>(val));
}
void SetValLong(long val) override
{
this->SetValue(static_cast<T>(val));
}
void SetValFloat(float val) override
{
this->SetValue(static_cast<T>(val));
}
void SetValDouble(double val) override
{
this->SetValue(static_cast<T>(val));
}
signed char GetValByte() override
{
return static_cast<signed char>(this->m_val);
}
short GetValShort() override
{
return static_cast<short>(this->m_val);
}
uint32_t GetValChar() override
{
return static_cast<uint32_t>(this->m_val);
}
int GetValInt() override
{
return static_cast<int>(this->m_val);
}
long GetValLong() override
{
return static_cast<long>(this->m_val);
}
float GetValFloat() override
{
return static_cast<float>(this->m_val);
}
double GetValDouble() override
{
return static_cast<double>(this->m_val);
}
bool Eq(CBotVar* left, CBotVar* right) override
{

View File

@ -127,14 +127,19 @@ set(SOURCES
CBotVar/CBotVarArray.h
CBotVar/CBotVarBoolean.cpp
CBotVar/CBotVarBoolean.h
CBotVar/CBotVarByte.h
CBotVar/CBotVarChar.h
CBotVar/CBotVarClass.cpp
CBotVar/CBotVarClass.h
CBotVar/CBotVarDouble.h
CBotVar/CBotVarFloat.cpp
CBotVar/CBotVarFloat.h
CBotVar/CBotVarInt.cpp
CBotVar/CBotVarInt.h
CBotVar/CBotVarLong.h
CBotVar/CBotVarPointer.cpp
CBotVar/CBotVarPointer.h
CBotVar/CBotVarShort.h
CBotVar/CBotVarString.cpp
CBotVar/CBotVarString.h
stdlib/Compilation.cpp

View File

@ -236,8 +236,13 @@ std::string GetHelpFilename(const char *token)
if ( strcmp(token, "continue" ) == 0 ) helpfile = "cbot/continue";
if ( strcmp(token, "return" ) == 0 ) helpfile = "cbot/return";
if ( strcmp(token, "sizeof" ) == 0 ) helpfile = "cbot/sizeof";
if ( strcmp(token, "byte" ) == 0 ) helpfile = "cbot/byte";
if ( strcmp(token, "short" ) == 0 ) helpfile = "cbot/short";
if ( strcmp(token, "char" ) == 0 ) helpfile = "cbot/char";
if ( strcmp(token, "int" ) == 0 ) helpfile = "cbot/int";
if ( strcmp(token, "long" ) == 0 ) helpfile = "cbot/long";
if ( strcmp(token, "float" ) == 0 ) helpfile = "cbot/float";
if ( strcmp(token, "double" ) == 0 ) helpfile = "cbot/double";
if ( strcmp(token, "bool" ) == 0 ) helpfile = "cbot/bool";
if ( strcmp(token, "string" ) == 0 ) helpfile = "cbot/string";
if ( strcmp(token, "point" ) == 0 ) helpfile = "cbot/point";
@ -388,8 +393,13 @@ std::string GetHelpFilename(const char *token)
bool IsType(const char *token)
{
if ( strcmp(token, "void" ) == 0 ) return true;
if ( strcmp(token, "byte" ) == 0 ) return true;
if ( strcmp(token, "short" ) == 0 ) return true;
if ( strcmp(token, "char" ) == 0 ) return true;
if ( strcmp(token, "int" ) == 0 ) return true;
if ( strcmp(token, "long" ) == 0 ) return true;
if ( strcmp(token, "float" ) == 0 ) return true;
if ( strcmp(token, "double" ) == 0 ) return true;
if ( strcmp(token, "bool" ) == 0 ) return true;
if ( strcmp(token, "string" ) == 0 ) return true;
if ( strcmp(token, "point" ) == 0 ) return true;