parent
baba6081b3
commit
92a8c48953
|
@ -1745,6 +1745,9 @@ msgstr ""
|
||||||
msgid "Non-void function needs \"return;\""
|
msgid "Non-void function needs \"return;\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "This parameter needs a default value"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Dividing by zero"
|
msgid "Dividing by zero"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
3
po/de.po
3
po/de.po
|
@ -1522,6 +1522,9 @@ msgstr ""
|
||||||
msgid "This object is not a member of a class"
|
msgid "This object is not a member of a class"
|
||||||
msgstr "Das Objekt ist nicht eine Instanz einer Klasse"
|
msgstr "Das Objekt ist nicht eine Instanz einer Klasse"
|
||||||
|
|
||||||
|
msgid "This parameter needs a default value"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "This program is read-only, clone it to edit"
|
msgid "This program is read-only, clone it to edit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
3
po/fr.po
3
po/fr.po
|
@ -1494,6 +1494,9 @@ msgstr ""
|
||||||
msgid "This object is not a member of a class"
|
msgid "This object is not a member of a class"
|
||||||
msgstr "L'objet n'est pas une instance d'une classe"
|
msgstr "L'objet n'est pas une instance d'une classe"
|
||||||
|
|
||||||
|
msgid "This parameter needs a default value"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "This program is read-only, clone it to edit"
|
msgid "This program is read-only, clone it to edit"
|
||||||
msgstr "Ce programme est en lecture-seule, le dupliquer pour pouvoir l'éditer"
|
msgstr "Ce programme est en lecture-seule, le dupliquer pour pouvoir l'éditer"
|
||||||
|
|
||||||
|
|
3
po/pl.po
3
po/pl.po
|
@ -1496,6 +1496,9 @@ msgstr "Ten objekt jest obecnie zajęty"
|
||||||
msgid "This object is not a member of a class"
|
msgid "This object is not a member of a class"
|
||||||
msgstr "Ten obiekt nie jest członkiem klasy"
|
msgstr "Ten obiekt nie jest członkiem klasy"
|
||||||
|
|
||||||
|
msgid "This parameter needs a default value"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "This program is read-only, clone it to edit"
|
msgid "This program is read-only, clone it to edit"
|
||||||
msgstr "Ten program jest tylko do odczytu, skopiuj go, aby edytować"
|
msgstr "Ten program jest tylko do odczytu, skopiuj go, aby edytować"
|
||||||
|
|
||||||
|
|
3
po/ru.po
3
po/ru.po
|
@ -1510,6 +1510,9 @@ msgstr ""
|
||||||
msgid "This object is not a member of a class"
|
msgid "This object is not a member of a class"
|
||||||
msgstr "Этот объект не член класса"
|
msgstr "Этот объект не член класса"
|
||||||
|
|
||||||
|
msgid "This parameter needs a default value"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "This program is read-only, clone it to edit"
|
msgid "This program is read-only, clone it to edit"
|
||||||
msgstr "Эта программа только для чтения, для редактирования клонируйте её"
|
msgstr "Эта программа только для чтения, для редактирования клонируйте её"
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,9 @@
|
||||||
|
|
||||||
#include "CBot/CBotDefParam.h"
|
#include "CBot/CBotDefParam.h"
|
||||||
|
|
||||||
|
#include "CBot/CBotInstr/CBotInstrUtils.h"
|
||||||
|
#include "CBot/CBotInstr/CBotParExpr.h"
|
||||||
|
|
||||||
#include "CBot/CBotUtils.h"
|
#include "CBot/CBotUtils.h"
|
||||||
#include "CBot/CBotCStack.h"
|
#include "CBot/CBotCStack.h"
|
||||||
|
|
||||||
|
@ -33,11 +36,13 @@ namespace CBot
|
||||||
CBotDefParam::CBotDefParam()
|
CBotDefParam::CBotDefParam()
|
||||||
{
|
{
|
||||||
m_nIdent = 0;
|
m_nIdent = 0;
|
||||||
|
m_expr = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
CBotDefParam::~CBotDefParam()
|
CBotDefParam::~CBotDefParam()
|
||||||
{
|
{
|
||||||
|
delete m_expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -51,6 +56,7 @@ CBotDefParam* CBotDefParam::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||||
if (IsOfType(p, ID_OPENPAR))
|
if (IsOfType(p, ID_OPENPAR))
|
||||||
{
|
{
|
||||||
CBotDefParam* list = nullptr;
|
CBotDefParam* list = nullptr;
|
||||||
|
bool prevHasDefault = false;
|
||||||
|
|
||||||
if (!IsOfType(p, ID_CLOSEPAR)) while (true)
|
if (!IsOfType(p, ID_CLOSEPAR)) while (true)
|
||||||
{
|
{
|
||||||
|
@ -77,6 +83,26 @@ CBotDefParam* CBotDefParam::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsOfType(p, ID_ASS)) // default value assignment
|
||||||
|
{
|
||||||
|
CBotCStack* pStk = pStack->TokenStack(nullptr, true);
|
||||||
|
if (nullptr != (param->m_expr = CBotParExpr::CompileLitExpr(p, pStk)))
|
||||||
|
{
|
||||||
|
CBotTypResult valueType = pStk->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC);
|
||||||
|
|
||||||
|
if (!TypesCompatibles(type, valueType))
|
||||||
|
pStack->SetError(CBotErrBadType1, p->GetPrev());
|
||||||
|
|
||||||
|
prevHasDefault = true;
|
||||||
|
}
|
||||||
|
else pStack->SetError(CBotErrNoExpression, p);
|
||||||
|
delete pStk;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (prevHasDefault) pStack->SetError(CBotErrDefaultValue, p->GetPrev());
|
||||||
|
|
||||||
|
if (!pStack->IsOk()) break;
|
||||||
|
|
||||||
if ( type.Eq(CBotTypArrayPointer) ) type.SetType(CBotTypArrayBody);
|
if ( type.Eq(CBotTypArrayPointer) ) type.SetType(CBotTypArrayBody);
|
||||||
CBotVar* var = CBotVar::Create(pp->GetString(), type); // creates the variable
|
CBotVar* var = CBotVar::Create(pp->GetString(), type); // creates the variable
|
||||||
// if ( pClass ) var->SetClass(pClass);
|
// if ( pClass ) var->SetClass(pClass);
|
||||||
|
@ -109,40 +135,63 @@ bool CBotDefParam::Execute(CBotVar** ppVars, CBotStack* &pj)
|
||||||
assert(this != nullptr);
|
assert(this != nullptr);
|
||||||
CBotDefParam* p = this;
|
CBotDefParam* p = this;
|
||||||
|
|
||||||
|
bool useDefault = false;
|
||||||
|
|
||||||
while ( p != nullptr )
|
while ( p != nullptr )
|
||||||
{
|
{
|
||||||
// creates a local variable on the stack
|
// creates a local variable on the stack
|
||||||
CBotVar* newvar = CBotVar::Create(p->m_token.GetString(), p->m_type);
|
CBotVar* newvar = CBotVar::Create(p->m_token.GetString(), p->m_type);
|
||||||
|
|
||||||
|
CBotVar* pVar = nullptr;
|
||||||
|
CBotStack* pile = nullptr; // stack for default expression
|
||||||
|
|
||||||
|
if (useDefault || (ppVars == nullptr || ppVars[i] == nullptr))
|
||||||
|
{
|
||||||
|
assert(p->m_expr != nullptr);
|
||||||
|
|
||||||
|
pile = pj->AddStack();
|
||||||
|
useDefault = true;
|
||||||
|
|
||||||
|
while (pile->IsOk() && !p->m_expr->Execute(pile));
|
||||||
|
if (!pile->IsOk()) return pj->Return(pile); // return the error
|
||||||
|
|
||||||
|
pVar = pile->GetVar();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pVar = ppVars[i];
|
||||||
|
|
||||||
// serves to make the transformation of types:
|
// serves to make the transformation of types:
|
||||||
if ( ppVars != nullptr && ppVars[i] != nullptr )
|
if ((useDefault && pVar != nullptr) ||
|
||||||
|
(ppVars != nullptr && pVar != nullptr))
|
||||||
{
|
{
|
||||||
switch (p->m_type.GetType())
|
switch (p->m_type.GetType())
|
||||||
{
|
{
|
||||||
case CBotTypInt:
|
case CBotTypInt:
|
||||||
newvar->SetValInt(ppVars[i]->GetValInt());
|
newvar->SetValInt(pVar->GetValInt());
|
||||||
|
newvar->SetInit(pVar->GetInit()); // copy nan
|
||||||
break;
|
break;
|
||||||
case CBotTypFloat:
|
case CBotTypFloat:
|
||||||
newvar->SetValFloat(ppVars[i]->GetValFloat());
|
newvar->SetValFloat(pVar->GetValFloat());
|
||||||
|
newvar->SetInit(pVar->GetInit()); // copy nan
|
||||||
break;
|
break;
|
||||||
case CBotTypString:
|
case CBotTypString:
|
||||||
newvar->SetValString(ppVars[i]->GetValString());
|
newvar->SetValString(pVar->GetValString());
|
||||||
break;
|
break;
|
||||||
case CBotTypBoolean:
|
case CBotTypBoolean:
|
||||||
newvar->SetValInt(ppVars[i]->GetValInt());
|
newvar->SetValInt(pVar->GetValInt());
|
||||||
break;
|
break;
|
||||||
case CBotTypIntrinsic:
|
case CBotTypIntrinsic:
|
||||||
(static_cast<CBotVarClass*>(newvar))->Copy(ppVars[i], false);
|
(static_cast<CBotVarClass*>(newvar))->Copy(pVar, false);
|
||||||
break;
|
break;
|
||||||
case CBotTypPointer:
|
case CBotTypPointer:
|
||||||
{
|
{
|
||||||
newvar->SetPointer(ppVars[i]->GetPointer());
|
newvar->SetPointer(pVar->GetPointer());
|
||||||
newvar->SetType(p->m_type); // keep pointer type
|
newvar->SetType(p->m_type); // keep pointer type
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CBotTypArrayPointer:
|
case CBotTypArrayPointer:
|
||||||
{
|
{
|
||||||
newvar->SetPointer(ppVars[i]->GetPointer());
|
newvar->SetPointer(pVar->GetPointer());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -152,12 +201,19 @@ bool CBotDefParam::Execute(CBotVar** ppVars, CBotStack* &pj)
|
||||||
newvar->SetUniqNum(p->m_nIdent);
|
newvar->SetUniqNum(p->m_nIdent);
|
||||||
pj->AddVar(newvar); // add a variable
|
pj->AddVar(newvar); // add a variable
|
||||||
p = p->m_next;
|
p = p->m_next;
|
||||||
i++;
|
if (!useDefault) i++;
|
||||||
|
if (pile != nullptr) pile->Delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CBotDefParam::HasDefault()
|
||||||
|
{
|
||||||
|
return (m_expr != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void CBotDefParam::RestoreState(CBotStack* &pj, bool bMain)
|
void CBotDefParam::RestoreState(CBotStack* &pj, bool bMain)
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,6 +63,12 @@ public:
|
||||||
*/
|
*/
|
||||||
bool Execute(CBotVar** ppVars, CBotStack* &pj);
|
bool Execute(CBotVar** ppVars, CBotStack* &pj);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Check if this parameter has a default value expression.
|
||||||
|
* \return true if the parameter was compiled with a default value.
|
||||||
|
*/
|
||||||
|
bool HasDefault();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief RestoreState
|
* \brief RestoreState
|
||||||
* \param pj
|
* \param pj
|
||||||
|
@ -96,6 +102,9 @@ private:
|
||||||
//! Type of paramteter.
|
//! Type of paramteter.
|
||||||
CBotTypResult m_type;
|
CBotTypResult m_type;
|
||||||
long m_nIdent;
|
long m_nIdent;
|
||||||
|
|
||||||
|
//! Default value expression for the parameter.
|
||||||
|
CBotInstr* m_expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace CBot
|
} // namespace CBot
|
||||||
|
|
|
@ -240,6 +240,7 @@ enum CBotError : int
|
||||||
CBotErrFuncNotVoid = 5045, //!< function needs return type "void"
|
CBotErrFuncNotVoid = 5045, //!< function needs return type "void"
|
||||||
CBotErrNoClassName = 5046, //!< class name expected
|
CBotErrNoClassName = 5046, //!< class name expected
|
||||||
CBotErrNoReturn = 5047, //!< non-void function needs "return;"
|
CBotErrNoReturn = 5047, //!< non-void function needs "return;"
|
||||||
|
CBotErrDefaultValue = 5048, //!< this parameter needs a default value
|
||||||
|
|
||||||
// Runtime errors
|
// Runtime errors
|
||||||
CBotErrZeroDiv = 6000, //!< division by zero
|
CBotErrZeroDiv = 6000, //!< division by zero
|
||||||
|
|
|
@ -503,8 +503,13 @@ CBotFunction* CBotFunction::FindLocalOrPublic(const std::list<CBotFunction*>& lo
|
||||||
// parameters are compatible?
|
// parameters are compatible?
|
||||||
CBotDefParam* pv = pt->m_param; // expected list of parameters
|
CBotDefParam* pv = pt->m_param; // expected list of parameters
|
||||||
CBotVar* pw = ppVars[i++]; // provided list parameter
|
CBotVar* pw = ppVars[i++]; // provided list parameter
|
||||||
while ( pv != nullptr && pw != nullptr)
|
while ( pv != nullptr && (pw != nullptr || pv->HasDefault()) )
|
||||||
{
|
{
|
||||||
|
if (pw == nullptr) // end of arguments
|
||||||
|
{
|
||||||
|
pv = pv->GetNext();
|
||||||
|
continue; // skip params with default values
|
||||||
|
}
|
||||||
CBotTypResult paramType = pv->GetTypResult();
|
CBotTypResult paramType = pv->GetTypResult();
|
||||||
CBotTypResult argType = pw->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC);
|
CBotTypResult argType = pw->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC);
|
||||||
|
|
||||||
|
@ -561,8 +566,13 @@ CBotFunction* CBotFunction::FindLocalOrPublic(const std::list<CBotFunction*>& lo
|
||||||
// parameters sont-ils compatibles ?
|
// parameters sont-ils compatibles ?
|
||||||
CBotDefParam* pv = pt->m_param; // list of expected parameters
|
CBotDefParam* pv = pt->m_param; // list of expected parameters
|
||||||
CBotVar* pw = ppVars[i++]; // list of provided parameters
|
CBotVar* pw = ppVars[i++]; // list of provided parameters
|
||||||
while ( pv != nullptr && pw != nullptr)
|
while ( pv != nullptr && (pw != nullptr || pv->HasDefault()) )
|
||||||
{
|
{
|
||||||
|
if (pw == nullptr) // end of arguments
|
||||||
|
{
|
||||||
|
pv = pv->GetNext();
|
||||||
|
continue; // skip params with default values
|
||||||
|
}
|
||||||
CBotTypResult paramType = pv->GetTypResult();
|
CBotTypResult paramType = pv->GetTypResult();
|
||||||
CBotTypResult argType = pw->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC);
|
CBotTypResult argType = pw->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC);
|
||||||
|
|
||||||
|
@ -690,7 +700,14 @@ int CBotFunction::DoCall(CBotProgram* program, const std::list<CBotFunction*>& l
|
||||||
// initializes the variables as parameters
|
// initializes the variables as parameters
|
||||||
if (pt->m_param != nullptr)
|
if (pt->m_param != nullptr)
|
||||||
{
|
{
|
||||||
pt->m_param->Execute(ppVars, pStk3); // cannot be interrupted
|
if (!pt->m_param->Execute(ppVars, pStk3)) // interupts only if error on a default value
|
||||||
|
{
|
||||||
|
if ( pt->m_pProg != program )
|
||||||
|
{
|
||||||
|
pStk3->SetPosError(pToken); // indicates the error on the procedure call
|
||||||
|
}
|
||||||
|
return pStack->Return(pStk3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pStk1->IncState();
|
pStk1->IncState();
|
||||||
|
@ -812,7 +829,14 @@ int CBotFunction::DoCall(const std::list<CBotFunction*>& localFunctionList, long
|
||||||
// initializes the variables as parameters
|
// initializes the variables as parameters
|
||||||
if (pt->m_param != nullptr)
|
if (pt->m_param != nullptr)
|
||||||
{
|
{
|
||||||
pt->m_param->Execute(ppVars, pStk3); // cannot be interrupted
|
if (!pt->m_param->Execute(ppVars, pStk3)) // interupts only if error on a default value
|
||||||
|
{
|
||||||
|
if ( pt->m_pProg != pProgCurrent )
|
||||||
|
{
|
||||||
|
pStk3->SetPosError(pToken); // indicates the error on the procedure call
|
||||||
|
}
|
||||||
|
return pStack->Return(pStk3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pStk->IncState();
|
pStk->IncState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,7 +200,7 @@ bool CBotNew::Execute(CBotStack* &pj)
|
||||||
}
|
}
|
||||||
ppVars[i] = nullptr;
|
ppVars[i] = nullptr;
|
||||||
|
|
||||||
if ( !pClass->ExecuteMethode(m_nMethodeIdent, pThis, ppVars, CBotTypResult(CBotTypVoid), pile2, GetToken())) return false; // interrupt
|
if ( !pClass->ExecuteMethode(m_nMethodeIdent, pThis, ppVars, CBotTypResult(CBotTypVoid), pile2, &m_vartoken)) return false; // interrupt
|
||||||
|
|
||||||
pThis->ConstructorSet(); // indicates that the constructor has been called
|
pThis->ConstructorSet(); // indicates that the constructor has been called
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,16 @@ CBotInstr* CBotParExpr::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||||
return pStack->Return(nullptr, pStk);
|
return pStack->Return(nullptr, pStk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return CompileLitExpr(p, pStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
CBotInstr* CBotParExpr::CompileLitExpr(CBotToken* &p, CBotCStack* pStack)
|
||||||
|
{
|
||||||
|
CBotCStack* pStk = pStack->TokenStack();
|
||||||
|
|
||||||
|
CBotToken* pp = p;
|
||||||
|
|
||||||
// is it a number or DefineNum?
|
// is it a number or DefineNum?
|
||||||
if (p->GetType() == TokenTypNum ||
|
if (p->GetType() == TokenTypNum ||
|
||||||
p->GetType() == TokenTypDef )
|
p->GetType() == TokenTypDef )
|
||||||
|
|
|
@ -54,6 +54,14 @@ public:
|
||||||
*/
|
*/
|
||||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Compile a literal expression ("string", number, true, false, null, nan, new)
|
||||||
|
* \param p[in, out] Pointer to first token of the expression, will be updated to point to first token after the expression
|
||||||
|
* \param pStack Current compilation stack frame
|
||||||
|
* \return The compiled instruction or nullptr on error
|
||||||
|
*/
|
||||||
|
static CBotInstr* CompileLitExpr(CBotToken* &p, CBotCStack* pStack);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CBotParExpr() = delete;
|
CBotParExpr() = delete;
|
||||||
CBotParExpr(const CBotParExpr&) = delete;
|
CBotParExpr(const CBotParExpr&) = delete;
|
||||||
|
|
|
@ -722,6 +722,7 @@ void InitializeRestext()
|
||||||
stringsCbot[CBot::CBotErrFuncNotVoid] = TR("Function needs return type \"void\"");
|
stringsCbot[CBot::CBotErrFuncNotVoid] = TR("Function needs return type \"void\"");
|
||||||
stringsCbot[CBot::CBotErrNoClassName] = TR("Class name expected");
|
stringsCbot[CBot::CBotErrNoClassName] = TR("Class name expected");
|
||||||
stringsCbot[CBot::CBotErrNoReturn] = TR("Non-void function needs \"return;\"");
|
stringsCbot[CBot::CBotErrNoReturn] = TR("Non-void function needs \"return;\"");
|
||||||
|
stringsCbot[CBot::CBotErrDefaultValue] = TR("This parameter needs a default value");
|
||||||
|
|
||||||
stringsCbot[CBot::CBotErrZeroDiv] = TR("Dividing by zero");
|
stringsCbot[CBot::CBotErrZeroDiv] = TR("Dividing by zero");
|
||||||
stringsCbot[CBot::CBotErrNotInit] = TR("Variable not initialized");
|
stringsCbot[CBot::CBotErrNotInit] = TR("Variable not initialized");
|
||||||
|
|
|
@ -1594,11 +1594,12 @@ TEST_F(CBotUT, StringFunctions)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CBotUT, DISABLED_TestNANParam_Issue642)
|
TEST_F(CBotUT, TestNANParam_Issue642)
|
||||||
{
|
{
|
||||||
ExecuteTest(
|
ExecuteTest(
|
||||||
"float test(float x) {\n"
|
"float test(float x) {\n"
|
||||||
" return x;\n"
|
" ASSERT(x == nan);\n"
|
||||||
|
" return x;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"extern void TestNANParam() {\n"
|
"extern void TestNANParam() {\n"
|
||||||
" ASSERT(nan == nan);\n" // TODO: Shouldn't it be nan != nan ??
|
" ASSERT(nan == nan);\n" // TODO: Shouldn't it be nan != nan ??
|
||||||
|
@ -2308,3 +2309,80 @@ TEST_F(CBotUT, IncrementDecrementSyntax)
|
||||||
CBotErrBadType1
|
CBotErrBadType1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CBotUT, ParametersWithDefaultValues)
|
||||||
|
{
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void ParametersWithDefaultValues() {\n"
|
||||||
|
" ASSERT(true == Test());\n"
|
||||||
|
" ASSERT(true == Test(1));\n"
|
||||||
|
" ASSERT(true == Test(1, 2));\n"
|
||||||
|
"}\n"
|
||||||
|
"bool Test(int i = 1, float f = 2.0) {\n"
|
||||||
|
" return (i == 1) && (f == 2.0);\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void NotUsingDefaultValues() {\n"
|
||||||
|
" ASSERT(true == Test(2, 4.0));\n"
|
||||||
|
"}\n"
|
||||||
|
"bool Test(int i = 1, float f = 2.0) {\n"
|
||||||
|
" return (i == 2) && (f == 4.0);\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void NextParamNeedsDefaultValue() {\n"
|
||||||
|
"}\n"
|
||||||
|
"void Test(int i = 1, float f) {}\n"
|
||||||
|
"\n",
|
||||||
|
CBotErrDefaultValue
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void ParamMissingExpression() {\n"
|
||||||
|
"}\n"
|
||||||
|
"void Test(int i = 1, float f = ) {}\n"
|
||||||
|
"\n",
|
||||||
|
CBotErrNoExpression
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void ParamDefaultBadType() {\n"
|
||||||
|
"}\n"
|
||||||
|
"void Test(int i = 1, float f = null) {}\n"
|
||||||
|
"\n",
|
||||||
|
CBotErrBadType1
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void DefaultValuesAmbiguousCall() {\n"
|
||||||
|
" Test();\n"
|
||||||
|
"}\n"
|
||||||
|
"void Test(int i = 1) {}\n"
|
||||||
|
"void Test(float f = 2.0) {}\n"
|
||||||
|
"\n",
|
||||||
|
CBotErrAmbiguousCall
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void AmbiguousCallOneDefault() {\n"
|
||||||
|
" Test(1);\n"
|
||||||
|
"}\n"
|
||||||
|
"void Test(int i, float f = 2) {}\n"
|
||||||
|
"void Test(int i) {}\n"
|
||||||
|
"\n",
|
||||||
|
CBotErrAmbiguousCall
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void DifferentNumberOfDefaultValues() {\n"
|
||||||
|
" Test(1, 2.0);\n"
|
||||||
|
"}\n"
|
||||||
|
"void Test(int i, float f = 2.0) {}\n"
|
||||||
|
"void Test(int i, float f = 2.0, int ii = 1) {}\n"
|
||||||
|
"\n",
|
||||||
|
CBotErrAmbiguousCall
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue